周 海,謝雨芮,葛 平,劉毅錕
(1.西安測繪總站,陜西 西安710054)
局域網條件下的瓦片地圖應用研究

周 海1,謝雨芮1,葛 平1,劉毅錕1
(1.西安測繪總站,陜西 西安710054)
通過Python網絡爬蟲獲取互聯網地圖瓦片并存儲到本地數據庫MongoDB中,在B/S架構下利用Leaflet實現瓦片地圖瀏覽功能,利用Python-PIL在服務器端實現瓦片地圖拼接。為適應地圖和地圖拼接服務高并發的需求,利用Nginx實現多臺服務器間的負載均衡。該項研究提供了網絡地圖瓦片的獲取、存儲、瀏覽和拼接方法,服務器端拼接的方式降低了客戶端依賴,為局域網條件下瓦片地圖應用提供良好的思路。
瓦片地圖;爬蟲;Leaflet;瓦片拼接
目前,國內外已有很多成熟軟件提供瓦片地圖的生產、服務發布、訪問和拼接功能,如SuperMap、ArcGIS均可用來切割瓦片[1]、服務發布和地圖訪問,稻歌、水經注和太樂等提供瓦片地圖的拼接功能。許多學者開展了瓦片地圖存儲[2,3]、訪問[4]和拼接方面的研究,如韋勝[5]在ArcEngine上結合ArcBruTile(GitHub),利用Win32類庫和GDAL兩種不同方式實現對地圖瓦片的拼接。這些工具和研究對推進瓦片地圖應用發揮了重要作用,但仍然存在一些問題:對地圖瓦片獲取研究較少,不能直接利用Google Map等互聯網瓦片地圖來構建自己的地圖服務;地圖拼接工作大都是在C/S架構的Client端完成,只有安裝客戶端才能使用,受網絡影響大不易擴展。針對這些問題,首先研究通過Python爬蟲對Google Map等地圖瓦片進行獲取,基于B/S架構實現地圖瓦片的瀏覽與服務器端的拼接,最后實現拼接服務的負載均衡以提高服務器性能。
傳統的瓦片生產由矢量地圖或影像來切割生成,預先對地圖數據渲染、切片,然后存放在服務器端,客戶端訪問時直接訪問這些瓦片數據,以避免服務器端地圖實時渲染給服務器造成的壓力[2]。在全球范圍內,無論是地圖數據采集還是編繪都是巨大的工作量,通過網絡爬蟲來獲取現有互聯網地圖瓦片以便直接利用。局域網內應用互聯網地圖瓦片的技術路線如圖1。

圖1 局域網內應用互聯網地圖瓦片的技術路線
地圖瓦片數據一般采用金字塔結構對不同分辨率(比例尺)的數據進行組織,由于數據坐標系統和地圖用途的不同,采用的投影和瓦片切割算法也可能不同[2]。目前,主流的網絡地圖多采用WGS 1984Web Mercator投影(地球近似為圓球體),經度的投影范圍取(-180,180),緯度投影范圍取(-85.051 129,85.051 129)。金字塔的不同級別對應于不同分辨率的地圖,地圖瓦片的大小通常采用256×256或512×512像素,并采用PNG格式。特定級別的地圖范圍(通常是全球)可以確定每塊瓦片的地理跨度和實際分辨率,進而計算出該瓦片在地圖圖層中的相對位置,即行列號。確定地圖等級z,行列號x、y便對應于網絡地圖中的一塊瓦片[6]。
能夠通過網絡爬蟲來獲取網絡地圖瓦片,是因為這些網絡地圖服務提供了獲得每一塊瓦片的接口,通常每一塊瓦片均由獨立的URL地址唯一確定。可以通過Request請求獲取指定位置和級別的地圖瓦片。以Google Map影像為例,用戶request請求以下URL可以分別獲得圖2中4張瓦片。其中的主要參數x、y、z分別表示瓦片的行號、列號和級別。
1)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=1&y=0&z=1;
2)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=0&y=0&z=1;
3)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=1&y=1&z=1;
4)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=0&y=1&z=1;

圖2 Google影像數據
其他地圖瓦片可以通過URL來獲取,并根據其行列號和級別反解出其角點坐標。主要對Google Map的影像層(含注記層)、地圖層以及OpenStreetMap的標準圖層進行獲取,這些圖層的投影方式、投影范圍、瓦片切割算法相同,可以在地圖顯示時很好地集成和切換。實際工作中通過Python爬蟲程序獲取Google Map影像、地圖及OpenStreetMap3種地圖0~10級全球范圍內的瓦片數據。
地圖瓦片是固定尺寸的圖片,通常為PNG格式,隨著地圖級別的增加,地圖瓦片的數據量呈指數級上升,如在第10級全球瓦片的數量達到410,如何實現地圖瓦片的高效存取非常重要。若將這些海量的地圖瓦片以文件的形式存儲在硬盤中,則不僅造成磁盤存儲碎片化嚴重、數據冗余,而且I/O性能差、不便于備份和恢復。通常的做法是將瓦片存儲在數據庫中,而且是非關系型數據庫(NoSQL)中,因為傳統關系型數據庫對文件、二進制等數據的讀寫性能依然受限[3,7]。
MongoDB[3,7]是一個開源、基于分布式文件存儲的NoSQL數據庫。它使用一種類似JSON的BSON格式進行數據存儲,因格式松散而支持復雜數據格式,尤其是內置GridFS功能,特別適應于大量小文件存儲。在數據備份和恢復方面,可以使用mongodump和mongorestore工具輕易實現數據遷移。此外,MongoDB還支持Python、Java、C++、PHP等多種語言,而且操作簡單便捷。基于這些特點,選用MongoDB來存儲獲取的地圖瓦片,以實現對地圖瓦片的高效存儲和訪問。采用Python的MongoDB操作工具pymongo實現對數據庫中瓦片的讀寫。存儲的信息除了圖片文件,還包含行列號、文件格式、圖層類別、下載時間等其他信息。
地圖訪問的實現主要包括服務器端地圖服務發布和Web端地圖服務調用及交互兩部分,如圖3所示。

圖3 地圖訪問與拼接的實現
服務器端主要實現地圖服務器的功能,完成對數據庫中瓦片的讀取,并暴露服務接口。目前有許多商業GIS軟件(如ArcGIS Server)和開源GIS(如GeoServer)可以用來發布瓦片地圖服務。這些軟件雖提供了豐富的GIS服務功能,但部署和操作復雜。本研究僅涉及地圖服務和拼接服務,因此運用Python的Tornado框架來搭建自己輕量級的GIS服務器。
Tornado是 FriendFeed的Web服務器及其常用工具的開源版本,采用epoll非阻塞I/O,響應快速,每秒可處理數千并發連接,特別適用于實時的Web服務。基于該框架利用Python實現RESTful風格的地圖瓦片服務。每塊瓦片對應唯一一個URL,結構為http://localhost:3000/tile?z={z}&x={x}&y={y}&layer=g oogle_sat,其中x、y、z分別對應于瓦片的行號、列號和級別,layer為幾種不同的瓦片圖層,如Google影像、OpenStreetMap標準圖層等。這樣,瀏覽器端便可以通過URL獲取每一塊瓦片。
Web端(客戶端)主要實現地圖的瀏覽、漫游、縮放、定位等功能。要實現這些功能,一般要借助于WebGIS工具。目前,地圖服務廠商和GIS廠商都有自己的WebGIS產 品, 如 GoogleMap JavaScript API、ArcGIS API for JavaScript等。除此之外,出現了越來越多的JavaScript開源WebGIS客戶端,如 Leaflet、Openlayers、MapEasy、OpenScales等。由于開源GIS產品具有免費、開放、可擴展性和可定制性強,以及開發周期短、成本低等特點,基于開源GIS軟件的應用項目越來越多[9,10]。
Leaflet 是一個為建設移動設備友好的互動地圖而開發的開源JavaScript 庫。代碼量雖小,但具有開發人員開發在線地圖的大部分功能。而且支持插件擴展,有一個友好、易于使用的API文檔和一個簡單的、可讀的源代碼。利用leaflet實現了瀏覽器端對瓦片地圖的瀏覽、漫游、縮放、定位等功能,并利用leaflet工具實現對要素層的編輯(框選要拼接的地圖范圍)。
地圖拼接在服務器端完成,客戶端和服務器配合完成。通過在瀏覽器端輸入坐標范圍、圖層、圖幅大小等參數,在服務器端實現瓦片的拼接,返回給瀏覽器端。瓦片拼接的一般過程如圖4。

圖4 拼接的實現過程
在客戶端(瀏覽器):首先利用leaflet的draw工具在地圖上繪制矩形范圍框,為避免用戶選擇的地圖范圍過大,將用戶選擇的拼接范圍分割成多個圖幅進行拼接,因而用戶還需要輸入拼接后的圖幅大小。為避免瓦片的裁剪,圖幅大小采用瓦片大小的整數倍,如2 560×2 560、5 120×5 120像素等;接著選擇要拼接的圖層等級,并根據范圍對級別進行限定,以避免拼接任務過于龐大;最后,選擇需要拼接的圖層,以滿足不同地圖瓦片的拼接需求。
在服務器端:根據從客戶端接收過來的圖幅范圍、等級、圖幅大小、圖層等參數開始拼接任務,為了讓客戶端實時獲取服務器端瓦片的拼接進度,在服務器端給每一個任務生成一個唯一的ID,然后將拼接的進度存儲在Session中,這樣瀏覽器就可以實時獲取拼接進度,并在完成拼接后下載。
地圖瓦片拼接服務使用Python來編寫,主要用到兩個工具:Imaging Library (PIL)和Geospatial Data Abstraction Library(GDAL)。PIL是 Python下的圖像處理模塊,支持多種格式,并提供強大的圖形與圖像處理功能。利用PIL將多塊瓦片PNG圖像拼接到一起。GDAL是一個在X/MIT許可協議下的開源柵格空間數據轉換庫。用它將EPSG描述的坐標系轉換為WKT坐標系。瓦片拼接的成果主要包括3類文件:拼接好的圖片PNG文件,記錄圖幅左上角點坐標及圖片分辨率等參數的PNW文件,以及采用WKT描述的坐標系PRJ文件。后兩者文件共同構成了PNG文件的空間參考。地圖瓦片拼接將選定范圍的瓦片拼接成一個或多個圖幅,地圖拼接的算法如下:
1)根據輸入的拼接范圍和級別計算要拼接的起始行列號、終止行列號以及瓦片分辨率;
2)根據起始行列號和終止行列號以及輸入的圖幅大小,計算出每一塊圖幅的起止行列號以及起始坐標;
3)根據每塊圖幅的起止行列號,將落在該范圍的瓦片從數據庫中取出拼在一起,完成每一個圖幅的拼接,并根據起始坐標生成WKT描述的坐標系PRJ文件,將起始坐標及分辨率等參數記錄到PRJ參數文件中;
4)將拼接的每一個圖幅的PNG、PNW和PRJ文件壓縮為一個壓縮包。
為適應用戶對地圖和瓦片拼接的大量并發訪問,對服務器進行優化。利用Nginx反向代理實現對地圖服務和瓦片拼接服務的負載均衡。Nginx是一個高性能的HTTP和反向代理服務器,作為負載均衡服務器時,支持作為HTTP代理服務器對外進行服務。當用戶訪問網站時,負載均衡服務器(Nginx)將應用服務請求轉發至5臺應用服務器,以保證某一臺應用服務器負載過高,或是當某臺應用服務器宕機時,系統能夠繼續運行。負載均衡部署如圖5。

圖5 服務器負載均衡
當對地圖拼接服務實現負載均衡時,由于拼接任務是在某一臺應用服務器上完成的,因此需要將所有任務的進度存儲在一個Memcached的session服務器上,這樣便可以獲得每個拼接任務的進度。當拼接任務完成后,若拼接文件不在本機,同樣需將下載請求轉發至實際任務進行的應用服務器。
實驗下載了全球范圍內Google Map影像、地圖及OpenStreetMap三類瓦片的0~10級數據,并將數據存儲在mongodb中,數據大小約為26 GB。系統部署在VMware的centos虛擬機中,部署的結構如圖5。系統主要包括地圖瀏覽和瓦片拼接下載功能,截圖如圖6。

圖6 瓦片拼接效果圖
地圖瀏覽:地圖瀏覽允許用戶實現Google地圖、Google影像、OpenStreetMap 3類瓦片地圖的瀏覽、漫游、縮放和圖層切換。地圖瀏覽界面包括了右下角的圖層切換按鈕和右上角的地圖拼接下載工具條,圖層切換按鈕允許用戶切換瀏覽不同的圖層,地圖下載工具條主要完成地圖拼接等功能,如圖6a。
瓦片拼接下載:地圖拼接下載主要通過地圖拼接下載工具條完成,通過輸入拼接范圍、拼接圖層、拼接圖層的級別以及拼接圖幅尺寸,向服務器提交拼接請求(如圖6b),在拼接過程中界面將顯示拼接進度,完成拼接后瀏覽器會彈出文件下載提示。圖6c是下載拼接好的文件,圖6d是將下載的文件在Global Mapper中打開的效果。
通過爬蟲獲取Google Map等互聯網地圖瓦片并存儲在數據庫,利用Python搭建輕量級地圖服務器并利用leaflet實現地圖的瀏覽功能。在此基礎上,利用PIL和GDAL等工具實現瓦片地圖的拼接服務,實現服務的負載均衡。實際應用效果較好,為局域網下利用互聯網瓦片數據提供了一套有效的解決方案。下一步工作將實現瓦片緩存以便進一步提高系統性能,并研究局域網條件下瓦片地圖服務的具體應用,如將瓦片地圖服務引入生產作業網以直接作為數據參考、在瓦片拼接基礎上利用瓦片完成地圖的在線制作等。
[1]蘇旭明, 譚建成. WebGIS中瓦片地圖關鍵技術研究[J].北京測繪, 2012(2):9-12
[2]羅智勇,黎小東.基于數據庫存儲方案的高性能瓦片地圖服務研究[J].地理與地理信息科學,2013,29(3): 52-55
[3]陳超, 王亮, 閆浩文,等. 一種基于NoSQL的地圖瓦片數據存儲技術[J].測繪科學, 2013, 38(1):142-143
[4]張廣春, 仲偉政. 基于ArcGIS Engine組件實現瓦片地圖的應用[J].測繪通報, 2015(3):115-116
[5]韋勝. ArcEngine環境下實現瓦片地圖的訪問與拼接[J].武漢大學學報(信息科學版), 2012, 37(6):737-740
[6]OpenStreetMap Wiki. Slippy Map Tilenames [EB/OL]. http://wiki.openstreetmap.org/w/index.php?title=Slippy_map_tilenam es&oldid=1342885.2016-09-08 / 2016-11-15
[7]邱新忠. 基于MongoDB GridFS的地圖瓦片數據存儲研究[J].地理空間信息, 2016(2):50-52
[8]邱儒瓊, 鄭麗娜, 李兵. 基于MongoDB的電子地圖瓦片數據存儲和服務研究[J].地理空間信息, 2014(6):155-157
[9]李光師. 基于開源平臺構建WebGIS應用系統[J].測繪科學,2011, 36(6):259-261
[10]胡達天, 胡慶武. 基于開源系統的跨平臺地圖客戶端開發[J].測繪科學, 2015, 40(7):142-145
P208
B
1672-4623(2017)12-0018-04
10.3969/j.issn.1672-4623.2017.12.006
2016-11-18。
地理信息工程國家重點實驗室開放研究基金資助項目(SKLGIE2015-Z—2-1)。
周海,碩士研究生,主要從事地理編碼、空間數據挖掘、GIS應用開發等工作。