Mapbox GL JS построена вокруг идеи полностью клиентского рендеринга
карт с использованием WebGL. В отличие от традиционных решений, где
растровые тайлы собираются на сервере, здесь вся визуализация происходит
в браузере, что переносит основную нагрузку на GPU устройства.
Ключевая модель: декларативное описание карты + императивный
рендеринг через WebGL. Пользователь описывает что
должно быть отображено (слои, источники данных, стили), а библиотека
самостоятельно решает как это отрисовать.
Векторные тайлы как
базовый источник данных
Основой системы выступают vector tiles — компактные
бинарные фрагменты геоданных, обычно в формате Mapbox Vector Tile (MVT).
Каждый тайл содержит:
- геометрию (точки, линии, полигоны),
- атрибуты объектов,
- метаданные слоёв.
Принцип работы:
- карта разбивается на квадродерево (z/x/y),
- при изменении масштаба загружаются новые тайлы,
- тайлы кэшируются в памяти и на диске браузера.
Важный момент: данные не являются готовым изображением. Это только
геометрия и свойства, которые затем интерпретируются стилем.
Слой как единица
визуализации
Внутри Mapbox GL JS всё строится вокруг концепции
layers.
Слой — это правило отображения данных из источника. Он не содержит
геометрии, а только описывает:
- тип визуализации (fill, line, circle, symbol, heatmap,
fill-extrusion),
- фильтрацию объектов,
- стиль (цвет, ширина, прозрачность),
- порядок отрисовки.
Слои рендерятся строго последовательно, образуя стек (z-order).
Порядок слоёв критичен: он определяет итоговую композицию
изображения.
Источники данных (sources) и
их роль
Каждый слой привязан к source — источнику геоданных.
Источники бывают нескольких типов:
- vector — векторные тайлы,
- raster — растровые изображения,
- geojson — локальные или удалённые GeoJSON-данные,
- video — видеопотоки,
- image — одиночные изображения.
Принцип разделения:
- source отвечает за данные,
- layer отвечает за отображение.
Это разделение позволяет переиспользовать один источник в нескольких
слоях с разными стилями.
Декларативная модель стилей
Стиль карты описывается JSON-структурой, где задаются:
- источники,
- слои,
- глобальные параметры (центр, zoom, pitch, bearing),
- шрифты и спрайты.
Пример логики:
- данные не изменяются при изменении стиля,
- меняется только визуальная интерпретация.
Это делает систему предсказуемой и позволяет динамически переключать
темы без перезагрузки данных.
Рендеринг через WebGL
В основе отрисовки лежит WebGL pipeline:
- загрузка тайлов,
- декодирование MVT,
- преобразование геометрии в буферы GPU,
- применение шейдеров,
- компоновка слоёв.
Каждый тип слоя имеет собственные шейдеры:
- line — обработка линий с учётом ширины в пикселях,
- fill — заливка полигонов,
- symbol — текст и иконки,
- circle — точечные объекты.
GPU используется для:
- трансформации координат,
- антиалиасинга,
- интерполяции стилей,
- батчинга большого количества объектов.
Камера и матрицы
преобразований
Отображение карты управляется camera system,
включающей:
- center (географический центр),
- zoom (уровень масштабирования),
- bearing (поворот),
- pitch (наклон).
Эти параметры преобразуются в матрицы:
- projection matrix,
- view matrix,
- mercator transformation.
Географические координаты (longitude/latitude) переводятся в
координаты Web Mercator (EPSG:3857), затем в экранное пространство.
Уровни детализации и LOD
Система LOD (Level of Detail) критична для производительности.
Принцип:
- на низких zoom используются крупные обобщённые тайлы,
- на высоких zoom — более детальные,
- геометрия упрощается на сервере или при генерации тайлов.
Mapbox GL JS выбирает подходящие тайлы автоматически, балансируя
между:
- количеством объектов,
- нагрузкой на GPU,
- качеством визуализации.
Динамическое
обновление и diff-рендеринг
Изменения карты не приводят к полной перерисовке сцены.
Используется diffing state:
- сравнивается предыдущее и новое состояние стиля,
- пересчитываются только изменённые слои,
- повторно загружаются только нужные тайлы.
Это обеспечивает плавность взаимодействия даже при сложных
сценах.
Система фильтров
Фильтры позволяют ограничивать отображение данных внутри слоя:
- по атрибутам,
- по диапазонам значений,
- по логическим выражениям.
Фильтрация выполняется на этапе подготовки данных к GPU, что снижает
нагрузку на рендеринг.
Работа с текстом и символами
Symbol layer — один из самых сложных компонентов системы.
Он включает:
- размещение текста вдоль линий,
- предотвращение пересечений (collision detection),
- управление приоритетами отображения,
- подгрузку спрайтов и шрифтов.
Алгоритм размещения:
- вычисление возможных позиций,
- проверка пересечений в screen space,
- отбрасывание конфликтующих объектов,
- закрепление выбранных позиций в кэше.
Кэширование и управление
памятью
Производительность обеспечивается многоуровневым кэшированием:
- тайлы в памяти (RAM cache),
- тайлы в IndexedDB,
- GPU buffers,
- кэш стилей и шрифтов.
Система эвикции удаляет:
- невидимые тайлы,
- редко используемые регионы,
- устаревшие буферы.
Асинхронная модель загрузки
Все операции выполняются асинхронно:
- загрузка тайлов через HTTP/HTTPS,
- декодирование в Web Workers,
- подготовка буферов вне основного потока,
- передача данных в WebGL контекст.
Это предотвращает блокировку UI-потока даже при интенсивной работе с
картой.
Интерполяция и анимации
Переходы между состояниями карты основаны на интерполяции:
- zoom easing,
- плавное изменение цвета,
- анимация перемещения камеры,
- переходы между стилями.
Интерполяция выполняется на GPU или через высокочастотные обновления
frame loop.
Событийная модель
Mapbox GL JS использует систему событий:
- загрузка тайлов,
- завершение рендеринга,
- клики по объектам,
- hover-события,
- изменения состояния камеры.
Объекты карты проецируются обратно в географические координаты через
reverse projection, что позволяет точно определять интерактивные
элементы.
Производительность и
оптимизация
Основные принципы оптимизации:
- минимизация draw calls через batching,
- использование instanced rendering,
- ограничение перерисовки dirty tiles,
- приоритизация видимых слоёв,
- упрощение геометрии при масштабировании.
Дополнительно используется:
- frustum culling,
- tile preloading,
- адаптивная деградация качества при нагрузке.
Система спрайтов и шрифтов
Иконки и шрифты загружаются как атлас:
- sprite atlas содержит изображения в одном файле,
- JSON-описание координат элементов,
- шрифты разбиваются на glyph ranges.
Это снижает количество HTTP-запросов и ускоряет доступ к ресурсам
GPU.
Геометрическая
проекция и координатные системы
Основная проекция — Web Mercator:
- широта ограничивается диапазоном [-85.0511, 85.0511],
- долгота нормализуется в [-180, 180].
Причина выбора:
- простота тайлинга,
- совместимость с квадратной сеткой,
- предсказуемая деформация на глобальных масштабах.
Взаимодействие слоёв и
порядок отрисовки
Слои группируются в пайплайны:
- opaque layers (без прозрачности),
- translucent layers,
- symbol layers (часто последними).
Это уменьшает overdraw и улучшает производительность GPU.
Инкрементальный рендеринг
Каждый кадр не пересоздаёт сцену:
- обновляются только изменённые тайлы,
- пересчитываются только активные слои,
- GPU state переиспользуется между кадрами.
Рендеринг работает как непрерывный цикл, реагирующий на изменения
состояния карты.
Управление состоянием карты
Состояние карты включает:
- текущий viewport,
- активные слои,
- фильтры,
- загруженные источники,
- параметры камеры.
Любое изменение состояния вызывает минимальный набор пересчётов,
достаточный для актуализации изображения без полной перестройки
сцены.