地图坐标系转换
同一栋楼在三种坐标系里能差出几百米。这里把 WGS84、GCJ02、BD09 两两互转,并给出偏移距离,方便对齐 GPS 原始点和地图底图。
三种坐标系下的结果
| 坐标系 | 纬度 | 经度 | 与输入点的距离 |
|---|---|---|---|
| WGS84 GPS 原始坐标、国际通用标准,OpenStreetMap 和 Google 海外版也用这套 | 39.908700 | 116.397500 | 0 米 |
| GCJ02 国测局坐标系(俗称火星坐标),高德、腾讯、Google 中国版在用 | 39.910103 | 116.403744 | 554.93 米 |
| BD09 百度在 GCJ02 之上又做了一次加密,只在百度地图生态里有效 | 39.916443 | 116.410117 | 1378.1 米 |
距离是把输入点当作同一地理位置、换算后的大圆距离,用来直观说明偏移量级。
六种互转
| 转换方向 | 纬度 | 经度 | 偏移 |
|---|---|---|---|
| WGS84 → GCJ02 | 39.910103 | 116.403744 | 554.93 米 |
| WGS84 → BD09 | 39.916443 | 116.410117 | 1378.1 米 |
| GCJ02 → WGS84 | 39.907299 | 116.391259 | 554.67 米 |
| GCJ02 → BD09 | 39.915043 | 116.403873 | 890.49 米 |
| BD09 → WGS84 | 39.900993 | 116.384873 | 1376.4 米 |
| BD09 → GCJ02 | 39.902390 | 116.391109 | 888.53 米 |
批量转换
逗号、空格和中文逗号都能当分隔符,输入按上面的坐标系解释,统一转成 GCJ02。
| 行 | 输入纬度 | 输入经度 | 结果纬度 | 结果经度 | 偏移 |
|---|---|---|---|---|---|
| 1 | 39.908700 | 116.397500 | 39.910103 | 116.403744 | 554.93 米 |
| 2 | 31.230400 | 121.473700 | 31.228458 | 121.478223 | 481.25 米 |
| 3 | 23.129100 | 113.264400 | 23.126423 | 113.269730 | 620.97 米 |
为什么会有偏移
WGS84 是 GPS 卫星定位得到的原始坐标,也是国际通用标准。GCJ02 是在 WGS84 基础上按一套非线性公式加偏得到的「火星坐标」,国内的高德、腾讯以及 Google 中国版地图都使用它。BD09 则是在 GCJ02 之上再做一次非线性变换,只有百度地图用。三层套下来,同一个位置在三套坐标里的数值都不同,混用就会偏移几百米,在市区可能是隔了一条马路甚至一个街区。
偏移量不是固定值,它随经纬度按三角函数级数变化,国内大部分地区在 300 到 700 米之间,同一个城市不同位置的偏移方向和大小都不一样。所以不能简单地对经纬度加减一个常数来「纠偏」,必须用完整的公式计算,本页用的就是业界通行的 GCJ02 偏移算法(克拉索夫斯基椭球参数加上那组正弦级数)。
转换公式里有一个境内判定:落在境外(以及港澳台和周边海域)的坐标不加偏,GCJ02 与 WGS84 完全相同,页面会给出提示。这也是为什么用国内地图看国外地点时不会偏移,而把国外的 GPS 坐标拿去和高德底图对齐时,如果地点在国内边缘地带,要特别注意这个边界判定。
GPS 原始数据入库前先想清楚这一列是什么坐标系,并把它写进字段名或注释里,比如 wgs84_lat 和 gcj02_lng。日常最容易出错的是三件事:手机定位拿到 WGS84 直接显示在高德地图上、从百度地图复制坐标存进只用高德的业务库、以及把转换过的坐标又转了一次。建议在入库前统一转成业务系统使用的那一套坐标,并在页面上展示前再做一次方向检查。
需要注意精度边界:GCJ02 与 BD09 的转换公式是公开的拟合公式,各家地图的私有实现存在米级差异,百度那对公式正反变换的残差在 0.1 米量级。日常展示、周边搜索足够用,但涉及测绘出图、精确面积计算或执法取证时,必须使用具备资质的坐标系统与工具,不能依赖这类离线换算。