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, these waypoints could be places that 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 CoreGPX.
1guard let inputPath = Bundle.main.path(forResource: "Test", ofType: "gpx"),2 let gpx = GPXParser(withPath: inputPath)?.parsedData() else { return }34print("coordinates:", gpx.waypoints.map { ($0.latitude, $0.longitude) })
Next, you can create a route by either reconstructing it, utilizing the imported waypoints and 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 OffRoadTomTomNavigation page.
Exporting a route into a GPX file
To export a route from the SDK, extract its waypoints and legs as track segments as follows:
1private func locationsToGpx(locations: [CLLocationCoordinate2D], waypoints: [RouteStop]) -> String {2 let root = GPXRoot(creator: "Example root")3 var trackpoints = [GPXTrackPoint]()4 locations.forEach { location in5 let point = GPXTrackPoint(latitude: location.latitude, longitude: location.longitude)6 trackpoints.append(point)7 }8 let track = GPXTrack() // initiates a track9 let tracksegment = GPXTrackSegment() // initiates a tracksegment10 tracksegment.add(trackpoints: trackpoints) // adds an array of trackpoints to a track segment11 track.add(trackSegment: tracksegment) // adds a track segment to a track12 root.add(waypoints: waypoints.map { waypoint -> GPXWaypoint in13 let coordinate = waypoint.navigableCoordinates.first ?? waypoint.place.coordinate14 return GPXWaypoint(latitude: coordinate.latitude, longitude: coordinate.longitude)15 })16 root.add(track: track)1718 return root.gpx()19}
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:
1private func splitRoute(route: Route, waypointIndex: Int) {2 assert(route.legs.count > waypointIndex + 1)34 let firstHalf = route.legs[..<waypointIndex]5 let secondHalf = route.legs[waypointIndex...]67 let firstGeometry = firstHalf.flatMap { $0.geometry }8 let secondGeometry = secondHalf.flatMap { $0.geometry }910 print("firstGeometry: \(firstGeometry)")11 print("secondGeometry: \(secondGeometry)")12}
Once the legs have been split, you can reconstruct them into separate routes.
Combining routes
Routes can be joined by combining their geometries:
1private func joinRoutes(route1: Route, route2: Route) {2 let geometry1 = route1.geometry3 let geometry2 = route2.geometry45 let joinedGeometry = geometry1 + geometry267 print("joinedGeometry: \(joinedGeometry)")8}
The resulting geometry can then be used to reconstruct the combined route.
Navigating an imported route
The imported route can then be navigated like a regular route. Be aware that if a user veers off the planned route, they are automatically guided back to a location on the original route located up to 1 kilometer beyond where the deviation occurred.
Next steps
Since you have learned how to modify a route, here are recommendations for the next steps: