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圖片表示。

    

    第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

發佈了7 篇原創文章 · 獲贊 4 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章