Ведение

Guidance - содержит информацию о текущей сессии ведения, позволяет подписаться на различные события во время ведения. Для его получения используйте метод Navigation.guidance.

Отслеживание локации

По умолчанию, Navigation создается в режиме suspended, в котором локация не отслеживается и ведение не работает. Для включения отслеживания текущей локации устройства, чтобы местоположение пользователя оставалось актуальным, используется режим resumed.

Для управления режимом слежения за локацией используются методы Navigation.resume и Navigation.suspend.

Совет

Хорошей практикой является переключение Navigation в режим suspended при сворачивании приложение с картой, и переключение в resumed при повторном открытии приложения.

Не рекомендуется переводить Navigation в режим suspended если вы реализуете сценарий фонового ведения.

Старт/стоп ведения

Начать ведение по маршруту можно с помощью метода Navigation.startGuidance. В качестве единственного аргумента он принимает маршрут, по которому начнется ведение.

Для окончание ведения существует симметричный метод Navigation.stopGuidance.

Примечание

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

Данные во время ведении

Рассмотрим основные данные, доступ к которым предоставляет Guidance во время ведения.

  • Текущий маршрут - Guidance.currentRoute содержит маршрут, по которому в текущий момент активно ведение, либо значение null если ведения нет. В ходе ведения текущий маршрут может быть изменен, если, например, пользователь съехал с маршрута или был выбран другой альтернативный маршрут.

  • Локация пользователя - Guidance.location содержит текущую локацию пользователя. Она состоит из координат, определяющих местоположение, текущего направления, точности определения локации, скорости ведения и т.д.

  • Превышение скорости - Guidance.speedLimit и Guidance.speedLimitStatus предоставляют информацию о максимально разрешенной скорости на данном участке маршрута. Guidance.speedLimitsPolicy содержит информацию о скоростных ограничений для данного региона в различных местностях (в городе, загородом и на шоссе).

Полный API приведен в документации Guidance.

Windshield

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

Для обращения к объекту NavigationWindshield используется метод Guidance.windshield.

Состояние сущности NavigationWindshield определяется следующими данным:

  • Маневры - с помощью NavigationWindshield.manoeuvres можно получить список предстоящих маневров на маршруте. Каждый маневр описывается позицией на маршруте, его местоположением и объектом DrivingAnnotation, который содержит информацию о его типе.

  • Дорожная разметка - NavigationWindshield.laneSigns возвращает список, где каждый элемент содержит информацию в какой полосе дороги пользователь должен находиться, он характеризуется позицией на маршруте, и объектом DrivingLaneSign, который определяет вид разметки на данном участке дороги. Объект DrivingLaneSign содержит список DrivingLane с информацией о каждой конкретной полосе дороги, ее направлении, типе и вариантах маневров.

  • Дорожные события - при помощи NavigationWindshield.roadEvents можно получить список предстоящих дорожных событий на маршруте вместе с информацией о скоростных ограничениях.

  • Указатели - метод NavigationWindshield.directionSigns возвращает список предстоящих указателей на дороге. Например, указатель того, что следующий участок маршрута будет проходить через туннель или через скоростное шоссе.

С помощью NavigationWindshieldListener можно подписаться на события изменения состояния NavigationWindshield.

С примером использования NavigationWindshield для реализации UI-компонента, который отображает информацию о следующем маневре и полосной разметке, можно ознакомиться в демо-приложении.

События

В ходе ведения приложения состояние ведения постоянно изменяется. Для подписки на события ведения используется интерфейс GuidanceListener.

final class GuidanceListenerImpl implements GuidanceListener {

  @override
  void onAlternativesChanged() {}

  @override
  void onCurrentRouteChanged(RouteChangeReason reason) {}

  @override
  void onFastestAlternativeChanged() {}

  @override
  void onLocationChanged() {}

  @override
  void onReturnedToRoute() {}

  @override
  void onRoadNameChanged() {}

  @override
  void onRouteFinished() {}

  @override
  void onRouteLost() {}

  @override
  void onSpeedLimitStatusUpdated() {}

  @override
  void onSpeedLimitUpdated() {}

  @override
  void onStandingStatusChanged() {}

  @override
  void onWayPointReached() {}
}

final GuidanceListener listener = GuidanceListenerImpl();
guidance.addListener(listener);

GuidanceListener предоставляет возможность подписаться на события навигации (съезда с маршрута, возвращение к маршруту, достижение промежуточных и конечных точек маршрута) и изменения состояния ведения (текущей локации пользователя, маршрута, названия улицы, информации о лимитах скорости, списка альтернатив и т.д).

Альтернативы во время ведения

Альтернативные маршруты, которые доступны во время ведения, называются локальными альтернативами. Они имеют свойство автоматически перестраиваться. Для подписки на это событие используется метод GuidanceListener.onAlternativesChanged.

Для смены текущего маршрута на альтернативный используется метод Guidance.switchToRoute.

Более быстрые альтернативы

Сессия ведения по маршруту может быть очень продолжительной, иногда достигать нескольких часов. В таких случаях маршрут, который был построен на момент начала ведения, через некоторое время может устареть и стать не таким оптимальным. Эта проблема особенно актуальна при ведении в городе, где дорожная ситуация на дороге способна меняться достаточно часто. NaviKit SDK решает данную проблему и предоставляет возможность получить более быстрый альтернативный маршрут.

Метод Guidance.fastestAlernative возвращает информацию о более быстрой альтернативе во время ведения, если она существует. Начните ведение по такому маршруту, чтобы изменить текущий маршрут на более оптимальный.

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

Аннотации

Для настройки голосовых подсказок на маршруте (голосовых аннотаций), используется класс Annotator.

Для включения и выключения аннотаций используются методы Annotator.mute и Annotator.unmute.

Чтобы аннотатор начал свою работу необходимо добавить в него делегат - объект с типом Speaker, который нужно реализовать самостоятельно.

Примечание

NaviKit SDK не предоставляет свою реализацию Speaker.

Язык аннотаций можно изменять при помощи метода Navigation.annotationLanguage.

Аннотации делятся на несколько видов, связанные с дорожными событиями AnnotatedRoadEvents и с предупреждениями на маршруте AnnotatedEvents. При помощи методов Annotator.annotatedRoadEvents и Annotator.annotatedEvents можно изменять активность отдельных аннотаций.

Существует возможность подписаться на события класса Annotator с помощью интерфейса AnnotatorListener. Он оповещает о действиях аннотатора - какой тип события был воспроизведен.

Восстановление состояния

Существует возможность восстановления состояния ведения при помощи механизма сериализации/десериализации Navigation.

  1. Сначала сериализуйте Navigation, используя метод NavigationSerialization.serialize.

    final serializedNavigation = NavigationSerialization.serialize(navigation);
    
  2. Теперь в serializedNavigation хранится слепок навигации. Его можно куда-нибудь сохранить, например на диск, а позже восстановить используя десериализацию.

  3. С помощью NavigationSerialization.deserialize создайте новый инстанс навигации.

    final navigation = NavigationSerialization.deserialize(serializedNavigation);
    

Таким образом, перед закрытием приложения можно сохранить Navigation на диск, и затем при следующем открытии восстановить его. Так как состояние ведения содержится в Guidance, а ведение является частью Navigation, оно тоже восстановится и последняя сессия ведения продолжится.

С примером реализации логики восстановления состояния ведения можно ознакомиться в нашем демо-приложении.

Симуляция ведения

В ходе разработки и тестирования навигационных приложений часто требуется проверить как работает сценарий ведения по маршруту. Для этого можно использовать сторонние средства симуляции локации пользователя или воспользоваться готовым API симуляции из NaviKit SDK.

Cуществует возможность включения симуляции движения по маршруту или произвольной траектории, для этого используется LocationSimulator класс.

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

final class SimulationManager {

  LocationSimulator? _locationSimulator;

  late final _locationSimulatorListener = LocationSimulatorListenerImpl(stopSimulation);

  @override
  void startSimulation(DrivingRoute route) {
    _locationSimulator = mapkit.createLocationSimulatorWithGeometry(route.geometry)
      ..subscribeForSimulatorEvents(_locationSimulatorListener)
      ..speed = 20.0;

    _locationSimulator?.let((it) {
      mapkit.setLocationManager(it);
      it.startSimulation(SimulationAccuracy.Coarse);
    });
  }

  void resetSimulation() {
    _locationSimulator?.unsubscribeFromSimulatorEvents(_locationSimulatorListener);
    _locationSimulator = null;
    mapkit.resetLocationManagerToDefault();
  }

  void setSpeed(double speed) {
    _locationSimulator?.speed = speed;
  }
}
final class LocationSimulatorListenerImpl implements LocationSimulatorListener {

  final void Function() _onSimulationFinished;

  const LocationSimulatorListenerImpl(this._onSimulationFinished);

  @override
  void onSimulationFinished() => _onSimulationFinished();
}

extension LetExtension<T> on T {
  R let<R>(R Function(T it) block) => block(this);
}

Метод startSimulation принимает маршрут, по которому должна начаться симуляция ведения. Затем при помощи mapkit.createLocationSimulatorWithGeometry создается новый экземпляр LocationSimulator, который нужно сконфигурировать:

  1. подписаться на событие завершения симуляции при помощи LocationSimulatorListener;
  2. выставить значение скорости движения во время ведения;
  3. заменить реализацию LocationManager на только что созданный locationSimulator;
  4. начать симуляцию.

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

Более подробно с примером реализации симуляции по маршруту можно ознакомиться в демо-приложении.

Фоновое ведение

Фоновым ведением называется такая сессия ведения, которая способна продолжаться после скрытия приложения и даже после уничтожения его процесса.

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

Примечание

NaviKit SDK не предоставляет сервис для фонового ведения. Для реализации сценария фонового ведение вам потребуется реализовать свой собственный Foreground service с нотификацией.