Waypoints and custom routes

VERSION 0.34.2
PUBLIC PREVIEW

In a more advanced navigation experience, the user may want to provide more locations through which the route should be calculated. These optional intermediate locations are known as waypoints.

Planning a route may involve locations beyond the origin and destination. These can be used in two different ways:

  • Adding Waypoints to a route. These can be stops along the way or places that the user wants to visit during the journey.
  • Constructing a custom route from a polyline (defined as a list of supporting points). This allows users to import routes from another source or reconstruct driven paths.

Setup

When creating OnlineTomTomNavigationFactory.Configuration add the StandaloneRouteProgressEngine for routeProgressEngine parameter.

1let configuration = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationProvider,
3 routeReplanner: routeReplanner,
4 apiKey: "YOUR_API_KEY",
5 routeProgressEngine: StandaloneRouteProgressEngine()
6)
7
8let navigation = try OnlineTomTomNavigationFactory.create(configuration: configuration)

Waypoints

The maximum allowed number of waypoints is 150.

Waypoints are defined using an array of ItineraryPoint instances, that are stored in the Itinerary.waypoints property. The Itinerary type is stored in the RoutePlanningOptions.itinerary property. Each ItineraryPoint includes: - An ItineraryPoint.id property, used to synchronize between the waypoints in the input to planning (RoutePlanningOptions) and those in the output (Route). - An ItineraryPoint.place property of the type Place, that includes the place’s coordinates (CLLocationCoordinate2D), plus its name and address if they are supplied.

There are two options for defining waypoints while creating RoutePlanningOptions: with just its coordinates or with detailed data as well.

To define a waypoint using only its coordinates:

1let amsterdamCoordinate = CLLocationCoordinate2DMake(52.3764527, 4.9062047)
2let berlinCoordinate = CLLocationCoordinate2DMake(52.5069751, 13.3631919)
3let hagueCoordinate = CLLocationCoordinate2DMake(52.078663, 4.288788)
4let itinerary = Itinerary(
5 origin: ItineraryPoint(coordinate: amsterdamCoordinate),
6 destination: ItineraryPoint(coordinate: berlinCoordinate),
7 waypoints: [ItineraryPoint(coordinate: hagueCoordinate)]
8)
9
10let options: RoutePlanningOptions
11do {
12 options = try RoutePlanningOptions(itinerary: itinerary)
13} catch {
14 print("Invalid planning options: \(error.localizedDescription)")
15 return
16}

To define a waypoint using its coordinates, address, and name:

1let amsterdamCoordinate = CLLocationCoordinate2DMake(52.3764527, 4.9062047)
2let berlinCoordinate = CLLocationCoordinate2DMake(52.5069751, 13.3631919)
3let hagueCoordinate = CLLocationCoordinate2DMake(52.078663, 4.288788)
4let hagueAddress = Address(
5 streetNumber: "70",
6 streetName: "De Perponcherstraat",
7 municipality: "Den Haag",
8 postalCode: "2518 SW",
9 country: "The Netherlands"
10)
11let haguePlace = Place(coordinate: hagueCoordinate, name: "Den Haag", address: hagueAddress)
12
13let itinerary = Itinerary(
14 origin: ItineraryPoint(coordinate: amsterdamCoordinate),
15 destination: ItineraryPoint(coordinate: berlinCoordinate),
16 waypoints: [ItineraryPoint(place: haguePlace)]
17)
18
19let options: RoutePlanningOptions
20do {
21 options = try RoutePlanningOptions(itinerary: itinerary)
22} catch {
23 print("Invalid planning options: \(error.localizedDescription)")
24 return
25}

RoutePlanningOptions accepts waypoints inside the Itinerary as a list of ItineraryPoint.

An ItineraryPoint can be created with a single coordinate:

let point = ItineraryPoint(coordinate: .init(latitude: 0, longitude: 1))

There is also an initializer for offering the full Place model:

let point = ItineraryPoint(place: myPlaceObject)

Route planning returns a Route array. Waypoints are included in the Route in the order they are specified in the Itinerary of the RoutePlanningOptions. When planning a route, each waypoint results in an extra leg in the response.

The Route.routePoints property contains an array of RoutePoint instances. This array includes values of the types Origin, Destination, and Waypoint (for the respective points of the route). Waypoints from this array can be accessed via the Route.waypoints property.

Custom routes

The user may want to import a custom polyline and reconstruct a route based on it. The RouteLegOptions.supportingPoints parameter is used for this:

  • The provided sequence of supporting points is used as input for route reconstruction.
  • The RoutePlanningOptions.routeLegOptions accepts the supporting points per leg.
    • The number of items in the RoutePlanningOptions.routeLegOptions array must match the number of legs of the route as specified by the Itinerary.
  • Alternative routes are calculated using the origin point, potential waypoints, and destination point as specified by the Itinerary.
  • If both AlternativeRoutesOptions.minDeviationDistance and AlternativeRoutesOptions.minDeviationTime are set to zero, the origin and destination points are expected to be at (or very near) the beginning and end of the reference route.
  • The reference route may contain road closures, which are ignored for the calculation of travel time and traffic delay for the reference route.
  • When using the Waypoints, it is essential to set the routeProgressEngine to StandaloneRouteProgressEngine for precise route progress calculation.
1let amsterdamCoordinate = CLLocationCoordinate2DMake(52.3764527, 4.9062047)
2let berlinCoordinate = CLLocationCoordinate2DMake(52.5069751, 13.3631919)
3let supportingPoints = loadSupportingPointsFromFile()
4let routeLegOptions = supportingPoints.map { RouteLegOptions(supportingPoints: $0) }
5let itinerary = Itinerary(
6 origin: ItineraryPoint(coordinate: amsterdamCoordinate),
7 destination: ItineraryPoint(coordinate: berlinCoordinate)
8)
9
10let options: RoutePlanningOptions
11do {
12 options = try RoutePlanningOptions(
13 itinerary: itinerary,
14 alternativeRoutesOptions: AlternativeRoutesOptions(
15 maxAlternatives: 1,
16 minDeviationDistance: Measurement.tt.meters(100),
17 minDeviationTime: Measurement.tt.seconds(10)
18 ),
19 routeLegOptions: routeLegOptions
20 )
21} catch {
22 print("Invalid planning options: \(error.localizedDescription)")
23 return
24}

Next steps

Since you have learned how to add waypoints, here are recommendations for the next steps: