mcpField
M
maplibre-cartography

maplibre-cartography

github.com/maplibre设计与 UI155432 次安装今天更新
代码仓库

关于 maplibre-cartography

面向 MapLibre 样式作者的制图指导,涵盖标签对比度、视觉层级和图层顺序。内容还说明如何针对影像底图调整符号与道路样式,避免自定义数据遮挡标签。

主要功能

  1. 01按底图类型设置标签颜色与光晕
  2. 02建立文字和要素的视觉层级
  3. 03调整影像底图上的道路样式
  4. 04确定数据图层的插入顺序
  5. 05检查样式的对比度与可访问性

适用场景

  1. 01发布前审查地图样式
  2. 02提高影像地图上的标签可读性
  3. 03向现有底图添加数据而不遮挡标签
  4. 04为影像底图调整道路配色与层级

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/maplibre/maplibre-agent-skills --skill maplibre-cartography

安装后在 Claude Code 中输入/maplibre-cartography确认已加载。

详细介绍

MapLibre 制图

MapLibre 会精确渲染你描述的样式。本技能介绍如何做好描述:为标签选择在任何底图上都清晰易读的颜色、构建连贯的视觉层级,以及正确排列样式图层。有关字体/字形设置,请参阅 maplibre-fonts-glyphs;有关精灵图、图标来源和路线盾牌,请参阅 maplibre-sprites-icons。

何时使用本技能

  • 在发布前,根据制图最佳实践审查样式
  • 为新样式或迁移后的样式选择标签 text-color 和 text-halo-color,或点符号/图标颜色——包括在纯色矢量底图上清晰可读,但切换到影像底图后消失或与背景混在一起的情况
  • 设置或调试 sprite、图标或路线盾牌——请参阅 maplibre-sprites-icons;有关 glyphs,请参阅 maplibre-fonts-glyphs
  • 向现有底图注入自定义数据图层,同时不遮挡标签
  • 将浅色底图矢量调色板中的道路重新设置样式,使其融入影像,而非浮于影像之上
  • 审查样式的对比度可访问性

底图类型决定标签颜色

MapLibre 会动态放置标签,因此无法像静态地图那样遮住每个标签背后的背景。相反,应选择一种 text-halo-color,使标签与可能出现的所有背景区分开来,并选择一种能在光晕上清晰可读的 text-color。对于色调统一的底图(纯浅色或深色矢量底图),光晕可以与底图色调一致,而无需与其形成对比——由文字本身与底图形成对比。影像没有统一的色调可供匹配,因此光晕必须与所有可能的背景形成对比:

底图类型背景推荐文字颜色推荐光晕
浅色矢量(街道、OpenFreeMap positron)浅色/白色深色(#333 或类似颜色)浅色半透明(rgba(255,255,255,0.8))
深色矢量(dark-matter、夜间导航)深色白色或近白色(#ffffff)深色半透明(rgba(0,0,0,0.75))
卫星或航空影像(NAIP、Sentinel-2)不可预测——明亮的农田、深色森林、城市屋顶白色(#ffffff)深色半透明(rgba(0,0,0,0.75))

最常见的错误是使用不透明的白色光晕:除非背景是纯白色,否则它会破坏标签与其所标注要素之间的空间联系——请添加透明度。第二常见的错误是在影像上沿用浅色矢量调色板,这样在深色地形、森林和水面上就无法清晰显示。在影像上,始终使用白色文字和深色半透明光晕("text-color": "#ffffff"、"text-halo-color": "rgba(0,0,0,0.75)"、"text-halo-width": 1.2)。

对于有色调的标签(公园、水域、兴趣点),请使用语义颜色的浅色调(公园用 #c8f5cc,水域用 #a8d8ff),而不要使用深色饱和版本:浅色调在深色光晕上清晰可读,同时保留语义含义;完全饱和的颜色在小尺寸下对比效果较差。

光晕宽度

较宽的光晕能提高可读性,但也会增加视觉重量。常用值如下:

场景text-halo-width
正文标签(城市、城镇、村庄)0.8–1.5
国家/大陆(大号文字)1.5–2.0
小型 POI 或山峰标签0.8–1.2
使用彩色文字的水域/公园标签1.0–1.5

text-halo-width 的单位是相对于文字的像素。光晕不得延伸到相邻标签上:小字号文字的光晕应保持紧凑,并增加透明度。

影像上的点符号和图标

标记面临着与标签相同的图底关系问题,但需要采用不同的处理方式。航空影像上的彩色图标会与不可预测、繁杂且_低饱和度_的摄影背景争夺视觉注意力。

  • 如果背景本身就有符号的色相,就无法将符号与背景区分开来。 绿色图标叠在绿色公园上,棕色图标叠在裸露土壤上:两者都会被伪装起来。大多数航空影像的饱和度都较低,因此背景最弱的维度是彩度。使用高饱和度填充色(琥珀色、陶土色),既能形成区分,又保留自然、质朴的色调。如果场景中也有该色调,只改变色相、换成另一种大地色调并无帮助。
  • 使用 icon-halo-color/icon-halo-width 将符号从背景中凸显出来,方法与给标签加光晕完全相同——这只对 SDF 精灵图有效(通过 addImage(..., { sdf: true }) 添加的图像,或以 SDF 构建的精灵图);全彩图标没有光晕绘制属性,因此必须将边缘效果直接绘制到图稿中。浅色的细光晕在深色树冠和水面上清晰可见;深色边缘则能在亮色土壤和屋顶上保持清晰。光晕应保持纤细——粗环看起来像贴纸——但有一类符号例外:需要主导地图的符号(紧急标记、最重要的单个专题要素),此时较粗的光环正是所需效果。
  • 纯色填充在照片上看起来像贴纸。 为地貌或 3D 符号添加能体现立体感的线索。渐变(受光坡面较亮、背光坡面较暗)能呈现形状。_接触阴影_是在底部下方聚集的扁平模糊椭圆,比偏移的投影更能将符号固定在地面上;偏移投影会让符号看起来悬浮起来。符号的光照和阴影方向应与底图的 hillshade-illumination-direction(通常为 NW,即 315°)一致,这样符号就能与地形处于相同的光照环境中。

通过 addImage 添加 SVG 图标: 在运行时将 SVG 加载到精灵图图像中时(获取 SVG,将其解码为 Image,然后调用 map.addImage),SVG 会在解码时栅格化,因此 linearGradient 和 feDropShadow 滤镜会正确烘焙进去。[1] 有两点需要注意:扩展 viewBox,避免光晕和阴影在图标边缘被裁切;并确保 width/height 与 viewBox 成比例,避免字形变形。对于密集的点数据,请使用 "icon-allow-overlap": true。

视觉层级

层级安排合理,意味着最重要的要素会在适当的缩放级别占据主导地位——这对标签和线/面数据图层同样适用。对于标签,MapLibre 通过文字大小、字重、字间距、对比度和缩放范围内的可见性来控制层级。线和面也适用同样的方法:line-width 和填充饱和度可替代文字大小;与底图的对比度(低饱和背景上的高饱和线条、繁杂背景上的低饱和填充)在层级塑造上的作用不亚于尺寸——有关线/面的详细说明,请参阅下文的在影像上设置矢量道路样式。

按要素类别设置文字大小

要素重要性越低,文字大小应越小。以下缩放级别是起点;请根据你的瓦片架构和缩放范围进行调整:

标签类型基础缩放级别最大缩放级别大小范围(px)
洲1414–20
国家2711–17
城市71114–24
城镇101411–16
村庄 / 小村落111610–14
机场 / POI101612–14
山峰 / 峰顶81310–11

在相同缩放级别下,兴趣点(POI)标签的视觉效果应比居民点标签更轻(尺寸更小、字重更细)。在显示起伏平缓地形(如丘陵)的影像地图上,山峰标签应比机场标签更小——它们是海拔标记,而不是主要地标。

字体粗细

使用 text-font(例如 ["Noto Sans Bold"])通过字重强化层级:国家和首府使用粗体,城镇、城市和大多数标签使用常规体,水体、公园和地区使用_斜体_(这是一种如今已不总是遵循的制图惯例)。

多行标签

对于紧凑的双行标签(例如符号字符位于名称上方),请将 text-line-height 降至 1.0 以下,以避免行间距过大:

{
  "text-field": "△\n{name:latin}",
  "text-line-height": 0.9,
  "text-max-width": 8
}

约 0.9 的值可以在小字号下生成紧凑易读的双行标签。不要低于约 0.8,否则使用标准字号时文本行会重叠。

文字转换和间距
  • 国家和洲的标签使用 "text-transform": "uppercase"——这是一种传统的制图惯例
  • 地区标签使用 "text-letter-spacing": 0.05–0.1,使文字在区域内展开

在影像上设置矢量道路样式

浅色底图样式(OSM Bright、OSM Liberty)中的矢量道路调色板经过调校,能在浅色纸面上醒目呈现,因此使用了高饱和度、暖色调和完全不透明的颜色。底图换成影像后,这些特性就会与照片争抢注意力。应将影像作为主体,将道路作为叠加其上的参考信息,而不是反过来。

  • 大幅降低饱和度。 将填充和描边调整为中性灰或柔和色调。鲜亮的橙色 / 黄色道路层级(#f90、#fd4、#b06010)最容易造成问题;请用浅灰色替换填充,并用深灰色或深色同色系替换描边。
  • 用宽度和明度体现层级,而非色相。 宽度阶梯已经表达了高速公路 > 居住道路;无需使用鲜艳的颜色来传达这一点。
  • 保持不透明,而非透明。 半透明道路会让影像纹理透出,使整张地图显得扁平。建议使用不透明填充,并搭配明度受控的描边,以呈现清晰、分层的道路。
  • 用描边勾勒道路。 比填充更深的描边能绘制出中线,防止双幅车道合并成一团。_镂空描边_采用填充色自身的深色调,而非突兀的黑色,可以勾勒边缘,又不会产生卡通式的粗重轮廓。
  • 按缩放级别控制亮度。 为高缩放级别调校的道路,在初始的低缩放级别下往往显得过重,因为此时只显示细窄的主要道路,而且描边会占据主导。应按缩放级别插值颜色:低缩放级别时描边较深,放大时逐渐变浅;填充则应是最浅的元素,并在道路网络逐渐完整显示时变亮。
{
  "line-color": ["interpolate", ["linear"], ["zoom"], 10, "#454545", 12, "#5a5a5a", 14, "#6e6e6e"]
}

精灵图和图标

精灵图配置、加载多个精灵图集、托管精灵图资源、从 SVG 构建精灵图以及诊断路线盾牌相关内容,请参阅 maplibre-sprites-icons。

样式图层顺序

MapLibre 按照样式中 layers 数组的顺序渲染图层——第一项最先绘制(位于底部),最后一项最后绘制(位于顶部)。顺序设置不当,是数据图层遮挡底图标签的最常见原因。

注入模式

在运行时向现有底图样式添加自己的数据时,应将数据图层插入第一个符号图层之前(使用 map.getStyle().layers.find((l) => l.type === 'symbol')?.id 查找其 ID,并将其作为 addLayer 的第二个参数传入),这样几何图形才会显示在标签下方。如果不传入该参数,数据图层会显示在所有内容上方,包括标签。

自定义样式的规范图层顺序

从头构建样式时,请遵循以下从底到顶的顺序:

  1. background
  2. 栅格影像(如果使用卫星/航拍数据源)
  3. 山体阴影图层(如有 — 配置请参见 maplibre-terrain-rendering)
  4. 地形填充(水域、陆地、公园 — 多边形图层)
  5. 线图层(道路、边界、河流)
  6. 你的数据多边形和线图层
  7. 底图自身的符号图层(地点标签、道路标签)
  8. 你的数据符号/标签图层(如有)

山体阴影应紧邻栅格影像上方、所有矢量图层下方,并设置足够的透明度,使影像能够透显。如果为影像添加透明度并将其叠加在山体阴影上方,影像会显得褪色或黯淡。如果将山体阴影应用于矢量图层,线条和填充颜色会显得斑驳、模糊或暗淡。

无障碍

MapLibre 样式会在浏览器中渲染为 WebGL 画布。无障碍方面的注意事项:

  • 文本对比度: WCAG 2.1 AA 要求普通文本的对比度为 4.5:1,大号文本为 3:1(SC 1.4.3)。白色文本配合 rgba(0,0,0,0.75) 光晕,在大多数背景下都符合要求 — 请使用 WebAIM Contrast Checker 等工具检查文本与光晕组合后的颜色,而不只是文本本身。
  • 不要只依赖颜色: 除色相外,还应使用形状、大小或图案。
  • 标签最小尺寸: 即使在低缩放级别,也应优先选择从 10px 开始的尺寸档位。
  • 屏幕阅读器与 WebGL 画布: MapLibre 的画布本身无法供屏幕阅读器访问。为提供无障碍地图体验,请提供可访问的替代内容,例如数据表或地图内容的文字说明。

相关技能

  • maplibre-sprites-icons — sprite 基础 URL 和 {id, url} 数组格式、自托管和构建精灵图、使用 addImage 添加运行时图像,以及路线盾牌。
  • maplibre-fonts-glyphs — 设置 glyphs URL、自托管或生成字体 PBF、GL JS 本地字体回退、MapLibre Native 的 font-faces,以及非拉丁文字脚本支持。
  • maplibre-tile-sources — 为数据集选择 GeoJSON 或瓦片。
  • maplibre-source-wiring — 让已配置的数据源完成渲染:TileJSON、source-layer、图层顺序和 CORS。
  • maplibre-pmtiles-patterns — 从 PMTiles 文件提供影像(栅格)和地形数据源。
  • maplibre-terrain-rendering — 山体阴影、彩色地形渲染、等高线和 3D 地形配置。

参考资料

  1. Map.addImage()(MapLibre GL JS API)

此技能内容为快照。 如果主要来源与本文档内容相矛盾 — 上方的参考资料、MapLibre 当前文档,或运行 MapLibre 时观察到的实际行为 — 请以该来源为准。请遵循该来源,然后报告此处的不一致,并注明来源和 MapLibre 版本:修改你本地安装的副本对其他人没有帮助,而且下次更新时会被覆盖。

评论

支持 Markdown