Координатная система в Mapbox GL JS основана на долгоживущем веб-стандарте представления геоданных через долготу и широту. Все визуальные сущности на карте — от центра вида до отдельных точек, линий и полигонов — привязываются к географическим координатам, а не к пикселям экрана. Это фундаментальный принцип, определяющий поведение всей системы рендеринга и взаимодействия.
Основная единица работы — пара значений [долгота, широта], где:
В Mapbox GL JS порядок всегда фиксирован: сначала долгота, затем широта. Нарушение этого порядка приводит к смещению объектов на тысячи километров, поскольку значения интерпретируются в глобальном масштабе.
const center = [37.6173, 55.7558]; // Москва: [lng, lat]
Эта пара координат используется для установки центра карты, размещения маркеров, построения источников данных и любых геометрических операций.
Карта в Mapbox GL JS всегда имеет логический центр, определяющий,
какая часть мира отображается в текущем viewport. Центр задаётся через
параметр center при инициализации или динамически через
методы управления камерой.
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [30.3351, 59.9343],
zoom: 10
});
Изменение центра приводит не к перемещению объектов, а к изменению виртуальной камеры, которая «смотрит» на разные участки глобальной координатной плоскости.
Ключевая особенность заключается в том, что координаты объектов остаются неизменными, а изменяется только матрица трансформации вида.
Каждый маркер в Mapbox GL JS жёстко связан с координатами. Он не существует в системе пикселей, пока не будет отрисован.
new mapboxgl.Marker()
.setLngLat([37.6173, 55.7558])
.addTo(map);
Метод setLngLat закрепляет элемент за конкретной
географической точкой. При изменении масштаба или перемещении карты
маркер автоматически пересчитывает своё экранное положение.
Внутри системы происходит постоянное преобразование:
географические координаты → мировые координаты → экранные координаты
Одной из ключевых возможностей является двунаправленное преобразование между экранными и географическими координатами.
const pixel = map.project([37.6173, 55.7558]);
Результат содержит координаты в пикселях относительно контейнера карты. Это используется для позиционирования пользовательских HTML-элементов поверх карты.
const lngLat = map.unproject([200, 150]);
Этот механизм особенно важен при обработке событий мыши, когда необходимо определить географическую точку клика.
Каждое событие взаимодействия с картой содержит уже рассчитанные координаты:
map.on('click', (e) => {
console.log(e.lngLat);
});
e.lngLat представляет собой объект с полями
lng и lat, что избавляет от необходимости
ручного преобразования пикселей в географические значения.
Эта модель обеспечивает строгую географическую привязку всех пользовательских действий.
GeoJSON является основным форматом хранения геометрии. Все координаты
внутри GeoJSON также задаются в формате
[longitude, latitude].
map.addSource('points', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [37.6173, 55.7558]
}
}
]
}
});
Любой слой, использующий этот источник, автоматически интерпретирует координаты и размещает объекты в географическом пространстве.
Слои (layers) не содержат координат напрямую. Они опираются на источники данных, которые уже включают геометрию.
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 6,
'circle-color': '#ff0000'
}
});
Каждый объект слоя рендерится строго в соответствии с его координатами в источнике, без дополнительной геометрической логики на уровне слоя.
Камера карты описывается тремя основными параметрами:
map.flyTo({
center: [37.6173, 55.7558],
zoom: 12,
bearing: 30
});
Все эти параметры влияют на матрицу преобразования, которая связывает географическое пространство с экранным.
Важно, что координаты объектов не изменяются при анимации камеры — изменяется только способ их проекции.
Привязка к координатам используется не только для объектов, но и для ограничения области видимости карты.
map.setMaxBounds([
[29.0, 59.0],
[31.0, 60.5]
]);
Здесь задаётся прямоугольная область в географических координатах, за пределы которой камера не может перемещаться.
Помимо встроенных маркеров, можно привязывать произвольные DOM-элементы к координатам карты.
const el = document.createElement('div');
el.className = 'custom-marker';
new mapboxgl.Marker(el)
.setLngLat([37.6173, 55.7558])
.addTo(map);
Такой подход позволяет синхронизировать географическое положение с кастомной визуализацией.
Всплывающие окна также привязываются к координатам и автоматически смещаются относительно точки якоря.
new mapboxgl.Popup()
.setLngLat([37.6173, 55.7558])
.setHTML('Точка интереса')
.addTo(map);
Позиционирование попапа зависит от текущего масштаба и положения камеры, но его географическая привязка остаётся неизменной.
Границы карты задаются двумя угловыми точками:
const bounds = [
[37.0, 55.0],
[38.0, 56.0]
];
map.fitBounds(bounds);
Метод fitBounds вычисляет оптимальный центр и масштаб,
чтобы вся область была полностью видна.
Внутри Mapbox GL JS используется Web Mercator projection. Она переводит сферические координаты в плоскую систему координат, пригодную для отображения на экране.
Упрощённая схема преобразования:
широта/долгота → сферическая модель → проекция Меркатора → мировые координаты → экранные координаты
Именно эта цепочка обеспечивает корректное масштабирование и непрерывность карты при любом уровне zoom.
При увеличении масштаба координаты не изменяются, но увеличивается плотность их отображения. Один и тот же географический участок при zoom 5 и zoom 15 представляет собой разные размеры в пикселях, хотя координаты остаются фиксированными.
Это создаёт эффект бесшовного масштабирования без потери географической точности.
При обработке drag-событий карта постоянно пересчитывает центральные координаты:
map.on('move', () => {
console.log(map.getCenter());
});
Каждое смещение мыши или жест приводит к обновлению центра в географических координатах, а не в пикселях.
Привязка к координатам позволяет синхронизировать несколько независимых карт:
mapA.on('move', () => {
mapB.setCenter(mapA.getCenter());
});
Здесь географические координаты выступают единственным источником истины, обеспечивая идентичное отображение разных экземпляров карты.