Importing, Exporting and Modifying Routes

VERSION 1.1.0
PUBLIC PREVIEW

In addition to generating routes, the SDK allows developers to manipulate them to a limited degree. Specifically, you can:

  • Import routes from GPX files.
  • Export routes to GPX files.
  • Split one route into smaller routes.
  • Combine multiple routes into one larger route.

These manipulations are done by treating a route as a series of points. A route in the SDK can contain two kinds of points:

  • Waypoints are locations that a route can be planned to pass through. They generate arrival events when the driver reaches them. For example, they can be places a driver wants to visit on a road trip or delivery locations for a cargo van.
  • Supporting points are geographical points that define the geometry of an existing route.

Before the SDK can use a series of points as a route (e.g., to show it on a map), it must be turned into a TomTom route. There are two ways to do this:

  • Planning a new route that passes through the route’s waypoints.
  • Reconstructing the route from its supporting points. This results in a route with a similar geometry to the original. The returned RoutePlanningResponse can be used in the SDK like any other route. To include waypoints when reconstructing a route in this way, divide the geometry into legs that connect the waypoints, and pass them as a list of RouteLegOptions instances.

This tutorial contains code snippets to do all of these things except for planning a new route, which is explained in the Waypoints and custom routes guide.

Constructing a route from a GPX file

To use a route from a GPX file, first extract the route data from it. Use a third-party GPX file parser library to do so. This example uses com.github.ticofab:android-gpx-parser:v2.2.0.

1val parser = io.ticofab.androidgpxparser.parser.GPXParser()
2val gpx = parser.parse(gpxInputStream)
3val tracks =
4 gpx.tracks.map { trk ->
5 trk.trackSegments.map { trkseg ->
6 trkseg.trackPoints.map { point ->
7 GeoPoint(point.latitude, point.longitude)
8 }
9 }
10 }
11val waypoints = gpx.wayPoints.map { GeoPoint(it.latitude, it.longitude) }

Then create a route, either by reconstructing it by using the track points in the imported geometry as supporting points, or by planning a new one that passes through the imported waypoints.

This functionality produces a navigable route matched to the road network. This is not to be confused with the off-road navigation described in the OffRoadTomTomNavigationFactory page.

Exporting a route into a GPX file

To export a route from the SDK, extract its legs as track segments as follows:

1fun routeToGpx(route: Route, out: Writer) {
2 out.write("<gpx>")
3 out.write("\n\t<trk>")
4 route.legs.forEach { leg ->
5 out.write("\n\t\t<trkseg>")
6 leg.points.forEach {
7 out.write("\n\t\t\t<trkpt lat=\"${it.latitude}\" lon=\"${it.longitude}\"></trkpt>")
8 }
9 out.write("\n\t\t</trkseg>")
10 }
11 out.write("\n\t</trk>")
12 out.write("\n</gpx>")
13}

Splitting a route

Every leg of a route is self-contained. This means that a route can be split into combinations of one or more legs:

1fun splitRoute(route: Route, waypointIndex: Int) {
2 require(route.legs.size > waypointIndex + 1)
3 val firstHalf = route.legs.subList(0, waypointIndex)
4 val secondHalf = route.legs.subList(waypointIndex, route.legs.size)
5
6 val firstGeometry = firstHalf.flatMap { it.points }
7 val secondGeometry = secondHalf.flatMap { it.points }
8}

Once the legs have been split, you can reconstruct them into separate routes.

Combining routes

Routes can be joined by combining their geometries:

1fun joinRoutes(route1: Route, route2: Route) {
2 val geometry1 = route1.geometry
3 val geometry2 = route2.geometry
4
5 val joinedGeometry = geometry1 + geometry2
6}

The resulting geometrycan then be used to reconstruct the combined route.

Reconstructing a route with the TomTom Routing Service

To reconstruct a route from a list of supporting points, do the following:

1fun trackToRoute(
2 track: List<List<GeoPoint>>
3): Result<RoutePlanningResponse, RoutingFailure> {
4 val waypoints = (track.dropLast(1).map { it.last() })
5 val routePlanningOptions = RoutePlanningOptions(
6 itinerary = Itinerary(
7 origin = track.first().first(),
8 destination = track.last().last(),
9 waypoints = waypoints
10 ),
11 routeLegOptions = track.map { trackSegment ->
12 RouteLegOptions(supportingPoints = trackSegment)
13 }
14 )
15 return routePlanner.planRoute(routePlanningOptions)
16}

Next steps

Since you have learned how to modify a route, here are recommendations for the next steps: