05. 地图样式(Style)详解

2 阅读4分钟

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": []
      }
    }
  }
}

支持的数据源类型:vectorrasterraster-demgeojsonimagevideo(详见第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')

样式调试工具

// 在控制台查看当前样式
console.log(JSON.stringify(map.getStyle(), null, 2))

本课小结

  • 样式 JSON 是 MapLibre 的核心,version/sources/layers 是必需字段
  • glyphs 为文字标注提供字体,sprite 为图标提供雪碧图
  • 支持在线 URL 和本地对象两种样式加载方式
  • setStyle 整体切换样式,运行时可通过 API 局部修改
  • Maputnik 是优秀的可视化样式编辑工具

📌 上一节:04. 地图控件 📌 下一节:06. 数据源 Sources