如果你曾经把手机 GPS 记录的坐标粘到国内地图里,发现标记偏到了隔壁街区,那你已经遇见过坐标系问题。坐标不是“绝对真理”,它是建立在一定基准上的数值表达;基准不同,同一地点的数值就不同。
三套坐标系分别是什么
GPS 原始坐标
由美国建立的大地坐标系统,也是 GPS 的基准。航拍照片 EXIF、手机原始定位、OpenStreetMap 都使用它。可以把它理解为未经偏移的“国际通用语言”。
国内地图加密坐标
在 WGS-84 基础上叠加非线性偏移得到,高德、腾讯及多数国内地图底图使用。偏移量随位置变化,不能用固定差值处理。
百度二次偏移坐标
百度在 GCJ-02 基础上再做一次偏移,百度地图和相关接口使用。它与 GCJ-02 的差距通常在几百米。
三者的关系可以粗略理解为:WGS-84 是起点,GCJ-02 是在起点上做了一次非线性偏移,BD-09 又在 GCJ-02 上做了一次偏移。转换必须按顺序进行,不能直接从百度坐标“减一个固定数”得到 GPS 坐标。
偏移有多大
偏移量随经纬度变化,不同城市的方向和距离都不同。下表是几个城市中心附近的近似换算,保留 6 位小数,用于说明量级。实际使用时请以工具计算结果为准。
| 地点 | WGS-84 | GCJ-02 | BD-09 | GCJ 偏移 |
|---|---|---|---|---|
| 北京 | 116.397500 39.908700 | 116.403744 39.910103 | 116.410117 39.916443 | 约 555 m |
| 上海 | 121.490000 31.240000 | 121.494468 31.238015 | 121.501076 31.243671 | 约 479 m |
| 广州 | 113.324500 23.106400 | 113.329921 23.103798 | 113.336477 23.109504 | 约 625 m |
| 乌鲁木齐 | 87.616800 43.792800 | 87.619648 43.794024 | 87.626075 43.800157 | 约 266 m |
| 拉萨 | 91.132200 29.660400 | 91.133743 29.657680 | 91.140343 29.663426 | 约 337 m |
注意,偏移不是简单的“向东多少米”。它由一组随经纬度变化的三角函数计算得到,所以不能用线性平移来近似,也不能用一个城市的偏移量去套另一个城市。
怎么判断手里的坐标属于哪套
最可靠的办法是追溯来源:GPS 设备、航拍 EXIF、OSM 数据通常是 WGS-84;高德、腾讯地图复制的坐标通常是 GCJ-02;百度地图复制的坐标通常是 BD-09。如果来源不明,可以用下面的方法交叉验证。
- 看落点:把坐标分别按三套坐标系放到地图上,看哪一套落在预期地物上。
- 看差值:与已知 GPS 点比较,几百米量级的差异通常是 GCJ-02,GCJ 与 BD 之间再差几百米。
- 看接口文档:接口参数里常写 coord_type、coordinate、crs 等字段,明确写着 gcj02、bd09ll、wgs84。
- 看数据来源:从哪个 App、哪个设备、哪个系统导出,通常比看数值更可靠。
数据处理中的正确做法
如果要做长期的数据管理,建议以 WGS-84 作为内部基准:采集时保留原始坐标,入库时统一转成 WGS-84,并额外记录原始坐标系名称。展示时再按目标平台转换,这样以后接入新平台或更换底图,不需要重新采集。
批量处理时,先统一坐标系再计算距离、去重和空间分析。混用坐标系会让距离、方位和聚类结果都出现系统偏差,而且这种偏差不容易通过看表格发现。
本站的坐标转换和批量查询都遵循这个思路:输入时声明坐标系,内部统一到 WGS-84,输出时给出三套结果。
四个常见误区
- “GCJ-02 更准”。它不是精度更高的坐标,而是经过偏移的坐标;准不准取决于采集方式和底图,不取决于坐标系名称。
- “差几百米是地图标错了”。在坐标系不同的情况下,几百米偏移是预期行为,先换坐标系再判断标注。
- “四舍五入到整数就行”。整数度约 111 公里,整数分约 1.85 公里;这种精度无法用于定位。
- “百度坐标减去固定值就是 GPS”。BD-09 的偏移是叠加的,必须按算法逐步转换。
什么时候需要转换
当坐标要跨越系统边界时,就需要转换:GPS 数据上图、国内地图坐标下发给设备、合并不同来源的点位、把历史数据迁移到新平台。转换本身不复杂,复杂的是确认“输入到底是哪一套”。先确认来源,再谈算法,顺序不能反。