经纬志
首页 / 实战手册 / 坐标与投影

把 EPSG:4479 当地理坐标用,点位数值到了七位数

先看结论

天地图服务目录里写着 CGCS2000,选了 4479,拿到的却是 X/Y/Z 三个米值。

最后验证 2026-11-03 · 多技术栈 · 更新 2026-10-29 · 引用本文

现象

请求参数写 TILEMATRIXSET=4490 时一切正常; 改成某个文档里提到的 4479 后,返回的坐标是 -2177350, 4389500, 4070300 这样的三个数, 前两个远超 ±180 / ±90,第三个也不是高程的合理量级。

把这三个数直接传进 Cesium.Cartesian3.fromDegrees(x, y, z), 相机飞到地球外面,屏幕只剩黑色。

原因

EPSG 码里同一基准往往有多个「坐标系」:

EPSG名称单位典型数值
4490CGCS2000 地理 2D度116.397, 39.909
4479CGCS2000 地心直角米-2177350, 4389500, 4070300
4547CGCS2000 3 度带 111°E米500000, 3800000

地心坐标是以地球质心为原点的 X/Y/Z,中国区域三个分量的绝对值都在 2.0e6~6.4e6 之间。它必须经过地心→地理的转换才能变成经纬度, 这一步不是简单的除以 111320。

排查过程

  1. 数一下有几个分量。三个分量且第三个不能当地理高度解释,就是地心坐标。
  2. 看绝对值量级:地心坐标必然小于 6378137 加高程,且三个分量都在百万级。
  3. 核对服务文档里的 TILEMATRIXSET 或 SRS 参数,确认要的是 4490 而不是 4479。
  4. 用 proj4 从 4479 转到 4490,结果落在中国境内即可确认。
// 地心 -> 地理
proj4.defs('EPSG:4479',
  '+proj=geocent +ellps=GRS80 +units=m +no_defs');
proj4.defs('EPSG:4490',
  '+proj=longlat +ellps=GRS80 +no_defs');

proj4('EPSG:4479', 'EPSG:4490', [-2177350, 4389500, 4070300]);
// => [116.3974, 39.9092]

解决方案

接入时只用 4490。确实拿到地心坐标时,在进入渲染层之前做一次转换, 并显式声明 geocent,不要依赖库去猜。

// 三维场景下也可以直接用地心坐标构造笛卡尔点
// 注意:Cesium 的 Cartesian3 就是地心坐标,不需要 fromDegrees
const p = new Cesium.Cartesian3(-2177350, 4389500, 4070300);
viewer.camera.lookAt(p, new Cesium.Cartesian3(0, 0, 0));

// 若手上是经纬度,才用 fromDegrees
// Cesium.Cartesian3.fromDegrees(116.3974, 39.9092, 50)

fromDegrees 与 Cartesian3 的入参不是同一套东西。 前者接受度,后者接受米;混用不会报错,只会把相机送到错误位置。

验证

转换结果经度 116.3974、纬度 39.9092,落在北京; 地心坐标反算回经纬度后再正算,三个分量误差应小于 1 毫米。

const g = proj4('EPSG:4479', 'EPSG:4490', [-2177350, 4389500, 4070300]);
console.assert(Math.abs(g[0] - 116.3974) < 0.001, '经度不对');
console.assert(Math.abs(g[1] - 39.9092) < 0.001, '纬度不对');

适用版本

工具 / 服务版本说明
天地图 WMTS1.0.0CGCS2000 用 TILEMATRIXSET=4490
proj4js2.9 及以上geocent 投影类型可用
Cesium1.100 及以上Cartesian3 即地心坐标,单位为米
引用本文

经纬志(2026)。《把 EPSG:4479 当地理坐标用,点位数值到了七位数》。https://www.jingweizhi.com/cookbook/tdt-4490-4479.html(访问日期 2026-11-03)。