天地图还是 OSM?国内地图底图怎么选、瓦片怎么拼、GeoJSON 怎么叠
做国内地理项目,被问最多的一个问题就是:底图到底用天地图还是 OpenStreetMap?两个我都线上跑过,结论不复杂,但坐标系和瓦片这两个坑踩过一次就记住了。
先说坐标系,不然叠图会"飘"
GeoJSON 用的是 WGS84 经纬度。OpenStreetMap 的瓦片也是 WGS84,天地图的经纬度底图(vec_w / cgcs2000)用的是 2000 国家大地坐标系。CGCS2000 和 WGS84 在绝大多数显示场景下偏差在米级以内,肉眼基本看不出,所以 GeoJSON 直接往天地图、OSM 上叠,位置是对得上的。
但同一份 GeoJSON 叠到高德、腾讯这类用 GCJ-02 的底图上,会整体偏移几百米到一公里,这正好是 坐标系那篇 讲的事。简单记:WGS84/CGCS2000 算一类,GCJ-02 算一类,跨类得先转换。
瓦片是怎么拼出来的
浏览器里的地图几乎都跑在 Web 墨卡托(EPSG:3857)上,把地球压成正方形再切成 256×256 的小瓦片,按层级 z、列 x、行 y 去取。两种底图的差别主要在 URL 约定。
OpenStreetMap 是最朴素的 XYZ:
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
天地图走 WMTS,但给了一个等价的 DataServer 简写,在 Leaflet 里当 XYZ 用也行:
https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=你的密钥
下面这张表把几个核心差异列清楚:
| 维度 | OpenStreetMap | 天地图 |
|---|---|---|
| 坐标系 | WGS84 | CGCS2000(与 WGS84 可视对齐) |
| 瓦片协议 | XYZ | WMTS / DataServer(XYZ 兼容) |
| 国内访问 | 不稳定 | 稳定(国内节点) |
| 鉴权 | 无需 | 需免费 token |
| 数据来源 | 社区 | 官方测绘 |
| 适合场景 | 海外 / 测试 | 国内生产 |
在 Leaflet 里切底图、叠 GeoJSON
不绕弯,直接给能跑的代码:
// 天地图经纬度矢量底图(CGCS2000,与 WGS84 可视对齐)
const tdt = L.tileLayer(
'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=YOUR_TDT_TOKEN',
{ maxZoom: 18, attribution: '© 天地图' }
);
// OpenStreetMap 标准瓦片(WGS84)
const osm = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{ maxZoom: 19, attribution: '© OpenStreetMap contributors' }
);
const map = L.map('map', { layers: [tdt] }).setView([39.9, 116.4], 10);
// GeoJSON 直接叠加:WGS84/CGCS2000,无需二次偏移
const GEOJSON_URL = 'https://geojsoncn.com/mapjson/110000.json'; // 换成你的数据
fetch(GEOJSON_URL)
.then(r => r.json())
.then(gj => L.geoJSON(gj, { style: { color: '#e0492f', weight: 1.5 } }).addTo(map));
// 右上角切换底图
L.control.layers({ '天地图': tdt, 'OSM': osm }).addTo(map);
叠加逻辑和 渲染那篇 一致,区别只在于底图层的来源。两边都是 WGS84/CGCS2000,所以你的 GeoJSON 不用做任何坐标变换就能对上边界。
国内上线的两个现实问题
一是访问稳定性。OSM 的瓦片服务器在国内经常抽风,正式服务基本不能指望它。天地图有国内 CDN 节点,我用下来延迟和可用性都稳,前提是先去官网申请一个 token。个人开发者有免费额度,但超过额度要按量计费,别当成完全不要钱。
二是加载体积。一个市的区县边界 GeoJSON 轻松几 MB,直接 fetch 进页面会转圈。生产里我会先把边界做 压缩和量化,再靠 边缘缓存 把这几万张页在国内 4G 下也压到秒开。
我的选型建议
- 面向国内用户、要稳定上线:天地图加申请 token,GeoJSON 直接叠。
- 做海外或纯本地调试:OSM 零配置最省事。
- 别把 WGS84 的 GeoJSON 直接喂给 GCJ-02 底图,那是另一个坑,见 坐标系。
底图层再稳,几万张边界页的 收录和 canonical 也得单独做,不然百度根本不理你。底图只是第一公里,SEO 是另一回事。