文档章节

GIS地图开发编码原理

睡得
 睡得
发布于 2015/07/27 14:43
字数 3152
阅读 100
收藏 2

 

转自:http://blog.3snews.net/space.phpuid=13931537&do=blog&id=230677

 

GIS(地图)编码开发部分

注:FreeMicaps是我写的一套气象数据分析软件,从底层实现了一套小型地图引擎,对GIS开发人员也有一定参考价值。软件从这里下载:http://www.forbst.com本文观点由上海为卓信息科技有限公司提供技术支持。

FreeMicaps为一套气象数据分析系统,需要从面上来展示气象数据的分布情况,以地图方式进行快速数据浏览和检索可以极大地提高工作效率。从界面上看,它包含一个可以缩放平移的地图,具有图层方式管理功能,可以做地图投影变换,包含缩略图等,很像一套GIS系统,所以天气图分析软件最好能基于GIS系统做。对FreeMicaps的讲解也从GIS系统讲起。

GIS系统很适合做气象数据分析系统,很多朋友都利用一些开源或商业GIS系统进行二次开发来做气象数据分析软件。但因为气象数据分析有很多它独有的特点,很多必须的功能用无法用通用的GIS系统完成,并且还会因版权原因,难以进行推广应用。由于气象数据分析仅需GIS的绘图部分,自己实现并不是很复杂,因此FreeMicaps就从底层实现了一套简单GIS系统(严格来说,它还算不上GIS,只能算简单地计算机地图制图),在此基础上做天气图分析功能。

一、 地图是怎么做出来的

首先说一下地图是怎么出来的,可能你感觉是废话,但实际上很多人并不知道如何下手。我觉得这里需要先给你个思路准备:地图就是使用绘图语句画出来的!

从底层绘制地图,能使用的就是绘图函数,在.NET里,就是用Graphics类的方法,在窗口中绘制点、线、面、标准、栅格等,组合起来,就是一张地图(瓦片图方式除外)。

关于.NET的绘图,本文不进行讲解,如果你还还不熟悉,建议你先看看这方面资料。

二、 坐标转换-地图绘制的关键

.NET提供了大量绘图方法,基本上都是以Graphics类的函数形式提供,包括各类几何形状、图像、文字的绘制,灵活运用这些方法,就可以画出精美的图出来。假设你已熟悉.NET的绘图,这样就只有有一个问题要解决:图我会画了,但拿到地图元素一般为地理坐标(经纬度),应该画在地图上什么位置?这就需要涉及到坐标转换问题。

先不考虑怎么实现,首先需要这么一个函数:

/// <summary>

/// 经纬度转换为屏幕坐标

/// </summary>

/// <param name="xy">经纬度</param>

/// <returns>屏幕坐标</returns>

public Point WorldToScreen(PointF xy)

再一个,有时,还需要根据屏幕上点位置反算出它的经纬度,如在需要显示鼠标指针处的经纬度,所以还需要这么一个函数:

/// <summary>

/// 屏幕坐标转换为经纬度

/// </summary>

/// <param name="xy">屏幕坐标</param>

/// <returns>经纬度</returns>

public PointF ScreenToWorld(Point xy)

有了这两个函数,就可以将以经纬度表示的地理坐标转换为屏幕坐标,然后再屏幕绘图了。

为了完成坐标转换,需要使用几个地图参数的变量:地图缩放倍数、地图中心点经纬度、地图大小,关于地图参数,可参考这篇文章:

http://hi.baidu.com/geochenyj/blog/item/6b5c5c1294057557f819b835.html

另外,还需要对地图进行缩放、平移,这些操作实质上也是对地图参数的操作,如放大就是对地图缩放倍数操作,平移就是对地图中心点进行操作,我们将这些操作也写Coordinator类的方法。投影变换也作为坐标转换的一部分,Coordinator类还增加了投影方面方法,这个后面再讲。

将上面两个坐标转换函数和三个地图参数封装为一个类Coordinator。,的类如下所示:

三、 绘图

有了坐标转换类Coordinator,就可以用经纬度数据来绘图了,如拿到某省的行政边界经纬度坐标数据,就可以将经纬度数据转换为屏幕坐标,然后用Graphics的方法来画出来了,Graphics对象又从哪里来呢?可以从一个Image对象创建,也可以从一个控件的Paint事件中取得,总之,有了坐标,发挥你的想象力,自己画吧。

在气象数据分析中,除了要绘制点、线、面、文字、栅格外,还需要绘制一些特殊符号,如风、天气现象、云等。这些符号,可以用图片、天气字库、符号库来实现,图片方式实现简单,色彩丰富,但缩放效果不好;字库方式,需要安装字库,程序部署比较麻烦;符号库方式代码编写较麻烦。FreeMicaps的天气现象符号采用符号库方式,祥见: http://blog.csdn.net/HZGJF/archive/2009/05/27/4220508.aspx

风符号和云量符号采用计算坐标绘制方式。

为了使用方便,FreeMicaps把符号绘制功能封装到三个符号类中,以静态方法提供。

.NET的绘图是对GDI+的封装,包括了对点、线、面等各种图形元素的封装,图形图像的绘制、坐标旋转,各种反走样和平滑等功能,功能十分强大(当然,效率不太高),利用它可以绘出漂亮的图形。

根据OGC标准,GIS系统首先需要对地图元素进行抽象和封装,但FreeMicaps中,经再三考虑,放弃了这种方式,一个是因为工作量比较大,另一个是因为我不敢保证能很好地进行封装,可能给插件开发带来麻烦,不如把绘图权完全交给图层,大家自由发挥。

四、 图层

为了使绘图过程便于管理,可将绘图过程分为组,如可以将一张地图的绘制分为:绘制世界地图、绘制中国地图、绘制河流、填地名几个过程,每次绘图好像就是在一张玻璃上绘制,叠加起来就形成了一张地图图,这里把每次绘图过程形象地称为一个图层。地图分层后,图层可以增删,每个图层可以单独进行隐藏、设置属性等,更重要的是可以将利用面向对象技术把每个图层当做一个对象进行管理。详细介绍见:http://blog.csdn.net/HZGJF/archive/2008/10/03/3014558.aspx

对图层进行抽象,它应该有一个图层绘制方法(Render),一个图层标题(LayerName),一个用于表示数据源的字符串(DataSource),一个用于表示绘图样式的设置的LayerStyle,加上一些辅助方法属性,最终形成如下抽象图层类(CustomLayer),各种图层均从它继承:

FreeMicaps中,每种数据对应一种图层类,为了使图层类编写方便,使用了设计模式中的模板方法,定义绘制流程,主程序在调用图层的Render()方法时,会自动判断是否已经读入数据,根据需要读数据绘图。

对于一种类型数据,需要从CustomLayer继承新建一个图层类。各种类型数据图层的工作方式完全一样,仅在数据读取和绘制方面不同,所以,写新图层类时,仅需实现DoLoad()DoRender()两个抽象方法,完成读取数据和绘制图层代码即可。FreeMicaps里使用了字符串作为数据源标识,通用GIS系统对数据源进行了抽象,我也尝试这么做,但代码过于复杂,增加图层开发难度,最终增大插件开发难度,所以放弃了。

前面说了,一张地图有多个图层,所以还需要将图层放入一个列表,绘制地图时遍历图层,调用每个图层的Render()方法,画出一张完整的地图。对于图层列表,大家马上会想到使用List类,但图层绘制是需要有顺序的,如在卫星云图上面叠加地名,需要先画卫星云图,再填地名,否则云图会把地名盖住,所以在图层的样式(LayerStyle)中放了一个ZOrder属性,通过它来控制图层顺序。但由于List本身的排序方法是一种“非稳固排序”,也就是说当两个图层的ZOrder相等时,它们的顺序是不确定的,为了避免这个问题,FreeMicapsCollectionBase继承了一个类LayerList,实现对图层的管理,并实现了IXmlSerializable接口,完成图层序列化功能。另外,还增加了添加图层、删除图层事件。LayerList类如下:

五、 封装地图

有了坐标转换类、图层类、图层列表类,就可以利用它们做出一个具有缩放平移、图层管理等功能的地图了,但为了更方便地对地图进行操作,还需要对这些类进行组合封装。新建一个类WeatherMap,添加CoordinatorLayerList类的实例作为它的属性,为了更符合大家操作习惯,将Coordinator类的实例作为私有成员,将地图坐标转换等方法加入WeatherMap类,也就是说地图坐标转换中,不访问Coordinator,而要调用WeatherMap类的方法。类图如下:

再回到抽象图层类CustomLayer,它有一个成员Map,即为WeatherMap对象,在将图层加入图层列表时会自动赋值。在编写CustomLayer的子类时,可调用它来进行坐标转换和地图操作。

为了使地图在绘制复杂图形过程中不至于假死,并在绘图过程中能随时中断绘图,如快速缩放平移地图中可终止前次绘图过程直接绘制最后一次,地图绘制使用了多线程,但多线程增加了代码编写难度,特别是多线程操作UI,对程序流程造成了一定混乱,程序结构受到影响,所幸并不会对图层代码造成困难。

六、 再次封装-增加UI

上面已完成了地图绘制的核心代码,为了使代码编写更加容易,需要对WeatherMap类再次进行封装(MapView),加入UI部分,即给地图加一个具有界面的壳,并在上面实现地图的操作如缩放、拖动功能。

MapViewPictureBox类继承,内建了WeatherMap类的实例,在MapViewRefresh()方法中调用WeatherMap.Render()对地图进行绘制。

为了完成对地图的操作,FreeMicaps定义一个IMapTool接口,包含了鼠标和键盘操作方法,MapView类内建一个IMapTool接口成员,MapView的鼠标和键盘操作,将被IMapTool接口的实例接管,在实现IMapTool接口的类中,可对地图做各种操作,如平移、缩放等操作,这个对象可随时替换以实现不同方式的地图操作。在FreeMicaps中,已完成一个实现IMapTool接口的类ZoomTool,此类为默认的地图缩放和平移工具。IMapTool接口类图如下:

另外,在MapView中,还引入了一个当前图层的概念CurrentLayer,用它来表示当前操作的图层,后面用它来实现图层元素拾取、图层工具条等功能。

MapView类图如下:

七、 总览

地图部分类关系图如下:

地图绘制部分活动图如下:

以上已经介绍完FreeMicaps地图部分设计框架,相信大家的已对设计思路已有一定了解,此框架不仅适用于天气图分析软件,也适用于一般的GIS系统。本文仅对FreeMicaps的地图部分框架进行了介绍,未涉及到具体的地图数据读取及绘制,这些将在下一篇文章中介绍。

本文转载自:http://blog.3snews.net/space.php?uid=13931537&do=blog&id=230677

睡得
粉丝 2
博文 21
码字总数 24036
作品 0
徐汇
私信 提问
Web开发系列 - GIS

Google Maps JQuery Maps google map是怎样工作的 Google Maps API编程资源大全 google map限制地图缩放级别和显示范围 WebGIS近来学习小结,GoogleMap影像在线矢量化简述 google map v3 ap...

长征2号
2017/08/09
0
0
《web GIS技术原理与应用开发》笔记

实现web GIS的基本方法 基于CGI方式 基于plug-in方式 基于ActiveX方式 基于Java Applet方式 基于“切片”方式 OGC的几个开放式GIS服务标准 WMS(操作:GetCapabilities,GetMap,GetFeatureI...

tkorays
2013/07/14
479
0
地图行业竞争如此巨大,改何去何从?

室内GIS开发将大放异彩 本人从事GIS领域已经5年了,这几年随着移动智能终端的迅速发展。地图行业更是日新月异,随着公共地图几大厂商的兴起,像百度,高德,腾讯,等几大地图研发公司稳稳占据...

谁把酒打翻
2014/07/23
51
0
GIS专业书籍、文档、数据、网站、工具等干货

整理、分享一些个人整理的GIS专业书籍、文档、数据、网站、工具等。也希望大家将自己的心得也分享出来,一起交流,共同进步。 如果下载链接失效,请到这里去:地信网 一、原理应用类 GIS基础...

gisweis
2015/02/27
0
0
Web GIS与OGC Web服务规范

随着计算机技术、网络技术、数据库技术的不断发展,GIS的发展呈现新的特点和趋势。Web GIS是一个交互式的、分布式的、动态的地理信息系统,而XML技术与web服务技术的成熟为数据的共享和功能的...

tkorays
2013/07/14
3.6K
2

没有更多内容

加载失败,请刷新页面

加载更多

如何使用soapUI模拟webservice客户端发送请求

参考资料 https://jingyan.baidu.com/article/cbcede0712849a02f40b4d88.html 左边是请求参数,可以自己填写!按着那个绿色三角箭头可以模拟发送请求,右边是返回的报文 soapui如何发送xml格...

故久呵呵
14分钟前
2
0
Java Security 介绍

1.介绍 Java平台设计的重点是安全性。在其核心,java语言本身是类型安全的并且提供了垃圾自动回收,这使其增加了应用程序代码的健壮性。安全的类加载以及验证机制确保了只有合法的代码才能够...

lixiaobao
20分钟前
3
0
Niushop开源商城系统-分销商管理

分销商管理 1.分销员的招募与管理 如何申请成为分销员? 在wap端个人中心满足之前设置的升级条件,可以申请分销员 开启分销商审核,需要在后台分销商管理——》待审核处进行审核通过。 通过完...

niushop-芳
21分钟前
1
0
为什么大公司一定要使用 DevOps?

究竟什么是DevOps? 要想回答这个问题,首先要明确DevOps这个过程参与的人员是谁,即开发团队和IT运维团队。那么,DevOps的意图是什么呢?即在两个团队之间,建立良好的沟通和协作,更快更可靠...

cs平台
23分钟前
2
0
高危预警|RDP漏洞或引发大规模蠕虫爆发,用户可用阿里云免费检测服务自检,建议尽快修复

2019年9月6日,阿里云应急响应中心监测到Metasploit-framework官方在GitHub空间公开了针对Windows远程桌面服务远程命令执行漏洞(CVE-2019-0708)的利用代码。利用该代码,无需用户交互操作,即...

Mr_zebra
28分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部