Любой объект на карте в Mapbox GL JS привязывается к определённым координатам. Маркеры, всплывающие окна, линии, полигоны, маршруты и пользовательские слои используют географические координаты для определения своего положения.
Основой координатной системы служит стандарт WGS84, в котором местоположение задаётся двумя значениями:
lng);lat).Пример координат города Алматы:
[76.886, 43.238]
Здесь:
76.886 — долгота;43.238 — широта.В Mapbox GL JS порядок координат всегда следующий:
[longitude, latitude]
Это одно из наиболее важных правил при работе с картой.
Долгота определяет положение точки относительно нулевого меридиана.
Диапазон значений:
-180 ... 180
Примеры:
-74.0060 // Нью-Йорк
37.6173 // Москва
139.6917 // Токио
Отрицательные значения находятся западнее нулевого меридиана, положительные — восточнее.
Широта определяет положение точки относительно экватора.
Диапазон значений:
-90 ... 90
Примеры:
40.7128 // Нью-Йорк
55.7558 // Москва
35.6895 // Токио
Отрицательные значения располагаются южнее экватора, положительные — севернее.
Очень распространённая ошибка — перепутать широту и долготу местами.
Правильно:
const coordinates = [37.6173, 55.7558];
Неправильно:
const coordinates = [55.7558, 37.6173];
При неправильном порядке объект может оказаться:
Создание маркера:
new mapboxgl.Marker()
.setLngLat([37.6173, 55.7558])
.addTo(map);
Метод setLngLat() всегда ожидает сначала долготу, затем
широту.
Карта также использует географические координаты для определения центра отображаемой области.
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [37.6173, 55.7558],
zoom: 10
});
Здесь центр карты находится в Москве.
Получение текущего центра:
const center = map.getCenter();
console.log(center.lng);
console.log(center.lat);
Результат:
LngLat {
lng: 37.6173,
lat: 55.7558
}
Mapbox GL JS предоставляет специальный класс LngLat.
Создание объекта:
const point = new mapboxgl.LngLat(
37.6173,
55.7558
);
Доступ к значениям:
console.log(point.lng);
console.log(point.lat);
Использование при центрировании карты:
map.setCenter(point);
GeoJSON является основным форматом пространственных данных в Mapbox GL JS.
Точка:
{
"type": "Point",
"coordinates": [37.6173, 55.7558]
}
Линия:
{
"type": "LineString",
"coordinates": [
[37.6173, 55.7558],
[37.6500, 55.7800]
]
}
Полигон:
{
"type": "Polygon",
"coordinates": [[
[37.60, 55.75],
[37.70, 55.75],
[37.70, 55.85],
[37.60, 55.85],
[37.60, 55.75]
]]
}
Во всех случаях сохраняется одинаковый порядок:
[longitude, latitude]
При работе с картой существуют два различных типа координат:
Описывают положение объекта на Земле.
Пример:
[37.6173, 55.7558]
Используются для:
Описывают положение пикселя внутри контейнера карты.
Пример:
{x: 400, y: 300}
Используются для:
Метод project() переводит географические координаты в
экранные.
const pixel = map.project([37.6173, 55.7558]);
console.log(pixel);
Результат:
Point {
x: 512,
y: 384
}
Теперь известна точка на экране, соответствующая заданному месту на карте.
Обратное преобразование выполняет метод unproject().
const lngLat = map.unproject([512, 384]);
console.log(lngLat);
Результат:
LngLat {
lng: 37.6173,
lat: 55.7558
}
Подобное преобразование часто применяется при создании пользовательских интерфейсов поверх карты.
Во время клика Mapbox GL JS предоставляет оба типа координат.
map.on('click', (e) => {
console.log(e.lngLat);
console.log(e.point);
});
Объект:
e.lngLat
содержит географические координаты:
LngLat {
lng: 37.61,
lat: 55.75
}
Объект:
e.point
содержит экранные координаты:
Point {
x: 450,
y: 320
}
Эти объекты часто путают, хотя они решают разные задачи.
LngLat {
lng: 37.6173,
lat: 55.7558
}
Используется для описания реального положения на поверхности Земли.
Point {
x: 300,
y: 200
}
Используется для описания положения внутри окна карты.
Сравнение:
| Характеристика | LngLat | Point |
|---|---|---|
| Тип данных | Географические координаты | Экранные координаты |
| Единицы измерения | Градусы | Пиксели |
| Используется для | Карты мира | DOM-контейнера |
| Зависит от масштаба | Нет | Да |
Одна и та же географическая точка остаётся неизменной независимо от масштаба.
Например:
[37.6173, 55.7558]
Однако экранные координаты изменяются.
При масштабе:
zoom: 5
точка может находиться здесь:
{x: 420, y: 310}
При масштабе:
zoom: 15
уже здесь:
{x: 1500, y: 980}
Причина заключается в том, что карта увеличивается, а географическое положение остаётся постоянным.
После панорамирования экранные координаты объекта изменяются.
Географическая точка:
[37.6173, 55.7558]
остаётся прежней.
Но результат:
map.project(...)
будет другим, поскольку объект окажется в новой позиции внутри контейнера карты.
Координаты объекта описывают постоянное положение элемента на карте.
Пример маркера:
const marker = new mapboxgl.Marker()
.setLngLat([37.6173, 55.7558])
.addTo(map);
Координаты события отражают текущую позицию курсора.
map.on('mousemove', (e) => {
console.log(e.lngLat);
});
Даже если курсор проходит над маркером, это не означает, что координаты события совпадают с координатами маркера.
Многие методы принимают массивы координат.
Точка:
[37.6173, 55.7558]
Маршрут:
[
[37.6173, 55.7558],
[37.6300, 55.7600],
[37.6500, 55.7800]
]
Обработка массива:
route.forEach(coord => {
console.log(
coord[0],
coord[1]
);
});
Где:
coord[0] // longitude
coord[1] // latitude
Перед отображением объектов полезно проверять диапазон значений.
Пример:
function isValidCoordinate(lng, lat) {
return (
lng >= -180 &&
lng <= 180 &&
lat >= -90 &&
lat <= 90
);
}
Использование:
if (isValidCoordinate(37.6173, 55.7558)) {
console.log('Координаты корректны');
}
Подобная проверка предотвращает ошибки при загрузке данных из внешних источников.
[55.7558, 37.6173]
вместо:
[37.6173, 55.7558]
Нежелательно:
["37.6173", "55.7558"]
Предпочтительно:
[37.6173, 55.7558]
Некорректно:
[250, 95]
Корректно:
[120, 45]
Неверно:
map.setCenter([500, 300]);
Здесь используются экранные координаты вместо географических.
Правильный вариант:
map.setCenter([37.6173, 55.7558]);
Рассмотрим обработчик клика:
map.on('click', (e) => {
console.log('География:', e.lngLat);
console.log('Пиксели:', e.point);
});
Если пользователь нажал на карту, результат может выглядеть следующим образом:
География:
LngLat {
lng: 37.621,
lat: 55.751
}
Пиксели:
Point {
x: 684,
y: 412
}
Первое значение показывает реальное местоположение на Земле, второе — положение внутри HTML-контейнера карты. Понимание этой разницы является фундаментальным для разработки интерактивных карт, поскольку Mapbox GL JS постоянно выполняет преобразования между географическими координатами и экранными пикселями при масштабировании, повороте, наклоне и перемещении карты.