在使用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数字的计算方法是:

  1. 获取对应切片,查看图片的长和宽(以cm为单位),计为width。将cm转换为对应的英寸,即为width / 2.54
  2. 根据dpi定义,计算dpi为 256 / (width / 2.54)。

lods

lods为切片地图的重要参数,相对来说复杂一些。不同的切片地图,对应的lods参数也往往不同。lods的形式通常为数组形式,每一个数组项都表示了一个lod,lod中包含了level、resolution、scale等信息。

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"level": 16,
"resolution": 2.38865713397468,
"scale": 9027.977411
},
{
"level": 17,
"resolution": 1.19432856685505,
"scale": 4513.988705
}
]

level

level即为切片方案的层级,用数字表示,反应到地图上即表示的是地图的zoom信息,也可以称之为缩放级别。具体数字为0或是1,并不重要,可以自行定义。

resolution

resolution表示的为切片的分辨率,意义为图上1px的距离表示实际距离的多少。resolution的作用为确定当前点位置所在的切片的行列号。大致的计算的方法如下:

  1. 计算出当前点位置和origin点位置的x和y的差值,表示了两点之间的实际距离。已知origin点所在的切片的行列号为(0,0)。
  2. 使用两点之间的实际距离,去除当前的resolution,可以得出当前点和origin点之间的像素距离。
  3. 计算出了两点之间的像素距离,并且已知了每一个切片的大小(比如为256px * 256px),则可以计算出两者之间的切片的个数,即大体可得当前点和origin点在水平方向和竖直方向上存在着多少个切片,即得出行号和列号。

以上,说明了resolution参数的作用。下面,来说明如何来计算resolution的值。

以天地图的web mercator投影(wkid:3857)的在线切片地图为例,其在线地图切片的第0个层级的resolution信息如下:

1
2
3
4
5
{
"level": 0,
"resolution": 156543.033928,
"scale": 591657527.591555
}

那以上的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 items = extract(part);        int factor = Integer.parseInt(items.get(0), 32);        int difference = 0;        int inx = 0;        for (int i = 1; i < items.size(); i++) {            int value = Integer.parseInt(items.get(i), 32);            difference += value;            consumer.accept(line.getPoints()[inx++], difference * 1.0 / factor);       }   }java

如下图所示,天地图的第0层级中,四张切片拼接之后,表示了整个的世界范围(从图上可以看出来,web mercator投影中,在高纬度地区,面积和形状的变形都相当之大,特别明显的就是北极附近的格陵兰岛。这也是为什么不推荐在web mercator投影下,计算大面积地物的面积。实践证明,对于省市行政区的面积计算,在web mercator投影下的面积计算,确定不具备现实意义)。

1

图片上的序号为切片的行号和列号,它们的url地址分别为,感兴趣的可以自行加载验证。

https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL=0&TILEROW=0&TILEMATRIX=1&tk=cd7427b91c597d6e859908210e8cb5ed

https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL=1&TILEROW=0&TILEMATRIX=1&tk=cd7427b91c597d6e859908210e8cb5ed

https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL=0&TILEROW=1&TILEMATRIX=1&tk=cd7427b91c597d6e859908210e8cb5ed

https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL=1&TILEROW=1&TILEMATRIX=1&tk=cd7427b91c597d6e859908210e8cb5ed

4x4

如上所示,为天地图第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参数后,即可获取任一需要的切片。

https://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILECOL=0&TILEROW=0&TILEMATRIX=1&tk=cd7427b91c597d6e859908210e8cb5ed。

地理坐标系下,第1层级的切片拼接后,展示如下。由于地理坐标系下的切图整个范围为[-180,-90,180,90]。水平方向上的长度是竖直方向上的2倍,导致水平方向上需要的切片数量也将是竖直方向上切片数量的2倍。因此,(0,0)和(0,1)两张图片即可表示整个世界范围,(1,0)和(1,1)两张图片为空白图片。

1x2

第2层级的切图拼接效果如下所示。

2x4

scale

scale是指图上距离与实际距离的比值(表示形式为1:M,图上1cm,表示真实的距离为Mcm),表示的含义是放缩的尺度。scale与具体的切图方案无关,而是切图方案确定之后的衍生信息。根据以上的dpi、resolution等信息,可以计算出在给定resolution的情况下,比例尺的大小。

scale的计算可以从以下的推导得出:

  1. 已知resolution的概念为1px表示实际距离的多少(在投影坐标系下,以米为单位;在地理坐标系下,以度为单位),dpi的概念为1英寸中包含多少个像素(px)。
  2. 从1可知,1英寸中包含的实际距离为dpi * resolution。
  3. 1英寸等价于2.54cm。从2可知,图上距离的0.0254米,表示了真实距离的dpi * resolution 米,则可知比例尺的大小为 dpi * resolution / 0.0254。

再看一下,天地图的web mercator投影(wkid:3857)的在线切片地图,其在线地图切片的第0个层级的resolution信息如下:

1
2
3
4
5
{
"level": 0,
"resolution": 156543.033928,
"scale": 591657527.591555
}

根据我们以上的推导,计算出的比例尺应该为 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
2
3
4
5
{

"resolution": 0.703125,
"scale": 2.958293554545656E8
}

通过我们上述的说明,计算scale = 0.703125 * 96 / 0.0254 * (math.pi * 2 * 6378137) / 360 = 295829355.45456564。和上述给出的scale数字相比,验证了计算方法的正确。

以上,即对切片地图相关的配置信息、用途,以及如何对这些配置信息进行计算给出了详细的说明。具体的数字无需记忆。从定义入手,可以简单的计算得出。

常见地图切片方案总结

天地图

天地图的相关信息,在上文中已进行了详尽说明。此处为了使用上的方便,给出总结性信息。

天地图切图方案的最小层级为1级,最大层级为18级。

其web mercator投影的切片方案,切片地址格式为https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={level}&tk=cd7427b91c597d6e859908210e8cb5ed,其中TILEMATRIX为切片层级,TILEROW为切片行号,TILECOL为切片列号,第1级的resolution为78271.5169639999。

其wgs84地理坐标的切片方案,切片地址格式为https://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={level}&tk=cd7427b91c597d6e859908210e8cb5ed,其中TILEMATRIX为切片层级,TILEROW为切片行号,TILECOL为切片列号,第1级的resolution为0.703125。

web mercator投影切图方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{
dpi: 96,
size: [256, 256],
origin: [-20037508.342787, 20037508.342787],
fullExtent: [-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787]
lods: [{
"level": 0,
"resolution": 156543.033928,
"scale": 591657527.591555
}, {
"level": 1,
"resolution": 78271.5169639999,
"scale": 295828763.795777
}, {
"level": 2,
"resolution": 39135.7584820001,
"scale": 147914381.897889
}, {
"level": 3,
"resolution": 19567.8792409999,
"scale": 73957190.948944
}, {
"level": 4,
"resolution": 9783.93962049996,
"scale": 36978595.474472
}, {
"level": 5,
"resolution": 4891.96981024998,
"scale": 18489297.737236
}, {
"level": 6,
"resolution": 2445.98490512499,
"scale": 9244648.868618
}, {
"level": 7,
"resolution": 1222.99245256249,
"scale": 4622324.434309
}, {
"level": 8,
"resolution": 611.49622628138,
"scale": 2311162.217155
}, {
"level": 9,
"resolution": 305.748113140558,
"scale": 1155581.108577
}, {
"level": 10,
"resolution": 152.874056570411,
"scale": 577790.554289
}, {
"level": 11,
"resolution": 76.4370282850732,
"scale": 288895.277144
}, {
"level": 12,
"resolution": 38.2185141425366,
"scale": 144447.638572
}, {
"level": 13,
"resolution": 19.1092570712683,
"scale": 72223.819286
}, {
"level": 14,
"resolution": 9.55462853563415,
"scale": 36111.909643
}, {
"level": 15,
"resolution": 4.77731426794937,
"scale": 18055.954822
}, {
"level": 16,
"resolution": 2.38865713397468,
"scale": 9027.977411
}, {
"level": 17,
"resolution": 1.19432856685505,
"scale": 4513.988705
}, {
"level": 18,
"resolution": 0.597164283559817,
"scale": 2256.998866688275
}]
}

wgs84地理坐标系切图方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{
size: [256, 256],
dpi: 96,
origin: [-180, 90],
fullExtent: [-180, -90, 180, 90],
lods: [{
"level": 0,
"resolution": 1.40625,
"scale": 5.916587109091312E8
}, {
"level": 1,
"resolution": 0.703125,
"scale": 2.958293554545656E8
}, {
"level": 2,
"resolution": 0.351563,
"scale": 1.479146777272828E8
}, {
"level": 3,
"resolution": 0.175781,
"scale": 7.39573388636414E7
}, {
"level": 4,
"resolution": 0.0878906,
"scale": 3.69786694318207E7
}, {
"level": 5,
"resolution": 0.0439453,
"scale": 1.848933471591035E7
}, {
"level": 6,
"resolution": 0.0219727,
"scale": 9244667.357955175
}, {
"level": 7,
"resolution": 0.0109863,
"scale": 4622333.678977588
}, {
"level": 8,
"resolution": 0.00549316,
"scale": 2311166.839488794
}, {
"level": 9,
"resolution": 0.00274658,
"scale": 1155583.419744397
}, {
"level": 10,
"resolution": 0.00137329,
"scale": 577791.7098721985
}, {
"level": 11,
"resolution": 0.000686646,
"scale": 288895.85493609926
}, {
"level": 12,
"resolution": 0.000343323,
"scale": 144447.92746804963
}, {
"level": 13,
"resolution": 0.000171661,
"scale": 72223.96373402482
}, {
"level": 14,
"resolution": 8.58307e-005,
"scale": 36111.98186701241
}, {
"level": 15,
"resolution": 4.29153e-005,
"scale": 18055.990933506204
}, {
"level": 16,
"resolution": 2.14577e-005,
"scale": 9027.995466753102
}, {
"level": 17,
"resolution": 1.07289e-005,
"scale": 4513.997733376551
}, {
"level": 18,
"resolution": 5.36445e-006,
"scale": 2256.994353
}]
}

高德地图

高德地图的切片方案和天地图的切片方案完全一致,包括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为切片列号。

2x2

谷歌地图

谷歌地图服务的切片方案和天地图的切片方案也是大致相同,其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层级,切片如下

000

第1层级,切片如下

2x2

百度地图

2023年6月19日更新:以下关于百度切片方案的说明,存在着诸多错误或是不精确的的确,此处不再进行修改。修正信息请查看百度地图切片方案这篇文章。

百度在线地图使用的坐标为百度投影米坐标,为自定义坐标格式,非标准web mercator投影坐标。百度在线地图的切片方案和上述几种在线地图的切片方案,存在着较大差异。除dpi因素和size因素一致之外,以下信息存在着区别:

  1. 百度地图切片的起点为[-3.3554432E7, 3.3554432E7],转换成经纬度表示为[-180, 85],可以得出百度地图切片的实际全图范围为百度经纬度[-180,-85, 180, 85]这个范围,用百度米来表示的话全图范围为[-3.3554432E7, -3.3554432E7, 3.3554432E7,3.3554432E7]。

  2. 根据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. 百度地图的最小层级为3, 最大层级为19。第3层级对应的resolution为32768.0。在第3层级中,使用8 * 8张图片来表示整个世界范围,其切片拼接之后效果如下所示(图片长宽不一致的原因为部分切片为空白图片,没有显示的原因)。

    8x8

  4. 百度地图的切片的行列号计算方式为非标准形式,在根据行号、列号、切图层级计算其真实切图图片对应地址的过程中,需要进行一番转换,具体的运算过程如下所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    getTileUrl: 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。其它的转换结果,可自行验证。

  5. 其切片地址格式为http://online1.map.bdimg.com/tile/?qt=vtile&x={x}&y={y}&z={level}&styles=pl&scaler=1&udt=20190929,其中level为层级,x为列号,y为行号。

ArcGIS Server 切片地图

在使用ArcGIS js api来加载ArcGIS Server发布的切片地图服务的时候,往往不需要额外的关心切片地图方案的上述配置项,原因是arcgis js api来加载arcgis server切片地图服务的过程中,中间有一个步骤是自动获取和服务的元数据页面获取相关配置项,获取方式为在服务地址后拼接?f=json参数。

额外说明

以上所说的相关信息,只适用于传统的切片地图服务。近段时间,矢量切片技术使用的愈加广泛,当前主流的地图服务厂商,如高德、百度等,都已经将站点切换到了新方案地图,访问最新的服务地址如map.baidu.com等,将不会再获取传统的切片地图。

勘误

  1. 关于高德地图的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。



👨‍💻本站使用 Stellar 主题创建

📃本"页面"访问 次 | 👀总访问 次 | 🥷总访客

⏱️本站已运行 小时