01 · NOTES / WebGIS 开发
第 02 节 · 底图与瓦片源
2026 年 9 月 1 日
第 02 节 · 底图与瓦片源
📌 版本信息:Leaflet 1.9.4 / leaflet-providers 2.x(2026-08-29 核对) 📚 来源:leaflet-providers 预览页(上百种底图在线试) | 天地图 API 文档 | 本地
resources/05-leaflet/leaflet-providers/🎯 解决"底图从哪来、怎么换、怎么合规"三个问题。
一、这一节的目标
- 精通 TileLayer 的完整参数(URL 模板/子域/缩放范围/attribution)
- 掌握 providers 插件:一行换百种底图
- 掌握天地图接入(国内合规首选:分层 + key)
- 理解"底图 + 注记层"的叠加模型
二、TileLayer 参数全解
L.tileLayer(urlTemplate, options).addTo(map);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19, // 该源支持的最大级别(超了会 404——Leaflet 不再请求新瓦片)
minZoom: 0,
subdomains: 'abc', // {s} 占位符的候选值:轮换子域规避浏览器同域并发限制(6 连接/域)
attribution: '© OpenStreetMap', // 版权(义务)
opacity: 1, // 透明度(叠加层常用 0.5~0.7)
className: 'my-tiles', // 挂 CSS 类(滤镜做暗色底图:filter: invert(1) hue-rotate(180deg))
crossOrigin: true, // 需要 canvas 读像素(截图/分析)时必须
errorTileUrl: '占位图URL', // 404 瓦片的替身
keepBuffer: 2, // 视口外保留几圈旧瓦片(拖动不平滑就调大它)
updateWhenIdle: false, // 移动端:拖动中是否加载(桌面默认 true)
noWrap: false, // 世界是否水平循环(经度 ±180 续接)
bounds: [[..],[..]], // 只在该范围加载(局部图层省流量)
});
💡 暗色底图的免费技巧:
className: 'dark-tiles'+.dark-tiles { filter: invert(1) hue-rotate(180deg) brightness(.9) }——把亮色 OSM 一键变暗色(大屏项目快速方案,正式项目用第 08 模块的矢量样式)。
三、providers 插件:一行换百种底图
<script src="https://unpkg.com/leaflet-providers@2.0.0/leaflet-providers_2.js"></script>
// 装插件后 L.tileLayer.provider('名字') 一行搞定(内置 URL/attribution)
L.tileLayer.provider('CartoDB.Positron').addTo(map); // 浅灰简约
L.tileLayer.provider('CartoDB.DarkMatter').addTo(map); // 暗色
L.tileLayer.provider('Esri.WorldImagery').addTo(map); // 卫星影像
L.tileLayer.provider('Stadia.StamenTerrain', { key: '...' }) // 地形(部分需 key)
// 全目录见官方预览页;含高德/ogle 系(部分在国内不可用或需 key,预览页可筛)
注意:providers 只是"URL 收藏夹"——合规性要自己把关(商用配额、国内可访问性)。国内生产环境底图三选一:天地图(官方合规)/ 高德(体验好)/ 自建瓦片(可控,模块 14)。
四、天地图接入(国内合规标准流程)
const KEY = '你的key'; // lbs.tianditu.gov.cn 注册申请(免费,有配额)
// 天地图是"分层服务":底图与注记是两个服务,要叠两层!
const base = L.tileLayer(
`https://t{s}.tianditu.gov.cn/vec_w/wmts?layer=vec&style=default&tilematrixset=w&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileRow={y}&TileCol={x}&tk=${KEY}`,
{ subdomains: ['0','1','2','3','4','5','6','7'], maxZoom: 18 }
);
const labels = L.tileLayer(
`https://t{s}.tianditu.gov.cn/cva_w/wmts?layer=cva&style=default&tilematrixset=w&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileRow={y}&TileCol={x}&tk=${KEY}`,
{ subdomains: ['0','1','2','3','4','5','6','7'], maxZoom: 18 }
);
base.addTo(map);
labels.addTo(map); // 注记层叠在底图上(没有它地图上没有文字!)
// 影像版:底图 img_w + 注记 cia_w;地形版 ter_w
第一次接天地图必踩的三坑:①忘了叠注记层(地图没字);②key 没配域名白名单(403);③用 w(球面墨卡托)服务却当 4326 数据对(坐标系口径,模块 04)。
五、动手跟练:02 · 多底图对比页
配套文件:05-leaflet/examples/02-多底图对比页.html
步骤:
- 一个页面四宫格或切换按钮:OSM / CartoDB 浅色 / Esri 卫星 / 天地图(vec+cva 叠加)四源同屏对比
- 完成 6 个 TODO:用 providers 插件换三种底图、天地图双层接入(自己填 key)、暗色滤镜实验(className + filter)、透明度滑块(opacity)、分层显隐(底图去/注记留——注记可单独存在)、subdomains 实验看 Network 的域名轮换
- 建一张"底图速查卡"(页面底部):每个源的名字/级别范围/是否需 key/合规场景
通关标准:
- 四种底图切换流畅,天地图出字
- 能背出 TileLayer 的 6 个常用参数
- 能说出"国内生产底图三选一"及理由
六、自测题
{s}与{r}占位符各是什么?- 为什么 TileLayer 的 maxZoom 要与数据源匹配?
- 天地图底图与注记的关系?
- keepBuffer 调大解决什么问题?
- 暗色底图的快速方案?
参考答案
- {s}=子域轮换(破并发限制);{r}=retina 高清占位(源支持 @2x 时用)。
- 超出源能力的级别会持续 404;设对后 Leaflet 用放大算法兜底。
- 两个独立服务层:底图(vec/img/ter)+ 注记(cva/cia/cta),前端叠加成完整地图。
- 拖动时多保留视口外的旧瓦片,来回拖不闪白。
- 亮色源 + CSS filter invert+hue-rotate(className 方案);正式方案是矢量样式(模块 08)。
七、下一步
底图齐了 → 第 03 节:标记与图标,往地图上放"你的东西"。