参考地址 地图瓦片规则分析
1.腾讯地图瓦片与Google地图瓦片区别和联系
1)腾讯地图瓦片与Google的地图瓦片切割方法相同,只不过腾讯地图瓦片完全遵循TMS标准,Google地图瓦片则是TMS的一种变种。
2)地图投影坐标系均采用Web Mercator投影,地图瓦片分辨率也完全一致。
3)腾讯地图瓦片的坐标原点在左下角【-85.05112877980659,-180】,Google 地图瓦片的坐标原点在左上角【85.05112877980659,-180】。
4)腾讯瓦片的最小缩放级别为4级,通过与腾讯低级别瓦片地址的对比分析,得出其ULR地址与xyz参数的对应关系如下:
腾讯瓦片计算方法:URL = z / Math.Floor(x / 16.0) / Math.Floor(y / 16.0) / x_y.png,其中x,y,z为TMS瓦片坐标参数。
5)与Google瓦片坐标的关系,上式中腾讯地图瓦片坐标的x,z与Google 瓦片坐标系的X 、Z是相等的,Y 的转换关系为:Y(Tencent) + Y(Google) = Math.pow(2,zoom) - 1
6)为了保密,腾讯地图与Google地图在大陆地区均进行了偏移处理,采用的是国家火星坐标系GCJ-02。
2.腾讯与Google地图瓦片转换实例:
Google瓦片: http://mt2.google.cn/vt/lyrs=m@258000000&hl=zh-CN&gl=CN&src=app&x=214130&y=114212&z=18&s=Ga
腾讯瓦片:http://p3.map.gtimg.com/maptilesv2/18/13383/9245/214130_147931.png?version=20130701
下面示例中 xyz为Google瓦片地图的参数。
int x = 214130;
int y = 114212;
int z = 18;
y = int.Parse( Math.Pow(2, z).ToString()) - 1 - y;
string url = z.ToString() + "/" + Math.Floor(x / 16.0).ToString() + "/"
+ Math.Floor(y / 16.0).ToString() + "/" + x.ToString() + "_"
+ y.ToString() + ".png"; //计算结果:18/13383/9245/214130_147931.png
由经纬度坐标得到腾讯地图的瓦片/切片行列号
经纬度坐标 => 投影坐标;腾讯地图使用的是Web Mercator投影。
private double[] getXY(double lon, double lat) {
double earthRad = 6378137.0;
double x = lon * Math.PI / 180.0 * earthRad;
double a = lat * Math.PI / 180.0;
double y = earthRad / 2.0 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
return new double[]{x, y};
}
腾讯地图坐标原点在左下角,根据瓦片级数求出瓦片长宽;18级代表该级数下,每行每列的瓦片数为Math.pow(2,18)。
计算行列号,即投影坐标值之差 / 瓦片大小;下为完整代码,其中-85.05112877980659, -180是原点的经纬度。
double[] sz = getXY(120.141554 ,30.273926);
int z = 18;
double[] bl = getXY(-180, -85.05112877980659);
double[] tl = getXY(-180, 85.05112877980659);
double[] br = getXY(180, -85.05112877980659);
System.out.println(String.format("坐标BL点:%f,%f", bl[0], bl[1]));
System.out.println(String.format("坐标TL点:%f,%f", tl[0], tl[1]));
System.out.println(String.format("坐标BR点:%f,%f", br[0], br[1]));
System.out.println(String.format("坐标:%f,%f", sz[0], sz[1]));
double w = (br[0] - bl[0]) / Math.pow(2, z);//格网宽度
double h = (tl[1] - bl[1]) / Math.pow(2, z);//格网高度
System.out.println(String.format("格网大小:%f x %f", w, h));
int[] gridxy = new int[2];
int c = (int) ((sz[0] - bl[0]) / w);
int r = (int) ((sz[1] - bl[1]) / h);
System.out.println(String.format("对应行列号:%d,%d", c, r));
double c_d = Math.floor(c / 16.0);
double r_d = Math.floor(r / 16.0);
System.out.println(String.format("对应请求url:http://p3.map.gtimg.com/maptilesv2/%d/%d/%d/%d_%d.png", z, (int) c_d, (int) r_d, c, r));
3.百度地图坐标系统及地图瓦片分辨率
1)百度地图坐标系统解析:https://blog.csdn.net/qq_18298439/article/details/93327120
2)百度地图瓦片分辨率与比例尺:
18级,1个像素代表1米,17级,1个像素代表2米,16级代表4米,依此类推。
3)百度地图地图投影采用的依然是Web Mercator投影,地图瓦片的切片规则遵循TMS标准,瓦片坐标原点在经纬度为0的附近,但却做了一定的偏移处理,经测算深圳地区的偏移量约为(-865,15850),即地图瓦片(0, 0)是从Web Mercator投影坐标系的(-865,15850)点开始的。
4)为了保密,百度地图做了偏移处理,使用的是百度的BD-09坐标系,在国家要求的火星坐标系GCJ-02上做了进一步的处理,因此GPS经纬度定位会出现偏移。
4.地图分辨率、比例尺及像素PPI之间的关系
比例尺,通常以比率(如 1:10000 )来表示,表示图上距离与实地距离之比。例如 1:10000 表示图上 1cm 代表实际距离 10000cm,即100米。 由于比例尺起源较早,通常用(纸质)图上的距离衡量实际距离;而分辨率则通常用设备屏幕上的距离来衡量实际距离。而同一个地图视图,尺度是唯一的,比例尺和分辨率只不过是两种表示方法,因此它们是一一对应的。 比例尺与分辨率之间的换算公式如下:
Scale:地图比例尺;Resolution:地图分辨率;PPI:每英寸的像素点数。
其中 PPI,即 Pixel per Inch,即每英寸的像素点数(在不混淆情况下,也有用 DPI 来表示该参数)。0.0254 为英寸和米的转换常数。
5.总结
腾讯、百度、Google的地图投影均采用Web Mercator 投影坐标系;腾讯与Google的地图瓦片分辨率及切片范围是完全相同的,仅仅是命名规则稍有不同,这就使得同一位置和缩放级别的地图瓦片是完全可以重叠的;而百度地图每个缩放级别分辨率与前两者均不相同,而且地图瓦片的坐标原点做了一定的偏移,导致百度地图与前两者的瓦片是无法重叠的,这是因为百度在GCJ-02的基础上又进行了加密处理,形成了百度独有的BD-09坐标系。