百度墨卡托漏了 MCBAND 分段,点位偏出三公里
用 lng * 20037508.34 / 180 自己算百度瓦片坐标,结果和百度的瓦片对不上。
现象
北京天安门 BD-09 坐标 116.410172, 39.916634。
按标准 Web 墨卡托算得 x = 12958335, y = 4855942,
按百度自己的瓦片规则反推,实际位置约为 12962180, 4859510,
相差约 3.8 公里,落到瓦片编号上差了 15 个瓦片(18 级)。
拼接出来的百度瓦片图整体向西南错位,缩放级别越高错得越明显。
原因
百度的 BD09MC 不是 EPSG:3857。它的 Y 轴用一组 18 段的查找表
MCBAND 与 LLBAND 做分段拟合,
每段的系数不同,用来在低纬度保持接近等距、在高纬度压缩。
标准墨卡托只有一个全局的对数公式,无法拟合这套分段。
| 纬度段(LLBAND) | 对应的 MCBAND 上限 |
|---|---|
| 75° | 20037726.37 |
| 60° | 12474105.01 |
| 45° | 8399737.89 |
| 30° | 5621521.49 |
| 15° | 2817904.64 |
| 0° | 0 |
正算时先用纬度确定落在哪一段,再取该段的 MC2LL 系数表对应的一行;
反算时先用 Y 值定位 MCBAND 段。跳过这一步,误差在中纬度就能到公里级。
排查过程
- 用标准公式算出瓦片坐标,与百度瓦片服务的实际瓦片编号比对,若整片偏移,说明投影不同。
- 检查代码里是否出现
MCBAND、LLBAND、MC2LL这几个常量。 - 用一个已知点(拾取器坐标 + 对应瓦片编号)反推,看是否需要分段系数才能对上。
- 比较同一纬度带上不同经度的点,若误差只随纬度变化,就是 Y 轴分段的问题。
const MCBAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0];
const LLBAND = [75, 60, 45, 30, 15, 0];
const x = 116.410172 * 20037508.34 / 180; // 12958335
const y = Math.log(Math.tan((90 + 39.916634) * Math.PI / 360)) / (Math.PI / 180);
const yy = y * 20037508.34 / 180; // 4855942
// 与百度实际值 12962180 / 4859510 差约 3.8 km
解决方案
不要自己实现 BD09MC。能用 BD-09 经纬度就用经纬度, 必须用平面坐标时调用官方转换或成熟的第三方实现。
// 百度 JS API 自带转换,最稳
const projection = new BMapGL.MercatorProjection();
const p = projection.lngLatToPoint(new BMapGL.Point(116.410172, 39.916634));
// => { x: 12962179.6, y: 4859509.1 }
// 反向
const ll = projection.pointToLngLat(new BMapGL.Pixel(12962179.6, 4859509.1));
// => { lng: 116.410172, lat: 39.916634 }
Cesium 场景下同理,用百度官方插件提供的投影函数,
不要用 WebMercatorProjection 顶替。
验证
北京点在 BD09MC 下应为 12962180, 4859510 左右(允许 ±50 米,因拟合表版本差异);
用该坐标算出的 18 级瓦片编号应与百度地图实际请求的编号一致。
const z = 18, tileSize = 256;
const n = Math.pow(2, z);
const tx = Math.floor((12962180 + 20037726.37) / (2 * 20037726.37) * n);
const ty = Math.floor((20037726.37 - 4859510) / (2 * 20037726.37) * n);
console.log(tx, ty); // 与浏览器网络面板里的 tile 编号对照
适用版本
| 组件 | 版本 | 说明 |
|---|---|---|
| 百度地图 JS API | 3.0 / 4.0(BMapGL) | MercatorProjection 内置分段表 |
| 百度瓦片服务 | — | 层级 3~19,18 级为常用底图 |
| Cesium 百度插件 | 1.x | 必须用插件自带投影 |
经纬志(2026)。《百度墨卡托漏了 MCBAND 分段,点位偏出三公里》。https://www.jingweizhi.com/cookbook/bd09-mcband.html(访问日期 2026-11-03)。