Guidance

Guidance contains information on the current guidance session and lets you follow events in guidance mode. Use the Navigation.guidance method to get it.

Track location

By default, Navigation is created in suspended mode, where location isn't tracked and guidance is off. To start tracking the current device location, use resumed mode. That keeps the user's location up to date.

To manage the location tracking mode, use the Navigation.resume and Navigation.suspend methods.

Tip

It's a good idea to switch Navigation to suspended mode when you collapse the app and the map and switch it back to resumed when you reopen the app.

We don't recommend switching Navigation to suspended mode for the background guidance scenario.

Start/stop guidance

To start route guidance, use the Navigation.startGuidance method. It takes the route as its only argument.

To stop guidance, use the matching Navigation.stopGuidance method.

Note

The number of possible active guidance sessions is limited. There can only be one active guidance session at a time.

Guidance data

Let's look at the main data Guidance provides access to.

  • Current route: Guidance.currentRoute contains the route where guidance is currently active or the null value if guidance is inactive. In guidance mode, the current route can change, for example, if the user deviates from the route or chooses an alternate route.

  • User location: Guidance.location contains the current user location. That includes the location coordinates, current direction, location precision, guidance speed, and more.

  • Speeding: Guidance.speedLimit and Guidance.speedLimitStatus provide information on the speed limit for the current route section. Guidance.speedLimitsPolicy provides information about speed limits for different areas in the current region (in the city, outside the city, and on highways).

The complete API is available in the Guidance documentation.

Windshield

The NavigationWindshield entity is used to provide information about oncoming maneuvers on the route, road markings and events, speed limits, and road signs.

To access the NavigationWindshield instance, use the Guidance.windshield method.

The NavigationWindshield entity status is defined by the following data:

  • Maneuvers: Using NavigationWindshield.manoeuvres, you can get a list of maneuvers on the route. Each maneuver is described by its position on the route, location, and the DrivingAnnotation instance that contains information about its type.

  • Road markings: NavigationWindshield.laneSigns returns a list where each instance contains information about the lane the user must be on. It is characterized by its position on the route and the DrivingLaneSign instance, which defines the road markings type at a road section. The DrivingLaneSign instance contains the list of DrivingLane with information about each separate traffic lane, its direction, type, and possible maneuvers.

  • Road events: Using NavigationWindshield.roadEvents, you can get a list of road events on the route as well as information about speed limits.

  • Road signs: The NavigationWindshield.directionSigns method returns a list of road signs on the route. For example, a sign that indicates the next route section includes a tunnel or a highway

Using NavigationWindshieldListener, you can follow NavigationWindshield status change events.

You can see an example of how NavigationWindshield can be used for implementing the UI component that displays information about the next maneuver and lane markings in the demo app.

Events

In guidance mode, the guidance status changes constantly. Use the GuidanceListener interface to follow guidance events.

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 lets you follow navigation events (deviation from the route, return to the route, and arrival at intermediate and final stops) and guidance status changes (for the current user location, street name, speed limit information, list of alternatives, and more).

Guidance alternatives

Local alternatives are the alternate routes available in guidance mode. They're recalculated automatically. To follow this event, use the GuidanceListener.onAlternativesChanged method.

To switch from the current route to an alternate one, use the Guidance.switchToRoute method.

Faster alternative routes

Route guidance sessions might sometimes last as long as several hours. In these cases, the initially built route might become outdated and less convenient with time. This is relevant for city guidance since the traffic situation might change quite often. NaviKit SDK solves this problem and provides an opportunity to get a faster alternative route.

The Guidance.fastestAlernative method returns information about a faster alternative route, if one exists. Start guidance along such a route to change the current route to a faster one.

Using the GuidanceListener.onFastestAlternativeChanged handler method, you can follow notifications about changes in the faster route.

Annotations

To set up voice guidance (voice annotations) for the route, use the Annotator class.

To enable and disable annotations, use the Annotator.mute and Annotator.unmute methods.

For the annotator to start working, add a Speaker delegate to it and implement it yourself.

Note

NaviKit SDK doesn't provide Speaker implementation.

To change the annotation language, use the Navigation.annotationLanguage method.

Annotations are divided into two types: AnnotatedRoadEvents are related to road events and AnnotatedEvents are related to route warnings. You can manage the amount of activity for specific annotations using the Annotator.annotatedRoadEvents and Annotator.annotatedEvents methods.

You can follow Annotator class events using the AnnotatorListener interface. It notifies you about annotator actions (the type of event that was performed).

Restore status

You can restore the guidance status by serializing/deserializing Navigation.

  1. To do so, serialize Navigation using the NavigationSerialization.serialize method.

    final serializedNavigation = NavigationSerialization.serialize(navigation);
    
  2. serializedNavigation now contains a navigation copy. You can save it to a disk and later restore it using deserialization.

  3. Using NavigationSerialization.deserialize, create a new navigation instance.

    final navigation = NavigationSerialization.deserialize(serializedNavigation);
    

Before closing the app, you can save Navigation to a disk and restore it when you open the app again later. Because guidance status is in Guidance and guidance is part of Navigation, it'll also be restored, and the last guidance session will continue.

There's an example of how to implement the logic for restoring guidance statuses in the demo app.

Guidance simulation

When developing and testing navigation apps, you may need to check how the guidance scenario works. To do so, use third-party tools for simulating user locations or the ready-made simulation API in NaviKit SDK.

To enable location simulation along a route or in an arbitrary direction, use the LocationSimulator class.

Here's an example of how to implement the guidance simulation manager:

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);
}

The startSimulation method accepts the route for guidance simulation. When you use mapkit.createLocationSimulatorWithGeometry, a new LocationSimulator is created. You need to configure it:

  1. Follow the simulation finish event using LocationSimulatorListener.
  2. Set the movement speed value.
  3. Change the LocationManager implementation to the newly created locationSimulator.
  4. Start the simulation.

The simulation is reset in resetSimulation. With mapkit.resetLocationManagerToDefault, the location simulation manager changes to the default option, which reads the user's current location.

There's a detailed example of route simulation in the demo app.

Background guidance

Background guidance refers to a guidance session that can continue even after the app is hidden or killed.

After the app loses focus, the system may kill it to free up resources.

Note

NaviKit SDK doesn't provide a background guidance service. To implement the background guidance scenario, you need to implement your own foreground service with a notification.