瓦片地圖座標相關計算

來源:互聯網
上載者:User
在給定level下,把行號tileY和列號tileX 轉換為2進位,然後 行列交叉儲存,再 轉換為4進位,即得到了相應的quadkey。譬如Level 3的第6行第4列的Tile計算:tileY = 5 = 101 ,tileX = 3 = 011;quadkey = 100111 = 213(4進位) = “213”。那麼,下面我們給出C#的代碼實現
/// <summary>
/// Converts tile XY coordinates into a QuadKey at a specified level of detail.
/// </summary>
/// <param name="tileX">Tile X coordinate.</param>
/// <param name="tileY">Tile Y coordinate.</param>
/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
/// to 23 (highest detail).</param>
/// <returns>A string containing the QuadKey.</returns>
public static string TileXYToQuadKey(int tileX, int tileY, int levelOfDetail)
{
StringBuilder quadKey = new StringBuilder();
for (int i = levelOfDetail; i > 0; i--)
{
char digit = '0';
int mask = 1 << (i - 1);
if ((tileX & mask) != 0)
{
digit++;
}
if ((tileY & mask) != 0)
{
digit++;
digit++;
}
quadKey.Append(digit);
}
return quadKey.ToString();
}
接下來是反算代碼
/// <summary>
/// Converts a QuadKey into tile XY coordinates.
/// </summary>
/// <param name="quadKey">QuadKey of the tile.</param>
/// <param name="tileX">Output parameter receiving the tile X coordinate.</param>
/// <param name="tileY">Output parameter receiving the tile Y coordinate.</param>
/// <param name="levelOfDetail">Output parameter receiving the level of detail.</param>
public static void QuadKeyToTileXY(string quadKey, out int tileX, out int tileY, out int levelOfDetail)
{
tileX = tileY = 0;
levelOfDetail = quadKey.Length;
for (int i = levelOfDetail; i > 0; i--)
{
int mask = 1 << (i - 1);
switch (quadKey[levelOfDetail - i])
{
case '0':
break;

case '1':
tileX |= mask;
break;

case '2':
tileY |= mask;
break;

case '3':
tileX |= mask;
tileY |= mask;
break;

default:
throw new ArgumentException("Invalid QuadKey digit sequence.");
}
}
}
上面所講到的是針對bingmap的情況,googleearth採用QRTS編碼,即Q、R、T、S分別代表0、1、2、3,運算方法類似,代碼如下
        /// <summary>        /// 由tileX、tileY和level求解quadkey        /// </summary>        /// <param name="tileX"></param>        /// <param name="tileY"></param>        /// <param name="levelOfDetail"></param>        /// <returns></returns>        private static string TileXYToQuadKey(int tileX, int tileY, int levelOfDetail)        {            var quadKey = new StringBuilder();            for (int i = levelOfDetail; i > 0; i--)            {                char digit = '0';                //掩碼,最高位設為1,其他位設為0                int mask = 1 << (i - 1);                //與運算取得tileX的最高位,若為1,則加1                if ((tileX & mask) != 0)                {                    digit++;                }                //與運算取得tileY的最高位,若為1,則加2                if ((tileY & mask) != 0)                {                    digit++;                    digit++;                }                //也即2*y+x                quadKey.Append(digit);            }            return quadKey.ToString();        } protected static string QuadKeyNumberToAlpha(string base4)        {            return base4.Replace('0', 'q').Replace('1', 'r').Replace('2', 't').Replace('3', 's');        }private static string QuadKeyNumberToAlphaUrl(string url, int tilePositionX, int tilePositionY, int zoom)        {            string quadKey = TileXYToQuadKey(tilePositionX, tilePositionY, zoom);            //擷取最後一位,選擇4個伺服器中的一台            string str3 = quadKey.Substring(quadKey.Length - 1, 1);            string str4 = QuadKeyNumberToAlpha(quadKey);            url = string.Format(url, str4, str3);            return url;        }
Google衛星地圖是由256x256大小的jpg圖片拼接而成,每塊圖片的URL格式為“http://kh.google.com/kh?v=3&t=trstrq”樣。參數v選擇4台伺服器中的一台,起到均衡負載的作用,參數t是“qrst”4個字元排列而成的字串。為擷取某經緯度的URL,就需要把經緯度轉化為“qrst”字串。 Google衛星地圖在zoom=1時,全球就為一個256x256的圖片,它的中心經緯度為(0,0),URL為“http://kh.google.com/kh?v=3&t=t”。zoom=2時裂化為4塊,每塊的編號為:左上”t=tq”,右上”t=tr”,右下“t=ts”,左下”t=tt”。依此類推,每放大一倍,每一小塊都裂分為四,從左上到右下順時針按qrst編號,裂分後的編碼為裂分前的編號上小塊的編號。代碼如下:
function GetQuadtreeAddress(long, lat){var PI = 3.1415926535897;var digits = 18; // how many digits precision// now convert to normalized square coordinates// use standard equations to map into mercator projectionvar x = (180.0 + parseFloat(long)) / 360.0;var y = -parseFloat(lat) * PI / 180; // convert to radiansy = 0.5 * Math.log((1+Math.sin(y)) / (1 - Math.sin(y)));y *= 1.0/(2 * PI); // scale factor from radians to normalizedy += 0.5; // and make y range from 0 - 1var quad = "t"; // google addresses start with tvar lookup = "qrts"; // tl tr bl brwhile (digits–){// make sure we only look at fractional partx -= Math.floor(x);y -= Math.floor(y);quad = quad + lookup.substr((x >= 0.5 ? 1 : 0) + (y >= 0.5 ? 2 : 0), 1);// now descend into that squarex *= 2;y *= 2;}return quad;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.