我之前的几篇文章都有提到过地理坐标系,这是实现地图应用绕不过去的一个知识点。
坐标系说白了就是给地球表面的位置划分经纬度的一套系统,用经纬度描述位置,单位一般是度。
之前也聊过投影相关的内容,今天就把坐标系的知识点串一串。本文是一篇网络整合文,当然也结合了我自己的一些验证数据。关于地图的坐标系网络上文章不少,但对于绝大部分人来收,看我这一篇就够了。
地理坐标系 vs 投影坐标系
一句话分清:投影坐标系(PROJCS)是平面坐标系,单位是米;地理坐标系(GEOGCS)是椭球面坐标系,单位是经纬度。投影坐标系是由地理坐标系通过投影算法转换而来。
| 对比维度 | 地理坐标系(GCS) | 投影坐标系(PCS) |
|---|---|---|
| 坐标本质 | 球面坐标,角度单位(度) | 平面坐标,长度单位(米/千米) |
| 计算能力 | 不能直接计算距离、面积 | 可直接用平面公式计算距离、面积 |
| 核心用途 | 全球定位,记录地理位置 | 地图制图、空间分析 |
大地基准面:椭球体的"定位锚点"
先提一个概念------大地基准面。椭球体其实就是个数学模型,而大地基准面的作用,就是把这个数学模型和地球真实表面绑定起来,简单说就是通过平移、旋转椭球体,让它尽可能贴合特定区域的地球表面(大地水准面)。
基准面主要分两类:
-
地心基准面:椭球体中心和地球质心重合,是全球通用的,比如我们熟悉的WGS84、国内的CGCS2000都属于这类。
-
区域基准面:椭球体中心偏离地球质心,是专门为特定区域优化的。比如我国早期用的北京54基准面、西安80基准面,都是为了适配中国本土地形设计的。
同一经纬度,基于不同基准面的实际位置可能差几十米甚至上百米。不过现在地心基准面是主流,区域基准面已经很少用了,我们知道有这么个东西就行。
说到区域基准面,就不得不提我国的大地原点------位于陕西省咸阳市泾阳县永乐镇北流村。之所以选在这,就是因为它地处中国大陆中部,便于数据均匀推算。西安80就是基于这个大地原点实现的,缺了原点,基准面就成了"无锚之船",没法准确落地到真实的地球表面。
常见坐标系
| 坐标系名称 | 核心参数 | 特点与适用场景 |
|---|---|---|
| WGS84 | 椭球:WGS84(长半轴6378137m,扁率1/298.257223563); 基准面:地心基准面 | 全球通用,GPS定位、谷歌地图、OpenStreetMap、Mapbox的原生坐标系;Web开发中最基础的地理坐标系,经纬度可直接转换为Web墨卡托投影。 |
| CGCS2000(2000 国家大地坐标系) | 椭球:CGCS2000(参数与WGS84几乎一致); 基准面:地心基准面 | 中国国家强制标准,国土测绘、规划、国内GIS项目(如天地图)的必须坐标系;与WGS84坐标偏差极小,实际开发中可近似兼容(高精度场景需转换),也是北斗导航系统使用的坐标系。 |
| 北京54(BJ54) | 椭球:克拉索夫斯基椭球;基准面:区域基准面(参考苏联普尔科沃原点) | 我国早期坐标系,精度较低,目前逐步被CGCS2000替代;仅用于处理老旧测绘数据。 |
| 西安80(XA80) | 椭球:IAG75椭球; 基准面:区域基准面(锚定中国泾阳大地原点) | 北京54的升级版本,曾是国内主流坐标系;目前仍有部分历史数据使用,需转换为CGCS2000后使用。 |
| GCJ-02(国测局02) (火星坐标系) | 基于WGS84加密而来 | 国内高德、百度、腾讯地图的加密坐标系;GPS采集的WGS84坐标需加密后才能在国内地图上准确定位,反之解密需合规授权。 |
各大地图厂商的坐标系
-
天地图:天地图属于国家队,用的是CGCS2000(2000国家大地坐标系)。实际开发中,我们常用WGS84坐标代替CGCS2000,因为两者定义实质一致,参考椭球参数非常接近,扁率差异带来的纬度和高度变化小到厘米级。在常规精度范围内,这点差异通常可以忽略。
-
高德地图、腾讯地图:用的就是标准的GCJ-02火星坐标系。火星坐标是国家测绘局为了国家安全,在原始WGS84坐标基础上做偏移得到的,国内几乎所有电子地图、导航设备都用这个坐标系。而且要注意,火星坐标没有精确的反向解密算法。
-
百度地图:用的是BD09II坐标。在火星坐标(GCJ-02)的基础上又做了一次二次加密,形成了专属的百度坐标(BD-09)。
-
Google Map、OSM:海外厂商不用怀疑,就是WGS84。(google中国曾经也用过GCJ02)
示例
以瓦片位置:z: 14 x: 13597 y: 6651为例

左边是google无偏移(WGS-84)右边是google有偏移(GCJ02)

上面是天地图(CGCS2000,和WGS-84基本一致)

上面是高德(GCJ02)

上面是腾讯(GCJ02)

上面是OSM(WGS-84)
百度会有更大的偏移(BD-09 在 GCJ02基础上2次加密,很难解析)
重点拆解:火星坐标系(GCJ-02)
火星坐标系的核心规则与加密逻辑
首先,中国大陆所有公开地理数据,都必须至少用GCJ-02进行加密,绝大部分国内互联网地图提供商都遵循这个规则,包括高德、谷歌地图中国区等。GCJ-02的坐标偏移量不是固定的,最小值约0.000213487度(对应地面20多米),最大值约0.0104393度(对应地面1公里多,不过这个偏移量对应的地点已经超出我国范围了)。
这里要注意一个细节:底层接口(比如HTML5 Geolocation、iOS或安卓的定位API)通过GPS设备获取的坐标,本质还是WGS84坐标系,必须经过加密转换才能和国内地图匹配上。
GCJ02在各地的误差大致如下:(参考https://www.cnblogs.com/xiaowangba/p/6313913.html)

GCJ-02加密流程
火星坐标的加密有固定流程,核心是国家保密插件:
-
地图生产阶段:厂商先把测绘好的原始WGS84坐标数据,送到国家测绘局,用专门的保密插件(也叫加密插件、加偏或SM模组)做非线性加偏处理,处理后的地图才符合GCJ-02标准,才能公开使用。
-
设备适配阶段:导航仪、手机地图APP等终端设备,都要集成这个保密插件。这样设备接收的GPS真实WGS84坐标,才能实时转换成GCJ-02坐标,保证定位位置和地图显示能对应上。
这个保密插件的核心是非线性加偏算法,偏移量各地不同、方向也不固定,而且算法是国家机密,不对外公开。每次去测绘局加密都要预约,还得在封闭环境中进行,编译后的文件直接打包进主程序EXE,不能做成外部DLL文件,为了防止有人逆向破解。
另外,保密插件不是免费用的,需要购买许可。早期是按设备收费,一台导航仪收10块钱;后来改成,按预估地图发行量一次性收取几百万,再由地图公司和导航软件客户分摊成本。
Web开发中:WGS84(GPS经纬度)转GCJ02的实现方式
Web开发中,地图数据是GCJ02坐标。定位的时候拿到的是WGS84,所以需要把定位的经纬度转成GCJ02,才能在地图上正确显示。核心原则是:优先用官方/厂商接口保证合规与精度,自用场景可备选开源拟合方案。
一、推荐方案:调用地图厂商官方接口
国内主流地图厂商(高德、百度、腾讯)均提供坐标转换API,可直接将WGS84坐标转为对应坐标系(高德/腾讯直接转GCJ02,百度需先转GCJ02再转BD09),接口适配Web端调用,且符合国家地理信息安全要求。
优势:完全合规,精度贴合官方标准,适配各类终端Web场景(PC端、移动端H5);
劣势:依赖厂商接口,需申请密钥,存在调用频率/额度限制,部分商用场景需付费。
二、备选方案:开源拟合算法
如GitHub上的wgs2mars.js、coordtransform等库,这类库基于实测数据反向推导经验公式,实现WGS84到GCJ02的近似转换。
使用注意:
-
精度有限,在城市核心区误差约5-20米,边境、敏感区域误差会显著增大;
-
理论上属于非法工具。
GCJ-02的现状:名存实亡但无法完全破解
网络上的一些坐标转换代码,其实这些都是开发者通过实测拟合、逆向推测出来的经验公式,只能满足部分民用场景,达不到官方精度,尤其是在边境、敏感区域,误差会特别大,而且理论上这类工具是非法的。但事实上也有很多小型软件在用这些工具实现转换。
如果从国家安全来说,GCJ02也仅仅是套了一层外衣,很难实现本质的信息保护。即使不考虑非法的转换,获取各大地图厂商的API也不是什么难事,并且天地图官方提供的地图(CGCS2000)已经和WGS84几乎一致了。
很多有人说GCJ-02已经名存实亡,其实也能理解------它诞生的时候,没人能预料到硬件计算力会发展这么快。但即便如此,GCJ-02也不可能被完全破解,因为它没有解析解,最多只能做到非100%的近似纠偏,始终达不到官方的加密和解密标准。
实用工具分享
-
查看不同地图厂商坐标显示差异:https://map.bmcx.com/,输入同一经纬度,就能直观看到各大地图的显示位置差别。
-
坐标系转换工具:https://tool.lu/coordinate/,支持常见坐标系之间的转换,适合民用场景粗略使用。
参考资料
最后,我会继续写一些文章来介绍这些内容:
- 地图合规(https://blog.csdn.net/tzy233/article/details/156914011)
- 地图投影(https://blog.csdn.net/tzy233/article/details/156996224)
- 地图开发工具
- 离线地图
- 3D地图