Построение маршрутов с пересадками представляет собой задачу поиска оптимального пути между несколькими точками с учетом порядка посещения, транспортных ограничений, времени в пути и дополнительных параметров маршрутизации. В экосистеме HERE Maps эта функциональность реализуется через сервис Routing API, который позволяет рассчитывать маршруты между произвольным количеством промежуточных точек.
Маршрут с пересадками может включать:
Типичная схема маршрута:
Точка A → Точка B → Точка C → Точка D
Каждый сегмент между двумя соседними точками называется участком маршрута (section).
Для построения маршрутов необходимо подключить платформу HERE и создать экземпляр сервиса маршрутизации.
const platform = new H.service.Platform({
apikey: 'YOUR_API_KEY'
});
const router = platform.getRoutingService(null, 8);
В современных версиях рекомендуется использовать API v8, обеспечивающий поддержку расширенных возможностей маршрутизации.
Простейший маршрут с промежуточными остановками формируется через
параметр via.
Пример:
router.calculateRoute({
transportMode: 'car',
origin: '50.4501,30.5234',
via: [
'49.8397,24.0297',
'48.9226,24.7111'
],
destination: '48.4647,35.0462',
return: 'polyline,summary'
}, onSuccess, onError);
Здесь:
Сервис автоматически рассчитает маршрут через все заданные координаты в указанном порядке.
После успешного расчета API возвращает объект маршрута.
Пример обработки:
function onSuccess(result) {
const route = result.routes[0];
console.log(route);
}
Структура данных:
{
routes: [
{
sections: [
{...},
{...},
{...}
]
}
]
}
Каждая секция соответствует отдельному участку пути между двумя соседними точками.
Например:
| Секция | Откуда | Куда |
|---|---|---|
| 1 | A | B |
| 2 | B | C |
| 3 | C | D |
Каждая секция содержит сводную статистику.
route.sections.forEach(section => {
console.log(section.summary.length);
console.log(section.summary.duration);
});
Основные показатели:
| Параметр | Описание |
|---|---|
| length | Расстояние в метрах |
| duration | Время движения |
| baseDuration | Время без учета трафика |
| trafficDelay | Задержка из-за пробок |
Пример суммирования длины всего маршрута:
let totalDistance = 0;
route.sections.forEach(section => {
totalDistance += section.summary.length;
});
console.log(totalDistance);
Маршрут возвращается в виде полилинии.
Получение геометрии:
const linestring =
H.geo.LineString.fromFlexiblePolyline(
route.sections[0].polyline
);
Создание объекта карты:
const routeLine = new H.map.Polyline(
linestring,
{
style: {
lineWidth: 5
}
}
);
map.addObject(routeLine);
Для маршрутов с несколькими пересадками необходимо отображать каждую секцию.
route.sections.forEach(section => {
const linestring =
H.geo.LineString.fromFlexiblePolyline(
section.polyline
);
const polyline = new H.map.Polyline(
linestring,
{
style: {
lineWidth: 6
}
}
);
map.addObject(polyline);
});
Для визуализации пересадок удобно размещать маркеры.
const marker = new H.map.Marker({
lat: 49.8397,
lng: 24.0297
});
map.addObject(marker);
Создание нескольких остановок:
const stops = [
{ lat: 49.8397, lng: 24.0297 },
{ lat: 48.9226, lng: 24.7111 }
];
stops.forEach(stop => {
map.addObject(
new H.map.Marker(stop)
);
});
При наличии нескольких возможных путей сервис способен возвращать альтернативы.
router.calculateRoute({
transportMode: 'car',
origin: start,
destination: finish,
alternatives: 3,
return: 'polyline,summary'
}, onSuccess, onError);
Результат:
result.routes.forEach(route => {
console.log(route);
});
Каждый вариант может отличаться:
В некоторых сценариях известен набор остановок, но порядок их посещения неизвестен.
Пример:
Для решения подобных задач используется Waypoint Sequence API.
Сервис анализирует расположение точек и определяет оптимальный порядок посещения.
Пример структуры запроса:
{
start: '50.4501,30.5234',
destination: '50.4501,30.5234',
intermediates: [
'49.8397,24.0297',
'48.4647,35.0462',
'46.4825,30.7233'
]
}
Результатом будет перестроенный порядок точек с минимальными затратами времени или расстояния.
Подобная функциональность активно применяется в:
HERE Routing API поддерживает общественный транспорт.
router.calculateRoute({
transportMode: 'publicTransport',
origin: start,
destination: finish,
return: 'polyline,actions,summary'
}, onSuccess, onError);
В результате могут присутствовать:
Каждая пересадка отображается как отдельная секция.
Пример:
route.sections.forEach(section => {
console.log(section.transport.mode);
});
Возможный вывод:
pedestrian
bus
pedestrian
metro
pedestrian
Для общественного транспорта каждая секция содержит подробные сведения.
console.log(section.departure.place.name);
console.log(section.arrival.place.name);
Также доступны:
console.log(section.departure.time);
console.log(section.arrival.time);
Дополнительная информация:
console.log(section.transport.name);
console.log(section.transport.category);
console.log(section.transport.headsign);
Например:
Автобус №24
Направление: Центральный вокзал
Маршрут может содержать пошаговые указания.
Для этого необходимо запросить действия:
return: 'actions,instructions,polyline'
Получение инструкций:
route.sections.forEach(section => {
section.actions.forEach(action => {
console.log(action.instruction);
});
});
Пример результата:
Поверните направо
Через 500 метров поверните налево
Продолжайте движение прямо
При маршрутизации можно задавать ограничения.
Избегать платных дорог:
router.calculateRoute({
transportMode: 'car',
origin: start,
destination: finish,
avoid: {
features: ['tollRoad']
}
}, onSuccess, onError);
Избегать паромов:
avoid: {
features: ['ferry']
}
Избегать тоннелей:
avoid: {
features: ['tunnel']
}
Такие параметры особенно полезны при длинных маршрутах с большим количеством остановок.
HERE использует данные о дорожном движении в реальном времени.
router.calculateRoute({
transportMode: 'car',
routingMode: 'fast',
traffic: true,
origin: start,
destination: finish
}, onSuccess, onError);
В ответе можно анализировать влияние пробок:
const delay =
section.summary.trafficDelay;
Если задержка значительна, маршрут может быть автоматически перестроен.
Часто возникает необходимость динамически добавлять остановки.
Исходный набор:
const via = [
point1,
point2
];
Добавление новой пересадки:
via.push(point3);
Повторный расчет:
router.calculateRoute({
transportMode: 'car',
origin,
via,
destination,
return: 'polyline'
}, onSuccess, onError);
Такой подход широко применяется в системах доставки и диспетчеризации.
Иногда маршрут должен завершаться в исходной точке.
Пример:
router.calculateRoute({
transportMode: 'car',
origin: warehouse,
via: [
customer1,
customer2,
customer3
],
destination: warehouse
}, onSuccess, onError);
Подобная схема характерна для:
При большом количестве промежуточных точек рекомендуется:
Пример хранения результатов:
const routeCache = new Map();
routeCache.set(
routeId,
route
);
Повторный запрос:
if (routeCache.has(routeId)) {
return routeCache.get(routeId);
}
Типовая обработка ошибок:
function onError(error) {
console.error(error);
}
Расширенный вариант:
function onError(error) {
if (error.message) {
console.error(
'Ошибка маршрута:',
error.message
);
}
}
Наиболее распространённые причины ошибок:
| Причина | Описание |
|---|---|
| Неверные координаты | Ошибка геопозиции |
| Недоступный транспорт | Маршрут не существует |
| Отсутствие соединения | Ошибка сети |
| Некорректный API Key | Ошибка авторизации |
| Недопустимые параметры | Ошибка запроса |
router.calculateRoute({
transportMode: 'car',
origin: '50.4501,30.5234',
via: [
'49.8397,24.0297',
'48.9226,24.7111',
'46.4825,30.7233'
],
destination: '48.4647,35.0462',
routingMode: 'fast',
traffic: true,
return: 'polyline,summary,actions'
},
function(result) {
const route = result.routes[0];
route.sections.forEach(section => {
console.log(
section.summary.length,
section.summary.duration
);
const lineString =
H.geo.LineString.fromFlexiblePolyline(
section.polyline
);
map.addObject(
new H.map.Polyline(lineString)
);
});
},
function(error) {
console.error(error);
});
Данный пример объединяет ключевые возможности работы с маршрутами через несколько точек: промежуточные остановки, учет дорожной обстановки, получение статистики маршрута и визуализацию всех участков пути на карте.