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

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:

  1. загрузка тайлов,
  2. декодирование MVT,
  3. преобразование геометрии в буферы GPU,
  4. применение шейдеров,
  5. компоновка слоёв.

Каждый тип слоя имеет собственные шейдеры:

  • 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,
  • активные слои,
  • фильтры,
  • загруженные источники,
  • параметры камеры.

Любое изменение состояния вызывает минимальный набор пересчётов, достаточный для актуализации изображения без полной перестройки сцены.