Пользовательские проекции

Mapbox GL JS использует систему проекций для преобразования географических координат (долгота/широта) в экранные координаты WebGL-контекста. По умолчанию применяется Web Mercator (EPSG:3857), но современная архитектура рендеринга позволяет использовать альтернативные глобусы и кастомные проекции, влияющие на визуализацию карты, поведение зума, перспективу и геометрические искажения.

Mapbox GL JS реализует проекционную систему как часть рендер-пайплайна WebGL: координаты тайлов, векторов и слоёв преобразуются через матрицы проекции, которые определяют форму мира в трёхмерном или псевдотрёхмерном пространстве. Это означает, что смена проекции затрагивает не только визуальный слой, но и всю модель координатного пространства карты.

Проекция в Mapbox GL JS определяется на уровне Map-объекта и влияет на следующие компоненты:

  • преобразование координат lng/lat → world coordinates
  • вычисление тайловой сетки
  • поведение камеры (pitch, bearing, zoom)
  • отрисовка слоёв WebGL
  • взаимодействие с источниками данных (sources)

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

Внутри движка Mapbox GL JS проекционная матрица обновляется при каждом изменении камеры. Это позволяет плавно анимировать переходы между различными моделями мира без перезагрузки источников данных.

Базовые проекции

Web Mercator

Web Mercator является стандартной проекцией:

  • прямолинейная сетка меридианов и параллелей
  • сохранение углов (конформность)
  • сильные искажения у полюсов
  • совместимость с тайловыми серверами XYZ

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

Globe (3D-глобус)

Глобус представляет Землю как сферу:

  • минимизация искажений площадей
  • естественная перспектива
  • необходимость работы с 3D-камерой
  • корректная обработка горизонта

При включении глобуса WebGL сцена переходит в сферическое пространство, а тайлы «оборачиваются» на поверхность сферы.

Пример конфигурации:

import mapboxgl from "mapbox-gl";

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/streets-v12",
  projection: "globe"
});

В этом режиме камера работает в сферических координатах, а уровень зума интерпретируется как расстояние до поверхности глобуса.

Переключение проекций

В современных версиях Mapbox GL JS поддерживается динамическое изменение проекции через API:

map.setProjection("mercator");
map.setProjection("globe");

Переключение сопровождается перерасчётом матриц камеры и пересборкой сценического состояния. При этом источники данных (GeoJSON, vector tiles) не перезагружаются, что делает переход визуально непрерывным.

Математическая модель проекций

Проекция в Mapbox GL JS представляет собой функцию:

P(lng, lat) → (x, y, z)

Для Mercator:

x = R * lng
y = R * ln(tan(π/4 + lat/2))

x = R ,y = R (( + ))

Для глобуса используется сферическая модель:

x = R cos(lat) cos(lng)
y = R cos(lat) sin(lng)
z = R sin(lat)

x = R,y = R,z = R

Внутри WebGL эти координаты преобразуются в clip space через матрицы вида и проекции.

Камера и проекционное пространство

Камера в Mapbox GL JS состоит из:

  • center (центр карты)
  • zoom (уровень приближения)
  • bearing (поворот)
  • pitch (наклон)

В Mercator камера фактически работает в 2.5D пространстве, где z-ось моделирует масштабирование. В глобусе камера становится полноценной 3D-камерой.

Это приводит к следующим изменениям:

  • zoom перестаёт быть линейным масштабом
  • pitch влияет на перспективу горизонта
  • bearing становится вращением сферы

Ограничения проекций

Каждая проекция накладывает ограничения:

Web Mercator

  • невозможность корректного отображения полюсов
  • сильные искажения размеров объектов
  • ограничение lat ≈ ±85°

Globe

  • повышенная нагрузка на GPU
  • необходимость отсечения обратной стороны сферы
  • сложность работы с высокими pitch-углами
  • некорректность некоторых 2D-слоёв

Влияние на источники данных

Источники данных в Mapbox GL JS остаются независимыми от проекции:

  • GeoJSON интерпретируется в географических координатах
  • vector tiles хранятся в PBF-формате
  • raster tiles перепроецируются на лету

Однако визуализация слоёв зависит от текущей проекции:

  • fill layers требуют пересчёта геометрии
  • line layers изменяют кривизну
  • symbol layers адаптируют размер и ориентацию

Кастомные проекции

Поддержка кастомных проекций в Mapbox GL JS ограничена внутренним API WebGL, но архитектурно можно выделить три подхода:

1. Использование встроенных проекций

Наиболее стабильный путь:

  • mercator
  • globe
map.setProjection("globe");

2. Проекционные трансформации через стиль

Некоторые эффекты достигаются через style transformations:

  • exaggeration terrain
  • sky layer
  • fog

Это не меняет проекцию напрямую, но имитирует альтернативную геометрию пространства.

3. Custom Layer Interface

Через CustomLayerInterface можно внедрять собственные WebGL-шейдеры:

const customLayer = {
  id: "custom-projection-layer",
  type: "custom",
  renderingMode: "3d",

  onAdd(map, gl) {
    this.map = map;
    this.gl = gl;
  },

  render(gl, matrix) {
    // собственная математика проекции
  }
};

Этот подход позволяет полностью заменить логику проекции для отдельных объектов, но не всей карты.

Перспективные модели проекций

Современная эволюция Mapbox GL JS движется в сторону поддержки дополнительных глобальных моделей:

Equal Earth

  • более равномерное распределение площадей
  • уменьшение искажений континентов

Lambert Conformal Conic

  • используется для региональных карт
  • точная передача углов на ограниченной территории

Azimuthal projections

  • локальные виды (полярные области)
  • радиальная симметрия

Эти проекции особенно полезны в аналитических и научных приложениях, где Web Mercator не подходит.

Производительность при смене проекций

Проекции напрямую влияют на производительность WebGL-сцены:

  • globe требует дополнительной vertex processing
  • mercator оптимизирован под tile batching
  • кастомные проекции увеличивают нагрузку на CPU/GPU синхронизацию

Оптимизация внутри Mapbox GL JS включает:

  • переиспользование буферов вершин
  • кэширование матриц камеры
  • упрощение геометрии на дальних зумах

Координатные преобразования и матрицы

Каждый кадр проходит через цепочку матриц:

  1. model matrix (объект)
  2. world matrix (карта)
  3. projection matrix (проекция)
  4. view matrix (камера)

Итоговое преобразование:

MVP = P × V × M

M_{MVP} = P V M

В глобусной модели матрица P становится нелинейной функцией сферического преобразования, а не линейной матрицей перспективы.

Взаимодействие с пользовательским вводом

Проекции изменяют интерпретацию событий:

  • координаты мыши преобразуются обратно через inverse projection
  • hit-testing зависит от геометрии мира
  • drag и pan становятся вращением сферы в globe

В Mercator перемещение экрана соответствует линейному смещению координат, в globe — вращению 3D-объекта.

Гибридные подходы

Некоторые реализации в Mapbox GL JS комбинируют несколько моделей:

  • globe при низком зуме
  • mercator при высоком зуме
  • плавный morph между проекциями

Это достигается интерполяцией матриц и геометрий, что позволяет избежать резких переходов между системами координат.

Влияние на визуальные слои

Разные типы слоёв по-разному реагируют на проекцию:

  • fill — требует перерасчёта полигонов
  • line — изменяет кривизну сегментов
  • symbol — адаптирует billboard-ориентацию
  • raster — перепроецируется текстурно

Особенно критично поведение symbol-слоёв в globe, где необходимо учитывать curvature и perspective scaling.

Итоговая модель поведения проекций

Проекции в Mapbox GL JS можно рассматривать как заменяемый слой геометрического мира, который:

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

Эта архитектура позволяет расширять систему от плоской карты до полноценного 3D-глобуса и специализированных научных проекций без изменения базовой модели данных.