admin 管理员组文章数量: 1184232
这个是从别人哪里转来的,具体网址忘了copy来了,请作者见谅,呵呵
转自去年看到的一篇文章 目前已经不能访问了,另外Tile服务器的地址也换了。更新一下,留作备份。
Google Map 瓦片图算法分析
Map tile编码
Google map使用两种算法对tile的位置进行编码。
对于Google ditu,tile的url地址类似于: 使用x和y来设置tile坐标和放大因子。放大因子从17(完全缩小)到0(最大比例)。当放大因子为17时,整个地球在一个tile中显示,此时x=0 ,y=0;放大因子为16时,地球被分为2x2部分,这时0<=x<=1 且0<=y<=1。每放大一次,每个tile被分为4个部分。因此,当放大因子为z时,显示的水平和垂直tile个数为2^(17-z)。
理论上的算法会像下面这样的:
//correct the latitude to go from 0 (north) to 180 (south),
// instead of 90(north) to -90(south)
latitude=90-latitude;
//correct the longitude to go from 0 to 360
longitude=180+longitude;
//find tile size from zoom level
double latTileSize=180/(pow(2,(17-zoom)));
double longTileSize=360/(pow(2,(17-zoom)));
//find the tile coordinates
int tilex=(int)(longitude/longTileSize);
int tiley=(int)(latitude/latTileSize);
上面是假设投影为平面。
实际上googlemap,51ditu在显示时使用了墨卡托投影,因此上述的算法需要进行修改。
在墨卡托投影中,两条纬线间的距离不一定相等,所以纬度对应的titley会依据它的垂直位置。
以下代码为从tile的纬度位置计算的tile的垂直个数
Collapse
private int getMercatorLatitude(double lati)
{
double maxlat = Math.PI;
double lat = lati;
if (lat > 90) lat = lat - 180;
if (lat < -90) lat = lat + 180;
// conversion degre=>radians
// 转换度数到弧度
double phi = Math.PI * lat / 180;
double res;
//网上其他帖子这个地方有问题,应该为加号
//double temp = Math.Tan(Math.PI / 4 + phi / 2);
//res = Math.Log(temp);
//下面这一句是上面的合并
res = 0.5 * Math.Log((1 + Math.Sin(phi)) / (1 - Math.Sin(phi)));
double maxTileY = Math.Pow(2, zoom);
int result = (int)(((1 - res / maxlat) / 2) * (maxTileY));
return (result);
}
覆盖地带:
理论上,纬度范围应该是-90度到90度,但事实上,由于墨卡托投影使得两级无穷大,覆盖的地带小于-90 到 90。
最后加上 Python 验证代码
版权声明:本文标题:地图爱好者的福音:利用Google Map和Flash创造沉浸式体验 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1773625269a3564089.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论