Система отображения текста в MapLibre GL JS основана на использовании glyphs — специальных наборов глифов (символьных изображений), которые используются для рендеринга подписей на карте. Каждый символ текста не хранится внутри стиля карты напрямую. Вместо этого движок загружает необходимые глифы с сервера по мере необходимости и собирает из них текстовые надписи.
Такой подход обеспечивает несколько важных преимуществ:
При работе с текстовыми слоями (symbol) система glyphs
является обязательным компонентом практически любого картографического
стиля.
Внутри MapLibre GL JS текст отображается следующим образом:
Схема выглядит следующим образом:
Текст объекта
↓
Определение символов
↓
Загрузка glyphs
↓
Кэширование
↓
Отрисовка текста
Например, если карта содержит подпись:
Москва
движок загружает глифы для символов:
М
о
с
к
в
а
После этого они могут многократно использоваться для других подписей без повторной загрузки.
Путь к серверу глифов задаётся через свойство:
{
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf"
}
Данное свойство находится в корне JSON-описания стиля.
Полный пример:
{
"version": 8,
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf",
"sources": {},
"layers": []
}
В URL используются специальные переменные.
Содержит название шрифта или набора шрифтов.
Пример:
Open Sans Regular
или
Noto Sans Regular
В результате запрос может выглядеть так:
https://example.com/fonts/Open Sans Regular/0-255.pbf
Содержит диапазон Unicode-символов.
Пример:
0-255
256-511
512-767
Если на карте используются кириллические символы, MapLibre автоматически запрашивает соответствующий диапазон Unicode.
Например:
https://example.com/fonts/Open Sans Regular/1024-1279.pbf
Файлы glyphs используют расширение:
.pbf
Это бинарный формат Protocol Buffers.
Преимущества:
Обычный TTF-файл может занимать несколько мегабайт, тогда как набор glyphs для одного диапазона символов зачастую занимает всего несколько килобайт.
После настройки glyphs текстовые слои могут ссылаться на конкретные шрифты.
Пример:
map.addLayer({
id: 'cities',
type: 'symbol',
source: 'cities',
layout: {
'text-field': ['get', 'name'],
'text-font': ['Open Sans Regular'],
'text-size': 14
}
});
Здесь MapLibre будет искать глифы для шрифта:
Open Sans Regular
через URL, указанный в свойстве glyphs.
Разрешается указывать несколько шрифтов одновременно.
Пример:
layout: {
'text-font': [
'Open Sans Regular',
'Arial Unicode MS Regular'
]
}
В этом случае используется механизм резервного отображения.
Если символ отсутствует в первом шрифте:
Open Sans Regular
то будет выполнена попытка найти его во втором:
Arial Unicode MS Regular
Подобная схема особенно полезна для мультиязычных карт.
Unicode содержит более миллиона возможных кодовых точек.
Загрузка полного шрифта для каждой карты привела бы к серьёзным проблемам:
Поэтому используется разбиение на диапазоны.
Например:
0–255
256–511
512–767
...
Если карта содержит только латиницу:
Berlin
Paris
London
будет загружен лишь небольшой набор диапазонов.
Если появляются китайские подписи:
北京
上海
广州
движок запросит дополнительные диапазоны только для нужных символов.
MapLibre GL JS не создаёт glyphs самостоятельно в браузере.
Подготовка выполняется заранее специальными инструментами.
Наиболее распространённый вариант:
fontnik
Этот инструмент преобразует обычные шрифты:
.ttf
.otf
в наборы:
.pbf
разбитые по диапазонам Unicode.
Fontnik был разработан компанией Mapbox и долгое время являлся стандартным инструментом генерации glyphs.
Типичная схема работы:
TTF
↓
Fontnik
↓
PBF glyphs
↓
MapLibre GL JS
После обработки создаётся структура каталогов:
fonts/
├─ Open Sans Regular/
│ ├─ 0-255.pbf
│ ├─ 256-511.pbf
│ ├─ 512-767.pbf
│ └─ ...
└─ Noto Sans Regular/
├─ 0-255.pbf
├─ 256-511.pbf
└─ ...
Для небольших проектов файлы glyphs часто размещаются на том же сервере, что и приложение.
Структура может выглядеть так:
public/
├─ fonts/
│ ├─ Open Sans Regular/
│ └─ Noto Sans Regular/
├─ style.json
└─ index.html
Тогда путь в стиле будет следующим:
{
"glyphs": "/fonts/{fontstack}/{range}.pbf"
}
Glyphs могут загружаться и с внешнего сервера.
Пример:
{
"glyphs": "https://cdn.example.com/fonts/{fontstack}/{range}.pbf"
}
Преимущества такого подхода:
После загрузки глифы сохраняются в памяти браузера.
Поэтому при повторном появлении тех же символов повторный запрос не выполняется.
Например:
Москва
Мурманск
Минск
Символ:
М
будет загружен только один раз.
Это значительно повышает производительность при работе с большими наборами данных.
Одно из ключевых преимуществ системы glyphs — эффективная работа с различными языками.
Пример данных:
{
"name_en": "Moscow",
"name_ru": "Москва",
"name_zh": "莫斯科",
"name_ar": "موسكو"
}
Стиль может динамически выбирать поле:
'text-field': ['get', 'name_ru']
или
'text-field': ['get', 'name_en']
MapLibre автоматически загрузит необходимые диапазоны символов.
Каждый диапазон обычно охватывает 256 символов.
Примеры:
| Диапазон | Символы |
|---|---|
| 0–255 | Базовая латиница |
| 256–511 | Расширенная латиница |
| 1024–1279 | Кириллица |
| 1536–1791 | Арабский |
| 19968+ | Китайские иероглифы |
При появлении нового символа движок определяет его Unicode-код и вычисляет требуемый диапазон.
Открыв инструменты разработчика браузера на вкладке Network, можно увидеть запросы:
0-255.pbf
256-511.pbf
1024-1279.pbf
Например:
GET /fonts/Open Sans Regular/0-255.pbf
GET /fonts/Open Sans Regular/1024-1279.pbf
Если запросы завершаются ошибкой:
404 Not Found
подписи на карте могут не отображаться.
Ошибка:
{
"glyphs": "/font/{fontstack}/{range}.pbf"
}
при фактическом расположении:
/fonts/
Результат:
404 Not Found
В слое указан:
'text-font': ['Roboto Regular']
но каталог:
Roboto Regular/
отсутствует.
Результат:
Failed to load glyph range
Каталог:
OpenSans-Regular
а в стиле:
'text-font': ['Open Sans Regular']
MapLibre рассматривает эти строки как разные значения.
При размещении glyphs на отдельном домене необходимо настроить заголовки:
Access-Control-Allow-Origin: *
или более строгие разрешения для конкретных доменов.
Без корректной настройки браузер заблокирует загрузку.
Типичный процесс подготовки:
glyphs.text-font.Схема:
Шрифт
↓
Генератор glyphs
↓
PBF-файлы
↓
Веб-сервер
↓
MapLibre GL JS
Корректно организованная система glyphs позволяет:
Особенно заметен эффект при отображении:
Glyphs используются только слоями типа:
type: 'symbol'
Пример:
map.addLayer({
id: 'roads-labels',
type: 'symbol',
source: 'roads',
layout: {
'text-field': ['get', 'name']
}
});
Если текстовые подписи отсутствуют, система glyphs практически не участвует в работе карты.
Для слоёв:
fill
line
circle
raster
hillshade
background
загрузка glyphs не требуется.
Содержимое свойства:
'text-field'
определяет, какие символы будут запрошены.
Пример:
'text-field': ['get', 'name']
При появлении нового объекта:
{
"name": "Караганда"
}
MapLibre анализирует строку, определяет необходимые Unicode-символы и автоматически загружает отсутствующие диапазоны glyphs.
Таким образом, система генерации glyphs представляет собой фундаментальный механизм текстового рендеринга в MapLibre GL JS, обеспечивающий компактное хранение шрифтов, эффективную загрузку символов по диапазонам Unicode и высокопроизводительное отображение подписей на картах любого масштаба и языкового состава.