Матрица расстояний в геопространственных вычислениях представляет собой таблицу попарных расстояний и/или времен маршрутизации между наборами точек. В контексте веб-картографии и клиентских приложений эта задача решается через сервисы маршрутизации и API, наиболее типичным из которых в экосистеме Mapbox GL JS является Matrix API платформы Mapbox.
Пусть задан набор источников ( O = {o_1, o_2, …, o_n} ) и набор назначений ( D = {d_1, d_2, …, d_m} ). Требуется получить матрицу ( M ), где каждый элемент:
Функция ( f ) может возвращать:
В Mapbox Matrix API чаще всего используется именно время маршрута по дорожному графу, а не евклидово расстояние.
При работе с матрицей расстояний важно учитывать ограничения:
максимальное количество точек в одном запросе (обычно до 25×25 в стандартном тарифе)
необходимость деления задач на батчи при больших наборах координат
зависимость от выбранного профиля маршрутизации:
drivingwalkingcyclingdriving-trafficКаждый профиль использует собственный граф дорог и, соответственно, даёт разные результаты.
Все точки передаются в формате долгота/широта:
longitude,latitude
Пример набора координат:
const coordinates = [
[71.4304, 51.1284],
[71.4631, 51.1605],
[71.4100, 51.1500]
];
Ключевой момент: порядок координат строго фиксирован — сначала долгота, затем широта.
Запрос строится через HTTP GET:
https://api.mapbox.com/directions-matrix/v1/mapbox/{profile}/{coordinates}
Пример:
https://api.mapbox.com/directions-matrix/v1/mapbox/driving/71.4304,51.1284;71.4631,51.1605;71.4100,51.1500?annotations=distance,duration&access_token=YOUR_TOKEN
Параметр annotations определяет тип возвращаемых
данных:
distance — расстояние в метрахduration — время в секундахconst accessToken = 'YOUR_TOKEN';
const coords = [
[71.4304, 51.1284],
[71.4631, 51.1605],
[71.4100, 51.1500]
];
const coordString = coords.map(c => c.join(',')).join(';');
const url = `https://api.mapbox.com/directions-matrix/v1/mapbox/driving/${coordString}` +
`?annotations=distance,duration&access_token=${accessToken}`;
async function getMatrix() {
const response = await fetch(url);
const data = await response.json();
return data;
}
getMatrix().then(matrix => {
console.log(matrix.distances);
console.log(matrix.durations);
});
Ответ содержит две ключевые матрицы:
{
"distances": [
[0, 1200, 3400],
[1100, 0, 2100],
[3300, 2000, 0]
],
"durations": [
[0, 180, 420],
[170, 0, 300],
[400, 290, 0]
]
}
Каждая строка соответствует источнику, каждый столбец — назначению.
Хотя Mapbox GL JS отвечает за визуализацию карты, матрица расстояний используется как вычислительный слой поверх карты.
Типичный сценарий:
Пользователь выбирает точки на карте
Координаты передаются в Matrix API
Результат используется для:
Пример связывания с событиями карты:
map.on('click', (e) => {
selectedPoints.push([e.lngLat.lng, e.lngLat.lat]);
if (selectedPoints.length >= 3) {
calculateMatrix(selectedPoints);
}
});
После получения данных обычно применяются вычисления:
function findNearest(matrix, index) {
const row = matrix.durations[index];
let minTime = Infinity;
let minIndex = -1;
row.forEach((val, i) => {
if (i !== index && val < minTime) {
minTime = val;
minIndex = i;
}
});
return minIndex;
}
Матрица интерпретируется как взвешенный граф:
Это позволяет применять алгоритмы:
При работе с большими наборами точек ключевой проблемой становится рост сложности:
Практические техники оптимизации:
function chunkArray(arr, size) {
const chunks = [];
for (let i = 0; i < arr.length; i += size) {
chunks.push(arr.slice(i, i + size));
}
return chunks;
}
Матрицы часто пересчитываются для одинаковых наборов точек, поэтому применяется:
Перед запросом можно уменьшать количество точек:
Профиль driving-traffic учитывает:
Это критично для:
Результаты матрицы часто отображаются в интерфейсе:
Пример логики подсветки:
function drawConnections(points, matrix) {
const features = [];
for (let i = 0; i < points.length; i++) {
for (let j = 0; j < points.length; j++) {
if (i !== j) {
features.push({
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [points[i], points[j]]
},
properties: {
duration: matrix.durations[i][j]
}
});
}
}
}
map.getSource('connections').setData({
type: 'FeatureCollection',
features
});
}
Типичные проблемы:
Стратегия обработки:
if (!data.durations) {
throw new Error('Matrix calculation failed');
}
Дополнительно применяются fallback-режимы:
В реальных системах матрица расстояний обычно является частью слоя сервисов:
Такой подход позволяет отделить визуализацию от вычислений и масштабировать обработку больших наборов координат без деградации интерфейса.