Skip to content

Navigation

In this section you will learn how to start a simple navigation from the current location to a position selected via the map.

Add a listener to your IwMapView:

First of all, you need to set a listener to your IwMapView to catch long press events:

1
2
3
4
mapView.setOnMapLongPressListener {
      x,y ->

  }

Next, create a Position object from the internal coordinates of the MapViewer by using Mapviewer.getGeoCoordFromFrameCoord():

1
2
3
4
5
6
7
mapView.setOnMapLongPressListener {
      x,y ->
      val destinationPosition: Position = mapView.mapviewer
        .getGeoCoordFromFrameCoord(
          Position(x.toDouble(), y.toDouble())
      )
  }

Info

In most use cases you will want to work with destination coordinates as WGS 84 standard from other sources, e.g. when showing a new Fragment. You can just create your destination waypoint by calling Position.createWGS84Position(lat,lon). As most of our objects the Waypoint class implements Android's Parcelable interface, so you can conveniently pass it to your Activity or Fragment as your Intent's extras.

Now, you will need to convert the Position to a Waypoint object:

1
2
val destinationWaypoint = Waypoint()
destinationWaypoint.position = mapPosition

Create an Itinerary

At next, create an Itinerary from your current position to the destination waypoint and set it for the Navigation class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// create a waypoint for your start position by calling a special function
val startWaypoint = Waypoint.createCurrentGPSPosWaypoint()

// Create an Itinerary
val itinerary = Itinerary()
// add your start waypoint
itinerary.appendWaypoint(startWaypoint)
// add your destination waypoint
itinerary.appendWaypoint(destinationWaypoint)
val navigation = Navigation()
navigation.itinerary = itinerary

Setting the computation site

Usually the MapTrip SDK is used in hybrid mode. It means, that the full map data is stored locally on the device but routes are calculated online. If there is no connection available, the SDK will calculate the route on the local data. If you want to force the SDK to calculate routes online or offline only, you can do so by using the static Navigation.setAllowedComputationSite method and pass the desired ComputationSite as parameter.

1
Navigation.setAllowedComputationSite(ComputationSite.OFFBOARD)

Info

The Navigation class offers further capabilities to influence the routing via static methods. For example, you can set whether you want to avoid highways, ferries or toll roads.

Setting the Routing type

By calling Navigation.setRoutingType you can set if your calculated route should be the fastest or shortest route.

1
Navigation.setRoutingType(RoutingType.FASTEST_ROUTE)

Calculate a route and start navigation

Finally, register a TaskListener and calculate the route. When the task is finished, start the navigation. You can also choose to simulate the route guidance. Moreover, you can display a destination flag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var calculateRouteTask : Task<Void>? = null

navigation.addTaskListener(object : TaskListener {
    override fun taskProgress(task: BaseTask) {
        // Not needed for now, use it for e.g. displaying a progress bar
    }

    override fun taskFinished(task: BaseTask) {

        // if the task originated from calculateRoute, start a navigation
        if (task == calculateRouteTask) {

            val retVal: Int = task.returnValue.intVal
            val apiError = ApiError.getByInt(retVal)

            // remove task listener
            navigation.removeTaskListener(this)

            if (retVal < ApiError.OK.intVal) {
              // Task-Callback: Route could not be calculated
              return
            }

            if (retVal > ApiError.OK.intVal) {
              // Task-Callback: Route could be calculated, but there are warnings
            }

            val navReturnValue: ApiError = navigation.startNavigation()
            // for simulation: val navReturnValue: ApiError = navigation.startSimulatedNavigation()

            if (navReturnValue != ApiError.OK) {
                // Navigation could not be started. Handle Error here.
            } else {
                val last = navigation.itinerary.waypointIterator.last()
                last.poiIcon = "DestinationArrow.png"
                mapView.mapviewer.showWaypoint(last, true)
            }
        }
    }

})

calculateRouteTask = navigation.calculateRoute()

Calculate alternative routes

In the previous example you have learned how to calculate a single route for your itinerary. Commonly, navigation apps offer multiple alternative routes. In order to do so with the MapTrip SDK you can simply call

1
calculateRouteTask = navigation.calculateRoutes(3)

When the task is finished you can get alternative routes from your Navigation object. It also returns an object of class Navigation.

1
2
3
4
5
6
7
8
override fun taskFinished(task: BaseTask) {

    ...
    val route1 = navigation.getRouteNumber(0)
    val route2 = navigation.getRouteNumber(1)
    val route3 = navigation.getRouteNumber(2)

}

Get route information

Before starting a navigation you will often provide buttons in your UI to display information such as route length or duration. For this purpose you can get the route statistics by calling Navigation.getRouteStatistic where you have to provide a NavRouteStatistic enum constant and the stops. If you only have one destination it will typically 0 for the first stop and 1 for the destination waypoint.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
override fun taskFinished(task: BaseTask) {

    ...
    val duration = navigation.getRouteStatistic(NavRouteStatistic.DRIVE_TIME_SECONDS, 0, 1)
    val length = navigation.getRouteStatistic(NavRouteStatistic.ROUTE_LENGTH_METERS, 0, 1)

    // or if you followed the alternative route example, e.g.
    val durationRoute1 = route1.getRouteStatistic(NavRouteStatistic.DRIVE_TIME_SECONDS, 0, 1)
    val lengthRoute1 = route1.getRouteStatistic(NavRouteStatistic.ROUTE_LENGTH_METERS, 0, 1)

}

Get Callbacks for your Navigation

During the route guidance the MapTrip SDK provides several callbacks that enables you to develop a Navigation UI or obtain route information like remaining time and distance. You will just need to add a NavigationListener.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
val navigationListener =
    object : NavigationListener {
        override fun navigationStarted() {}

        override fun destinationReached(index: Int) {}

        override fun crossingInfoReceived(
            actualStreetName: String,
            nextStreetName: String,
            pictoFileName: String,
            streetType: CrosswayStreetType,
            metersToCrossing: Double,
            secondsToCrossing: Double
        ) {}

        override fun destinationInfoReceived(
            secondsToDestination: Double,
            metersToDestination: Double,
            energyToDestination: Double
        ) {}

        override fun speedLimitReceived(speedLimit: Double) {}

        override fun laneInfoReceived(allArrows: String, divider: String, relevantArrows: String) {}

        override fun vehicleWarningReceived(
            restrictionType: VehicleWarningType,
            restrictionValue: Double
        ) {}

        override fun beforeAdviceStarts(
            speechIndependentSentence: String,
            additionalAdviceInfo: String,
            sentence: String
        ): Boolean {
            return true
        }

        override fun rerouting(reroutingTask: Task<Void>?) {}

        override fun routeUpdate(routeComparison: RouteComparison) {}
    }

Navigation.addNavigationListener(navigationListener)

Please check our MiniNavi example to see what you could do with these callbacks. If you do not want to develop your own UI we recommend that you use our new QuickUI library.