在使用openlayers等javascript库来加载互联网在线地图或是geoserver等发布的切片地图的时候,经常需要对地图服务的相关元数据进行配置,如size、origin、dpi、lods等。本文将对以上配置项进行详细的说明,并以天地图在线地图服务为例配合讲解。
配置项
size
size即是切片地图每一个图片的大小,一般表示形式为数组形式,即[width, height]。当前阶段,常用的切片大小为[256, 256],即每一个图片的大小为256 * 256,单位为px。
origin
origin为切片计算的起点,用于确定在每一个比例尺下,行列号为(0,0)的切片的位置。origin通常使用一组数字来表示,分别表示x和y坐标。具体来说,origin所表示的位置,为行列号为(0,0)的切片的左上角所表示的位置。
dpi
dpi,它表示的意义是图片上每英寸长度内的像素的个数。常用的切片方案中,dpi为96,即每英寸长度内的像素的个数为96个(每英寸中像素为96px)。切图dpi也可自行定义,比如在某些版本的geoserver(geowebcache)服务器下,切图dpi为90。在使用arcgis server发布切片地图服务的过程中,也可自行更改dpi参数,默认情况下arcgis server切片的dpi为96。
高德地图切片dpi不唯一,分两个阶段。在1-9层级,dpi为44.38498293515359。在10-18层级,dpi为96.04726735598229。(此处描述有误,详情见文末说明)
天地图、谷歌地图的dpi为96.04726735598229。
百度地图的切片dpi为72.00885935769656。
以上dpi数字的计算方法是:
- 获取对应切片,查看图片的长和宽(以cm为单位),计为width。将cm转换为对应的英寸,即为width / 2.54
- 根据dpi定义,计算dpi为 256 / (width / 2.54)。
lods
lods为切片地图的重要参数,相对来说复杂一些。不同的切片地图,对应的lods参数也往往不同。lods的形式通常为数组形式,每一个数组项都表示了一个lod,lod中包含了level、resolution、scale等信息。
1 | [ |
level
level即为切片方案的层级,用数字表示,反应到地图上即表示的是地图的zoom信息,也可以称之为缩放级别。具体数字为0或是1,并不重要,可以自行定义。
resolution
resolution表示的为切片的分辨率,意义为图上1px的距离表示实际距离的多少。resolution的作用为确定当前点位置所在的切片的行列号。大致的计算的方法如下:
- 计算出当前点位置和origin点位置的x和y的差值,表示了两点之间的实际距离。已知origin点所在的切片的行列号为(0,0)。
- 使用两点之间的实际距离,去除当前的resolution,可以得出当前点和origin点之间的像素距离。
- 计算出了两点之间的像素距离,并且已知了每一个切片的大小(比如为256px * 256px),则可以计算出两者之间的切片的个数,即大体可得当前点和origin点在水平方向和竖直方向上存在着多少个切片,即得出行号和列号。
以上,说明了resolution参数的作用。下面,来说明如何来计算resolution的值。
以天地图的web mercator投影(wkid:3857)的在线切片地图为例,其在线地图切片的第0个层级的resolution信息如下:
1 | { |
那以上的resolution是如何计算出来的呢?
计算过程如下:已知web mercator投影的地理坐标系为WGS84坐标系,参考椭球的长半轴长度为6378137米,那么此椭球的赤道周长为6378137 * 2 * math.pi = 40075016.68557849米。天地图的切图方案中,在0层级,会使用一张256 * 256的图片来表示整个世界范围。根据resolution的定义,在第0层级中,resolution则可以计算得出40075016.68557849 / 256 = 156543.03392804097,即是上面写出的数字。
上面已经说到,天地图的切图方案中,第0层级,使用一张256 * 256 大小的图片来表示整个世界范围。在下一个层级,即第1层级中,在水平方向和竖直方向,分别会一分为二,即使用共计4张256 * 256的图片来表示整个世界范围。由于同一方向上,图片一分为2,则可知resolution变为上一层级的二分之一,即78271.51696402048。往下的层级中,以此类推。
(实际上,当前的天地图切图方案中,第0层级中并没有真正的进行切图,访问第0层级的切片地址,将返回一个空白图片。)
说完了resolution之后,再回到上面提到的origin。回顾一下,origin是指切图方案中计算切片序号的起始点。起始点origin在一定程度上可以自行定义,只要定义的origin可以满足切图的需要。web mercator投影的天地图的切图方案origin定义为[-20037508.342787, 20037508.342787],整个的切图范围为[-20037508.342787, -20037508.342787,20037508.342787, 20037508.342787]。在以上说明的基础上,可以给出此origin的计算方法。
xxxxxxxxxx private static void decode(Line line, String part, BiConsumer<Point, Double> consumer) { List
如下图所示,天地图的第0层级中,四张切片拼接之后,表示了整个的世界范围(从图上可以看出来,web mercator投影中,在高纬度地区,面积和形状的变形都相当之大,特别明显的就是北极附近的格陵兰岛。这也是为什么不推荐在web mercator投影下,计算大面积地物的面积。实践证明,对于省市行政区的面积计算,在web mercator投影下的面积计算,确定不具备现实意义)。
图片上的序号为切片的行号和列号,它们的url地址分别为,感兴趣的可以自行加载验证。
如上所示,为天地图第2层级的16张切片拼接之后的展示效果,具体的切片地址就不再一一给出,从上述给出的地址中可以简单的推出。
天地图在线地图与谷歌在线地图服务、高德在线地图服务一个显著的区别是,它除了提供web mercator投影的切片方案之外,还额外提供了wgs84坐标系的切片方案。这两种方案的最大差异是,origin和lods信息都不一致。根据上面所讲的计算方案,可以得出在wgs坐标系下的切片方案,其origin为[-180, 90],整个切图范围在[-180,-90,180,90],在第0层级下的resolution为180 * 2 / 256 = 1.40625,其余层级的resolution可以依次计算。
在地理坐标系下,切图url地址如下所示。替换TILEMATRIX、TILEROW、TILECOL参数后,即可获取任一需要的切片。
地理坐标系下,第1层级的切片拼接后,展示如下。由于地理坐标系下的切图整个范围为[-180,-90,180,90]。水平方向上的长度是竖直方向上的2倍,导致水平方向上需要的切片数量也将是竖直方向上切片数量的2倍。因此,(0,0)和(0,1)两张图片即可表示整个世界范围,(1,0)和(1,1)两张图片为空白图片。
第2层级的切图拼接效果如下所示。
scale
scale是指图上距离与实际距离的比值(表示形式为1:M,图上1cm,表示真实的距离为Mcm),表示的含义是放缩的尺度。scale与具体的切图方案无关,而是切图方案确定之后的衍生信息。根据以上的dpi、resolution等信息,可以计算出在给定resolution的情况下,比例尺的大小。
scale的计算可以从以下的推导得出:
- 已知resolution的概念为1px表示实际距离的多少(在投影坐标系下,以米为单位;在地理坐标系下,以度为单位),dpi的概念为1英寸中包含多少个像素(px)。
- 从1可知,1英寸中包含的实际距离为dpi * resolution。
- 1英寸等价于2.54cm。从2可知,图上距离的0.0254米,表示了真实距离的dpi * resolution 米,则可知比例尺的大小为 dpi * resolution / 0.0254。
再看一下,天地图的web mercator投影(wkid:3857)的在线切片地图,其在线地图切片的第0个层级的resolution信息如下:
1 | { |
根据我们以上的推导,计算出的比例尺应该为 96 * 156543.033928 / 0.0254 = 591658710.9089763。结果与以上的比例尺数字相符。
以上,我们验证了在web mercator投影下的resolution和scale之间的关系,那这个计算方法在wgs84坐标下是否也成立呢?
结果是显然的,这个计算公式并不成立。原因也很明显,resolution的概念是和具体坐标系相关,在投影坐标系下,表示1px表示实际距离多少米,而在地理坐标系下,表示1px表示实际距离多少度,而scale的概念则一直是图上1cm表示实际距离多少cm。这之间就出现了一个单位上的不一致。弥补的方法也非常的简单,通过dpi * resolution / 0.0254,计算出的结果是图上1cm表示实际坐标单位。在投影坐标系的情况下,实际坐标单位为米,结果满足比例尺的定义,不需要再行计算。在地理坐标系的情况下,实际坐标单位为度,将此结果再乘以一个mpu(mpu = meter per unit,每一坐标单位表示多少米)即可。
对于投影坐标系,可以认为mpu为1。对于地理坐标系来说,可以认为mpu为赤道的周长 / 360。
先给出再wgs84坐标系下的某个lod定义,如下。
1 | { |
通过我们上述的说明,计算scale = 0.703125 * 96 / 0.0254 * (math.pi * 2 * 6378137) / 360 = 295829355.45456564。和上述给出的scale数字相比,验证了计算方法的正确。
以上,即对切片地图相关的配置信息、用途,以及如何对这些配置信息进行计算给出了详细的说明。具体的数字无需记忆。从定义入手,可以简单的计算得出。
常见地图切片方案总结
天地图
天地图的相关信息,在上文中已进行了详尽说明。此处为了使用上的方便,给出总结性信息。
天地图切图方案的最小层级为1级,最大层级为18级。
web mercator投影切图方案
1 | { |
wgs84地理坐标系切图方案
1 | { |
高德地图
高德地图的切片方案和天地图的切片方案完全一致,包括dpi、lods、size等。
最小层级为1,最大层级为18, 第1层级的resolution为78271.5169639999。高德在线地图只有web mercator投影的切片方案,其lods定义可以参考天地图在切片方案定义。
高德地图,典型切片格式地址为http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}。其中,z为切片层级,y为切片行号,x为切片列号。
谷歌地图
谷歌地图服务的切片方案和天地图的切片方案也是大致相同,其dpi、lods、origin等定义相同。区别在于,谷歌地图服务的最小层级为0,最大层级为19。第0层级的resolution为156543.033928。
国内谷歌在线地图地址,其切片地图地址格式为https://mt1.google.cn/vt/lyrs=m@226000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Gali。其中,z为切片层级,y为切片行号,x为切片列号。
谷歌国际在线地图地址,其切片地图地址格式为https://mts0.google.com/vt/lyrs=m@186112443&hl=en&src=app&x={x}&y={y}&z={z}&s=Gali。其中,z为切片层级,y为切片行号,x为切片列号。
第0层级,切片如下
第1层级,切片如下
百度地图
2023年6月19日更新:以下关于百度切片方案的说明,存在着诸多错误或是不精确的的确,此处不再进行修改。修正信息请查看百度地图切片方案这篇文章。
百度在线地图使用的坐标为百度投影米坐标,为自定义坐标格式,非标准web mercator投影坐标。百度在线地图的切片方案和上述几种在线地图的切片方案,存在着较大差异。除dpi因素和size因素一致之外,以下信息存在着区别:
百度地图切片的起点为[-3.3554432E7, 3.3554432E7],转换成经纬度表示为[-180, 85],可以得出百度地图切片的实际全图范围为百度经纬度[-180,-85, 180, 85]这个范围,用百度米来表示的话全图范围为[-3.3554432E7, -3.3554432E7, 3.3554432E7,3.3554432E7]。
根据1中得出的百度切图全图范围和lods的计算公式,可以得出百度在线地图服务的resolutions信息如下,进而可以计算出对应的scale信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22[
262144.0,
131072.26214452417,
65536.13107226208,
32768.0,
16384.0,
8192.0,
4096.0,
2048.0,
1024.0,
512.0,
256.0,
128.0,
64.0,
32.0,
16.0,
8.0,
4.0,
2.0,
1.0,
0.5
];百度地图的最小层级为3, 最大层级为19。第3层级对应的resolution为32768.0。在第3层级中,使用8 * 8张图片来表示整个世界范围,其切片拼接之后效果如下所示(图片长宽不一致的原因为部分切片为空白图片,没有显示的原因)。
百度地图的切片的行列号计算方式为非标准形式,在根据行号、列号、切图层级计算其真实切图图片对应地址的过程中,需要进行一番转换,具体的运算过程如下所示。
1
2
3
4
5
6
7
8
9
10
11
12
13getTileUrl: function (level, row, col) {
var zoom = level - 1;
var offsetX = parseInt(Math.pow(2, zoom));
var offsetY = offsetX - 1;
var numX = col - offsetX, numY = (-row) + offsetY;
if (numX < 0) {
numX = 'M' + (-numX);
}
if (numY < 0) {
numY = 'M' + (-numY);
}
return 'http://online1.map.bdimg.com/tile/?qt=vtile&x=' + numX + '&y=' + numY + '&z=' + level + '&styles=pl&scaler=1&udt=20190929';
}举例如下, 对于第3层级的行号(low)为0,列号(col)为0的切片,经过转换后,行号为3,列号为M4。对于第3层级的行号为2,列号为6的切片,转换后,行号为1,列号为2。其它的转换结果,可自行验证。
ArcGIS Server 切片地图
在使用ArcGIS js api来加载ArcGIS Server发布的切片地图服务的时候,往往不需要额外的关心切片地图方案的上述配置项,原因是arcgis js api来加载arcgis server切片地图服务的过程中,中间有一个步骤是自动获取和服务的元数据页面获取相关配置项,获取方式为在服务地址后拼接?f=json参数。
额外说明
以上所说的相关信息,只适用于传统的切片地图服务。近段时间,矢量切片技术使用的愈加广泛,当前主流的地图服务厂商,如高德、百度等,都已经将站点切换到了新方案地图,访问最新的服务地址如map.baidu.com等,将不会再获取传统的切片地图。
勘误
- 关于高德地图的dpi。经过测试,访问如下地址的切片:http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z},z在0-9范围时候,获取的切片的dpi经计算为2。但在访问如下地址的切片:http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z},z在0-9范围内,获取的切片的dpi经计算为96。关于style的含义,没有查找到相关资料,因此尚不明确此处的差异。根据经验,此处修正高德地图的切片访问地址为style=8。