天天看點

Google瓦片地圖算法解析 概述:主要是闡述如何将瓦片地圖圖檔拼接成完整地圖的一些概念以及相關算法。

概述:主要是闡述如何将瓦片地圖圖檔拼接成完整地圖的一些概念以及相關算法。

基本概念:

  • 地圖瓦片位址:http://mt2.google.cn/vt/[email protected]&hl=zh-CN&gl=cn&x=420&y=193&z=9&s=Galil

      

Google瓦片地圖算法解析 概述:主要是闡述如何将瓦片地圖圖檔拼接成完整地圖的一些概念以及相關算法。

      現在就是要将一張張這類的地圖瓦片,在用戶端拼接成一幅完整的地圖。

      瓦片大小為:256x256。

      url中關鍵參數解析:

參數 描述
mt2.google.cn Google瓦片服務伺服器,可以嘗試mt1.google.cn依然有效。Google提供多台瓦片伺服器,減輕伺服器負載,提高網絡通路效率。
x 瓦片的橫向索引,起始位置為最左邊,數值為0,向右+1遞增。
y 瓦片的縱向索引,起始位置為最上面,數值為0,向下+1遞增。
z 地圖的級别,以Google為例,最上一級為0,向下依次遞增。
  • 地圖投影:Web墨卡托——網際網路地圖通用的地圖投影方式,将橢圓形地圖投影成平面上的正文形,欲了解詳情請baidu之,如無特殊說明本文所指均為Web墨卡托投影下。
  • Bounds(地圖範圍):[ -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892],機關為米,20037508.3427892表示地圖周長的一半,以地圖中心點做為(0,0)坐标。
  • Levels:地圖的級别,例如:0……22。
  • Resolutions:分辨率數組,與級别相對應,即一個級别對應一個分辨率,分辨率表示目前級别下單個像素代表的地理長度。
Resolutions[n] = 20037508.3427892 * 2 / 256 / (2^n)      
  • Center:地圖顯示中心點。
  • Level:地圖顯示級别。
  • viewSize:地圖控件視窗的大小。

  根據已知地圖中心點、顯示級别可以将地圖顯示範圍計算出來:

viewBounds = [Center.x - Resolutions[l]*viewSize.width/2, Center.y - Resolutions[l]*viewSize.height/2, Center.x + Resolutions[l].viewSize.width/w, Center.y + Resolutions[l].viewSize.height/h]      

  地圖切圖方式:

    一幅地圖由4^n個256的正方形組成,n為級别

    例如:第0級為4^0個,即世界地圖由一個256圖檔表示。

    

Google瓦片地圖算法解析 概述:主要是闡述如何将瓦片地圖圖檔拼接成完整地圖的一些概念以及相關算法。

    第1級世界地圖應由4^1(4)個256圖檔組成,也就是将世界地圖(上一級的單個圖檔)等分成4塊256圖檔。

    往下每一級依此類推……

拼圖算法剖析:

 1、計算瓦片url

  要想出圖就發須知道地圖控件可視範圍起始點瓦片索引、末尾瓦片索引,中間區域的瓦片索引循環周遊即可得出。

  下面看看如果計算出起始點、末尾瓦片url索引:

    已知:l(縮放級别)、bounds(地圖範圍——[ -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892])、viewBounds(地圖控件可視範圍)、分辨率(Resolutions[l])、瓦片像素寬高(256)。

    未知:startX(視圖起始瓦片X方向索引)、startY(視圖起始瓦片Y方向索引)、endX(視圖未尾瓦片x方向索引)、endY(視圖未尾瓦片y方向索引)。

    求解:

startX = floor(((viewBounds.leftBottom.x - bounds.leftBottom.x) / Resolutions[l]) / 256);
startY = floor(((viewBounds.leftBottom.y - bounds.leftBottom.y) / Resolutions[l]) / 256);
endX = floor(((viewBounds.rightTop.x - bounds.rightTop.x) / Resolutions[l]) / 256);
endY = floor(((viewBounds.rightTop.y - bounds.rightTop.y) / Resolutions[l]) / 256);      

    firstTileUrl(起始瓦片Url) = http://**********?x=startX&y=startY&z=l;

    endTileUrl(末尾瓦片Url) = http://**********?x=endX&y=startY&z=l;

    中間部分的url循環周遊即可得出。

  好啦!組成視圖所有瓦片的url都已得出。下面就是要解決将這些瓦片放到哪的問題。

 2、計算瓦片放在地圖控件上的位置

  先分析一下:其實隻要将起始位置的瓦片像素位置算出來就可以了,由于瓦片像素大小為256,後面的各瓦片位置也就明了了。

  是以這裡隻探讨一下起始瓦片的像素位置。

    已知:startX(視圖起始瓦片X方向索引)、startY(視圖起始瓦片Y方向索引)、分辨率(Resolutions[l])、瓦片像素寬高(256)、bounds(地圖範圍——[ -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892])、viewBounds(地圖控件可視範圍)。

    未知:startTileX(起始瓦片左上角X方向地理坐标)、startTileY(起始瓦片左上角Y方向地理坐标)、distanceX(瓦片左邊與地圖控件左邊相距的像素距離)、distanceY(瓦片上邊與地圖控件上邊相距的像素距離)。

    求解:

startTileX = bounds.leftBottom.x + (startX * 256 * Resolutions[l]);
startTileY = bounds.rightTop.y - (startY * 256 * Resolutions[l]);
distanceX = (viewBounds.leftBottom.x - startTileX) / Resolutions[l];
distanceY = (startTileY - viewBounds.rightTop.y) / Resolutions[l]      

  公式不是最簡,以友善了解,相信看官此時已經知道起始瓦片在地圖控件中的擺放位置了——設地圖控件起始像素位置為(0,0),那麼此瓦片的像素的位置就是(-distanceX、-distanceY)。其它瓦片依據256像素寬高的關系依次而出。

到此已經算出了各瓦片的url以及它們應該擺放的位置,準備工作已完成,直接帖圖即可完成出圖工作。

算法可應用于Google、Baidu、Yahoo、Bing等web墨卡托投影的地圖瓦片。

原文出處:http://www.cnblogs.com/ninemilli/archive/2011/12/26/2289285.html

繼續閱讀