数据来源 | 坐标系 | 内容 |
|---|
野外采集的 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 proj4jsgcoord:为国内场景而生体积约 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 | | | |
|