1. 程式人生 > >Google Maps地圖投影全解析

Google Maps地圖投影全解析

Google Maps、Virtual Earth等網路地理所使用的地圖投影,常被稱作Web Mercator或Spherical Mercator,它與常規墨卡託投影的主要區別就是把地球模擬為球體而非橢球體。建議先對地圖投影知識做一個基本的瞭解,《地圖投影為什麼》。

什麼是墨卡託投影?

墨卡託(Mercator)投影,又名"等角正軸圓柱投影",荷蘭地圖學家墨卡託(Mercator)在1569年擬定,假設地球被圍在一箇中空的圓柱裡,其赤道與圓柱相接觸,然後再假想地球中心有一盞燈,把球面上的圖形投影到圓柱體上,再把圓柱體展開,這就是一幅標準緯線為零度(即赤道)的"墨卡託投影"繪製出的世界地圖。從球到平面,肯定有個轉換公式,這裡就不再羅列。

Google們為什麼選擇墨卡託投影?

墨卡託投影的"等角"特性,保證了物件的形狀的不變行,正方形的物體投影后不會變為長方形。"等角"也保證了方向和相互位置的正確性,因此在航海和航空中常常應用,而Google們在計算人們查詢地物的方向時不會出錯。

墨卡託投影的"圓柱"特性,保證了南北(緯線)和東西(經線)都是平行直線,並且相互垂直。而且經線間隔是相同的,緯線間隔從標準緯線(此處是赤道,也可能是其他緯線)向兩級逐漸增大。

但是,"等角"不可避免的帶來的面積的巨大變形,特別是兩極地區,明顯的如格陵蘭島比實際面積擴大了N倍。不過要是去兩極地區探險或可靠的同志們,一般有更詳細的資料,不會來檢視網路地圖的,這個不要緊。

(圖片來源:IDVUX部落格)

為什麼是圓形球體,而非橢球體?

這說來簡單,僅僅是由於實現的方便,和計算上的簡單,精度理論上差別0.33%之內,特別是比例尺越大,地物更詳細的時候,差別基本可以忽略。

Web墨卡託投影座標系:

以整個世界範圍,赤道作為標準緯線,本初子午線作為中央經線,兩者交點為座標原點,向東向北為正,向西向南為負。

X軸:由於赤道半徑為6378137米,則赤道周長為2*PI*r = 20037508.3427892,因此X軸的取值範圍:[-20037508.3427892,20037508.3427892]。

Y軸:由墨卡託投影的公式可知,同時上圖也有示意,當緯度φ

接近兩極,即90°時,y值趨向於無窮。這是那些"懶惰的工程師"就把Y軸的取值範圍也限定在[-20037508.3427892,20037508.3427892]之間,搞個正方形。

懶人的好處,眾所周知,事先切好靜態圖片,提高訪問效率云云。俺只是告訴你為什麼會是這樣子。因此在投影座標系(米)下的範圍是:最小(-20037508.3427892, -20037508.3427892 )到最大 (20037508.3427892, 20037508.3427892)。

對應的地理座標系:

按道理,先講地理座標系才是,比如球體還是橢球體是地理座標系的事情,和墨卡託投影本關聯不大。簡單來說,投影座標系(PROJCS)是平面座標系,以米為單位;而地理座標系(GEOGCS)

經度:這邊沒問題,可取全球範圍:[-180,180]。

緯度:上面已知,緯度不可能到達90°,懶人們為了正方形而取的-20037508.3427892,經過反計算,可得到緯度85.05112877980659。因此緯度取值範圍是[-85.05112877980659,85.05112877980659]。其餘的地區怎麼辦?沒事,企鵝們不在乎。

因此,地理座標系(經緯度)對應的範圍是:最小(-180,-85.05112877980659),最大(180, 85.05112877980659)。至於其中的Datum、座標轉換等就不再多言。

相關座標計算:

關於Google Maps等的組織方式——地圖瓦片金字塔,估計我在這裡重複一遍這玩意,怕也是沒人看了。儘管原理都一樣,但具體到寫不同廠商不同資料來源的程式碼時,你會發現,可縮放級別數不一樣,最小級別不一樣,編碼方式不一樣,比如Google的QRST,微軟的四叉樹,OSGeo的TMS等。

然而,你或許也不必這麼麻煩,因為這些演算法在網路上早已遍佈朝野,你儘可從他人部落格中獲取,或是從開源軟體裡學習。這本身都不是祕密,微軟自己也是公佈的。

Tiles à la Google Maps》 用互動性地方式可得到任一Tile的邊界範圍,各種流行編碼方式等。該頁面的連結都非常有價值,部分也是本文寫作的重要參考。作者用python完成了下列座標之間轉換演算法:經緯度(出現在KML中的座標,WMS的BBOX引數等),平面座標XY(米,Web Mercator投影座標系),金字塔的XYZ(即X軸的位置,Y軸的位置,和縮放級別ZoomLevel),每個Tile的編碼Key值(QRST或0123等)。轉換時,還需要注意兩個概念,Ground Resolution和Map Scale。

(圖片來源:maptiler.org)

Ground Resolution,地面解析度,類似Spatial Resolution(空間解析度),我們這裡主要關注用象元(pixel size)表示的形式:一個畫素(pixel)代表的地面尺寸(米)。以Virtual Earth為例,Level為1時,圖片大小為512*512(4個Tile),那麼赤道空間解析度為:赤道周長/512。其他緯度的空間解析度則為 緯度圈長度/512,極端的北極則為0。Level為2時,赤道的空間解析度為 赤道周長/1024,其他緯度為 緯度圈長度1024。很明顯,Ground Resolution取決於兩個引數,縮放級別Level緯度latitude ,Level決定畫素的多少,latitude決定地面距離的長短。地面解析度的公式為,單位:米/畫素:

ground resolution = (cos(latitude * pi/180) * 2 * pi * 6378137 meters) / (256 * 2level pixels)

    Map Scale,即地圖比例尺,小學知識,圖上距離比實地距離,兩者單位一般都是米。Ground Resolution的計算中,由Level可得到圖片的畫素大小,那麼需要把其轉換為以米為單位的距離,涉及到DPI(dot per inch),暫時可理解為類似的PPI(pixelper inch),即每英寸代表多少個畫素。256 * 2level / DPI 即得到相應的英寸inch,再把英寸inch除以0.0254轉換為米。實地距離仍舊是:cos(latitude * pi/180) * 2 * pi * 6378137 meters; 因此比例尺的公式為,一般都化為1XXX,無單位:

map scale = 256 * 2level / screen dpi / 0.0254 / (cos(latitude * pi/180) * 2 * pi * 6378137)

= 1 : (cos(latitude * pi/180) * 2 * pi * 6378137 * screen dpi) / (256 * 2level * 0.0254)

其實,Map Scale 和 Ground Resolution存在對應關係,畢竟都和實地距離相關聯,兩者關係:map scale = 1 : ground resolution * screen dpi / 0.0254 meters/inch

Virtual Earth Tile System》列舉了Virtual Earth在赤道上,Level、畫素數、地面解析度、地圖比例尺的對應關係,同時本文也簡單介紹了Mercator投影和上述兩個概念,推薦。

此外,《Addressing Google Maps image tiles》應用程式,輸入經緯度和縮放級別,即可縮放到相應的Google Maps位置,而且可以顯示出查詢過程的QRST。JavaScript實現的演算法,也可以抓下來和《Tiles à la Google Maps》對比下,從經緯度到到Tile編碼的轉換。

WKT形式表示

Google Maps和Virtual Earth等的流行程度不用多講,然而他們所使用的Web Mercator或Spherical Mercator在很長一段時間內並沒有被EPSG的投影資料庫所接納。EPSG認為它不能算作科學意義上的投影,所以只是給了一個EPSG:900913的標號(SRID),這個標號遊離在EPSG常規標號範圍之外。(EPSG、SRID是什麼?參見《EPSG 、SRID》。)

    到了2008年5月(據SharpGIS同學), EPSG恍然明白,不管橢球體還是球體,其實都是對地球的模擬,只是精確程度上的差別,沒有本質上的不同。或者是不得不接受廣泛的事實標準,接納了這個投影,定義投影座標系PROJCS的名字為"Popular Visualisation CRS / Mercator",SRID為EPSG:3785;地理座標系GEOGCS的名字為"Popular Visualisation CRS",SRID為"EPSG:4055"。這些標號已經進入"正常範圍"。(PS:這個Visualisation 是英式英語寫法?)

PROJCS 的WKT《Well Known Text》寫法如下,GEOGCS、Datum等的WKT表示參見《Spherical/Web Mercator: EPSG code 3785》。附帶說一句,Web Mercator在ESRI公司的編號(ESRI叫它Well Known ID?)暫時是102113,或許偶爾用得到。

PROJCS["Popular Visualisation CRS / Mercator",
    GEOGCS[
"Popular Visualisation CRS",
        DATUM[
"Popular_Visualisation_Datum",
            SPHEROID[
"Popular Visualisation Sphere",6378137,0,
                AUTHORITY[
"EPSG","7059"]],
            TOWGS84[
0,0,0,0,0,0,0],
            AUTHORITY[
"EPSG","6055"]],
        PRIMEM[
"Greenwich",0,
            AUTHORITY[
"EPSG","8901"]],
        UNIT[
"degree",0.01745329251994328,
            AUTHORITY[
"EPSG","9122"]],
        AUTHORITY[
"EPSG","4055"]],
    UNIT[
"metre",1,
        AUTHORITY[
"EPSG","9001"]],
    PROJECTION[
"Mercator_1SP"],
    PARAMETER[
"central_meridian",0],
    PARAMETER[
"scale_factor",1],
    PARAMETER[
"false_easting",0],
    PARAMETER[
"false_northing",0],
    AUTHORITY[
"EPSG","3785"],
    AXIS[
"X",EAST],
    AXIS[
"Y",NORTH]]

    附記:這個問題算是老問題,費這麼多時間,主要就是分享,畢竟自己還算是相當明白。也是看見有人不懂亂說,寫篇文章糾正下。當然誰都會犯錯誤,包括我這篇是否100%正確,你也可以質疑。起這個題目其實不是本意,因為它不科學,甚至EPSGINFORMATION_SOURCE欄位寫的都是Microsoft,只不過國內Google更火些,SEO一下。

這篇文章除了參考文中所列連結外, MicrosoftGoogleEPSGOGC等組織相關的說明外,Charlie SavageSharpGISNelson John等部落格也是非常重要的來源,在此致以謝意。