Google tile和TMS的索引算法


TMS是tile map service的縮寫,是一種瓦片地圖服務,也稱之為WMTS(web map tile service),具體的標准可以見OGC網站。TMS的算法很簡單,就是把投影后的世界地圖按照層級進行四叉樹(待驗證)切割,切割后的瓦片數量隨層級呈金字塔型,數量和層級關系如下表所示:

0 1 tile covers whole world 1 tile
1 2 × 2 tiles 4 tiles
2 4 × 4 tiles 16 tiles
n 2n × 2n tiles 22n tiles
12 4096 x 4096 tiles 16.777.216
16 Maximum zoom for OpenCycleMap (mostly) 232 = 4.294.967.296 tiles
17 Maximum zoom for Osmarender layer 17.179.869.184 tiles
18 Maximum zoom for Mapnik layer 68.719.476.736 tiles

對這些瓦片進行編號,由於瓦片編號的規律性(平面直角坐標系),加上投影也是一種算法(球形展開成平面),所以,編號和坐標之間就建立了一種索引關系,通過編號可以得到經緯度區間,通過經緯度可以找到瓦片的編號,具體的計算公式如下:

n = 2 ^ zoom
xtile = ((lon_deg + 180) / 360) * n
ytile = (1 - (log(tan(lat_rad) + sec(lat_rad)) / π)) / 2 * n

由公式可以看出,只要確定經緯度和層級,就可以得到瓦片的編號索引,相反,若知道編號就可以去推算未知的經緯度了,其計算公式如下:

n = 2 ^ zoom
lon_deg = xtile / n * 360.0 - 180.0
lat_rad = arctan(sinh(π * (1 - 2 * ytile / n)))
lat_deg = lat_rad * 180.0 / π

所以:一、顯示地圖的時候就可以根據中心坐標和層級以及bound范圍,就可以確定需要加載那些地圖瓦片;二、mark一個point的時候,根據point的經緯度以及tile的經緯度范圍,就可以確定point在某一tile的像素坐標位置,而tile同bound之間又有像素關系,所以point就可以mark到map的bound上了;三、同二相反,鼠標在bound上單機,也就可以得到具體的經緯度信息了。這應該是webmap引擎實現豐富多樣地圖效果的基礎吧,包括線、面、地圖疊加等更多功能。

我從網上找了一段開源的代碼,重新組了一下,可以通過在線的方式獲得編號同經緯度之間的正反算了,體驗網址:http://rovertang.com/labs/tileindex/,你輸入經緯度並選擇層級后就可以得到Google tile和TMS的瓦片索引編號了,效果如下圖:

tileIndex

需要說明的是,Google tile同TMS有差別,原因是:Google tile的直角坐標系原點在左上角(即北極點同中央子午線的交點),而TMS的原點在左下角(南極點同中央子午線的交點)。所以:編號索引中的x軸不變,y軸略有變化,結果為該列所有tile減去y再減去1,公式就不再羅列了,可以直接查看我提供的網址分析源代碼吧。我們以上海世博演藝中心(現為梅賽德斯奔馳演藝中心)的坐標來演示一下Google tile和TMS的索引差異吧,經過計算,在14層級下,Google tile的x和y分別為13721和6696,而TMS的x和y為13721和9687,兩者的tile網址可訪問這兩個連接:http://mt0.google.com/vt/lyrs=m@174000000&hl=zh-CN&src=app&x=13721&s=&y=6696&z=14&s=Galileohttp://rovertang.com/labs/GMAPIv3_Offline/expotile/14/13721/9687.png,后者是我通過maptiler工具切割的世博地圖tile(在上次的Google Maps API v3離線開發包一文中我有提供下載,現增加演示網址:http://rovertang.com/labs/GMAPIv3_Offline/),兩者對比如下:

tilecompare

BTW:如果你需要更多的將TMS算法公式變為可執行代碼,那么請參考OSM的wiki:Slippy map tilenames,文中提供了python、perl、PHP、.net等語言的code,有興趣的可以參考一下。

 

 

最后:本文雖然參考了較多的瓦片文章,但對瓦片地圖的理解可能仍然有片面之處,歡迎交流和指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM