一种低成本的离线地图GIS解决方案
2019-12-06朱森光
摘 要: 在GIS应用中,许多现有的商业GIS方案需要联网在线访问地图数据,如果网络状况不佳可能会访问延迟甚至失败,影响用户使用体验。本文使用C++编程技术实现了一种低成本的不依赖于网络的离线地图GIS解决方案。
关键词: GIS;WebGIS;离线地图;在线地图
中图分类号: TP302.1 文献标识码: A DOI:10.3969/j.issn.1003-6970.2019.10.032
本文著录格式:朱森光. 一种低成本的离线地图GIS解决方案[J]. 软件,2019,40(10):142146
A Low-cost Offline Map GIS Solution
ZHU Sen-guang
(Shanghai Yazhu Intelligent Technology Co., Ltd., Shanghai 201100, China)
【Abstract】: In GIS applications, many existing commercial GIS solutions require online access to map data. If the network is not in good condition, the access delay or even failure may affect the user experience. This paper uses C++ programming technology to implement a low-cost offline map GIS solution.
【Key words】: GIS; WebGIS; Offline map; Online map
0 引言
越来越越多的项目需要使用GIS地图功能[1-6],商业GIS地图软件功能繁多、复杂度高,核心功能模块封装成库,对外只提供二次开发接口,编程灵活度不高,价格也较贵,普通用户承受不起。本文研究实现了一种低成本的离线地图GIS方案,可在某些预算较少的项目中使用。
1 原理
我们平常看到的地图都是平面地图,而地球是个球体,这就需要一种将球体表面曲面映射成二维平面的方法,比较常用的映射方法是墨卡托投影法[7]。
墨卡托投影算法有好幾个变种,各GIS地图厂家使用自己的变种算法,本文的方案由于要用到开放地图openstreetmap网站的地图瓦片资源,所以使用openstreetmap的投影算法进行描述,设lon为经度,lat为纬度,z为地图放大层级,(x,y)为平面地图的像素坐标,则有:
(1)
(2)
这里解释一下地图放大层级z这个参数,当我们浏览平面地图时通过鼠标滚轮上下滚动可以缩放地图,当地图缩小时z就减小,当地图放大时z就增大。图1示意了当z=1时的世界地图。
从图1中可以看到,当z=1时,世界地图被分成了4小块,每小块小地图为256*256像素大小称之为一个瓦片,每个瓦片的坐标用列col和行row来表示,z=1时4个瓦片小地图拼成了一幅世界地图,地图在硬盘上就是以这4个瓦片小图片的形式存储的。
图2为z=5时的中国中部地区地图,可以看到此时地图上的西安市所在的瓦片坐标为列col=25,行row=12,瓦片个数已经远远大于4了,z越大组成地图的瓦片个数就越多,地图分辨率也越高。
2 软件实现
2.1 地图拼接显示
既然是离线GIS地图方案那么首先要把地图从网络下载到本地硬盘,可以从开放地图openstreet map网站下载。离线GIS地图是以瓦片小图片形式存储在本地硬盘的,图3为瓦片小图片在文件管理器里的浏览视图,每个瓦片小图片大小为256*256像素,以png图像格式存储。
将这些瓦片拼接在一起就形成了一幅完整的地图,软件显示地图时,首先根据当前分辨率计算出对应的放大层级z,然后根据地图显示区域计算出所需的一系列瓦片的行号和列号,最后将这些瓦片在内存中拼接成完整的地图在界面上显示。图4为地图在软件界面上显示的效果图。
需要指出的是本文使用的地图拼接方法跟目前流行的WebGIS[8]有所不同。WebGIS使用HTML5[9]的canvas画布技术,使用javascrip脚本来完成地图拼接显示,本文是用C++编程技术实现的,C++的编译后运行比脚本语言的解释运行效率要高很多,本地硬盘访问瓦片数据也比WebGIS通过网络在线访问服务器上的瓦片数据要快。
2.2 缩放平移
2.2.1 缩放
在图4所示的软件界面中,鼠标点击“放大”按钮,地图放大层级z增大,地图分辨率提高,点击“缩小”按钮,地图放大层级z减小,地图分辨率降低。z变化后拼接地图的瓦片列col,行row也相应变化,软件到硬盘上读取新的瓦片小图片重新拼接后在界面上显示即可。放大缩小也可以通过鼠标滚轮上下滚动来触发,滚轮上滚地图放大,滚轮下滚地图缩小。
图5为将图4的地图放大后的地图效果图。
图6为将图4的地图缩小后的地图效果图。
2.2.2 平移
通过鼠标点击拖拽可以实现平移,平移不会改变放大层级z,但平移后界面视野内的地图内容发生了变化,也就是视野内组成地图的瓦片列col,行row发生了变化,软件到硬盘上读取新的瓦片小图片重新拼接后在界面上显示就实现了平移效果。
图7为对图4的地图进行平移后的地图效果图,可以看到地图上黄浦江的位置往右明显平移了。
2.3 坐标计算
2.3.1 根据经纬度坐标计算地图像素坐标
GIS地图一个常用的功能就是根据经纬度坐标计算地图上的位置,这是通过式(1)、式(2)来计算的。为了验证此功能,事先通过GPS在上海市世纪大道沿线采集了如下16个经纬度坐标数据:
通过式(1)、式(2)计算出对应平面地图上的16个点的像素坐标,为了直观显示效果,软件以每个像素点为中心画出了16个红颜色填充的小圆圈,效果如图8所示。
图8中16个密集的红色小圆圈示意出了世纪大道上的一系列采集点的位置,拟合出来的路径跟实际GPS采集的路径数据基本吻合。
2.3.2 根据地图像素坐标计算经纬度坐标
计算地图上某点的经纬度坐标只要将式(1)、式(2)反推得到如下式(3)、式(4)所示的公式进行计算就可以了。
lon = *360 – 180 (3)
*(4)
在软件界面中通过缩放平移操作让上海国际会议中心位于地图正中心,然后将鼠标移至上海国际会议中心正上方位置取其在地图上的像素坐标(x,y),使用式(3)、式(4)的公式计算得到上海国际会议中心的经纬度坐标是(121.492395,31.241517),结果显示在界面左上角如图9所示。
2.4 位置标注
位置标注是指可以在地图上点击某个位置放置一个图标并标注描述文字,点击“标注”按钮然后在地图的北京位置上方点击鼠标左键弹出图10所示的输入框。
输入“北京测试点”后点“确定”按钮,此时在地图上上海的位置就出现了一个图标,图标下方显示“北京测试点”字样,用同样的方法再添加其它几个标注点,最终效果如图11所示。
这里有三个编程实现技术:位置定位、图标在地图上叠加和文字醒目显示。位置定位是指记录标注位置时记录的是换算后的经纬度数据而不是屏幕坐标数据,这样才能保证地图缩放平移后可以计算出新的屏幕坐标正确显示;图标在地图上叠加时要保证图标矩形区域不能完全遮住地图,要用到图像掩码技术[10];文字显示采用在蓝色矩形背景色上画白色文字的方法使其看上去更醒目。
2.5 矢量图叠加
矢量图包括点、线、面以及由它们组成的图案,矢量图在地图上叠加后的效果如图12所示。
画矢量图时矢量图的几何参数要转换为经纬度坐标数据,并且需要设计统一的格式进行存储[11],这样便于与其它软件进行数据交换,具备导入其它软件生成的矢量图数据文件在地图上叠加显示的 功能。
2.6 测距离
测距离指计算地图上两点之间的最短距离。地
球是个球体,地球表面两点之间的最短距离是通过这两点的大圆的劣弧线的长度。
设地球半径为R,起始点A经度为lng1,纬度为lat1,终点B经度为lng2,纬度为lat2,以球心O为原点,球心指向零经度、零纬度点方向为X轴,球心指向90度经度、零纬度点方向为Y轴,球心指向北极为Z轴建立XYZ坐标系。则:
起始点A在XYZ坐标系下的坐标为
Ax = R*cos(lat1)*cos(lng1) (5)
Ay = R*cos(lat1)*sin(lng1) (6)
Az = R*sin(lat1) (7)
终点B在XYZ坐标系下的坐标为
Bx = R*cos(lat2)*cos(lng2) (8)
By = R*cos(lat2)*sin(lng2) (9)
Bz = R*sin(lat2) (10)
设OA与OB的夹角为θ,则由向量点积公式得到:
(11)
那么AB两点的距离s就是过AB两点的圆弧长度,公式如式(12)所示。
(12)
如图13所示,点击“测距”按钮,然后在地图上先后点击南京和武汉两个位置,软件通过式(12)计算出南京和武汉之间的最短距离为458.212千米。
3 结语
本离线地图GIS方案使用C++编程技术实现,由于是自主开发,技术可控,后续进行功能扩展非常方便,可以实现很多在线WebGIS方案实现不了的功能,比如:通过图像边缘分析算法[12]对地图内容进行分析可以实现自动计算出某个地区边界线的长度和区域面积、根据道路图像特征自动提取道路坐标数据、根据建筑物图像特征自动统计人口居住密度等等,WebGIS方案由于采用的是脚本语言编程很难实现这些高级功能。目前是在windows平台下开发的,后面计划将其移植到linux平台下,实现跨平台的离线地图GIS方案。
参考文献
[1]赵桔青, 陶福寿. 基于GIS的城镇土地资源承载力评价[J]. 软件, 2018, 39(7): 52-56.
[2]沈亮. 基于手机APP\GIS\OLAP的移动运营商网格集中管理中心系统的设计与实现[J]. 软件, 2016, 37(4): 74-83.
[3]张思佳. 基于RS/GIS的长沙市土地利用和稳定性分析[J]. 软件, 2018, 39(7): 124-129.
[4]李振星, 邵峰晶, 孙仁诚, 李淑静, 吴舜尧. 基于分类的GIS地图符号快速標注算法[J]. 软件, 2012, 33(2): 108-110.
[5]陈美伊. 基于GIS 的旅游景区虚拟实现技术的研究[J]. 软件, 2015, 36(10): 30-32.
[6]梁秋实, 桑新柱, 邢树军. 利用多视点自由立体显示系统实时显示GIS 信息[J]. 软件, 2016, 37(01): 44-47.
[7]何碧容, 蔡倩. 基于Web墨卡托投影的导航电子地图设计[J]. 计算机测量与控制, 2017, 25(1): 119-122.
[8]徐子惠, 王方雄, 顾双飞, 等. 城市交通警情 WebGIS 设计与开发[J]. 软件, 2018, 39(9): 166-169.
[9]徐莎, 杨帆, 徐昌庆. 基于HTML5的WebGIS 的研究与应用[J]. 信息技术, 2012, (4): 149-151.
[10]黄静, 王希, 齐东旭, 唐泽圣. 基于二值掩码图像的图像合成方法及其应用[J]. 计算机辅助设计与图形学学报, 2009, 21(5): 674-679.
[11]钟云海, 郑海, 王孝通. 矢量图的统一表示框架[J]. 中国航海, 2006, (4): 20-22.
[12]李立宗. OpenCV编程案例详解[M]. 北京: 电子工业出版社, 2016: 99-140.