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

百度坐标用固定 0.0065 反算,剩下的 481 米没消掉

先看结论

从百度接口拿到的点是 BD-09,减掉 0.0065 和 0.006 之后仍然对不上 GPS 原始点,差 480 多米。

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

现象

上海人民广场 GPS 原始点 121.473701, 31.230416。 百度坐标拾取器给出 121.484724, 31.234474。 代码里按网上流传的写法做了 lng - 0.0065, lat - 0.006, 得到 121.478224, 31.228474,与 GPS 原始点仍相差 481.8 米。

换到深圳、广州,残差会变成 606.6 米和 621.7 米,说明剩下的差值不是常数。

原因

BD-09 与 GCJ-02 的关系是「极角平移」:以坐标原点为极点,先把点到原点的距离缩短 0.00002 倍的 sin(y·π·3000/180),再旋转 0.000003·cos(x·π·3000/180) 弧度。 减去 0.0065 和 0.006 只是把这一步的近似平移反解出来, 结果落回 GCJ-02,根本没有回到 WGS84。

所以那 481.8 米是 GCJ-02 与 WGS84 之间的固有偏移, 不是转换写错了,而是转换的目标坐标系只走了一半路程。

排查过程

  1. 把百度拾取器坐标减 0.0065/0.006,与已知 GCJ-02 值比对。若两者一致,说明代码止步于 GCJ-02。
  2. 用「BD-09 减差值」得到 121.478224, 31.228474,再用 GCJ-02→WGS84 正算一次,看是否回到 121.473701, 31.230416。
  3. 若两步串联后残差仍在百米级,检查是否把 BD-09 当成了 GCJ-02 直接套用 gcj2wgs。
// 只减差值:停在 GCJ-02
const gcj = [121.484724 - 0.0065, 31.234474 - 0.006];
// => [121.478224, 31.228474]  距 GPS 原始点 481.8 m

解决方案

完整链路是 BD-09 → GCJ-02 → WGS84 两步,第一步用极坐标反算,第二步用 GCJ-02 反算。

const X_PI = Math.PI * 3000 / 180;

// BD-09 -> GCJ-02
function bd09ToGcj(lng, lat) {
  const x = lng - 0.0065, y = lat - 0.006;
  const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
  const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
  return [z * Math.cos(theta), z * Math.sin(theta)];
}

// GCJ-02 -> WGS84(迭代三次,残差可降到 1e-9 度)
function gcjToWgs(lng, lat) {
  let wgs = [lng, lat];
  for (let i = 0; i < 3; i++) {
    const g = wgsToGcj(wgs[0], wgs[1]);
    wgs[0] -= g[0] - lng;
    wgs[1] -= g[1] - lat;
  }
  return wgs;
}

const wgs = gcjToWgs(...bd09ToGcj(121.484724, 31.234474));
// => [121.473701, 31.230416] 与 GPS 点相差 0.02 m

验证

用北京天安门做第二个校验点:BD-09 116.410172, 39.916634 应回到 116.403672, 39.910634,误差小于 0.5 米。 批量验证时对每个点算往返距离,全部应小于 1 米。

const g = bd09ToGcj(116.410172, 39.916634);
const w = gcjToWgs(g[0], g[1]);
console.log(w);  // [116.403672, 39.910634]
turf.distance(turf.point([116.397428, 39.909230]), turf.point(w), { units: 'meters' });
// ≈ 555.6 说明已到 WGS84

适用版本

库 / 服务版本说明
百度地图 JS API3.0 / 4.0所有入参出参均为 BD-09,BMapGL 同
百度坐标拾取器网页版显示值即 BD-09,可直接用于校验
gcoord1.0.0 及以上内置 BD09 分支,勿再手写差值
引用本文

经纬志(2026)。《百度坐标用固定 0.0065 反算,剩下的 481 米没消掉》。https://www.jingweizhi.com/cookbook/bd09-fixed-minus.html(访问日期 2026-11-03)。