百度的瓦片原点在原点偏移处,按 XYZ 算整层偏移
按 Google 的公式算百度瓦片编号,每个级别都差几十张瓦片,拼出来的图像条带错位。
现象
用 x = floor((lng + 180) / 360 * 2^z) 计算百度瓦片编号,
18 级下天安门得到 x = 215971, y = 99264。
实际打开百度地图,网络面板里的瓦片编号是 x = 209317, y = 96843,
横行相差 6654 张,纵列相差 2421 张。
拼接出的图片每一行都错位,越往东越偏。
原因
百度的瓦片网格不是以 (0,0) 为左上角的 Google 网格,而是:
- 层级从 3 级开始提供,1、2 级只有示意瓦片。
- 瓦片编号基于 BD09MC 坐标,原点与 XYZ 不同,且每级缩放原点会平移。
- 分辨率基数是 2 的幂次与
20037726.37的组合,不是标准墨卡托。
直接用 XYZ 公式,等于假设百度用的是 Google 的网格,从第一张瓦片就错了。
排查过程
- 在浏览器打开百度地图,缩放到 18 级,网络面板记录一张已知位置瓦片的 URL 编号。
- 用 XYZ 公式对同一点算一次,比较差值。
- 把差值除以
2^z,看是否为固定比例,判断是原点偏移还是尺度差异。 - 检查是否混用了 BD-09 经纬度与 BD09MC 平面坐标。
// 错误的 XYZ 公式
const z = 18;
const lng = 116.410172, lat = 39.916634;
const n = Math.pow(2, z);
const xXyz = Math.floor((lng + 180) / 360 * n); // 215971
const yXyz = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * n); // 99264
// 百度实际编号(同一位置)
const xBaidu = 209317, yBaidu = 96843;
解决方案
不要在百度瓦片上套 XYZ。展示用途直接引入百度 JS API; 确实需要自算编号时,用 BD09MC 平面坐标除以该级的分辨率。
// 百度瓦片编号:由 BD09MC 平面坐标换算
// 分辨率(米/像素)随层级变化,基数 2^(18 - z)
const RES = [0, 0, 0,
262144, 131072, 65536, 32768, 16384, 8192, 4096,
2048, 1024, 512, 256, 128, 64, 32, 16, 8];
function baiduTile(mx, my, z) {
const res = RES[z];
const x = Math.floor(mx / res);
const y = Math.floor(my / res);
return [x, y];
}
// 天安门 BD09MC 约 (12962180, 4859510),18 级 res = 8
baiduTile(12962180, 4859510, 18);
// 得到 [1620272, 607439],这是以 (0,0) 为原点的编号
// 与百度实际编号 209317 / 96843 仍差一个平移量,不能直接用
上例说明一个更重要的事实:编号还要叠加百度自己的原点偏移,
单靠分辨率相除仍会错。最稳的做法是解析百度 JS API 的
getTileUrl 结果,或直接使用成熟的百度图层插件。
// 用插件封装,避免自己算
L.tileLayer.baidu({ layer: 'sat', type: 'tile' }).addTo(map);
验证
自算编号与浏览器网络面板中的编号一致,最多允许 1 张的差异; 拼接出的瓦片图与百度地图截图逐像素对齐。
console.assert(xBaidu === 209317, '编号未与网络面板对齐');
// 相邻两张瓦片必须无缝衔接
const next = [xBaidu + 1, yBaidu];
console.assert(next[0] - xBaidu === 1, '横向编号不连续');
适用版本
| 组件 | 版本 | 说明 |
|---|---|---|
| 百度瓦片服务 | — | 层级 3~19,编号基于 BD09MC |
| 百度 JS API | 3.0 / 4.0 | 自带 getTileUrl,推荐直接用 |
| Leaflet 百度插件 | 1.x | 已封装编号换算 |
经纬志(2026)。《百度的瓦片原点在原点偏移处,按 XYZ 算整层偏移》。https://www.jingweizhi.com/cookbook/baidu-tile-origin.html(访问日期 2026-11-03)。