Пешеходная маршрутизация предназначена для построения маршрутов, рассчитанных на передвижение пешком. В отличие от автомобильной навигации, такие маршруты учитывают тротуары, пешеходные переходы, парковые дорожки, лестницы, пешеходные зоны, проходы между зданиями и другие элементы городской инфраструктуры, недоступные для транспортных средств.
В экосистеме HERE для расчёта маршрутов используется сервис Routing API, который позволяет строить маршруты для различных видов транспорта:
Для пешеходных маршрутов применяется параметр транспорта
pedestrian.
Перед использованием маршрутизации необходимо подключить основные модули HERE Maps.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
<link
rel="stylesheet"
href="https://js.api.here.com/v3/3.1/mapsjs-ui.css"
/>
</head>
<body>
<div id="map" style="width:100%;height:600px;"></div>
</body>
</html>
Создание карты:
const platform = new H.service.Platform({
apikey: "YOUR_API_KEY"
});
const defaultLayers = platform.createDefaultLayers();
const map = new H.Map(
document.getElementById("map"),
defaultLayers.vector.normal.map,
{
zoom: 14,
center: {
lat: 55.751244,
lng: 37.618423
}
}
);
const beh * avior = new H.mapevents.Behavior(
new H.mapevents.MapEvents(map)
);
const ui = H.ui.UI.createDefault(map, defaultLayers);
Для работы с маршрутами необходимо получить экземпляр сервиса Routing.
const router = platform.getRoutingService(null, 8);
Число 8 указывает на использование Routing API версии
8.
Маршрут строится между двумя географическими точками.
const routingParameters = {
transportMode: "pedestrian",
origin: "55.751244,37.618423",
destination: "55.758000,37.605000",
return: "polyline,summary"
};
router.calculateRoute(
routingParameters,
onSuccess,
onError
);
Обработка результата:
function onSuccess(result) {
console.log(result);
}
function onError(error) {
console.error(error);
}
Ответ Routing API содержит массив маршрутов.
result.routes
Каждый маршрут включает один или несколько участков.
const route = result.routes[0];
const section = route.sections[0];
Основные данные:
section.summary.length
Длина маршрута в метрах.
section.summary.duration
Время прохождения в секундах.
Например:
console.log(
`Расстояние: ${section.summary.length} м`
);
console.log(
`Время: ${section.summary.duration} сек`
);
Маршрут возвращается в виде закодированной полилинии.
Для декодирования используется утилита Flexible Polyline.
const lineString =
H.geo.LineString.fromFlexiblePolyline(
section.polyline
);
Создание линии маршрута:
const routeLine = new H.map.Polyline(
lineString,
{
style: {
strokeColor: "#0066ff",
lineWidth: 6
}
}
);
map.addObject(routeLine);
Центрирование карты:
map.getViewModel().setLookAtData({
bounds: routeLine.getBoundingBox()
});
Начальная точка:
const startMarker = new H.map.Marker({
lat: 55.751244,
lng: 37.618423
});
Конечная точка:
const finishMarker = new H.map.Marker({
lat: 55.758000,
lng: 37.605000
});
Добавление на карту:
map.addObjects([
startMarker,
finishMarker
]);
router.calculateRoute(
{
transportMode: "pedestrian",
origin: "55.751244,37.618423",
destination: "55.758000,37.605000",
return: "polyline,summary"
},
result => {
const route = result.routes[0];
const section = route.sections[0];
const lineString =
H.geo.LineString.fromFlexiblePolyline(
section.polyline
);
const routeLine =
new H.map.Polyline(lineString, {
style: {
strokeColor: "green",
lineWidth: 5
}
});
map.addObject(routeLine);
map.getViewModel().setLookAtData({
bounds: routeLine.getBoundingBox()
});
},
error => {
console.error(error);
}
);
Для отображения навигационных подсказок необходимо запросить действия маршрута.
const params = {
transportMode: "pedestrian",
origin: "55.751244,37.618423",
destination: "55.758000,37.605000",
return: "polyline,summary,actions,instructions"
};
После получения результата:
const actions =
result.routes[0]
.sections[0]
.actions;
Вывод инструкций:
actions.forEach(action => {
console.log(
action.instruction
);
});
Пример инструкций:
Двигайтесь на север
Поверните направо
Перейдите дорогу
Продолжайте движение
Прибытие в пункт назначения
Пешеходный маршрут может проходить через несколько контрольных точек.
router.calculateRoute(
{
transportMode: "pedestrian",
origin: "55.751244,37.618423",
via: [
"55.754500,37.615000",
"55.756000,37.612000"
],
destination: "55.758000,37.605000",
return: "polyline,summary"
},
onSuccess,
onError
);
Каждая промежуточная точка становится обязательной частью маршрута.
Часто точки маршрута выбираются пользователем кликом по карте.
Получение координат:
map.addEventListener("tap", event => {
const coord =
map.screenToGeo(
event.currentPointer.viewportX,
event.currentPointer.viewportY
);
console.log(coord.lat);
console.log(coord.lng);
});
После выбора двух точек можно автоматически строить маршрут.
Предположим, что имеются два маркера.
const pointA = markerA.getGeometry();
const pointB = markerB.getGeometry();
Маршрут:
router.calculateRoute(
{
transportMode: "pedestrian",
origin:
`${pointA.lat},${pointA.lng}`,
destination:
`${pointB.lat},${pointB.lng}`,
return:
"polyline,summary"
},
onSuccess,
onError
);
Данные маршрута содержат суммарную длительность.
const duration =
section.summary.duration;
Перевод секунд в минуты:
const minutes =
Math.round(duration / 60);
console.log(
`Время пешком: ${minutes} мин`
);
Перевод в часы и минуты:
function formatDuration(seconds) {
const hours =
Math.floor(seconds / 3600);
const minutes =
Math.floor(
(seconds % 3600) / 60
);
return `${hours} ч ${minutes} мин`;
}
const length =
section.summary.length;
Перевод в километры:
const km =
(length / 1000).toFixed(2);
console.log(
`${km} км`
);
Создание информационного блока:
<div id="routeInfo"></div>
Заполнение данными:
const summary =
route.sections[0].summary;
document.getElementById(
"routeInfo"
).innerHTML = `
<p>
Расстояние:
${summary.length} м
</p>
<p>
Время:
${summary.duration} сек
</p>
`;
Перед построением нового маршрута обычно удаляются ранее отображённые объекты.
map.removeObjects(
map.getObjects()
);
Более безопасный вариант:
if (routeLine) {
map.removeObject(routeLine);
}
Хранение ссылки:
let routeLine = null;
После создания:
routeLine =
new H.map.Polyline(
lineString
);
Для удобного управления всеми элементами маршрута применяется группа.
const routeGroup =
new H.map.Group();
map.addObject(routeGroup);
Добавление объектов:
routeGroup.addObject(routeLine);
routeGroup.addObject(startMarker);
routeGroup.addObject(endMarker);
Очистка:
routeGroup.removeAll();
Толщина линии:
lineWidth: 8
Цвет:
strokeColor: "#00AA00"
Прозрачность:
strokeColor:
"rgba(0,170,0,0.6)"
Пример:
const routeLine =
new H.map.Polyline(
lineString,
{
style: {
strokeColor:
"rgba(0,150,0,0.8)",
lineWidth: 7
}
}
);
Сервис может возвращать несколько вариантов пути.
const params = {
transportMode: "pedestrian",
origin: "55.751244,37.618423",
destination: "55.758000,37.605000",
alternatives: 3,
return: "polyline,summary"
};
Получение маршрутов:
result.routes.forEach(route => {
console.log(
route.sections[0]
.summary
);
});
Каждый вариант можно отображать своим цветом.
const colors = [
"blue",
"green",
"red"
];
Если используются промежуточные точки, маршрут делится на секции.
route.sections.forEach(
section => {
console.log(
section.summary.length
);
}
);
Общая длина:
const totalLength =
route.sections.reduce(
(sum, section) =>
sum +
section.summary.length,
0
);
Общее время:
const totalDuration =
route.sections.reduce(
(sum, section) =>
sum +
section.summary.duration,
0
);
Пешеходная маршрутизация в HERE обладает рядом особенностей:
Благодаря этим особенностям маршрут для пешехода зачастую существенно отличается от автомобильного пути между теми же координатами.