В основе работы с картой в Mapbox GL JS лежит постоянное преобразование координат между несколькими пространственными системами: географической (долгота/широта), проекционной (плоской картой) и экранной (пиксели холста). Эти преобразования определяют всё — от размещения маркеров до отрисовки слоёв и вычисления геометрии взаимодействия с пользователем.
Ключевая концепция состоит в том, что данные хранятся в одной системе координат, визуализируются в другой, а взаимодействие пользователя происходит в третьей. Переходы между ними являются непрерывным процессом внутри render-loop карты.
Базовая система координат в Mapbox GL JS — WGS84, где каждая точка задаётся парой:
Формат представления:
[longitude, latitude]
Пример:
[69.2401, 53.2145]
Эта система используется:
Координаты в WGS84 являются угловыми величинами, измеряемыми в градусах, и не могут быть напрямую отображены на плоскости без проекции.
Основная внутренняя система отображения в Mapbox GL JS — Web Mercator, также известная как EPSG:3857.
Web Mercator projection
Эта проекция преобразует сферические координаты в плоские, используя следующие свойства:
Математическая идея базируется на преобразовании:
Формально:
x = R * λ
y = R * ln(tan(π/4 + φ/2))
где:
После проекции данные переходят в экранное пространство, где:
Экранные координаты зависят от:
Mapbox GL JS использует каскадную модель трансформаций:
WGS84 (lon/lat)
↓
Web Mercator (projected world coordinates)
↓
Tile coordinates (zoom-dependent grid)
↓
Clip space (WebGL normalized coordinates)
↓
Screen coordinates (pixels)
Каждый слой этого пайплайна обслуживается отдельными компонентами:
Координаты в пользовательском API представлены объектом:
const point = new mapboxgl.LngLat(69.2401, 53.2145);
Этот объект выполняет роль контейнера для географических координат и предоставляет методы для:
При передаче в систему рендеринга происходит автоматическое преобразование в projected space.
Преобразует географическую координату в пиксельную относительно текущего состояния камеры.
const pixel = map.project([69.2401, 53.2145]);
Результат:
{
x: number,
y: number
}
Применяется:
Обратное преобразование: из экранных координат в географические.
const lngLat = map.unproject({ x: 300, y: 200 });
Используется для:
Внутренний механизм Mapbox GL JS основан на матрицах преобразования 4×4, объединяющих:
Обобщённо:
M_total = M_projection × M_camera × M_model
Где:
Эта система позволяет:
Карты разбиваются на тайлы:
/{z}/{x}/{y}
где:
Каждый тайл представляет собой квадрат фиксированного размера (обычно 512 или 256 пикселей в логическом пространстве).
Преобразование координат в тайлы:
Zoom является ключевым параметром, влияющим на все уровни трансформации.
При увеличении zoom:
Математически:
scale = 2^zoom
Это означает экспоненциальное увеличение масштаба, где каждый следующий уровень zoom удваивает размер отображаемого пространства.
В Mapbox GL JS применяется гибридная модель:
Перспектива проявляется через:
При pitch = 0 карта становится ортографической, и преобразования упрощаются до двумерных.
При обработке событий (click, mousemove) используется обратная цепочка преобразований:
Это позволяет точно определять:
Данные GeoJSON проходят последовательность:
Каждая вершина обрабатывается отдельно, но с общими матричными параметрами камеры, что обеспечивает согласованность отображения.
При анимации:
Особое внимание уделяется:
В Mapbox GL JS поддерживаются различные стандарты входных данных:
Все они приводятся к единой внутренней модели, что позволяет:
Основные источники искажений:
Особенно заметны:
Обобщённая модель преобразования координат:
GeoJSON → LngLat → Mercator → Tile → Camera → Screen → DOM/WebGL
И обратный путь:
Screen → Camera inverse → Mercator inverse → LngLat
Эта двунаправленная система делает возможным: