Route Navigation (v2.1.x - Android)

Route Navigation (v2.1.x - Android)

The core component of Navmii SDK responsible for route navigation is RouteNavigator. This class provides the API to control the route navigation process, to get navigation information and guidance updates. The class is also able to handle the rerouting and the rerouting by traffic.

Creating route navigator

Sdk class contains the getRouteNavigator method providing access to the instance of RouteNavigator. The route navigator instance can be accessed only after the SDK was started.

Using route navigator

Route navigator has different responsibilities all related to each other:

  • route navigator performs navigation along the specified route. Route navigator gets GPS position updates internally, updates the route navigation state and notifies if any changes occur.

  • route navigator is able to handle rerouting. This option is intended to ease handling the rerouting process for SDK user. If rerouting handling is enabled, navigator, once rerouting is required, notifies that rerouting has started, calculates a new route, starts navigating along the new route and notifies that new route navigation has started.

  • route navigator is able to handle rerouting by traffic. This option is intended to ease handing the rerouting by traffic process for SDK user. If rerouting by traffic is enabled, navigator, once traffic has been updated, applies it to the current route, if possible, or builds a new route otherwise, builds alternative routes if possible, and notifies that new route navigation has started, traffic was updated and alternative routes are available.

  • route navigator is able to visualize changes in route by emitting route visualizer requests. To achieve such a behaviour you need to connect the route visualizer (getRouteVisualizer method of Sdk) to route navigator using addRouteVisualizerRequestListener method of RouteNavigator:

    Sample: connecting route visualizer to route navigator

    public class RouteVisializerRequestListenerExample { private final RouteNavigator routeNavigator; private final RouteVisualizer routeVisualizer; private final RouteVisualizerRequestListener routeVisualizerRequestListener = new RouteVisualizerRequestListener() { @Override public void onRouteVisualizerRequestAvailable(RouteVisualizerRequest routeVisualizerRequest) { routeVisualizer.performRequest(routeVisualizerRequest); } }; public RouteVisializerRequestListenerExample(Sdk sdk) { routeNavigator = sdk.getRouteNavigator(); routeVisualizer = sdk.getRouteVisualizer(); } private void connectVisualizerToNavigatior() { routeNavigator.addRouteVisualizerRequestListener(routeVisualizerRequestListener); } private void disconnectVisualizerToNavigatior() { routeNavigator.removeRouteVisualizerRequestListener(routeVisualizerRequestListener); } }
Route navigation

Route navigation starts by calling the startNavigatingTheRoute method. The route parameter is an instance of Route class which represents a route to navigate. The source of routes is Routing Manager. After the route navigation has started, the route navigator gets GPS position updates internally, updates the route navigation state and notifies if any changes occur. Callbacks for the following events are available:

  • OnRouteStateChangedListener: the 'on-route state' changes: user has got off the route or got back on the route. The SDK user may need this information to handle rerouting manually;

  • PositionOnRouteChangedListener: position on route (distance or time to destination) changes;

  • NextDirectionChangedListener: the next direction information changes;

  • DistanceToNextDirectionChangedListener: the distance to the next direction changes;

  • WaypointsPassedListener: a waypoint has been passed;

  • DestinationReachedListener: destination has been reached.

Route navigator has methods to access the latest route navigation information at any time.

Route navigator also provides the route navigation guidance whose callbacks can be gotten by conforming to GuidanceListener interface.

User is able to stop the route navigation by calling the stopNavigation method.

Automatic rerouting handling

As mentioned above RouteNavigator is able to handle rerouting automatically. The feature is enabled by default, but RouteNavigator class has the setReroutingEnabled method, which can be used to disable or enable the feature. If automatic rerouting handling is enabled, the route navigator tracks the on-route state and, once the GPS position has got off the route, calculates a new route and applies it. Callbacks about the automatic rerouting process can be gotten by conforming to ReroutingListener interface. The interface has the onReroutingStarted method, which is called once automatic rerouting starts, and the onReroutingFinished method, which is called once the process finishes. The onReroutingFinished method has the newRoute parameter, which is a new instance of Route class representing the new route being navigated. The newRoute can be null if rerouting handling is no longer required (i.e. GPS position has returned back to the previous route).

The rerouting engine has an algorithm, which tries to use a route the most similar to the one passed to the startNavigatingTheRoute method. RouteNavigator has the setReroutingSettings method, which allows to tune the algorithm.

Rerouting strategy

It is possible to select one of the four available rerouting strategies using the ReroutingSettings.setReroutingStrategy() method:

  • To next waypoint – the route will be calculated to the next waypoint, or to the destination if there are no remaining waypoints.

  • To point of deviation – the route will always be calculated to the point where the original route was left.

  • Shortest distance missed – the route will be calculated to the closest possible intersection.

  • Lowest time to return – the route will be calculated to one of the next intersections, taking time into account.

Example:

sdk.getRouteNavigator().setReroutingSettings(new ReroutingSettings.Builder() .setReroutingStrategy(getReroutingStrategy()) .build());
Automatic rerouting by traffic handling

As mentioned above RouteNavigator is able to handle rerouting by traffic automatically. The feature is enabled by default, but RouteNavigator class has the setRroutingByTrafficEnabled method, which can be used to disable or enable the feature. If automatic rerouting by traffic is enabled, the route navigator internally gets notifications from the traffic service that traffic near the current position has been updated, and, once it happens, handles rerouting by traffic. The SDK user gets callbacks about the rerouting by traffic process by conforming to ReroutingByTrafficListener interface. The protocol has a single method, which is called once the rerouting by traffic occurred.

The rerouting by traffic engine may create a new instance of Route class. The newRoute parameter will have non-null value if that happens. The doesNewRouteResembleOldOne parameter indicates whether the route, being navigated after the rerouting by traffic occurred, is identical (takes the same roads) to the route being navigated before rerouting. So if the newRoute is non-null but the doesNewRouteResembleOldOne is true means that the route being navigated hasn't changed (takes the same roads).

The alternativeRoutes parameter is a list of alternative routes with the latest traffic applied, which can be used for navigation. Use startNavigatingTheRoute method to start navigation along one of the alternative routes.

Guidance

Navmii SDK allows you to setup the way the navigation guidance will be provided. It's possible throughout the NavigationManager.getGuidanceSettings method. You can set the guidance output either to text or switch it off. If you pass GuidanceOutput.TEXT to the GuidanceSettings.setGuidanceOutput method, you'll be able to receive String instances with navigation guidance in NavigationListener.onGuidanceTextReady method.

@Override public void onGuidanceTextReady(String text) {     Log.i("NavigationListener", "onGuidanceTextReady: " + text); }

You can also set guidance language via the GuidanceSettings.setLocale method. To get the list of all languages supported by the SDK use the getSupportedLocales method.

// Sets guidance language to American English GuidanceSettings settings = navigationManager.getGuidanceSettings(); settings.setLocale("en-US");

Currently supported languages:

  • Czech

  • Danish

  • English (UK)

  • English (US)

  • Finnish

  • French (France)

  • German

  • Italian

  • Korean

  • Norwegian

  • Polish

  • Portugese (Brazil)

  • Portugese (Portugal)

  • Russian

  • Spanish (Spain)

  • Swedish

  • Turkish

Voice guidance

It's also possible to receive voice guidance instructions. To do this, first set the path to the directory containing the voice packs by using the Sdk.ConfigurationSettings.Builder.setVoicePacksPath method. After initializing the SDK, you can retrieve the list of available voice packs with the GuidanceSettings.getAvailableVoicePacks method, and select one using GuidanceSettings.setVoicePack. By passing GuidanceOutput.VOICE_PACK to the GuidanceSettings.setGuidanceOutput method, directions will be announced using the chosen voice pack.

Example:

Sdk.ConfigurationSettings.Builder builder = new Sdk.ConfigurationSettings.Builder(); builder.setVoicePacksPath(new File(context.getFilesDir(), "voices").getPath()); // Initialize the SDK and wait for the initialization process to finish RouteNavigator routeNavigator = Sdk.getInstance().getRouteNavigator(); GuidanceSettings guidanceSettings = routeNavigator.getGuidanceSettings(); List<VoicePack> voicePacks = guidanceSettings.getAvailableVoicePacks(); if (!voicePacks.isEmpty()) { guidanceSettings.setVoicePack(value); guidanceSettings.setGuidanceOutput(GuidanceOutput.VOICE_PACK); }

Junction View

JunctionView is an Android view that displays a schematic perspective of an upcoming junction, the route arrow and available road destination boards. Scenes are rendered at runtime from supported templates. They are schematic illustrations, not an exact reproduction of the surrounding buildings or road geometry.

The feature works during route navigation. Supported situations include forks, motorway exits and flyover approaches, including cases where the route stays on the road beside the flyover. A junction is shown only when a supported template can represent it; not every direction or intersection produces a Junction View.

API availability: this section describes the current Android SDK implementation. Use a build exposing the APIs below; the version in this page's title does not imply that all earlier v2.1.x binaries contain this feature.

Adding JunctionView to an application

Add com.pathwaypro.sdk.map.JunctionView to your layout, for example as an overlay in a FrameLayout containing your map. The application controls its position and size. The 220dp height below is an example, not a fixed SDK requirement.

<com.pathwaypro.sdk.map.JunctionView android:id="@+id/junction_view" android:layout_width="match_parent" android:layout_height="220dp" android:layout_gravity="top" android:layout_margin="12dp" />

After the SDK has started, bind the view to the navigator used for route navigation. Run Android view operations on the main thread.

import com.pathwaypro.sdk.map.JunctionView; import com.pathwaypro.sdk.routenavigation.RouteNavigator; import com.pathwaypro.sdk.common.DistanceUnits; // In the Activity, after SDK initialization and setContentView: JunctionView junctionView = findViewById(R.id.junction_view); RouteNavigator routeNavigator = sdk.getRouteNavigator(); routeNavigator.setJunctionViewEnabled(true); routeNavigator.setJunctionViewDisplayDistanceInMeters(500); junctionView.setDistanceLabelVisible(true); junctionView.setDistanceLabelUnits(DistanceUnits.KILOMETERS); junctionView.setRouteNavigator(routeNavigator);

Start navigation using startNavigatingTheRoute as usual. The bound view handles scene preparation, display, distance updates and hiding automatically. An application does not need to subscribe to JunctionViewListener to use the built-in view.

When disposing of the UI, explicitly unbind it and clear any application display listener. For a Fragment, do this in onDestroyView; for an Activity, do it before releasing the SDK.

junctionView.setDisplayListener(null); junctionView.setRouteNavigator(null); // Also remove any JunctionViewListener registered by the application.
Layout, orientation and multiple views

Use standard Android layout parameters and constraints to place and size the view, including different layouts for portrait and landscape. The scene adapts to the measured aspect ratio without stretching its objects. When no exact height is imposed, the view prefers a 3:2 width-to-height ratio subject to the parent's constraints.

Several JunctionView instances can bind to the same RouteNavigator. Each has its own layout, rendering, display listener, distance-label settings and animation settings. Each RouteNavigator exposes at most one current junction at a time. All views bound to that navigator share its feature-enabled state, display-distance threshold and current junction metadata.

Automatic hiding uses content opacity; it does not remove the view from its parent's layout. If the application needs to reclaim layout space, manage the containing layout separately.

Navigator settings and current information

RouteNavigator method

Contract

RouteNavigator method

Contract

getJunctionViewEnabled() / setJunctionViewEnabled(boolean)

Disabled by default. Call setJunctionViewEnabled(true) to use the feature. Disabling makes the current junction unavailable and hides bound views.

getJunctionViewDisplayDistanceInMeters() / setJunctionViewDisplayDistanceInMeters(int)

Default: 500 metres of remaining route distance. Preparation starts 100 metres earlier (600 metres by default). The setting applies immediately to the current route and all bound views.

getCurrentJunctionViewInfo()

Returns an immutable snapshot, or null when no junction is available for display.

addJunctionViewListener(listener) / removeJunctionViewListener(listener)

Registers/removes application observers of navigation availability. These are separate from view rendering events.

The display distance must be nonnegative and no greater than Integer.MAX_VALUE - 100. Zero requests display at the junction, subject to position updates. Preparation is an internal optimization and does not make the junction publicly available before the display threshold. Reducing the threshold may make an already available junction unavailable with OUT_OF_RANGE.

JunctionViewInfo exposes getJunctionId(), getType() and getDistanceInMeters(). The ID is an opaque occurrence identifier scoped to its RouteNavigator, not a persistent map-object identifier. Types are FORK, EXIT and FLYOVER; they are semantic categories, not template numbers. A previously obtained snapshot does not change when the vehicle moves. Scene geometry is not part of the public API.

Per-view settings

JunctionView method

Default and behavior

JunctionView method

Default and behavior

setRouteNavigator(RouteNavigator)

Binds to a navigator. Pass null to unbind.

setVisibilityMode(VisibilityMode) / getVisibilityMode()

AUTO: display when navigation and rendering allow it. NEVER: hide this view without disabling the navigator's feature. Setting the mode applies immediately.

setDistanceLabelVisible(boolean) / isDistanceLabelVisible()

true. Shows or hides only the distance label.

setDistanceLabelUnits(DistanceUnits) / getDistanceLabelUnits()

KILOMETERS: metres/kilometres. MILES_FEET: feet/miles. MILES_YARDS: yards/miles. Affects only this view's label; API distances and navigation guidance are unchanged. Null is rejected. Metres, feet and yards are rounded down to tens throughout the countdown; kilometres and miles use one decimal place.

setVisibilityAnimationEnabled(boolean) / isVisibilityAnimationEnabled()

true. Enables fading on automatic appearance/disappearance, not animation of road geometry or distance changes. Disabling finishes the current transition immediately.

setVisibilityAnimationDurationMillis(long) / getVisibilityAnimationDurationMillis()

250 ms. Zero means immediate; negative values throw IllegalArgumentException. Changing a positive duration restarts a running fade from its current opacity. Does not enable disabled animation.

setDisplayListener(JunctionViewDisplayListener) / getDisplayListener()

One listener per view; pass null to remove it. Events are not replayed on registration.

retryRender()

Returns true when a retry of the current failed scene is scheduled; otherwise false. Requires a failed scene, nonzero view size and no pending render.

Navigation events and lifecycle

JunctionViewListener reports whether navigation has a junction to show. It does not report whether pixels are visible on screen.

import com.pathwaypro.sdk.routenavigation.JunctionViewInfo; import com.pathwaypro.sdk.routenavigation.JunctionViewListener; import com.pathwaypro.sdk.routenavigation.JunctionViewEndReason; JunctionViewListener listener = new JunctionViewListener() { @Override public void onJunctionViewAvailable(JunctionViewInfo info) { // A supported junction is now available within the display range. } @Override public void onJunctionViewDistanceChanged(String junctionId, int distanceInMeters) { // Update application state for this occurrence. } @Override public void onJunctionViewBecameUnavailable( String junctionId, JunctionViewEndReason reason) { // Clear application state for this occurrence. } }; routeNavigator.addJunctionViewListener(listener); // Later, on the same serialized navigation execution context: routeNavigator.removeJunctionViewListener(listener);

Registration synchronously delivers onJunctionViewAvailable if a junction is already current. There is no initial unavailable event. Replacing a junction delivers the previous occurrence's unavailable event before the new occurrence's available event. Distance updates keep the same occurrence ID.

Threading: these callbacks execute synchronously on the source event thread; registration notifications use the calling thread. Android main-thread delivery is not guaranteed. Post UI work to the main thread, serialize subscription changes with navigator operations, and enqueue navigation changes instead of changing navigation state reentrantly inside a callback.

JunctionViewEndReason

Meaning

JunctionViewEndReason

Meaning

PASSED

The junction has been passed.

ROUTE_CHANGED

The route or junction occurrence was replaced.

NAVIGATION_STOPPED

Navigation stopped.

NAVIGATION_PAUSED

Navigation paused.

OFF_ROUTE

The navigator is off route.

DISABLED

The feature was disabled.

OUT_OF_RANGE

The junction is outside the display range.

A temporary detach from the window unsubscribes the view and cancels its rendering; reattachment restores the remembered navigator binding. Explicit setRouteNavigator(null) also clears that remembered binding. Replacing a scene clears stale content so an old junction is not displayed for a new occurrence.

Rendering and visibility events

JunctionViewDisplayListener observes one view. All its callbacks are delivered on the Android main thread. Install it before binding if you need the initial rendering events.

Callback

When it is delivered

Callback

When it is delivered

onRenderReady(JunctionView view, String junctionId)

An up-to-date frame has been prepared and accepted. It may still be hidden, for example during advance preparation. Can occur again after a resize or color-scheme change; it is not a one-time event per junction.

onRenderFailed(JunctionView view, String junctionId, Exception error)

The current render failed. Canceled work and obsolete render results do not generate this event.

onBecameVisible(JunctionView view, String junctionId)

The first content frame is drawn in an eligible visible view hierarchy. This is not a guarantee that no other view or window covers it.

onBecameHidden(JunctionView view, String junctionId)

Previously visible junction content is no longer shown. No initial hidden event is sent for a view that has never displayed content.

Navigation availability, render readiness and actual content visibility are separate states. Do not treat onJunctionViewAvailable or onRenderReady as proof that the user has seen the scene. Likewise, hiding an individual view does not make the navigator's junction unavailable.

After onRenderFailed, an application can show a retry control that calls junctionView.retryRender(). There is no automatic retry loop. Do not retry unconditionally inside the failure callback; allow the cause to change or use a user action.

Colors, frame and distance-label font

Junction View uses the active loaded map color scheme. Its parameters are loaded from COL files by the SDK's regular color-scheme loader, including normal inheritance and overrides. There is no separate Junction View theme selector and no dependency on the Android system UI day/night setting. Load/select the map color scheme through the application's existing map-scheme flow.

The base day and night Default.col schemes define Junction View defaults. Override the corresponding parameters in your scheme. COLOR values use eight hexadecimal digits in AARRGGBB order, without a leading #.

COLOR JUNCTION_VIEW_ARROW_FILL FFFFC400 COLOR JUNCTION_VIEW_CHIP_BACKGROUND B3000000 COLOR JUNCTION_VIEW_CHIP_TEXT FFFFFFFF COLOR JUNCTION_VIEW_FRAME FF758493 JUNCTION_VIEW_FRAME 2 10 JUNCTION_VIEW_DISTANCE_FONT sans-serif 22 1 0

JUNCTION_VIEW_FRAME <widthDp> <cornerRadiusDp> controls the outer border and rounding. Both values must be finite and nonnegative. Width 0 disables the border; radius 0 uses square corners. The example uses a 2dp border and 10dp radius.

JUNCTION_VIEW_DISTANCE_FONT <family> <sizeSp> <bold> <italic> controls the distance label. The family is an Android font-family name such as sans-serif or sans-serif-condensed; size must be finite and positive; bold and italic are 0 or 1. The default is sans-serif, 22sp, bold, not italic. The size is in sp, follows the system font scale and uses the same value in 1x and 2x COL files. JUNCTION_VIEW_CHIP_TEXT controls the text color and JUNCTION_VIEW_CHIP_BACKGROUND its background.

COLOR keys (each starts with JUNCTION_VIEW_)

Use

COLOR keys (each starts with JUNCTION_VIEW_)

Use

SKY_TOP, SKY_BOTTOM, GROUND

Sky gradient and ground.

ROAD_SURFACE, ROAD_EDGE, LANE_MARKING

Road surface, edge lines and markings.

ELEVATED_SURFACE, ELEVATED_WALL, ROAD_BARRIER

Flyover surface, elevation walls and barriers.

BUILDING_FRONT, BUILDING_SIDE, BUILDING_TOP

Schematic building faces.

ARROW_FILL

Route arrow.

BOARD_MOTORWAY, BOARD_URBAN, BOARD_BORDER, BOARD_TEXT, BOARD_SHADOW, POLE

Road destination boards and supports.

EXIT_BACKGROUND, EXIT_TEXT

Exit information.

CLOUD_SHADOW, CLOUD_LIGHT

Cloud colors and opacity.

CHIP_BACKGROUND, CHIP_TEXT

Distance label background and text.

FRAME

Outer frame color.

After a new map color scheme finishes loading, bound Junction Views render using that active palette. The displayed frame and its labels retain a consistent palette while the replacement frame is prepared.

When Junction View does not appear
  • Check that the SDK is started, the view is bound to the correct navigator and route navigation is active.

  • Check getJunctionViewEnabled(), getCurrentJunctionViewInfo() and the display-distance threshold. A null snapshot can be normal: no supported junction is currently available, even if a direction exists.

  • Check VisibilityMode.AUTO, nonzero layout dimensions and the Android parent/window visibility. A view with no measured area cannot render.

  • Use JunctionViewDisplayListener to distinguish a render failure from a hidden or not-yet-ready frame. Use retryRender only for a current failed render.

  • Check the selected map color scheme if the expected colors, frame or label font are not applied. Changing the system UI theme alone does not change Junction View colors.