上一篇也說到瓦片,我們為什么使用瓦片?這一篇主要是關於如何拼接地圖?
下面的一張圖,可以一眼明了,地圖是如何切割以及拼接的。
瓦片信息 |
瓦片信息包括切圖原點,瓦片大小,格式,分辨率以及分辨率級別等。
切圖原點,一般是整個坐標系的最左上角,比如說,web墨卡托是[-20037508.3427892, 20037508.3427892]。切圖原點右側列數是正數,左側的列數是負數,下側行數是正數,上側行數是負數。
瓦片的寬度、高度,目前互聯網最常見的瓦片寬度和高度都是256像素。
瓦片格式,可能是png,jpg等。
分辨率,這里不是指電腦的分辨率。而這里意思是一像素代表多少米,類似於比例尺。
分辨率級別,含有若干級別的分辨率,不同的分辨率下面,顯示不同的要素信息。例如,低分辨率下面,顯示洲名稱和海洋名稱。中分辨率下面,顯示省名。高分辨率下面,就顯示POI信息。互聯網企業當中分辨率級別數在20上下。
地圖范圍,切圖的范圍,只在這個范圍下面才切圖,其他的區域都沒有相應的瓦片。如果把所有的分辨率都切完的話,是非常耗時間的。僅僅是中國區域,一台8核的機器,也得需要一個月才能切完,更何況全世界了。
Google為例 |
谷歌使用的web墨卡托投影,分辨率級別一共22級,他的每一級分辨率大小20037508.3427892*2/(256*(2^i))。20037508.3427892*2代表整個的X軸范圍,256代表圖片的像素大小,2代表是0級時有兩列(有的地圖0級只有1列,這個時候就是2^(i-1)),i代表級別。
這個時候,分辨率集合就是[78271.51696402031, 39135.758482010155, 19567.879241005077, 9783.939620502539, 4891.969810251269, 2445.9849051256347, 1222.9924525628173, 611.4962262814087, 305.74811314070433, 152.87405657035217, 76.43702828517608, 38.21851414258804, 19.10925707129402, 9.55462853564701, 4.777314267823505, 2.3886571339117526, 1.1943285669558763, 0.5971642834779382, 0.2985821417389691, 0.14929107086948454, 0.07464553543474227, 0.037322767717371134]。
我們現在需要計算兩個東東,一個是當前分辨率下面最大的行和列數,第二個某一個坐標在第幾行幾列。下面會列出好幾個公式,一定要理解為什么這么計算,否則移植到其他的切圖服務不會自己列出相應的公式了。
最大行數和列數 |
計算公式,20037508.3427892*2/(256*scale),20037508.3427892*2代表X軸和Y軸范圍,256代表圖片的像素大小,scale代表分辨率大小。
通過這個計算公式,我們知道最大的行數和列數,是[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304],注意的是行列值是從0開始的。
比如說,1級下面,有兩行和兩列。這四張圖片的地址如下:
我們把這四張圖片合在一起的話,就變成如下的圖,這就是一個世界的地圖了。
計算行,列位置 |
計算行位置公式:Math.floor((x-(-20037508.3427892))/256/scale))。x-(-20037508.3427892)是最左側的距離,scale分辨率,256代表寬度。Math.floor小於或等於指定數字的最大整數,這樣值是從0開始的。
計算列位置公式:Math.floor((20037508.3427892-y)/256/scale))。20037508.3427892-y是到最上側的距離,scale分辨率,256代表寬度。Math.floor小於或等於指定數字的最大整數,這樣值是從0開始的。
左上角是X值最小,Y值最大。屏幕是X和Y值都是最小的。這一點轉換關系需要明白,否則Y軸的方向都反了。
如果切圖不是從左上角開始的,就得計算每一個分辨率下面的左上角和右下角所處的行和列,就可以知道行和列的范圍。同理,可計算當前可視區域的行和列。
我們如果知道行列以及分辨率等級,就很容易知道這個瓦片的地址。http://mt2.google.cn/vt/x=0&y=0&z=1,這里的x代表參數行數,y代表列數,z代表分辨率等級。
Google這種圖片地址屬於非常好計算,幸好也是非常普遍的。比較難的,算是微軟的,行列以及分辨率等級計算都差不多,難的是想x,y,z參數不知道怎么計算的。
例如,http://ak.dynamic.t2.tiles.virtualearth.net/comp/ch/1232?mkt=en-us&it=G,VE,BX,L,LA&shading=hill&og=31&n=z ,這個圖片地址,這個1232不知道怎么來的。不過幸好找到一個論文才弄明白,《利用BingMaps地圖切片實現網絡地圖服務》,地址http://wenku.baidu.com/link?url=7Mh7h8Vn94V2ha8LJLIy3WF2ONjLwcEaRCywujCR-fk4Pa-PGKrmcKL1zBaOmUK5eDmaIrXbO6SyAPdMHCOAXTn6PnhqBsL6yPsenWdMkfK
我下面列出相關計算代碼。
function getBingMapsImageNumber(x,y,z){ //10進制轉化為2進制,前面補充0 _f=function(n,m){ var t= n.toString(2)+""; for(; t.length<m;){ t="0"+t; } return t; } var _if=_f(x,z); var _jf=_f(y,z); var r=""; for(var k=0;k!=z;++k){ r+=_jf[k]+_if[k]; } r=parseInt(r,2).toString(4); return _f(r,z); }