В Mapbox GL JS вся работа с геометрией и визуализацией опирается на несколько систем единиц измерения, которые постоянно преобразуются друг в друга: географические координаты, мировые координаты Web Mercator, экранные пиксели и условные единицы стиля. Корректное понимание этих преобразований определяет точность позиционирования объектов, адекватность масштабирования и стабильность кастомных визуализаций.
Географические координаты задаются в формате долгота/широта (lng/lat) и измеряются в градусах. Эти значения не являются линейными: один градус долготы в разных широтах соответствует разному физическому расстоянию, что делает невозможным прямое использование градусов в расчётах расстояний или размеров.
Основная проекционная система Mapbox GL JS — Web Mercator (EPSG:3857). Она переводит сферические координаты в псевдоплоские мировые координаты, где единицы измерения становятся линейными в пределах локальных областей.
В этой системе:
Проекция вводит ключевое свойство: масштабирование становится равномерным по осям, что позволяет применять стандартные операции линейной алгебры для рендеринга.
Система масштабирования в Mapbox GL JS основана на уровне zoom:
Связь между мировыми координатами и экранными единицами определяется формулой:
[ resolution = ]
где initial_resolution зависит от широты и начальной проекции.
На практике это означает, что одна и та же географическая длина в метрах будет занимать разное количество пикселей в зависимости от уровня увеличения.
Экранные координаты в Mapbox GL JS выражаются в CSS-пикселях. Однако физическая плотность пикселей устройства влияет на итоговую визуализацию через devicePixelRatio.
Фактически:
Это приводит к необходимости учитывать двойное преобразование:
Mapbox GL JS предоставляет методы для конвертации координат в пиксели и обратно.
const point = map.project([lng, lat]);
Результат:
x — координата по горизонтали в пикселяхy — координата по вертикали в пикселяхЭти значения зависят от текущего центра карты, zoom и наклона.
const lngLat = map.unproject([x, y]);
Операция инвертирует всю матрицу трансформации камеры карты, включая перспективные эффекты.
Для задач 3D и кастомных слоёв используется объект MercatorCoordinate, представляющий точку в нормализованном мировом пространстве.
const mc = mapboxgl.MercatorCoordinate.fromLngLat([lng, lat], altitude);
Особенности:
Это ключевой механизм согласования 2D карты и 3D сцены.
Физическое расстояние в метрах не имеет прямого отображения в пикселях, поэтому используется приближённое преобразование, зависящее от широты и масштаба:
[ metersPerPixel = ]
где C — константа окружности Земли в метрах, нормированная к тайловой системе.
В практической реализации чаще используется:
const metersPerPixel = (40075016.686 * Math.cos(lat * Math.PI / 180)) /
Math.pow(2, zoom + 8);
Отсюда:
const pixels = meters / metersPerPixel;
Искажения Web Mercator усиливаются ближе к полюсам. Один и тот же объект:
Поэтому любые расчёты расстояний должны учитывать cos(latitude), иначе возникает систематическая ошибка масштабирования.
Mapbox Style Specification оперирует абстрактными единицами, которые динамически интерпретируются:
Пример масштабирования размера:
"circle-radius": [
"interpolate",
["linear"],
["zoom"],
5, 2,
10, 8,
15, 20
]
Здесь единицы радиуса интерпретируются как пиксели, но изменяются в зависимости от zoom, что фактически создаёт нелинейную шкалу преобразования единиц.
В стиле используются два основных типа масштабирования:
["interpolate", ["linear"], ...]
Изменение пропорционально входному значению.
["interpolate", ["exponential", 1.5], ...]
Позволяет моделировать нелинейные физические процессы, например плотность объектов или визуальную иерархию.
Внутренний объект трансформации карты содержит:
Эти параметры формируют матрицу преобразования:
[ M = P V T]
где:
Все единицы измерений проходят через эту матрицу перед рендерингом.
Mapbox GL JS не использует геодезические расчёты по умолчанию для рендеринга, поэтому расстояния:
Для точных измерений применяется внешний расчёт или перевод через сферические формулы, но итоговая визуализация всегда возвращается в пиксельное пространство.
При использовании 3D объектов (extrusions, terrain):
const mc = mapboxgl.MercatorCoordinate.fromLngLat(
[lng, lat],
heightInMeters
);
Здесь высота становится частью единой системы координат сцены WebGL.
Mapbox GL JS использует тайловую систему:
Это создаёт дополнительный уровень преобразования:
lng/lat → world → tile → pixel
Каждый слой карты может оперировать на своём уровне абстракции, но финальный рендер всегда приводит данные к пиксельной сетке.
При комбинировании геометрии и интерфейса возникает необходимость постоянного преобразования:
Согласование этих систем требует постоянной нормализации через project/unproject и MercatorCoordinate API, иначе возникают расхождения между логической и визуальной позицией объектов.