使用HTML5 canvas做地圖(2)瓦片以及如何計算的


    上一篇也說到瓦片,我們為什么使用瓦片?這一篇主要是關於如何拼接地圖?

    下面的一張圖,可以一眼明了,地圖是如何切割以及拼接的。

瓦片信息

    瓦片信息包括切圖原點,瓦片大小,格式,分辨率以及分辨率級別等。

    切圖原點,一般是整個坐標系的最左上角,比如說,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);
}

  


免責聲明!

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



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