地图相关坐标系知多少

745 阅读6分钟

前一篇讲解了三维渲染中的坐标系变换,而我们常用的web地图又是如何将球体经纬度映射到屏幕的呢?本文将会介绍地图相关的坐标系,无论你是开发地图引擎还是开发地图应用服务,一定需要了解地图相关的坐标系,否则就会出现一些不知所以然的问题。一起来看一下吧~

image.png

1 经纬度坐标系

如初中地理所学,地球是一个赤道略宽两极略扁的椭球体,采用经纬度来表示地球上的位置点。常见的经纬度坐标系有WGS84坐标系、GCJ02坐标系、BD09坐标系。

WGS84坐标系: 基于GPS全球定位系统建立的坐标系,是国际上广泛接受并使用的一套坐标系。各家地图在海外采用的都是WGS84坐标系。

GCJ02坐标系: 在国内出于测绘安全考虑,不能公开使用WGS84坐标系,根据国家测绘局制定的加密标准,对WGS84坐标进行了偏移加密,得到了GCJ-02坐标系(又称国测距坐标系、火星坐标系),谷歌、高德、腾讯在中国大陆采用的都是GCJ-02坐标系。

BD09坐标系: 百度地图采用的坐标系,是在GCJ02坐标系的基础上再进行一次加密,是由于09年开始百度做自己的地图和地图数据,所以称为BD09坐标系。所以在你拿到一些经纬度数据时,首先要明确是什么坐标系的,否则你会发现这些点在地图上会有偏移。

2 平面投影坐标系

我们通常所见的地图都是平面图,如何将球体映射到平面上,可以采用投影模型来实现。制图学中有各种各样的投影,web地图通常采用的是墨卡托投影,更准确的说是web墨卡托投影或球形墨卡托投影,该投影方式是正轴等角圆柱投影。

可以想象将地球放入一个圆柱面内,赤道外切于圆柱面,在球心有个光源,光源射线将球面各点投影到圆柱内壁,然后沿着某条经线剪开圆柱即可得到平面地图,如下图所示:

image.png

平面墨卡托投影坐标的原点与经纬度原点保持一致,即赤道和本初子午线相交的位置。

目前谷歌、高德、腾讯、mapbox等绝大多数互联网地图采用的都是web墨卡托投影,这个投影方法简单,可以保证整个世界的墨卡托坐标宽度是2的整数次幂,实现起来很方便。百度由于历史原因采用的是跟搜狗地图类似的方法,投影算法相对复杂,且整个世界的宽度也不是2的整数次幂。

此外,注意区分投影与加密是两个独立的概念,如果经纬度是BD09的(BD09LL),那么投影之后的墨卡托坐标也是BD09的(BD09MC);同样的,如果经纬度是GCJ02的(GCJ02LL),那么投影之后的墨卡托也是G什么坐标系的,否则你会发现这些点在地图上会有偏移。

3 世界像素坐标系

互联网地图可以进行缩放,不同级别下地图大小和精细粒度不同,那么地图在不同层级下,分别应该用多大的尺寸来表示呢?

百度地图API是以18级为基准,即在地图缩放等级为18级时,1像素 = 1个墨卡托单位。

注意平面墨卡托坐标与地图级别是没有关系的,也就是说无论是3级还是18级地图,天安门POI的墨卡托坐标都是一样的,都为12958175, 4825923.77;但是像素坐标与地图级别有关,同一个POI在不同地图级别的像素坐标不同

墨卡托坐标换算像素坐标的公式为:

像素坐标 = 墨卡托坐标 × Math.pow(2, zoom - 18)

注意这里的像素并不是设备像素,而是一种设备无关的参照像素,可以理解为web中的css像素。

之所以转换为像素为单位的坐标系,是为了方便接下来计算不同地图级别下的瓦片编号。

4 瓦片坐标

一整幅地图的数据量非常大,而web地图通常只是查看部分区域地图,所以通常web地图采用将地图切分为若干个正方形小图块,称为瓦片

当地图视口发生变化或地图进行缩放时,只需要加载当前等级在当前视口范围内的瓦片即可。

各家互联网地图对瓦片编号方式不完全一致,比如Leaflet的瓦片是以左上角为原点,而百度地图的瓦片的坐标原点与墨卡托坐标原点一致,从原点向右上方开始编号0,0,使用x,y表示瓦片编号。

image.png

瓦片编号是根据当前层级的像素坐标计算出来的,公式如下:

瓦片坐标 = Math.floor(像素坐标 / TileSize)

其中TileSize为瓦片大小,通常栅格瓦片为256256,webgl矢量瓦片为512512。

以天安门为例,在第4级下天安门所在的瓦片编号为3,1,而在18级下,瓦片编号为50617,18851。

5 屏幕画布坐标系

地图一般是使用Canvas元素作为画布进行展示的,Canvas有自己的坐标系,以左上角为原点。

image.png

初始化地图时需要设置center和zoom两个必要参数,其中center就是屏幕中心点对应的经纬度,根据前面所述可以计算出该点的世界像素坐标,并且根据可视窗口的宽高可计算出该点的屏幕画布坐标(屏幕像素坐标)。

其他位置点的屏幕画布坐标就可以根据中心点的坐标计算出来,公式如下:

某点屏幕画布坐标 = (某点像素坐标 - 中心点像素坐标)+ 中心点屏幕画布坐标

总结

image.png

好啦,以上就是2D地图相关的地理坐标系~

对于3D地图WebGL渲染,还会涉及到前一篇文章讲的视图坐标系、裁切坐标系、纹理坐标系等,将在后续的3D地图渲染文章再做详细讲解~

【参考】

[1] www.jiazhengblog.com/blog/2011/0…

[2]pro.arcgis.com/zh-cn/pro-a…

【往期回顾】

三维坐标系变换的含义:juejin.cn/post/703578…