Матрица результатов в контексте сервисов расстояний и времени маршрутов формируется как двумерная структура, где каждая строка соответствует исходной точке, а каждый столбец — точке назначения. В рамках экосистемы Google и Google Maps Platform такие данные чаще всего поступают через Distance Matrix сервис и обрабатываются в клиентском JavaScript-коде для последующего отображения, фильтрации и аналитики.
Ключевая особенность структуры — вложенность объектов:
Каждый элемент матрицы представляет отдельный маршрутный расчёт, содержащий расстояние, длительность и дополнительные метрики.
Результат матрицы можно представить как таблицу:
| Origin Destination | B | C | D |
|---|---|---|---|
| A | A→B | A→C | A→D |
| B | B→B | B→C | B→D |
В реальном API эта структура разворачивается в JSON:
rows[i] соответствует origin[i]rows[i].elements[j] соответствует destination[j]Каждый element содержит:
distance.text и distance.valueduration.text и duration.valuestatusКаждый элемент матрицы имеет следующую структуру:
distance
value — расстояние в метрахtext — человекочитаемое представлениеduration
value — время в секундахtext — форматированное времяduration_in_traffic (если включён трафик)
status
OK — маршрут найденZERO_RESULTS — маршрут отсутствуетNOT_FOUND — точки не распознаныMAX_ROUTE_LENGTH_EXCEEDED — превышены ограниченияПри обработке данных основной задачей становится корректная навигация по двум уровням вложенности:
for (let i = 0; i < response.rows.length; i++) {
const row = response.rows[i];
for (let j = 0; j < row.elements.length; j++) {
const element = row.elements[j];
if (element.status === "OK") {
const distance = element.distance.value;
const duration = element.duration.value;
}
}
}
Такая структура позволяет строить произвольные таблицы расстояний, графы маршрутов и системы выбора оптимального пути.
Сырые данные матрицы редко используются напрямую. Чаще выполняется нормализация:
Пример преобразования:
function normalizeElement(element) {
return {
distanceKm: element.distance.value / 1000,
durationMin: element.duration.value / 60,
isAvailable: element.status === "OK"
};
}
Результатом становится структура, пригодная для алгоритмов поиска и сравнения.
Для аналитических задач матрица преобразуется в плоскую таблицу:
const table = [];
response.rows.forEach((row, i) => {
row.elements.forEach((el, j) => {
table.push({
originIndex: i,
destinationIndex: j,
distance: el.distance?.value ?? null,
duration: el.duration?.value ?? null,
status: el.status
});
});
});
Такая форма удобна для:
Особенность матричного API заключается в частичной деградации данных: даже при ошибке отдельных пар остальные элементы остаются валидными.
Типичная стратегия обработки:
NOT_FOUNDZERO_RESULTSnullif (element.status !== "OK") {
return null;
}
На основе матрицы строятся агрегированные метрики:
Пример нахождения ближайшего пункта:
function findNearest(originIndex, rows) {
let min = Infinity;
let bestIndex = -1;
rows[originIndex].elements.forEach((el, j) => {
if (el.status === "OK" && el.distance.value < min) {
min = el.distance.value;
bestIndex = j;
}
});
return bestIndex;
}
При увеличении числа точек возрастает сложность: O(n × m). В рамках Google Maps Platform существуют ограничения на размер запросов, поэтому обработка больших наборов данных требует архитектурных решений:
Для последующего использования матрицы часто сериализуются:
const serialized = JSON.stringify(response);
localStorage.setItem("distanceMatrix", serialized);
В серверных системах данные могут сохраняться в:
Матрица расстояний естественно трансформируется в взвешенный граф:
const graph = {};
rows.forEach((row, i) => {
graph[i] = {};
row.elements.forEach((el, j) => {
if (el.status === "OK") {
graph[i][j] = el.duration.value;
}
});
});
Такой подход используется в алгоритмах:
При включении параметра traffic данные становятся динамическими:
const duration = element.duration_in_traffic?.value
?? element.duration.value;
Матрица часто визуализируется в виде UI-таблиц:
Формирование структуры для интерфейса:
const uiMatrix = rows.map(row =>
row.elements.map(el => ({
value: el.distance?.text ?? "-",
status: el.status
}))
);
При работе с большими наборами точек применяется фильтрация:
const filtered = table.filter(el =>
el.status === "OK" && el.duration < 3600
);
В сложных системах данные могут объединяться:
При этом требуется унификация:
Основные узкие места:
Оптимизации:
При строгой архитектуре данные описываются интерфейсом:
interface MatrixElement {
distance?: {
text: string;
value: number;
};
duration?: {
text: string;
value: number;
};
status: string;
}
interface MatrixRow {
elements: MatrixElement[];
}
Такая типизация снижает вероятность ошибок при обработке вложенных структур и упрощает масштабирование логики вычислений.