zoukankan      html  css  js  c++  java
  • 瓦片地图坐标相关计算

    在给定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 projection
    var x = (180.0 + parseFloat(long)) / 360.0;
    var y = -parseFloat(lat) * PI / 180; // convert to radians
    y = 0.5 * Math.log((1+Math.sin(y)) / (1 - Math.sin(y)));
    y *= 1.0/(2 * PI); // scale factor from radians to normalized
    y += 0.5; // and make y range from 0 - 1
    var quad = "t"; // google addresses start with t
    var lookup = "qrts"; // tl tr bl br
    while (digits–)
    {
    // make sure we only look at fractional part
    x -= 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 square
    x *= 2;
    y *= 2;
    }
    return quad;
    }
  • 相关阅读:
    【PAT】B1041 考试座位号(15 分)
    【PAT】B1042 字符统计(20 分)
    【PAT】B1044 火星数字(20 分)
    LeetCode 3Sum Closest
    一定要做的事(备忘)
    LeetCode Integer to Roman
    Container With Most Water
    LeetCode ZigZag Conversion
    LeetCode 5 最长回文子串 Manacher线性算法
    LeetCode Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/junyuz/p/2021035.html
Copyright © 2011-2022 走看看