Web GIS 開(kāi)發(fā)入門(mén)
前言
最近在學(xué)習(xí) OSM ID 編輯器的過(guò)程中,我發(fā)現(xiàn)之前一兩個(gè)月雖然也開(kāi)始熟悉使用高德map的開(kāi)發(fā),但是自己對(duì) web GIS 領(lǐng)域相關(guān)基礎(chǔ)知識(shí)的了解卻少的可憐。導(dǎo)致在閱讀源碼的過(guò)程中,常常對(duì)一些數(shù)據(jù)轉(zhuǎn)化操作或者一些函數(shù)命名感到很奇怪,因此開(kāi)始了對(duì) GIS 基礎(chǔ)知識(shí)的學(xué)習(xí)。
因?yàn)闆](méi)有一個(gè)成體系的學(xué)習(xí)大綱,所以需要一個(gè)問(wèn)題作為切入點(diǎn)來(lái)幫助自己一步一步了解 GIS 相關(guān)知識(shí)。那么一個(gè)很容易想到的問(wèn)題就出現(xiàn)了:地圖是如何進(jìn)行點(diǎn)的定位和展示的呢,要知道我們生活在一個(gè)球形的天體上,而我們常使用的地圖是平面的,和球形毫無(wú)關(guān)系。
因此學(xué)習(xí)的第一步是了解坐標(biāo)系系統(tǒng)。
坐標(biāo)系
總所周知,地球不是一個(gè)標(biāo)準(zhǔn)的球體,而是一個(gè)近似的橢球體,越靠近赤道則越寬。既然是一個(gè)三維物體,那么進(jìn)行坐標(biāo)系定位一般來(lái)說(shuō)需要 x,y,z 一個(gè)三維坐標(biāo)系來(lái)定義。但是為了更好的在球面上進(jìn)行定位,所以就采取了使用經(jīng)緯度的方式,在 GIS 開(kāi)發(fā)中,以經(jīng)度、維度以及相對(duì)高度所組成的坐標(biāo)系將其稱(chēng)作為地理坐標(biāo)系(Geographic Coordinate System, 簡(jiǎn)稱(chēng) GCS) 。
而在平時(shí)使用手機(jī)地圖或者網(wǎng)頁(yè)地圖的時(shí)候,展現(xiàn)在我們面前的則是一個(gè)平面地圖。如果說(shuō)此時(shí)我們需要查詢(xún)自己去某個(gè)飯店有多遠(yuǎn),手機(jī)會(huì)告訴我們距離多少公里或者多少米,所以我們得到兩個(gè)地點(diǎn)之間的距離是平面距離,使用米或者千米做單位。而此時(shí)的定位坐標(biāo)系,就被稱(chēng)作為投影 坐標(biāo)系(Projection Coordinate System,簡(jiǎn)稱(chēng)PCS) 。
很顯然,我們平時(shí)使用的平面地圖,肯定是做了這樣一件事情,那就是將地理坐標(biāo)系轉(zhuǎn)換成投影坐標(biāo)系。但是,一個(gè)球面從直觀上是無(wú)法展開(kāi)成一個(gè)連續(xù)的,沒(méi)有褶皺的平面的,因此我們需要一定的數(shù)學(xué)方法進(jìn)行轉(zhuǎn)換。
其實(shí)從投影坐標(biāo)系的名稱(chēng)也可以看出,坐標(biāo)系轉(zhuǎn)化的方法就是投影??梢韵胂笠幌拢粋€(gè)3D的物品被光照射之后的影子,是不是就是2D平面了。當(dāng)然坐標(biāo)系的轉(zhuǎn)換肯定不是隨便投影就行,為了讓投影之后的坐標(biāo)系有一定的使用價(jià)值,投影的方式一般都會(huì)具備一定的規(guī)律,比如投影后距離不變,或者角度不變等。
墨卡托投影
墨卡托 投影 (Mercator Projection) 是在1569年,當(dāng)時(shí)的地理學(xué)家杰拉杜斯·墨卡托提出的一種角度不變的投影方式,又被稱(chēng)作為等角正切圓柱投影。我們可以想象一下,將地球置于一個(gè)空心圓柱體中,其中地球的赤道正切于圓柱體。然后假設(shè)地心有一個(gè)燈泡,燈泡的光線能夠透過(guò)地表照射到圓柱體表面,那么地球球面上的絕大部分區(qū)域都會(huì)相應(yīng)的被投影到圓柱體上。此時(shí)將圓柱體展開(kāi),以赤道的投影為橫坐標(biāo),以本初子午線的投影的縱坐標(biāo),就得到了以墨卡托投影所構(gòu)成的平面坐標(biāo)系。
我們可以看到該投影有以下特點(diǎn):
- 經(jīng)線、緯線分別為平行直線,并且經(jīng)緯線之間互相垂直
- 緯度越高的地方,投影面積形變?cè)酱?,而在緯度無(wú)限接近于極點(diǎn)的位置,面積則會(huì)無(wú)限大,因此緯度的上限和下限分別是北緯 89° 和南緯 89°。
- 雖然在面積上有形變,但是是各個(gè)方向上的均等擴(kuò)大,所以保證了地圖方向、角度以及位置關(guān)系的正確性。
Web墨卡托
web墨卡托,也稱(chēng)偽墨卡托(Pseudo Mercator Projection) ,屬于一種不嚴(yán)格的墨卡托投影方式,其被 Google Map 最先發(fā)明,后續(xù)又被Bing,百度, OSM 等各個(gè)網(wǎng)絡(luò)地圖服務(wù)商使用,因此成為了互聯(lián)網(wǎng)電子地圖最常見(jiàn)的投影方式。
其和墨卡托投影的最大區(qū)別在于,墨卡托投影是建立在地球是一個(gè)橢球體的基礎(chǔ)上進(jìn)行投影公式計(jì)算的,而 Web 墨卡托在其計(jì)算公式上直接將橢球體變成了球體,大大簡(jiǎn)化了投影轉(zhuǎn)化的計(jì)算方法,其計(jì)算公式為:
其中 x, y 為投影坐標(biāo)系中的坐標(biāo)值, 為赤道半徑, 為經(jīng)度, 為緯度。
此外,web 墨卡托投影一般默認(rèn)為一個(gè)正方形。已知赤道半徑為 6378137 米,則赤道的周長(zhǎng)則為 約為40075016.68557849,所以投影坐標(biāo)系中 X 軸的范圍為 [-20037508.342789244, 20037508.342789244],則 Y 軸的范圍也為 [-20037508.342789244, 20037508.342789244],可以通過(guò)上面公式反算出緯度被限制在了[-85.0511287, 85.0511287] 范圍內(nèi)。
在日常地圖使用中,使用 web 墨卡托投影的地圖已經(jīng)足夠了。但是如果有一些其他的要求,比如說(shuō)要精確描述區(qū)域面積,則一般使用圓錐投影,比如阿爾伯斯投影、蘭伯特投影等,這里就不再具體展開(kāi),感興趣的可以看一下 常見(jiàn)的地圖投影方式[1]。
EPSG
上個(gè)小節(jié)提到了地理坐標(biāo)系和投影坐標(biāo)系,還提到了一些投影方法。就拿墨卡托和web墨卡托來(lái)說(shuō),前者是將地球看作一個(gè)橢球體,后者將地球看作了一個(gè)球體。所以說(shuō)我們并沒(méi)有一個(gè)嚴(yán)格的標(biāo)準(zhǔn)且統(tǒng)一的方式來(lái)表述某個(gè)點(diǎn)的位置。當(dāng)沒(méi)有統(tǒng)一標(biāo)準(zhǔn)的時(shí)候,就會(huì)存在很多體系標(biāo)準(zhǔn),而當(dāng)各種體系標(biāo)準(zhǔn)變得龐大且失去統(tǒng)一管理的時(shí)候,人們想將不同體系之間的坐標(biāo)互相轉(zhuǎn)化的話就會(huì)變得異常困難。EPSG[2] 就是來(lái)管理這些坐標(biāo)體系的一個(gè)組織。
EPSG 通過(guò) WKID 來(lái)管理不同的坐標(biāo)體系,WKID 簡(jiǎn)單理解就是 ID,每個(gè)坐標(biāo)體系擁有獨(dú)一無(wú)二的ID。拿一些常用的WKID 舉例:
WGS84 (WKID = 4326)
在介紹 WGS84 之前,我們需要弄清楚一個(gè)概念:大地坐標(biāo)系。大地坐標(biāo)系是以參考橢球面為基準(zhǔn)面而建立起來(lái)的坐標(biāo)系,也可以簡(jiǎn)單理解成屬于地理坐標(biāo)系的一種。大地坐標(biāo)系又分為參心大地坐標(biāo)系和地心大地坐標(biāo)系。其中參心坐標(biāo)系是以橢球幾何中心為原點(diǎn)構(gòu)建的坐標(biāo)系,一般用來(lái)對(duì)局部地區(qū)大地測(cè)繪使用,而地心坐標(biāo)系是以地球質(zhì)心為原點(diǎn)構(gòu)建的坐標(biāo)系,一般用來(lái)對(duì)地球整體大地測(cè)繪使用。
WGS84 則屬于地心大地坐標(biāo)系,是世界上第一個(gè)統(tǒng)一的大地坐標(biāo)系,所以也被稱(chēng)為世界大地坐標(biāo)系,而我們常說(shuō)的GPS定位系統(tǒng)就是依據(jù)此坐標(biāo)系建立的。除了中國(guó)地區(qū)以外,很多電子地圖比如谷歌、Bing等都是用的是 WGS84。
CGCS2000(WKID = 4490)
我國(guó)在上世紀(jì)50年代和80年代分別建立了北京54和西安80參心大地坐標(biāo)系,后隨著社會(huì)經(jīng)濟(jì),科學(xué)的發(fā)展,中國(guó)測(cè)繪、地震部門(mén)和科學(xué)院有關(guān)單位重新建立了中國(guó)新一代地心大地坐標(biāo)系,也就是 CGCS2000,所以也被稱(chēng)為2000國(guó)家大地坐標(biāo)系。
和 WGS84 相比,兩者本質(zhì)上可以算是一致的,只是在計(jì)算過(guò)程中采用的參數(shù)有細(xì)微的差別。這個(gè)差別映射到地圖上,也只會(huì)有 cm 級(jí)別的不同,因此如果在精度不需要嚴(yán)格到 cm 級(jí)別的應(yīng)用中,兩者可以默認(rèn)相容。
Web 墨卡托 (WKID = 3857)
Web 墨卡托也在 EPSG 的管理范圍下,可見(jiàn) EPSG 管理的坐標(biāo)系不僅僅只有地理坐標(biāo)系,同樣也包括投影坐標(biāo)系。
其實(shí)原本 EPSG 不準(zhǔn)備將 web 墨卡托納入 WKID,因?yàn)?web 墨卡托畢竟是采用了不嚴(yán)謹(jǐn)?shù)募僭O(shè),使得原本是等角投影的墨卡托變成了近似等角,從而直接影響到投影坐標(biāo)的精度。但是隨著 web 墨卡托在 web 領(lǐng)域被廣泛使用從而名聲大噪,EPSG 也只能將其接受。
GCJ02 和 BD09
GCJ02 是中國(guó)國(guó)家測(cè)繪局所制定的坐標(biāo)系統(tǒng),其本質(zhì)就是在 WGS84 經(jīng)緯度的基礎(chǔ)上進(jìn)行了一層加密。由于國(guó)家相關(guān)安全保密規(guī)定,我國(guó)所有對(duì)外的地圖系統(tǒng)都需要進(jìn)行加密。所以高德以及谷歌的中國(guó)地圖都是使用GCJ02坐標(biāo)系。所以如果在 GCJ02 的坐標(biāo)系下直接使用 GPS 的經(jīng)緯度坐標(biāo),那么就會(huì)得到一個(gè)錯(cuò)誤的定位地點(diǎn)。
比如在手機(jī)上下載一個(gè)GPS定位軟件(部分硬件設(shè)備獲取的GPS信息是原始的GPS信息,而一般地圖軟件的定位信息都是GCJ02加密過(guò)后的),得到天安門(mén)的經(jīng)緯度是 39.907375,116.391349。
但是在高德地圖上,使用該坐標(biāo)點(diǎn)則定位到其他地方:
所以 GCJ02 坐標(biāo)系在業(yè)內(nèi)也常常被稱(chēng)為火星坐標(biāo)系。
而百度在GCJ02 的基礎(chǔ)上又進(jìn)行了一層加密,這就是 BD09。
至于 GCJ02 的加密算法是不對(duì)外公開(kāi)的,只有通過(guò)相關(guān)地圖資質(zhì)的審核,有關(guān)部門(mén)才會(huì)提供相應(yīng)的加密算法。而國(guó)內(nèi)一些拿到資質(zhì)的廠商也提供了相應(yīng)的 API 對(duì)外提供,可供用戶將 WGS84的坐標(biāo)轉(zhuǎn)換成 GSJ02的坐標(biāo)。
拿高德API[3]舉例,WGS84的坐標(biāo)點(diǎn)轉(zhuǎn)換成GCJ02后,得到新的坐標(biāo)點(diǎn)116.397588975695,39.908775499132,然后拿新的坐標(biāo)點(diǎn)在高德地圖上進(jìn)行定位:
此外,嚴(yán)格意義上并沒(méi)有 GCJ02 轉(zhuǎn)化成 WGS84 的反向轉(zhuǎn)化算法。
數(shù)據(jù)服務(wù)
通過(guò)了解坐標(biāo)系原理,我們知道了如何將三維的地理坐標(biāo)系轉(zhuǎn)換成平面的投影坐標(biāo)系。但是光有坐標(biāo)系肯定是不行的,我們還是需要將對(duì)應(yīng)的數(shù)據(jù)呈現(xiàn)在坐標(biāo)系中才能有一個(gè)完整的地圖,那么就不得不去了解地圖常見(jiàn)的數(shù)據(jù)服務(wù)。
OGC
OGC 是一個(gè)制定空間信息和基于位置服務(wù)相關(guān)標(biāo)準(zhǔn)的國(guó)際化組織。嚴(yán)格來(lái)說(shuō),OGC 并不算是一個(gè)“官方”組織,但是由于 OGC 有著ESRI、Google、Oracle 等業(yè)界強(qiáng)勢(shì)企業(yè)作為其成員,同時(shí)還和 W3C、ISO、IEEE 等協(xié)會(huì)或組織結(jié)成合作伙伴關(guān)系。因此在 GIS 開(kāi)發(fā)領(lǐng)域,絕大部分開(kāi)發(fā)者或者企業(yè)都會(huì)依據(jù) OGC 標(biāo)準(zhǔn)來(lái)提供地圖數(shù)據(jù)服務(wù)。
在地圖數(shù)據(jù)服務(wù)中最顯而易見(jiàn)的肯定是圖片服務(wù),用圖片來(lái)承載一個(gè)地理信息數(shù)據(jù),這個(gè)理所應(yīng)當(dāng)很好理解。所以當(dāng)?shù)乩硇畔?shù)據(jù)被封裝成了圖片信息并且可以根據(jù)用戶的請(qǐng)求而動(dòng)態(tài)返回的服務(wù)就被稱(chēng)作 WMS (web map service) 。
除了圖片資源以外,地圖上還會(huì)有道路信息,POI 信息等,而這些數(shù)據(jù)往往是靈活的,可編輯的,因此肯定不能通過(guò)圖片信息進(jìn)行傳遞,因此就有了矢量資源。而一般地圖的矢量數(shù)據(jù)會(huì)包含空間數(shù)據(jù)和屬性數(shù)據(jù),拿常見(jiàn)的 GeoJSON 格式舉例:
這種提供給用戶矢量數(shù)據(jù)并且支持增刪改查的服務(wù)就被稱(chēng)作 WFS(web feature service)。
在實(shí)際應(yīng)用中 WMS 和 WFS 也不能夠完全勝任要求,比如我打開(kāi)一張世界地圖,服務(wù)返回給我一張世界地圖的圖片,但是我想通過(guò)放大的方式來(lái)定位到我的家,那么要實(shí)現(xiàn)這個(gè)功能這個(gè)圖片的分辨率就會(huì)高的不可思議。這種要求顯然是不合理的,所以 OGC 在 WMS 服務(wù)端的基礎(chǔ)上制定了 WMTS(web map tile service) ,也就是我們常說(shuō)的瓦片服務(wù)。此外常見(jiàn)的瓦片服務(wù)還有 TMS(tiled map service) ,但是這個(gè)服務(wù)是不是OGC創(chuàng)建的協(xié)議。
瓦片
不同于 WMS,瓦片服務(wù)提供的圖片是提前制定好的靜態(tài)圖片,可以通過(guò)下面的示意圖來(lái)理解瓦片。
在上面的金字塔模型中,世界地圖分成了多層級(jí)別的瓦片服務(wù)。這個(gè)層就對(duì)應(yīng)著地圖的放大級(jí)別。在最上層,也就是地圖縮小到最小程度時(shí),只提供一張圖片來(lái)展示世界的全貌。用戶如果進(jìn)行放大操作提升地圖的放大級(jí)別,那么世界地圖相應(yīng)的展示第二個(gè)層級(jí)的圖片,而實(shí)際上展示的地理位置區(qū)域大小沒(méi)有變化,只是原本一張圖片展示世界全貌,變成了和原本圖片同等大小的四張圖片來(lái)展示世界全貌。和原本相比,就會(huì)更加清晰一些。
同樣,用戶繼續(xù)放大,用來(lái)展示的層級(jí)所擁有的圖片數(shù)量就會(huì)越多,展示的細(xì)節(jié)就會(huì)越來(lái)越清晰。但是由于屏幕大小范圍有限,所以可以只選擇在屏幕范圍之內(nèi)的圖片進(jìn)行下載,這樣就避免了下載一張超大的圖片,從而減輕了服務(wù)壓力提升了體驗(yàn)性能。而這種被分割的圖片,就被叫做瓦片。
拿高德地圖舉例,因?yàn)槭鞘褂玫?web 墨卡托投影,所以呈現(xiàn)的地圖是正方形的。其瓦片排布編碼的規(guī)律如下,其中 z 為放大層級(jí),每個(gè)瓦片大小默認(rèn)為 256 * 256,第 z 層級(jí)的瓦片數(shù)量為 。
高德地圖瓦片鏈接為 ??http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}??[4],其中 z 為放大層級(jí),x, y 為該瓦片在所在層級(jí)的編碼。
在放大層級(jí)為 3時(shí)(對(duì)于高德地圖來(lái)說(shuō),有意義的最小放大層級(jí)就是3),瓦片展示如下:
當(dāng)然這種瓦片排布的規(guī)律不是通用的,不同廠商制定的瓦片服務(wù)都可能存在著一些差別,所以在使用瓦片服務(wù)的時(shí)候要注意一些。
定位渲染
在知道坐標(biāo)系和地圖數(shù)據(jù)服務(wù)之后,我們其實(shí)就可以簡(jiǎn)單的模擬一下地圖上的點(diǎn)是如何渲染的了。
- 已知初始條件
- 定義 DOM container 大小為 1200 * 1000
- 初始放大層級(jí)為 12
- 中心定位點(diǎn)為天安門(mén),也就是 GCJ02坐標(biāo)系下的 116.397588,39.908775
- Web墨卡托投影正方形的邊長(zhǎng)
- 計(jì)算 container 要展示出的地圖區(qū)域
- 因?yàn)榉糯髮蛹?jí)是12,橫軸或縱軸存在的瓦片個(gè)數(shù)為
- 像素長(zhǎng)度比為
- container 展示的地圖面積為
中心點(diǎn)的投影坐標(biāo)點(diǎn)為
container 展示的地圖區(qū)域?yàn)?/p>
- 所在橫軸區(qū)間 [12934389.117239695, 12980251.334210802]
- 所在縱軸區(qū)間 [4833585.295927367, 4871803.810069955]
- 計(jì)算出要展示的瓦片
- 瓦片編號(hào)計(jì)算公式
那么屏幕可視區(qū)范圍展示的瓦片分布就應(yīng)該是:
- 驗(yàn)證
在 ID 編輯器上,將背景配置成高德瓦片,并將放大層級(jí)設(shè)定為12,中心定位到天安門(mén),可以得到如下圖所示內(nèi)容,發(fā)現(xiàn)屏幕內(nèi)瓦片展示和我們之前手動(dòng)算出來(lái)的結(jié)構(gòu)保持一致。
在弄清楚地圖的基本渲染邏輯之后,其實(shí)可以對(duì)地圖的渲染進(jìn)行一定程度的魔改,比如將游戲地圖嵌到世界地圖上去:
參考
【1】 基于Web墨卡托投影的地圖算法研究和實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用研究,2012,29(12):4793-4796.
【2】幾種互聯(lián)網(wǎng)地圖服務(wù)背后的解讀(WMS,WFS,WMTS,TMS)[5]
【3】參心坐標(biāo)系和地心坐標(biāo)系[6]
【4】墨卡托投影? ArcGIS Pro | 文檔[7]
【5】聊聊GIS中的坐標(biāo)系|再版[8]
參考資料
[1]常見(jiàn)的地圖投影方式: https://pro.arcgis.com/zh-cn/pro-app/latest/help/mapping/properties/list-of-supported-map-projections.htm
[2]EPSG: https://epsg.io/
[3]高德API: https://lbs.amap.com/api/webservice/guide/api/convert/
[4]http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}: http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}
[5]幾種互聯(lián)網(wǎng)地圖服務(wù)背后的解讀(WMS,WFS,WMTS,TMS): https://zhuanlan.zhihu.com/p/398998331
[6]參心坐標(biāo)系和地心坐標(biāo)系: https://www.jianshu.com/p/7bbbd86dec82
[7]墨卡托投影? ArcGIS Pro | 文檔: https://pro.arcgis.com/zh-cn/pro-app/latest/help/mapping/properties/mercator.htm
[8]聊聊GIS中的坐標(biāo)系|再版: https://zhuanlan.zhihu.com/p/98839097