mcpField
M
maplibre-fonts-glyphs

maplibre-fonts-glyphs

github.com/maplibre开发155243 次安装今天更新
代码仓库

关于 maplibre-fonts-glyphs

为使用 MapLibre 的开发者提供字体与字形配置指导,涵盖字形 PBF、自托管、GL JS 本地字体回退及多语言文字渲染限制。

主要功能

  1. 01配置字形 URL 与字体栈
  2. 02复用或生成字形 PBF
  3. 03了解 GL JS 本地字体回退
  4. 04处理 CJK 与其他文字脚本
  5. 05识别文字塑形限制

适用场景

  1. 01排查地图标签缺失或字体错误
  2. 02为自定义样式托管字形文件
  3. 03配置离线或本地字体渲染

安装

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

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

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

详细介绍

MapLibre 字体与字形

MapLibre 默认不会使用机器上已安装的字体来渲染文本。它会从服务器获取预先计算好的字形图像,或者(自 5.11.0 起的 GL JS)回退到本地/系统字体。本技能介绍字形的来源、GL JS 的本地字体回退机制、MapLibre Native 单独的 font-faces 机制,以及对非拉丁文字的支持。有关字体大小、字重和其他视觉层级设置,请参阅 maplibre-cartography。

何时使用本技能

  • 文本标签无法渲染,或渲染时使用了错误的字体
  • 为自定义或可自托管的样式设置 glyphs URL
  • 决定是自托管现有字体 PBF,还是从 TTF/OTF 生成自己的 PBF
  • 渲染非拉丁文字(中文、日文、韩文、阿拉伯文、希伯来文、天城文等)
  • 在 GL JS 或 Native 上本地/离线渲染字体,不使用字形服务

不要为了凑内容而在无关的回答中使用本技能。 字体和字形只会影响设置了 text-field 的符号图层。关于地形、山体阴影或任何不绘制文本的图层的问题,应直接给出正常且聚焦的回答,完全不提字体、字形和标签文字,也不加入相关注意事项或故障排查表格。

MapLibre 使用 SDF 字形渲染文本

MapLibre 使用 SDF(有符号距离场)字形 渲染文本——这些预先计算的字体文件可在任意缩放级别或屏幕密度下清晰缩放,并由与样式 glyphs 字段相匹配的 URL 提供。在 GL JS ≥ 5.11.0 中(PR #4564),无法解析 glyphs 不再是致命问题:MapLibre 会改用 TinySDF 在本地渲染文本,并将 text-font 视为本地/Web 字体名称的级联列表。这涵盖两种情况:

  • 完全省略 glyphs。 这是正式支持的本地字体模式,而不只是错误恢复机制。每个 text-font 名称都会被解析为 Web 字体(通过 @font-face 或 document.fonts.load() 加载)或系统字体,其方式与浏览器解析 CSS font-family 列表相同。不需要生成 PBF,也不需要字形服务。请参阅本地字体和 Web 字体示例。
  • 设置了 glyphs,但特定字形 PBF 加载失败(字体名称错误、404 等)。系统会针对相应字形范围启动相同的本地渲染路径,而不是让瓦片加载失败,并记录 Unable to load glyph range ... Rendering codepoint U+... locally instead.。这属于外观问题,而非正确性问题:文本会以通用的本地/系统字体渲染,具体字体因操作系统/浏览器而异,但不会变得不可见,也不会导致图层失效。

PR 作者提出的注意事项依然适用:此功能仅适用于 GL JS。 PR 文本表示不希望“鼓励样式作者依赖非 CJK 本地文本渲染”,因为 Native 仍需 Android 和 iOS 提供相匹配的实现,才能确保互操作性。若样式必须在 GL JS 和 Native 上呈现一致,就应继续显式提供字形,而不要依赖回退机制。

Native 的对应方案使用的是另一个属性,并非同一个属性。 Native 不支持省略 glyphs 来回退到本地字体(相关问题仍未解决:maplibre-native#165)。它有自己的 font-faces 属性(Android ≥ 11.13.0,iOS ≥ 6.18.0——GL JS 尚未实现,gl-js#6637),可将每个 text-font 名称映射到一个或多个本地字体文件,并由你明确指定 Unicode 范围。它和 GL JS 的回退机制目标相同——无需字形服务即可离线渲染——但 Native 采用手动而非自动的方式:你可以精确控制每个文件涵盖哪些码点,代价是必须自行确定这些范围。不要将 font-faces 配置移植到 GL JS 样式中,也不要将省略 glyphs 的 GL JS 模式移植到 Native——目前这两个 SDK 使用彼此无关的机制来实现本地字体。

设置字形 URL

样式的 glyphs 字段是一个以 /{fontstack}/{range}.pbf 结尾的 URL 模板(例如:https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf),其中 {fontstack} 是以逗号连接的 text-font 列表,{range} 是 Unicode 范围 — 具体机制请参阅:样式规范 — glyphs。text-font 本身是一个回退列表 — 请参阅下文的适用于全球地图的 Noto。

字体选项

来源可用字体备注
demotiles.maplibre.org/fontNoto Sans(拉丁文、阿拉伯文、CJK 等)、Noto Sans Bold、Italic免费,由公共服务器托管;适合原型开发
OpenMapTiles fonts.openmaptiles.orgKlokantech Noto Sans 系列与 OMT 架构样式相匹配
自托管,现有字体重用预构建的 PBF(openmaptiles/fonts、UNDP-Data/fonts,或当前服务的目录树)完全自主控制;标准字体无需生成
自托管,自定义字体根据自己的 TTF/OTF 生成 PBF仅当该字体没有预构建的 PBF 集时才需要

对于标准字体(Noto Sans、Open Sans、Roboto 等),无需生成任何内容。 最简单的做法是将字形服务已有的 {fontstack}/{range}.pbf 目录树(例如,样式当前指向的目录树)复制到自己的源站。openmaptiles/fonts 和 UNDP-Data/fonts 将常见的标准字体打包为字形 PBF,你可以自行构建或拉取。两者也各自运行托管端点 — 这些是第三方服务,因此如果你的目的是自托管,请跳过它们。将样式的 glyphs 字段指向自己的 URL 模板;text-font 数组中的字体名称必须与所提供的字体栈目录名称完全一致。

从 TTF/OTF 生成字形是另一项更繁重的任务 — 仅在需要使用没有现成 PBF 集的自定义字体或品牌字体时才需要。使用 Font Maker 或 fontnik 生成 .pbf 文件,然后按上述相同方式提供并引用。

面向全球地图的 Noto

Noto(“no tofu”,意为“不出现豆腐块”)是 Google 开源的字体系列,旨在实现近乎全面的 Unicode 覆盖:Noto Sans 覆盖拉丁文、希腊文和西里尔文,特定文字系统的字体(Noto Sans Arabic、Noto Sans Devanagari、Noto Sans Thai,以及按地区划分的 Noto Sans CJK SC/TC/JP/KR)则进一步扩展了覆盖范围。如何处理非拉丁文本取决于文字系统,而 CJK 是人们最常处理错误的情况。

CJK(中文、日文、韩文)——默认在本地渲染;不要提供 CJK 字形 PBF。 GL JS 的 localIdeographFontFamily 地图选项默认为 'sans-serif',因此 CJK 字符会在设备上生成(TinySDF),且 text-font 对它们无效(字重关键字除外)。添加此功能是因为 CJK 文本在 Unicode 范围内的分布较分散:否则单个瓦片就可能触发数十次大型字形请求。[2] 请保持启用;也可以将其指向设备上更美观的 CJK 字体。设置 localIdeographFontFamily: false 会恢复通过服务端提供 CJK 字形,但速度会慢得多——仅在你确实需要服务端字体的字形形状时才这样做。

const map = new maplibregl.Map({
  // ...
  localIdeographFontFamily: '"Noto Sans CJK SC", sans-serif' // optional; default is 'sans-serif'
});

其他非拉丁文字系统(阿拉伯文、希伯来文、泰文等)——需要实际字形。 localIdeographFontFamily 不适用于这些文字系统。请将相关 Noto 文字系统字体添加到样式图层的 text-font 回退列表中,并提供其字形 PBF(或依赖 GL JS ≥ 5.11.0 的本地回退功能,但这取决于环境——参见此技能顶部)。

天城文、高棉文及其他需要连字/重排的文字系统——仅有字形并不能解决问题。 MapLibre 会将每个 Unicode 码位映射到一个字形,且没有文本整形引擎(没有 HarfBuzz/Raqm),因此无法组合这些文字系统所需的连字,也无法进行重排——即使提供了正确字体的 PBF,文本仍无法正确显示。目前没有可通过配置解决的办法;这是已知的架构限制。[3]

{ "text-font": ["Noto Sans Regular", "Noto Sans Devanagari Regular"] }

阿拉伯文和希伯来文还需要 RTL 文本插件,才能正确进行从右向左的整形和排序——仅有字形覆盖还不够。GL JS 默认不处理 RTL[1]:

import { setRTLTextPlugin } from 'maplibre-gl';
setRTLTextPlugin('https://unpkg.com/maplibre-gl/dist/maplibre-gl-rtl-text.js', null, true);

请在初始化地图之前调用此函数。

相关技能

参考资料

  1. setRTLTextPlugin(MapLibre GL JS API) — 正确整形阿拉伯文/希伯来文所必需
  2. 使用本地生成的表意文字(MapLibre GL JS 示例) — localIdeographFontFamily 的默认值和 CJK 渲染行为
  3. “关于 MapLibre 中的文本渲染” — SDF 字形架构、码位到字形的映射,以及为什么依赖文本整形的文字系统(天城文、高棉文)无法正确渲染

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

评论

支持 Markdown