摘? 要: 在GIS應(yīng)用中,許多現(xiàn)有的商業(yè)GIS方案需要聯(lián)網(wǎng)在線訪問(wèn)地圖數(shù)據(jù),如果網(wǎng)絡(luò)狀況不佳可能會(huì)訪問(wèn)延遲甚至失敗,影響用戶使用體驗(yàn)。本文使用C++編程技術(shù)實(shí)現(xiàn)了一種低成本的不依賴于網(wǎng)絡(luò)的離線地圖GIS解決方案。
關(guān)鍵詞: GIS;WebGIS;離線地圖;在線地圖
中圖分類號(hào): TP302.1? ? 文獻(xiàn)標(biāo)識(shí)碼: 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? 引言
越來(lái)越越多的項(xiàng)目需要使用GIS地圖功能[1-6],商業(yè)GIS地圖軟件功能繁多、復(fù)雜度高,核心功能模塊封裝成庫(kù),對(duì)外只提供二次開(kāi)發(fā)接口,編程靈活度不高,價(jià)格也較貴,普通用戶承受不起。本文研究實(shí)現(xiàn)了一種低成本的離線地圖GIS方案,可在某些預(yù)算較少的項(xiàng)目中使用。
1? 原理
我們平常看到的地圖都是平面地圖,而地球是個(gè)球體,這就需要一種將球體表面曲面映射成二維平面的方法,比較常用的映射方法是墨卡托投影法[7]。
墨卡托投影算法有好幾個(gè)變種,各GIS地圖廠家使用自己的變種算法,本文的方案由于要用到開(kāi)放地圖openstreetmap網(wǎng)站的地圖瓦片資源,所以使用openstreetmap的投影算法進(jìn)行描述,設(shè)lon為經(jīng)度,lat為緯度,z為地圖放大層級(jí),(x,y)為平面地圖的像素坐標(biāo),則有:
(1)
(2)
這里解釋一下地圖放大層級(jí)z這個(gè)參數(shù),當(dāng)我們?yōu)g覽平面地圖時(shí)通過(guò)鼠標(biāo)滾輪上下滾動(dòng)可以縮放地圖,當(dāng)?shù)貓D縮小時(shí)z就減小,當(dāng)?shù)貓D放大時(shí)z就增大。圖1示意了當(dāng)z=1時(shí)的世界地圖。
從圖1中可以看到,當(dāng)z=1時(shí),世界地圖被分成了4小塊,每小塊小地圖為256*256像素大小稱之為一個(gè)瓦片,每個(gè)瓦片的坐標(biāo)用列col和行row來(lái)表示,z=1時(shí)4個(gè)瓦片小地圖拼成了一幅世界地圖,地圖在硬盤上就是以這4個(gè)瓦片小圖片的形式存儲(chǔ)的。
圖2為z=5時(shí)的中國(guó)中部地區(qū)地圖,可以看到此時(shí)地圖上的西安市所在的瓦片坐標(biāo)為列col=25,行row=12,瓦片個(gè)數(shù)已經(jīng)遠(yuǎn)遠(yuǎn)大于4了,z越大組成地圖的瓦片個(gè)數(shù)就越多,地圖分辨率也越高。
2? 軟件實(shí)現(xiàn)
2.1? 地圖拼接顯示
既然是離線GIS地圖方案那么首先要把地圖從網(wǎng)絡(luò)下載到本地硬盤,可以從開(kāi)放地圖openstreet map網(wǎng)站下載。離線GIS地圖是以瓦片小圖片形式存儲(chǔ)在本地硬盤的,圖3為瓦片小圖片在文件管理器里的瀏覽視圖,每個(gè)瓦片小圖片大小為256*256像素,以png圖像格式存儲(chǔ)。
將這些瓦片拼接在一起就形成了一幅完整的地圖,軟件顯示地圖時(shí),首先根據(jù)當(dāng)前分辨率計(jì)算出對(duì)應(yīng)的放大層級(jí)z,然后根據(jù)地圖顯示區(qū)域計(jì)算出所需的一系列瓦片的行號(hào)和列號(hào),最后將這些瓦片在內(nèi)存中拼接成完整的地圖在界面上顯示。圖4為地圖在軟件界面上顯示的效果圖。
需要指出的是本文使用的地圖拼接方法跟目前流行的WebGIS[8]有所不同。WebGIS使用HTML5[9]的canvas畫布技術(shù),使用javascrip腳本來(lái)完成地圖拼接顯示,本文是用C++編程技術(shù)實(shí)現(xiàn)的,C++的編譯后運(yùn)行比腳本語(yǔ)言的解釋運(yùn)行效率要高很多,本地硬盤訪問(wèn)瓦片數(shù)據(jù)也比WebGIS通過(guò)網(wǎng)絡(luò)在線訪問(wèn)服務(wù)器上的瓦片數(shù)據(jù)要快。
2.2? 縮放平移
2.2.1? 縮放
在圖4所示的軟件界面中,鼠標(biāo)點(diǎn)擊“放大”按鈕,地圖放大層級(jí)z增大,地圖分辨率提高,點(diǎn)擊“縮小”按鈕,地圖放大層級(jí)z減小,地圖分辨率降低。z變化后拼接地圖的瓦片列col,行row也相應(yīng)變化,軟件到硬盤上讀取新的瓦片小圖片重新拼接后在界面上顯示即可。放大縮小也可以通過(guò)鼠標(biāo)滾輪上下滾動(dòng)來(lái)觸發(fā),滾輪上滾地圖放大,滾輪下滾地圖縮小。
圖5為將圖4的地圖放大后的地圖效果圖。
圖6為將圖4的地圖縮小后的地圖效果圖。
2.2.2? 平移
通過(guò)鼠標(biāo)點(diǎn)擊拖拽可以實(shí)現(xiàn)平移,平移不會(huì)改變放大層級(jí)z,但平移后界面視野內(nèi)的地圖內(nèi)容發(fā)生了變化,也就是視野內(nèi)組成地圖的瓦片列col,行row發(fā)生了變化,軟件到硬盤上讀取新的瓦片小圖片重新拼接后在界面上顯示就實(shí)現(xiàn)了平移效果。
圖7為對(duì)圖4的地圖進(jìn)行平移后的地圖效果圖,可以看到地圖上黃浦江的位置往右明顯平移了。
2.3? 坐標(biāo)計(jì)算
2.3.1? 根據(jù)經(jīng)緯度坐標(biāo)計(jì)算地圖像素坐標(biāo)
GIS地圖一個(gè)常用的功能就是根據(jù)經(jīng)緯度坐標(biāo)計(jì)算地圖上的位置,這是通過(guò)式(1)、式(2)來(lái)計(jì)算的。為了驗(yàn)證此功能,事先通過(guò)GPS在上海市世紀(jì)大道沿線采集了如下16個(gè)經(jīng)緯度坐標(biāo)數(shù)據(jù):
通過(guò)式(1)、式(2)計(jì)算出對(duì)應(yīng)平面地圖上的16個(gè)點(diǎn)的像素坐標(biāo),為了直觀顯示效果,軟件以每個(gè)像素點(diǎn)為中心畫出了16個(gè)紅顏色填充的小圓圈,效果如圖8所示。
圖8中16個(gè)密集的紅色小圓圈示意出了世紀(jì)大道上的一系列采集點(diǎn)的位置,擬合出來(lái)的路徑跟實(shí)際GPS采集的路徑數(shù)據(jù)基本吻合。
2.3.2? 根據(jù)地圖像素坐標(biāo)計(jì)算經(jīng)緯度坐標(biāo)
計(jì)算地圖上某點(diǎn)的經(jīng)緯度坐標(biāo)只要將式(1)、式(2)反推得到如下式(3)、式(4)所示的公式進(jìn)行計(jì)算就可以了。
lon = *360 – 180 (3)
*(4)
在軟件界面中通過(guò)縮放平移操作讓上海國(guó)際會(huì)議中心位于地圖正中心,然后將鼠標(biāo)移至上海國(guó)際會(huì)議中心正上方位置取其在地圖上的像素坐標(biāo)(x,y),使用式(3)、式(4)的公式計(jì)算得到上海國(guó)際會(huì)議中心的經(jīng)緯度坐標(biāo)是(121.492395,31.241517),結(jié)果顯示在界面左上角如圖9所示。
2.4? 位置標(biāo)注
位置標(biāo)注是指可以在地圖上點(diǎn)擊某個(gè)位置放置一個(gè)圖標(biāo)并標(biāo)注描述文字,點(diǎn)擊“標(biāo)注”按鈕然后在地圖的北京位置上方點(diǎn)擊鼠標(biāo)左鍵彈出圖10所示的輸入框。
輸入“北京測(cè)試點(diǎn)”后點(diǎn)“確定”按鈕,此時(shí)在地圖上上海的位置就出現(xiàn)了一個(gè)圖標(biāo),圖標(biāo)下方顯示“北京測(cè)試點(diǎn)”字樣,用同樣的方法再添加其它幾個(gè)標(biāo)注點(diǎn),最終效果如圖11所示。
這里有三個(gè)編程實(shí)現(xiàn)技術(shù):位置定位、圖標(biāo)在地圖上疊加和文字醒目顯示。位置定位是指記錄標(biāo)注位置時(shí)記錄的是換算后的經(jīng)緯度數(shù)據(jù)而不是屏幕坐標(biāo)數(shù)據(jù),這樣才能保證地圖縮放平移后可以計(jì)算出新的屏幕坐標(biāo)正確顯示;圖標(biāo)在地圖上疊加時(shí)要保證圖標(biāo)矩形區(qū)域不能完全遮住地圖,要用到圖像掩碼技術(shù)[10];文字顯示采用在藍(lán)色矩形背景色上畫白色文字的方法使其看上去更醒目。
2.5? 矢量圖疊加
矢量圖包括點(diǎn)、線、面以及由它們組成的圖案,矢量圖在地圖上疊加后的效果如圖12所示。
畫矢量圖時(shí)矢量圖的幾何參數(shù)要轉(zhuǎn)換為經(jīng)緯度坐標(biāo)數(shù)據(jù),并且需要設(shè)計(jì)統(tǒng)一的格式進(jìn)行存儲(chǔ)[11],這樣便于與其它軟件進(jìn)行數(shù)據(jù)交換,具備導(dǎo)入其它軟件生成的矢量圖數(shù)據(jù)文件在地圖上疊加顯示的 功能。
2.6? 測(cè)距離
測(cè)距離指計(jì)算地圖上兩點(diǎn)之間的最短距離。地
球是個(gè)球體,地球表面兩點(diǎn)之間的最短距離是通過(guò)這兩點(diǎn)的大圓的劣弧線的長(zhǎng)度。
設(shè)地球半徑為R,起始點(diǎn)A經(jīng)度為lng1,緯度為lat1,終點(diǎn)B經(jīng)度為lng2,緯度為lat2,以球心O為原點(diǎn),球心指向零經(jīng)度、零緯度點(diǎn)方向?yàn)閄軸,球心指向90度經(jīng)度、零緯度點(diǎn)方向?yàn)閅軸,球心指向北極為Z軸建立XYZ坐標(biāo)系。則:
起始點(diǎn)A在XYZ坐標(biāo)系下的坐標(biāo)為
Ax = R*cos(lat1)*cos(lng1) (5)
Ay = R*cos(lat1)*sin(lng1) (6)
Az = R*sin(lat1) (7)
終點(diǎn)B在XYZ坐標(biāo)系下的坐標(biāo)為
Bx = R*cos(lat2)*cos(lng2) (8)
By = R*cos(lat2)*sin(lng2) (9)
Bz = R*sin(lat2) (10)
設(shè)OA與OB的夾角為θ,則由向量點(diǎn)積公式得到:
(11)
那么AB兩點(diǎn)的距離s就是過(guò)AB兩點(diǎn)的圓弧長(zhǎng)度,公式如式(12)所示。
(12)
如圖13所示,點(diǎn)擊“測(cè)距”按鈕,然后在地圖上先后點(diǎn)擊南京和武漢兩個(gè)位置,軟件通過(guò)式(12)計(jì)算出南京和武漢之間的最短距離為458.212千米。
3? 結(jié)語(yǔ)
本離線地圖GIS方案使用C++編程技術(shù)實(shí)現(xiàn),由于是自主開(kāi)發(fā),技術(shù)可控,后續(xù)進(jìn)行功能擴(kuò)展非常方便,可以實(shí)現(xiàn)很多在線WebGIS方案實(shí)現(xiàn)不了的功能,比如:通過(guò)圖像邊緣分析算法[12]對(duì)地圖內(nèi)容進(jìn)行分析可以實(shí)現(xiàn)自動(dòng)計(jì)算出某個(gè)地區(qū)邊界線的長(zhǎng)度和區(qū)域面積、根據(jù)道路圖像特征自動(dòng)提取道路坐標(biāo)數(shù)據(jù)、根據(jù)建筑物圖像特征自動(dòng)統(tǒng)計(jì)人口居住密度等等,WebGIS方案由于采用的是腳本語(yǔ)言編程很難實(shí)現(xiàn)這些高級(jí)功能。目前是在windows平臺(tái)下開(kāi)發(fā)的,后面計(jì)劃將其移植到linux平臺(tái)下,實(shí)現(xiàn)跨平臺(tái)的離線地圖GIS方案。
參考文獻(xiàn)
[1]趙桔青, 陶福壽. 基于GIS的城鎮(zhèn)土地資源承載力評(píng)價(jià)[J]. 軟件, 2018, 39(7): 52-56.
[2]沈亮. 基于手機(jī)APP\GIS\OLAP的移動(dòng)運(yùn)營(yíng)商網(wǎng)格集中管理中心系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J]. 軟件, 2016, 37(4): 74-83.
[3]張思佳. 基于RS/GIS的長(zhǎng)沙市土地利用和穩(wěn)定性分析[J]. 軟件, 2018, 39(7): 124-129.
[4]李振星, 邵峰晶, 孫仁誠(chéng), 李淑靜, 吳舜堯. 基于分類的GIS地圖符號(hào)快速標(biāo)注算法[J]. 軟件, 2012, 33(2): 108-110.
[5]陳美伊. 基于GIS 的旅游景區(qū)虛擬實(shí)現(xiàn)技術(shù)的研究[J]. 軟件, 2015, 36(10): 30-32.
[6]梁秋實(shí), 桑新柱, 邢樹(shù)軍. 利用多視點(diǎn)自由立體顯示系統(tǒng)實(shí)時(shí)顯示GIS 信息[J]. 軟件, 2016, 37(01): 44-47.
[7]何碧容, 蔡倩. 基于Web墨卡托投影的導(dǎo)航電子地圖設(shè)計(jì)[J]. 計(jì)算機(jī)測(cè)量與控制, 2017, 25(1): 119-122.
[8]徐子惠, 王方雄, 顧雙飛, 等. 城市交通警情 WebGIS 設(shè)計(jì)與開(kāi)發(fā)[J]. 軟件, 2018, 39(9): 166-169.
[9]徐莎, 楊帆, 徐昌慶. 基于HTML5的WebGIS 的研究與應(yīng)用[J]. 信息技術(shù), 2012, (4): 149-151.
[10]黃靜, 王希, 齊東旭, 唐澤圣. 基于二值掩碼圖像的圖像合成方法及其應(yīng)用[J]. 計(jì)算機(jī)輔助設(shè)計(jì)與圖形學(xué)學(xué)報(bào), 2009, 21(5): 674-679.
[11]鐘云海, 鄭海, 王孝通. 矢量圖的統(tǒng)一表示框架[J]. 中國(guó)航海, 2006, (4): 20-22.
[12]李立宗. OpenCV編程案例詳解[M]. 北京: 電子工業(yè)出版社, 2016: 99-140.