Символьные слои в MapLibre GL JS основаны на концепции объединения
иконок и текста в одном визуальном слое. Текстовые метки здесь не
являются «просто подписями» — это полноценные стилизуемые объекты, тесно
связанные с системой тайлов, шрифтами и векторным рендерингом. Их
поведение определяется декларативным стилем слоя symbol,
где каждая характеристика текста управляется выражениями и свойствами
рендера.
Текст в MapLibre GL JS не рисуется браузером напрямую. Вместо этого используется пайплайн:
text-fieldКлючевой компонент — сервер глифов, обычно доступный по шаблону:
/fonts/{fontstack}/{range}.pbf
Каждый диапазон (range) — это блок Unicode-символов. Такой подход минимизирует сетевой трафик и позволяет подгружать шрифты по мере необходимости, а не целиком.
text-field определяет содержимое метки. Он поддерживает
как простые строки, так и выражения.
Пример:
{
type: "symbol",
layout: {
"text-field": "{name}"
}
}
Использование выражений:
"text-field": [
"concat",
["get", "name"],
" - ",
["get", "type"]
]
Особенность системы заключается в том, что текст становится частью стиля данных, а не фиксированным UI-элементом.
Параметр text-font задаёт список гарнитур:
"text-font": ["Noto Sans Regular", "Arial Unicode MS Regular"]
Это не локальные шрифты браузера. Каждая гарнитура соответствует заранее подготовленному набору glyphs на сервере.
Fontstack работает как fallback-механизм:
Глифы передаются в бинарном формате Mapbox Vector Tile (PBF). Они содержат:
SDF (Signed Distance Field) позволяет:
Рендеринг текста фактически происходит в виде растеризации signed-distance функций в fragment shader.
"text-size": 16
Размер текста задаётся в пикселях, но фактически интерпретируется в координатах мира с учётом zoom-level.
Возможна динамическая зависимость:
"text-size": [
"interpolate",
["linear"],
["zoom"],
5, 10,
10, 16,
15, 24
]
Это позволяет реализовывать:
text-anchor определяет точку привязки текста
относительно геометрии:
centertopbottomleftrighttop-left,
bottom-right)Пример:
"text-anchor": "top"
Внутри рендеринга это влияет на baseline и alignment box, который вычисляется на основе метрик шрифта.
"text-offset": [0, 0.5]
Оффсет задаётся в единицах em и позволяет:
Важно: смещение применяется после вычисления anchor, но до collision detection.
MapLibre использует систему предотвращения наложений:
Ключевые параметры:
"text-allow-overlap": false
"text-ignore-placement": false
"text-padding": 2
text-padding расширяет bbox для создания «воздушного
пространства» между элементами.
"text-justify": "auto"
Поддерживаемые режимы:
При multi-line тексте каждая строка выравнивается отдельно, а общий bounding box пересчитывается как объединение всех строк.
"text-transform": "uppercase"
Возможные значения:
Важно: трансформация применяется после формирования glyph sequence, но до layout, что влияет на ширину строки и коллизии.
Для мультиязычных карт это критично, так как изменение регистра может влиять на CJK и кириллицу иначе, чем на латиницу.
Поддержка китайского, японского и корейского требует:
Особенности:
Это делает важным корректный выбор text-font, иначе
появляются пропуски или tofu-символы.
"text-rotation-alignment": "map"
Опции:
Используется в сочетании с:
"text-rotate": 45
Для линий (например дорог) чаще применяется map, чтобы
подписи следовали геометрии.
Когда текст используется вместе с иконкой:
"icon-text-fit": "both"
Возможные режимы:
Это позволяет:
"text-variable-anchor": ["top", "bottom", "left", "right"]
MapLibre может автоматически выбирать лучшее положение метки, минимизируя коллизии.
Алгоритм:
"text-writing-mode": ["vertical"]
Используется для:
Поддержка зависит от glyph availability и ориентации шрифта.
Основные узкие места:
Оптимизации:
max-text-field-lengthsymbol-placement: "line" только при
необходимостиВ WebGL рендерере текст превращается в батчи, минимизирующие draw calls.
Текстовые свойства поддерживают expressions:
"text-opacity": [
"interpolate",
["linear"],
["zoom"],
5, 0,
10, 1
]
Также:
"text-halo-color": "#ffffff",
"text-halo-width": 2
Halo (обводка) реализуется через SDF и шейдерные смещения, а не через отдельные геометрии.
В symbol слое текст и иконка делят одно
пространство:
Это позволяет строить сложные комбинированные маркеры, но требует точной настройки padding и alignment, иначе возникает визуальная перегруженность или скрытие элементов.
Текст в MapLibre GL JS фактически является набором quads, где каждая буква:
Shader выполняет:
При изменении:
Особенно важно при text-rotation-alignment: map, где
текст становится частью геометрии сцены, а не интерфейса.