瓦片地图坐标相关计算

瓦片地图坐标相关计算
在给定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;

}

你可能感兴趣的:(计算)