迪图
发布于 2026-10-20 / 53 阅读
0
0

网络地图坐标系完全指南:WGS84 / GCJ-02 / BD-09 / CGCS2000 与实战转换

网络地图坐标系完全指南:WGS84 / GCJ-02 / BD-09 / CGCS2000 与实战转换

写 WebGIS 的第一道坎不是渲染管线,是坐标系。这篇文章会让你的数据从此不再偏移。

坐标系为什么成了问题

先看一个真实场景。你手里有三份数据:

数据来源

坐标系

内容

野外采集的 GPS 轨迹

WGS-84

某城市的道路巡检点

高德地图检索结果

GCJ-02

周边 POI

百度地图 API 返回

BD-09

门店坐标

你把它们全部放进 CesiumJS 或 Leaflet 的地图上。结果是:GPS 轨迹准的、高德数据偏 50-500 米、百度数据偏得更多。

没有一个底图能同时容纳所有坐标系的数据。 这不是配置错误,是数学事实。国内互联网地图至少涉及四套坐标系,它们之间的关系可以概括为一句话:

原始卫星定位(WGS-84)→ 国家测绘局加密(GCJ-02)→ 各厂商二次加密(BD-09 等)

常见坐标系逐个拆解

WGS-84:一切的起点

定义机构:美国国防部 / NGA

椭球参数:长半轴 6378137.0 m,扁率 1/298.257223563

覆盖范围:全球

精度:民用 GPS 约 3–5 米

记忆点:WGS-84 = GPS 返回的原始坐标。你在野外打开手机 GPS 拿到的经纬度就是它。CesiumJS、ArcGIS、MapLibre GL JS 的国际版都以它为默认。

GCJ-02:国内地图的法定坐标系

定义机构:中国国家测绘局(现自然资源部)

加密方式:在 WGS-84 基础上加入非线性偏移,算法保密

偏移量:国内约 50–500 米,境外不偏移

法律地位:2002 年《公开地图内容表示若干规定》强制要求

关键在于:GCJ-02 的偏移不是简单的平移或缩放。偏移量随经纬度非线性变化,且官方算法不公开。社区库是通过逆向拟合实现的。

记忆点:GCJ-02 = 国内地图的法定坐标系。高德、腾讯、图吧、搜狗的底图和检索结果都是它。

BD-09:百度的私有坐标系

百度在 GCJ-02 基础上做了二次加密,形成独立体系。在 GCJ-02 基础上再偏移约 5–30 米。

因为是二次加密,BD-09 只在百度生态内流通,形成了事实上的封闭。

CGCS2000:专业测绘的国家基准

定义机构:中国自然资源部

椭球参数:长半轴 6378137.0 m,扁率 1/298.257222101

参考历元:2000.0

立法地位:2018 年 7 月 1 日起全面取代西安 80 和北京 54 坐标系

Web Mercator(EPSG:3857):严格说不是坐标系

它是投影——把椭球面经纬度投影到平面。但因为几乎所有 Web 地图瓦片服务都以它为数学基础,必须纳入讨论。

有效纬度范围:约 ±85.051129°。这是墨卡托投影在正球体上的数学极限,超过这个纬度投影会发散。

WGS-84 与 CGCS2000:同名不同质

这两个经常被混为一谈,因为参数极其相似:

参数

WGS-84

CGCS2000

差异

长半轴 a

6378137.0 m

6378137.0 m

完全一致

扁率 1/f

298.257223563

298.257222101

小数点后第 6 位

地心引力常数 GM

3.986004418×10¹⁴

3.986004418×10¹⁴

一致

自转角速度 ω

7.2921150×10⁻⁵

7.2921150×10⁻⁵

一致

参数几乎一样,但在大地测量学上它们是两个不同的参考框架:

1. 参考历元不同:CGCS2000 定义在 2000.0 历元,WGS-84 在 1984.0 历元。板块每年漂移几厘米,16 年历元差意味着约 0.5–1 米的系统偏差。

2. 维持方式不同:WGS-84 靠全球 GPS 监测站网维持;CGCS2000 靠中国的连续运行参考站(CORS)和 GNSS 控制网维持。

3. 精度分布不同:在中国境内,CGCS2000 的站点密度和控制精度优于 WGS-84,在地籍测量等高精度场景优势明显。

工程结论:Web 地图开发中,两者差异在厘米量级,小于瓦片本身的屏幕精度。代码里可以把 CGCS2000 坐标直接当 WGS-84 用,无需转换。只有测绘级精度才需要关注。

核心问题:多源数据如何共存

方案 A:统一转换数据,保持底图不变

适用于以国际引擎(CesiumJS / Leaflet / MapLibre)为底盘,集成国内数据源。

工作流:

1. 底图保持 WGS-84

2. 所有非 WGS-84 数据源在加载前统一转为 WGS-84

3. 若要叠加高德/腾讯 GCJ-02 瓦片,在 ImageryProvider / TileLayer 中嵌入纠偏逻辑:请求瓦片时 WGS-84→GCJ-02,反算位置时 GCJ-02→WGS-84

优点是数据源统一后心智负担小。缺点是底图侧的实时纠偏有性能成本。

方案 B:统一转换底图,保持数据不变

适用于以国内 SDK(高德 / 腾讯 / 百度)为底盘。底图天然是 GCJ-02/BD-09,所有 WGS-84 数据传入前统一转换。

优点是数据侧简单。缺点是换一家 SDK 就要反过来再转一次。

方案 C:以 WGS-84 为枢纽的中间层

同时接入多个坐标系数据源、需要灵活切换时使用。维护一个统一的中间坐标系作为枢纽:

WGS-84  ←→  GCJ-02  ←→  BD-09
   ↑          ↑           ↑
   └────── WGS-84 ────────┘

所有数据在入库时标注其原生坐标系,渲染时按目标底图动态转换。

转换库对比:gcoord vs proj4js

gcoord:为国内场景而生

体积约 20KB,无外部依赖,覆盖 WGS-84 / GCJ-02 / BD-09。API 极简:

// 单点转换
const gcj = gcoord.transform([116.404, 39.915], gcoord.WGS84, gcoord.GCJ02);

// 批量转换
const coords = [[116.404, 39.915], [121.473, 31.230]];
const gcjs = gcoord.transform(coords, gcoord.WGS84, gcoord.GCJ02);

// 整个 GeoJSON 转换
gcoord.transformGeoJSON(geojson, gcoord.BD09, gcoord.WGS84);

GCJ-02 ↔ WGS-84 转换精度优于 0.5 米。

proj4js:通用坐标参考系统引擎

PROJ(C 语言地理库)的 JavaScript 实现,覆盖所有 EPSG 注册的 CRS(数万种)。体积约 170KB。

// WGS-84 → Web Mercator
proj4("EPSG:4326", "EPSG:3857", [116.404, 39.915]);
// → [12958826.42, 4843953.52]

// 自定义 CGCS2000 3 度带
proj4.defs("EPSG:4547",
  "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 " +
  "+ellps=GRS80 +units=m +no_defs");

支持 WKT / PROJ / ESRI WKT 字符串,可定义任意投影。

选哪个

维度

gcoord

proj4js

体积

~20 KB

~170 KB

学习成本

极低

需理解 CRS / WKT / PROJ 概念

国内坐标系

内置三种

需自行定义加密部分

通用投影

不支持

所有 EPSG

OpenLayers

内置集成

内置集成

结论:只处理国内互联网地图三件套 → gcoord;涉及任意投影转换、测绘场景 → proj4js。

经典翻车清单

这四个错误每天都在发生:

1. 高德检索结果直接标到 CesiumJS 地球上 —— 高德返回 GCJ-02,Cesium 是 WGS-84

2. 百度 geocoding 结果喂给高德底图 —— BD-09 在 GCJ-02 底盘上偏 5–30 米

3. 野外采集的 GPS 轨迹直接拼到高德地图上 —— 反了,需要 WGS-84 → GCJ-02

4. 天地图 CGCS2000 标注和国外 WGS84 服务叠加 —— 这个不需要转换,Web 精度下没差别

关于逆转换的重要提醒

社区流传的 GCJ-02 → WGS-84 算法本质是近似反解:先用正向算法算出偏移量,再用 原值×2 - 偏移结果 反推。这在精度上不如正向转换。

工程建议:坐标转换应该尽可能单向进行——在数据入口处(数据入库、数据接入接口)统一转换成目标坐标系,而不是每次渲染时来回转。在入库层转换,精度和性能都是最优的。

精度红线

开源转换算法在中国大陆绝大部分地区,与官方产品的误差可控制在 1–5 米内。这对位置显示、轨迹绘制、POI 推荐完全够用。

但绝对禁止用于:法定测绘、土地勘界、军事用途、任何精度要求高于米级的场景。这些必须使用国家官方认可的测绘成果和标准流程。

参考资料

  • PostGIS 官方文档 — https://postgis.net/docs/

  • gcoord — https://github.com/dyngcn/gcoord

  • proj4js — https://github.com/proj4js/proj4js

  • coordtransform(多语言实现参考)— https://github.com/wandergis/coordtransform

  • 《公开地图内容表示若干规定》(2002 年)


评论