В веб-картах координаты всегда задаются в географической системе WGS84: долгота (lng) и широта (lat). В контексте Mapbox GL JS расчёт расстояний опирается не на плоскую евклидову геометрию, а на сферическую модель Земли.
Ключевая проблема: 1 градус долготы не равен фиксированному расстоянию в километрах, и это значение уменьшается к полюсам.
Поэтому любые корректные вычисления должны учитывать кривизну поверхности Земли.
Базовый объект координат в Mapbox GL JS —
mapboxgl.LngLat.
Он предоставляет метод:
const a = new mapboxgl.LngLat(30.3141, 59.9386);
const b = new mapboxgl.LngLat(37.6173, 55.7558);
const distance = a.distanceTo(b);
console.log(distance);
distanceToВнутри библиотека использует сферические вычисления, близкие к формуле гаверсинусов, но с оптимизациями.
Для понимания механики расчёта используется классическая формула:
d = 2R ()
где:
Эта формула устойчива к численным ошибкам на малых расстояниях и широко используется в GIS-системах.
В экосистеме Mapbox часто применяется библиотека Turf.js для геоаналитики.
Пример расчёта расстояния:
import distance from '@turf/distance';
const from = [30.3141, 59.9386];
const to = [37.6173, 55.7558];
const result = distance(from, to, { units: 'kilometers' });
console.log(result);
LngLat.distanceTo
Turf.js
Mapbox GL JS работает с двумя системами координат:
Для UI-задач часто требуется расстояние в пикселях:
const p1 = map.project([30.3141, 59.9386]);
const p2 = map.project([37.6173, 55.7558]);
const dx = p2.x - p1.x;
const dy = p2.y - p1.y;
const pixelDistance = Math.sqrt(dx * dx + dy * dy);
Этот расчёт не геодезический, а плоский, и используется для:
Mapbox GL JS использует проекцию Web Mercator.
Следствия:
Поэтому важно различать:
| Тип расстояния | Где применяется | Точность |
|---|---|---|
| Геодезическое | аналитика, маршруты | высокая |
| Экранное | UI, события | условная |
Особая проблема возникает при пересечении антимеридиана:
const a = new mapboxgl.LngLat(179, 10);
const b = new mapboxgl.LngLat(-179, 10);
console.log(a.distanceTo(b));
Хотя визуально точки рядом, численно долготы сильно отличаются.
Решение внутри Mapbox GL JS:
В задачах маршрутизации расстояние между двумя точками — лишь базовый элемент.
Типичный пайплайн:
Пример предварительной оценки:
function roughDistance(a, b) {
return a.distanceTo(b);
}
Это используется как heuristic в A* и Dijkstra.
При обработке массивов координат важно учитывать производительность.
Пример:
const points = [
[30.1, 59.9],
[30.2, 59.8],
[30.3, 59.7]
];
let total = 0;
for (let i = 1; i < points.length; i++) {
const a = new mapboxgl.LngLat(...points[i - 1]);
const b = new mapboxgl.LngLat(...points[i]);
total += a.distanceTo(b);
}
LngLatЛюбой расчёт расстояний в Mapbox GL JS имеет ограничения:
Для высокоточной геодезии применяются:
Расстояния часто используются для динамических эффектов:
Пример фильтрации:
const center = new mapboxgl.LngLat(30.3141, 59.9386);
const filtered = points.filter(p => {
const d = center.distanceTo(new mapboxgl.LngLat(...p));
return d < 5000;
});
При построении зон влияния часто используется приближение окружности в географических координатах:
const radius = 1000; // метров
Дальнейшее преобразование требует:
В аналитических задачах чаще применяется Turf.js buffer,
который учитывает геодезию корректнее, чем ручные расчёты.
| Метод | Точность | Производительность | Применение |
|---|---|---|---|
| LngLat.distanceTo | высокая | высокая | базовые вычисления |
| Turf.js distance | высокая | средняя | аналитика |
| Евклидово (pixels) | условная | очень высокая | UI |