Велосипедные маршруты

Велосипедная навигация представляет собой отдельный сценарий построения маршрутов, который существенно отличается от автомобильной и пешеходной маршрутизации. При расчёте маршрута учитываются велосипедные дорожки, специальные полосы движения, ограничения проезда, типы покрытий, рельеф местности и другие факторы, влияющие на комфорт и безопасность поездки.

В HERE Maps API велосипедные маршруты строятся через сервис Routing API с использованием режима передвижения, предназначенного для велосипедистов.

Особенности велосипедной маршрутизации

При выборе велосипедного режима система стремится:

  • использовать велосипедные дорожки;
  • минимизировать опасные участки дорог;
  • учитывать ограничения для велосипедистов;
  • избегать автомагистралей;
  • выбирать наиболее удобные участки движения;
  • учитывать особенности городской инфраструктуры.

В результате маршрут для велосипедиста может существенно отличаться от автомобильного маршрута между теми же точками.

Например:

  • автомобиль может двигаться по скоростной трассе;
  • велосипедный маршрут будет проходить через локальные дороги и велодорожки;
  • пешеходный маршрут может использовать тротуары и проходы, недоступные для велосипедов.

Подключение Routing API

Для расчёта велосипедных маршрутов используется класс H.service.RoutingService.

const platform = new H.service.Platform({
    apikey: "YOUR_API_KEY"
});

const routingService = platform.getRoutingService(null, 8);

Версия 8 обеспечивает доступ к современному Routing API.


Создание простого велосипедного маршрута

Маршрут между двумя координатами строится с помощью параметра transportMode.

const routingParameters = {
    transportMode: "bicycle",
    origin: "52.5200,13.4050",
    destination: "52.5100,13.4500",
    return: "polyline,summary"
};

routingService.calculateRoute(
    routingParameters,
    result => {
        console.log(result);
    },
    error => {
        console.error(error);
    }
);

Здесь:

  • origin — стартовая точка;
  • destination — конечная точка;
  • transportMode: "bicycle" — велосипедный режим;
  • polyline — геометрия маршрута;
  • summary — статистическая информация.

Получение информации о маршруте

После построения маршрута результат содержит массив маршрутов.

const route = result.routes[0];
const section = route.sections[0];

console.log(section.summary.length);
console.log(section.summary.duration);

Основные параметры:

Поле Описание
length Длина маршрута в метрах
duration Продолжительность в секундах
baseDuration Время без учёта дополнительных факторов

Пример вывода:

{
    length: 8200,
    duration: 1560,
    baseDuration: 1500
}

Маршрут длиной 8,2 км займёт примерно 26 минут.


Отображение велосипедного маршрута на карте

Полученную линию необходимо декодировать и отобразить.

const lineString =
    H.geo.LineString.fromFlexiblePolyline(
        section.polyline
    );

const routeLine = new H.map.Polyline(
    lineString,
    {
        style: {
            lineWidth: 5
        }
    }
);

map.addObject(routeLine);

Для велосипедных маршрутов часто используются отдельные стили отображения.

const routeLine = new H.map.Polyline(
    lineString,
    {
        style: {
            strokeColor: "green",
            lineWidth: 6
        }
    }
);

Зелёный цвет позволяет визуально отличать велосипедные маршруты от автомобильных.


Автоматическое масштабирование карты

После построения маршрута карта должна показывать весь путь.

map.getViewModel().setLookAtData({
    bounds: routeLine.getBoundingBox()
});

Карта автоматически подберёт масштаб и центр.


Построение маршрута через промежуточные точки

Велосипедные поездки часто проходят через несколько контрольных точек.

const routingParameters = {
    transportMode: "bicycle",
    origin: "52.5200,13.4050",
    via: [
        "52.5170,13.4200",
        "52.5130,13.4350"
    ],
    destination: "52.5100,13.4500",
    return: "polyline,summary"
};

Такой маршрут заставит алгоритм пройти через указанные координаты.


Работа с несколькими секциями маршрута

Каждый участок между точками образует отдельную секцию.

result.routes[0].sections.forEach(section => {
    console.log(section.summary.length);
});

Структура:

Старт
  ↓
Точка 1
  ↓
Точка 2
  ↓
Финиш

Каждый сегмент содержит собственную геометрию и статистику.


Получение пошаговых инструкций

Для велосипедной навигации полезны текстовые инструкции.

const routingParameters = {
    transportMode: "bicycle",
    origin: "52.5200,13.4050",
    destination: "52.5100,13.4500",
    return: "polyline,actions,instructions"
};

Извлечение инструкций:

section.actions.forEach(action => {
    console.log(action.instruction);
});

Пример:

Следуйте прямо
Поверните направо
Продолжайте движение по велодорожке
Поверните налево
Прибудьте в пункт назначения

Получение детальной информации о манёврах

Каждое действие содержит дополнительные сведения.

section.actions.forEach(action => {
    console.log(action.offset);
    console.log(action.length);
    console.log(action.duration);
});

Параметры:

  • расстояние до следующего манёвра;
  • продолжительность участка;
  • позиция на маршруте;
  • тип действия.

Это позволяет создавать полноценные велосипедные навигаторы.


Использование альтернативных маршрутов

Иногда полезно получить несколько вариантов поездки.

const routingParameters = {
    transportMode: "bicycle",
    origin: "52.5200,13.4050",
    destination: "52.5100,13.4500",
    alternatives: 3,
    return: "polyline,summary"
};

Система вернёт несколько вариантов.

result.routes.forEach(route => {
    console.log(route.sections[0].summary.length);
});

Возможные различия:

  • длина пути;
  • количество поворотов;
  • использование велодорожек;
  • загруженность дорог.

Отображение нескольких маршрутов

result.routes.forEach(route => {

    route.sections.forEach(section => {

        const lineString =
            H.geo.LineString.fromFlexiblePolyline(
                section.polyline
            );

        const routeLine = new H.map.Polyline(
            lineString
        );

        map.addObject(routeLine);
    });
});

Обычно основной маршрут отображается более ярко, альтернативные — полупрозрачно.

style: {
    strokeColor: "green",
    lineWidth: 6
}

и

style: {
    strokeColor: "gray",
    lineWidth: 4
}

Добавление маркеров начала и конца маршрута

const startMarker = new H.map.Marker({
    lat: 52.5200,
    lng: 13.4050
});

const endMarker = new H.map.Marker({
    lat: 52.5100,
    lng: 13.4500
});

map.addObject(startMarker);
map.addObject(endMarker);

Для велосипедных приложений часто используются специальные иконки:

const bikeIcon = new H.map.Icon("bike.png");

Создание маркера:

const marker = new H.map.Marker(
    position,
    {
        icon: bikeIcon
    }
);

Анализ расстояния маршрута

Получение общей длины маршрута:

const totalDistance =
    route.sections.reduce(
        (sum, section) =>
            sum + section.summary.length,
        0
    );

console.log(totalDistance);

Преобразование в километры:

const km =
    (totalDistance / 1000).toFixed(1);

console.log(`${km} км`);

Анализ времени поездки

Общее время маршрута:

const totalDuration =
    route.sections.reduce(
        (sum, section) =>
            sum + section.summary.duration,
        0
    );

Перевод в минуты:

const minutes =
    Math.round(totalDuration / 60);

console.log(minutes);

Создание карточки маршрута

Информация может отображаться в пользовательском интерфейсе.

const summary =
    route.sections[0].summary;

const distance =
    (summary.length / 1000).toFixed(1);

const duration =
    Math.round(summary.duration / 60);

info.innerHTML = `
    <h3>Маршрут</h3>
    <p>Расстояние: ${distance} км</p>
    <p>Время: ${duration} мин</p>
`;

Велосипедные маршруты с учётом нескольких остановок

Маршрут может включать множество точек интереса.

const routingParameters = {
    transportMode: "bicycle",
    origin: startPoint,
    via: [
        pointA,
        pointB,
        pointC,
        pointD
    ],
    destination: finishPoint,
    return: "polyline,summary"
};

Подобный подход применяется для:

  • туристических маршрутов;
  • велоэкскурсий;
  • спортивных заездов;
  • курьерских сервисов;
  • логистики доставки.

Построение кругового маршрута

Начальная и конечная точки могут совпадать.

const routingParameters = {
    transportMode: "bicycle",
    origin: "52.5200,13.4050",
    via: [
        "52.5300,13.4300",
        "52.5100,13.4500"
    ],
    destination: "52.5200,13.4050",
    return: "polyline,summary"
};

Получается кольцевой велосипедный маршрут.


Работа с событиями интерфейса

Маршрут может строиться после выбора точек пользователем.

button.addEventListener(
    "click",
    () => {
        buildBikeRoute();
    }
);

Получение координат после клика по карте:

map.addEventListener(
    "tap",
    event => {

        const coord =
            map.screenToGeo(
                event.currentPointer.viewportX,
                event.currentPointer.viewportY
            );

        console.log(coord);
    }
);

Это позволяет создавать интерактивные планировщики поездок.


Комбинирование маршрутов и объектов карты

После расчёта маршрута можно отображать дополнительные данные:

map.addObject(routeLine);
map.addObject(startMarker);
map.addObject(endMarker);

Дополнительно могут отображаться:

  • станции проката велосипедов;
  • ремонтные мастерские;
  • парковки;
  • точки отдыха;
  • достопримечательности;
  • заправочные станции для электровелосипедов.

Оптимизация производительности

При работе с длинными велосипедными маршрутами рекомендуется:

  • переиспользовать объекты карты;
  • удалять старые маршруты перед построением новых;
  • кэшировать результаты запросов;
  • ограничивать количество одновременно отображаемых маршрутов;
  • группировать объекты в контейнеры.

Удаление старого маршрута:

if (routeLine) {
    map.removeObject(routeLine);
}

Очистка группы объектов:

map.removeObjects(
    map.getObjects()
);

Практический сценарий велосипедного навигатора

Типичный цикл работы приложения выглядит следующим образом:

  1. Пользователь выбирает стартовую точку.
  2. Пользователь выбирает пункт назначения.
  3. Выполняется запрос Routing API.
  4. Получается велосипедный маршрут.
  5. Геометрия маршрута декодируется.
  6. Маршрут отображается на карте.
  7. Показываются расстояние и время поездки.
  8. Генерируются пошаговые инструкции.
  9. Карта масштабируется под весь маршрут.
  10. При изменении точек маршрут пересчитывается.

Такой подход позволяет создавать полноценные велосипедные навигационные системы на основе HERE Maps API и JavaScript с поддержкой построения маршрутов, отображения геометрии пути, анализа расстояния и времени движения, работы с промежуточными точками и визуализации альтернативных вариантов поездки.