05. 地图样式(Style)详解
概述
MapLibre 的地图渲染完全由**样式规范(Style Specification)**驱动。样式是一个 JSON 对象,定义了地图的数据来源、图层绘制规则、字体、图标等全部视觉表现。本节学习:
- Style Specification 的完整结构
- 各字段的作用与配置方法
- 在线样式 vs 本地样式 JSON
- 动态切换样式
Style Specification 结构
一个完整的样式 JSON 包含以下顶层字段:
{
"version": 8,
"name": "我的地图样式",
"sources": { ... },
"layers": [ ... ],
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf",
"sprite": "https://example.com/sprites/sprite",
"center": [116.39, 39.91],
"zoom": 10,
"bearing": 0,
"pitch": 0,
"metadata": { ... }
}
字段说明
| 字段 | 必需 | 说明 |
|---|---|---|
version | ✅ | 样式规范版本,当前固定为 8 |
sources | ✅ | 数据源定义(详见第06节) |
layers | ✅ | 图层数组,控制地图渲染顺序和样式 |
glyphs | ❌ | 字体 PBF 文件的 URL 模板(Symbol 图层需要) |
sprite | ❌ | 雪碧图(Sprite)URL 前缀(Symbol 图层图标需要) |
name | ❌ | 样式名称,仅用于标识 |
center | ❌ | 默认中心点 [lng, lat] |
zoom | ❌ | 默认缩放级别 |
bearing | ❌ | 默认旋转角度 |
pitch | ❌ | 默认倾斜角度 |
metadata | ❌ | 自定义元数据,MapLibre 不处理 |
sources — 数据源
定义地图使用的数据来源,是一个对象,key 为数据源名称:
{
"sources": {
"osm-tiles": {
"type": "raster",
"tiles": ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"],
"tileSize": 256
},
"my-geojson": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": []
}
}
}
}
支持的数据源类型:vector、raster、raster-dem、geojson、image、video(详见第06节)。
layers — 图层
图层数组决定了数据如何渲染。数组顺序即绘制顺序(后面的图层覆盖前面的)。
{
"layers": [
{
"id": "background",
"type": "background",
"paint": { "background-color": "#f0f0f0" }
},
{
"id": "roads",
"type": "line",
"source": "my-vector-source",
"source-layer": "road",
"paint": {
"line-color": "#888",
"line-width": 2
},
"filter": ["==", "class", "highway"]
}
]
}
图层必需属性
| 属性 | 说明 |
|---|---|
id | 唯一标识符 |
type | 图层类型:background/fill/line/symbol/circle/heatmap/fill-extrusion/raster/hillshade |
source | 数据源名称(background 类型不需要) |
图层可选属性
| 属性 | 说明 |
|---|---|
source-layer | 矢量瓦片数据源中的图层名 |
filter | 过滤表达式,筛选要素 |
layout | 布局属性(如 visibility) |
paint | 绑制属性(如颜色、宽度、透明度) |
minzoom / maxzoom | 图层可见的缩放范围 |
glyphs — 字体
Symbol 图层显示文字标注时需要字体文件,格式为 PBF(Protocol Buffer Format):
{
"glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"
}
{fontstack}:字体名称,如Open Sans Regular{range}:字符范围,如0-255
💡 如果不使用 Symbol 图层的文字标注,可以省略此字段。
sprite — 雪碧图
Symbol 图层使用图标时需要雪碧图:
{
"sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite"
}
MapLibre 会自动请求两个文件:
sprite.json— 图标元数据(名称、位置、尺寸)sprite.png— 图标合并图片
💡 可以使用
@2x后缀获取高分辨率图标。
在线样式 vs 本地样式
在线样式
直接使用 URL 指向样式 JSON:
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json'
})
本地样式 JSON 对象
直接传入 JavaScript 对象:
const myStyle: StyleSpecification = {
version: 8,
sources: {
'osm': {
type: 'raster',
tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
tileSize: 256
}
},
layers: [
{ id: 'osm-layer', type: 'raster', source: 'osm' }
]
}
const map = new maplibregl.Map({
container: 'map',
style: myStyle
})
对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 在线样式 URL | 简单、可复用、CDN 缓存 | 依赖网络、难以动态修改 |
| 本地样式对象 | 灵活、可动态构建 | 代码量大、需要管理资源 URL |
动态切换样式
setStyle — 整体替换
// 切换到新样式(会移除所有已有图层和数据源)
map.setStyle(newStyleObject)
// 监听样式加载完成
map.on('style.load', () => {
console.log('新样式已加载')
// 重新添加自定义图层/数据源
})
⚠️
setStyle会清除所有运行时添加的图层和数据源,需要在style.load事件中重新添加。
运行时修改样式(不切换)
// 修改图层的绘制属性
map.setPaintProperty('roads', 'line-color', '#ff0000')
// 修改图层的布局属性
map.setLayoutProperty('labels', 'visibility', 'none')
// 修改数据源(GeoJSON)
map.getSource('my-geojson').setData(newGeoJSON)
// 添加新图层
map.addLayer({ id: 'new-layer', type: 'circle', source: 'my-source', paint: { ... } })
// 移除图层
map.removeLayer('old-layer')
样式调试工具
- MapLibre Style Spec 文档:maplibre.org/maplibre-st…
- Maputnik:开源可视化样式编辑器 — maputnik.github.io/
- 浏览器开发者工具:
map.getStyle()查看当前完整样式
// 在控制台查看当前样式
console.log(JSON.stringify(map.getStyle(), null, 2))
本课小结
- 样式 JSON 是 MapLibre 的核心,
version/sources/layers是必需字段 glyphs为文字标注提供字体,sprite为图标提供雪碧图- 支持在线 URL 和本地对象两种样式加载方式
setStyle整体切换样式,运行时可通过 API 局部修改- Maputnik 是优秀的可视化样式编辑工具
📌 上一节:04. 地图控件 📌 下一节:06. 数据源 Sources