Glyphs в MapLibre

В MapLibre GL JS текстовые подписи на карте отображаются не в виде обычных HTML-элементов, а как графические символы, которые рендерятся непосредственно внутри WebGL-сцены. Для этого используется механизм glyphs — наборов глифов, представляющих отдельные символы различных шрифтов.

Каждая буква, цифра или специальный символ является отдельным глифом. При отображении надписей движок загружает необходимые глифы, формирует из них текстовые метки и размещает их на карте согласно настройкам стиля.

Glyphs используются для:

  • названий городов;
  • подписей улиц;
  • обозначений объектов;
  • текстов на пользовательских слоях;
  • отображения данных из GeoJSON и векторных тайлов.

Без корректно настроенного источника glyphs текстовые слои работать не будут.


Связь glyphs со стилем карты

Источник глифов задаётся на уровне объекта стиля.

Пример:

{
  "version": 8,
  "glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf"
}

Параметр glyphs содержит шаблон URL, по которому MapLibre GL JS будет получать файлы шрифтов.

Используются специальные плейсхолдеры:

Плейсхолдер Назначение
{fontstack} название набора шрифтов
{range} диапазон Unicode-символов

Во время работы библиотеки значения автоматически подставляются в URL.

Например:

https://example.com/fonts/Open Sans Regular/0-255.pbf

или

https://example.com/fonts/Noto Sans Regular/1024-1279.pbf

Что такое PBF-файлы

MapLibre использует специальный бинарный формат:

Protocol Buffer (PBF)

Каждый файл содержит:

  • контуры символов;
  • метрики шрифта;
  • параметры позиционирования;
  • сведения о рендеринге.

Преимущества формата:

  • компактный размер;
  • высокая скорость загрузки;
  • эффективное кэширование;
  • быстрое построение текстовых меток.

В отличие от традиционных TTF или OTF-файлов браузер не загружает весь шрифт целиком. Загружаются только необходимые диапазоны символов.


Диапазоны Unicode

Для уменьшения объёма данных глифы разделяются на диапазоны.

Примеры:

0-255.pbf
256-511.pbf
512-767.pbf
768-1023.pbf

Если на карте используются латинские символы:

London
Paris
Berlin

обычно достаточно загрузки диапазона:

0-255.pbf

При появлении кириллицы:

Москва
Киев
Минск

MapLibre автоматически запросит дополнительные диапазоны.

Такой подход позволяет существенно сократить сетевой трафик.


Настройка источника glyphs

Наиболее распространённый вариант:

const map = new maplibregl.Map({
    container: 'map',
    style: {
        version: 8,
        glyphs: 'https://example.com/fonts/{fontstack}/{range}.pbf',
        sources: {},
        layers: []
    }
});

После создания карты все текстовые слои смогут использовать указанный сервер шрифтов.


Использование шрифтов в слоях

Glyphs работают совместно со свойством:

text-font

Пример:

{
    "id": "cities",
    "type": "symbol",
    "source": "cities",
    "layout": {
        "text-field": ["get", "name"],
        "text-font": ["Open Sans Regular"]
    }
}

Когда слой становится видимым, MapLibre выполняет следующие действия:

  1. Читает значение text-font.
  2. Формирует название font stack.
  3. Определяет необходимые символы.
  4. Загружает нужные PBF-файлы.
  5. Создаёт текстовые подписи.

Font Stack

MapLibre позволяет указывать несколько шрифтов одновременно.

Пример:

"text-font": [
    "Open Sans Regular",
    "Arial Unicode MS Regular"
]

Такой набор называется font stack.

Принцип работы:

  1. Движок пытается найти символ в первом шрифте.
  2. Если символ отсутствует — используется следующий.
  3. Процесс продолжается до нахождения подходящего глифа.

Это особенно важно для мультиязычных карт.

Например:

English
Русский
日本語
العربية

Один шрифт редко содержит полный набор символов всех языков.


Генерация URL для загрузки глифов

Пусть задано:

"text-font": [
    "Open Sans Regular"
]

и требуется вывести слово:

MapLibre

Тогда движок может сформировать запрос:

https://example.com/fonts/Open Sans Regular/0-255.pbf

Если появляется кириллица:

Карта

дополнительно может быть запрошен файл:

https://example.com/fonts/Open Sans Regular/1024-1279.pbf

Механизм полностью автоматизирован.


Локальное размещение шрифтов

Glyph-сервер необязательно должен находиться в интернете.

Часто шрифты размещают непосредственно внутри проекта.

Структура каталогов:

project/
│
├── fonts/
│   ├── Open Sans Regular/
│   │   ├── 0-255.pbf
│   │   ├── 256-511.pbf
│   │   └── ...
│   │
│   └── Noto Sans Regular/
│       ├── 0-255.pbf
│       └── ...
│
└── index.html

Настройка:

glyphs: '/fonts/{fontstack}/{range}.pbf'

Преимущества:

  • независимость от сторонних сервисов;
  • работа во внутренних сетях;
  • полный контроль над шрифтами;
  • отсутствие внешних запросов.

Использование собственного сервера шрифтов

Во многих корпоративных проектах создаётся отдельный сервис для хранения glyph-файлов.

Пример:

glyphs:
'https://maps.company.local/fonts/{fontstack}/{range}.pbf'

Преимущества:

  • централизованное управление;
  • единый набор шрифтов;
  • возможность обновления без изменения приложений;
  • высокая производительность через CDN.

Поддержка кириллицы

Для русскоязычных карт необходимо убедиться, что используемый шрифт содержит кириллические символы.

Пример подходящего набора:

"text-font": [
    "Noto Sans Regular"
]

или

"text-font": [
    "Open Sans Regular",
    "Noto Sans Regular"
]

Если глифы отсутствуют, вместо текста могут отображаться:

□ □ □ □ □

или

???

либо подпись вообще не будет отображаться.


Поддержка азиатских языков

Для китайского, японского и корейского языков количество символов существенно больше.

Пример:

北京
東京
서울

Особенности:

  • большие объёмы glyph-файлов;
  • больше диапазонов Unicode;
  • повышенное количество сетевых запросов;
  • более высокие требования к кэшированию.

Поэтому часто используются специализированные шрифты:

Noto Sans CJK

или

Noto Serif CJK

Кэширование глифов

После первой загрузки глифы сохраняются в памяти браузера.

Сценарий работы:

Загрузка карты
↓
Загрузка PBF
↓
Создание текстур
↓
Кэширование
↓
Повторное использование

Преимущества:

  • уменьшение числа запросов;
  • ускорение масштабирования;
  • плавное перемещение карты;
  • снижение нагрузки на сервер.

Влияние glyphs на производительность

Текстовые подписи являются одной из самых ресурсоёмких частей картографического рендеринга.

На производительность влияют:

  • число отображаемых подписей;
  • количество шрифтов;
  • число языков;
  • объём Unicode-диапазонов;
  • размер текстовых атласов.

Менее эффективно:

"text-font": [
    "Font A",
    "Font B",
    "Font C",
    "Font D"
]

Более эффективно:

"text-font": [
    "Noto Sans Regular"
]

или

"text-font": [
    "Open Sans Regular",
    "Noto Sans Regular"
]

Ошибки загрузки glyphs

Типичная ошибка:

Failed to load glyph range

Причины:

  • неверный URL;
  • отсутствие файла;
  • ошибка сервера;
  • неверное имя шрифта;
  • проблемы CORS.

Пример неправильной конфигурации:

glyphs: '/font/{fontstack}/{range}.pbf'

при фактическом пути:

/fonts/{fontstack}/{range}.pbf

Результат — отсутствие текстовых подписей.


Диагностика через DevTools

Для проверки работы glyphs обычно используется вкладка Network.

Следует контролировать:

0-255.pbf
256-511.pbf
1024-1279.pbf

Успешная загрузка выглядит примерно так:

Status: 200 OK
Content-Type: application/x-protobuf

Ошибки:

404 Not Found

или

403 Forbidden

свидетельствуют о проблемах конфигурации.


Glyphs и символические слои

Текстовые подписи создаются в слоях типа:

type: "symbol"

Пример:

{
    "id": "labels",
    "type": "symbol",
    "source": "places",
    "layout": {
        "text-field": ["get", "name"],
        "text-font": ["Noto Sans Regular"],
        "text-size": 14
    }
}

Здесь glyphs используются для формирования содержимого свойства:

text-field

Без настроенного источника glyphs данный слой не сможет отображать текст.


Взаимодействие glyphs и text-field

Пример данных:

{
  "name": "Алматы"
}

Стиль:

"text-field": ["get", "name"]

Последовательность работы:

  1. Получение значения "Алматы".
  2. Разбор отдельных символов.
  3. Поиск соответствующих глифов.
  4. Загрузка отсутствующих диапазонов.
  5. Формирование текстовой метки.
  6. Размещение подписи на карте.

Формирование текстурного атласа

После загрузки PBF-файлов глифы преобразуются в текстуры.

Схема:

PBF
↓
Глифы
↓
Текстурный атлас
↓
WebGL
↓
Отображение текста

Текстурный атлас представляет собой большую текстуру, внутри которой находятся изображения множества символов.

Такой подход позволяет:

  • сократить число операций отрисовки;
  • уменьшить переключения текстур;
  • повысить FPS;
  • ускорить отображение больших наборов подписей.

Лучшие практики работы с glyphs

Использование современных универсальных шрифтов

Предпочтительны:

Noto Sans
Noto Serif
Open Sans
Roboto

Они содержат широкий набор символов и хорошо подходят для международных проектов.

Минимизация количества шрифтов

Лучше использовать:

"text-font": [
    "Noto Sans Regular"
]

чем большое число альтернативных наборов.

Локальное хранение glyph-файлов

Для производственных систем часто предпочтительнее:

glyphs: '/fonts/{fontstack}/{range}.pbf'

чем зависимость от внешнего сервиса.

Контроль сетевых запросов

Следует отслеживать:

  • количество загружаемых диапазонов;
  • размеры PBF-файлов;
  • корректность кэширования;
  • отсутствие лишних шрифтов.

Проверка многоязычных данных

При работе с международными картами необходимо тестировать отображение:

English
Русский
Deutsch
العربية
日本語
中文

Это позволяет заранее выявить отсутствующие глифы и проблемы совместимости шрифтов.