В экосистеме Mapbox GL JS координаты являются фундаментом всей модели взаимодействия пользователя с картой. Любое событие — клик, движение мыши, касание экрана — одновременно существует в двух пространствах: экранных пикселях и географических координатах. Понимание того, как происходит переход между этими системами, определяет качество всей логики обработки событий.
Каждое событие на карте содержит как минимум две системы координат:
При обработке событий это различие критично:
map.on('click', (e) => {
console.log(e.point); // { x: Number, y: Number } — пиксели
console.log(e.lngLat); // { lng: Number, lat: Number } — география
});
e.point всегда привязан к текущему состоянию
DOM-контейнера карты, тогда как e.lngLat учитывает все
трансформации: масштабирование, вращение, наклон и проекцию.
Объект LngLat представляет собой стандартную пару
значений:
lng — долгота (от -180 до 180)lat — широта (от -85.0511 до 85.0511 в Web
Mercator)Mapbox GL JS автоматически нормализует координаты при пересечении границ карты. Например, при панорамировании через 180-й меридиан значение longitude может «перепрыгивать», но визуально точка останется стабильной.
map.on('mousemove', (e) => {
const { lng, lat } = e.lngLat;
console.log(`Longitude: ${lng}, Latitude: ${lat}`);
});
Система e.point используется для операций, связанных с
рендерингом и взаимодействием с слоями:
map.on('click', (e) => {
const pixel = e.point;
console.log(pixel.x, pixel.y);
});
Эти координаты всегда считаются относительно контейнера
<div> карты и зависят от CSS-трансформаций.
Mapbox GL JS предоставляет прямые методы конвертации между системами координат:
const lngLat = { lng: 37.6173, lat: 55.7558 };
const point = map.project(lngLat);
console.log(point); // { x, y }
Метод учитывает текущие:
const point = { x: 200, y: 300 };
const lngLat = map.unproject(point);
console.log(lngLat); // { lng, lat }
Это основной инструмент для построения пользовательских взаимодействий вне стандартных событий.
Все pointer-события в Mapbox GL JS содержат одинаковую структуру координат:
mousedownmouseupclickdblclickmousemovemouseentermouseleaveПример унифицированной обработки:
map.on('mousemove', (e) => {
updateUI({
pixel: e.point,
geo: e.lngLat
});
});
Важно учитывать, что mousemove генерируется с высокой
частотой, поэтому работа с координатами должна быть оптимизирована.
Одной из ключевых операций является сопоставление координаты с объектами слоя:
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ['cities-layer']
});
console.log(features);
});
Метод queryRenderedFeatures использует именно
e.point, а не lngLat, так как поиск
выполняется в экранном пространстве рендеринга WebGL.
Перетаскивание карты создаёт непрерывный поток координат:
map.on('drag', (e) => {
console.log(e.point);
console.log(e.lngLat);
});
При этом:
point изменяется относительно DOM-движенияlngLat отражает реальное смещение камеры в
географическом пространствеСложность работы с событиями возрастает при включении:
bearing (поворот карты)pitch (наклон камеры)В этих режимах e.point больше не соответствует простой
декартовой проекции экрана. Mapbox GL JS применяет матрицы трансформации
WebGL, и преобразование происходит через внутреннюю камеру.
Пример:
map.setBearing(45);
map.setPitch(60);
map.on('click', (e) => {
console.log(e.lngLat);
});
Даже при сильном наклоне географические координаты остаются стабильными, тогда как пиксельные координаты становятся искажёнными перспективой.
Координаты событий часто используются для динамического создания объектов:
map.on('click', (e) => {
map.addSource('point', {
type: 'geojson',
data: {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [e.lngLat.lng, e.lngLat.lat]
}
}
});
});
Здесь происходит прямое преобразование события в GeoJSON-структуру,
где координаты строго соответствуют стандарту
[longitude, latitude].
Mapbox GL JS использует Web Mercator проекцию, поэтому:
При работе с событиями важно учитывать нормализацию:
map.on('click', (e) => {
const normalized = e.lngLat.wrap();
console.log(normalized);
});
Метод wrap() полезен при работе с повторяющимися мирами
(world copies).
На мобильных устройствах структура координат сохраняется идентичной:
map.on('touchstart', (e) => {
console.log(e.point);
console.log(e.lngLat);
});
Разница заключается лишь в источнике pointer-события, но модель координат остаётся унифицированной.
Каждое событие можно рассматривать как проекцию положения камеры:
lngLat — направление центра луча камеры в миреpoint — пересечение этого луча с плоскостью экранаПри изменении камеры изменяется вся система преобразования, но API событий остаётся стабильным интерфейсом.
На основе событий строятся ключевые инструменты:
Пример накопления координат:
const path = [];
map.on('click', (e) => {
path.push([e.lngLat.lng, e.lngLat.lat]);
});
Эта модель лежит в основе большинства интерактивных GIS-функций.