Importing, Exporting and Modifying Routes
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 ofRouteLegOptions
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.
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)56 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.geometry3 val geometry2 = route2.geometry45 val joinedGeometry = geometry1 + geometry26}
The resulting geometry
can 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 = waypoints10 ),11 routeLegOptions = track.map { trackSegment ->12 RouteLegOptions(supportingPoints = trackSegment)13 }14 )15 return routePlanner.planRoute(routePlanningOptions)16}
Navigating an imported Route
The imported route can then be navigated like a regular route. Note that on deviation of such routes, currently the given geometry will be ignored when the SDK queries to get a new route plan. This behavior will be improved soon.
Next steps
Since you have learned how to modify a route, here are recommendations for the next steps: