Route generation
This page uses v1.4.2 of the Mapbox Navigation SDK. A newer version of the SDK is available. Learn about the latest version, v2.19.0, in the Navigation SDK documentation.
The routes used in the Navigation SDK are generated by the Mapbox Directions API. When you install the Navigation SDK, it also includes Mapbox Directions for Swift, which provides a convenient way to access the Mapbox Directions API in iOS applications.
To generate a route, you'll create a new Route
object using Mapbox Directions for Swift. In most cases, you'll also use the NavigationRouteOptions
class (a subclass of Mapbox Directions for Swift's RouteOptions
class) to set a few options. You can specify any of the same options you could using the RouteOptions
class found in Mapbox Directions for Swift, but the defaults in NavigationRouteOptions
are better suited to how the Navigation SDK uses the resulting route.
Below are examples of how you can use specific options to generate routes for a few scenarios.
Request a route in a specific direction
With the Navigation SDK, you can consider the direction a user’s device is facing and request a route starting in a specific direction. To receive a route in a specific direction (for example, the direction a user is traveling or the direction a device is facing), pass in the user’s location heading
value. This property corresponds to the angles in the bearings query parameter in the Mapbox Directions and Map Matching APIs.
Waypoint: In the adjacent diagram, the blue dot with white stroke is the device location. Imagine this is the first (origin) Waypoint
in a Directions API request.
Heading: The Waypoint.heading
can be used to influence the direction in which a route leg should begin. The heading
value is the angle clockwise from true north between 0 and 359. For example, when the heading
value is 0, the heading direction is due north. In the adjacent diagram, the pink arrow is the direction that the device is the heading
(which is due west or 270°). Read about Waypoint.heading
in more detail.
Heading accuracy: The Waypoint.headingAccuracy
is the range of degrees by which a route can deviate from the Waypoint.heading
angle and still be recommended. The semi-transparent blue area illustrates headingAccuracy
. In this example headingAccuracy
is 90° (45° in either direction from the heading angle). Read about Waypoint.headingAccuracy
in more detail.
The system sets the default value for heading
to −1°, indicating that the heading will not be considered when calculating a route.
Consider the direction a device is facing
To request a route that starts in the direction that the device is facing, set Waypoint.heading
to use CLHeading.trueHeading
. This may be appropriate when requesting a route with the user's location as the origin before the user has started moving or for walking directions.
You can also set a Waypoint.headingAccuracy
to specify the range of degrees by which a route can deviate from the Waypoint.heading
angle. Though Waypoint.headingAccuracy
and CLHeading.headingAccuracy
have similar names, it is not appropriate to pass in the current CLHeading.headingAccuracy
. CLHeading.headingAccuracy
tends to result in too-strict route requests.
This can also be applied to any waypoint including the origin and any stops along the route.
let userWaypoint = Waypoint(location: mapView?.userLocation!.location, heading: CLHeading.trueHeading, headingAccuracy: 90)
Consider the direction a user is already traveling
If you need to request a route that's continuing along the path that the user is traveling, set the Waypoint.heading
to use CLLocation.course
. This may be appropriate for driving directions. Consider that the phone may be in a center cup holder, facing the driver rather than the rear-view mirror, as the car moves in a forward direction. You can also set a custom Waypoint.headingAccuracy
.
This can be applied to any waypoint including the origin, stops along the route, and the destination.
let userWaypoint = Waypoint(location: mapView?.userLocation!.location, heading: CLLocation.course, headingAccuracy: 90)
Specify a side of the road to approach
By default, routes generated will approach waypoints on either side of road. You can override the default by setting Waypoint.allowsArrivingOnOppositeSide
to false
. This will require that the route has the driver approach the waypoint on the same side of the road the waypoint is on. allowsArrivingOnOppositeSide
corresponds to the approaches query parameter in the Mapbox Directions and Map Matching APIs.
let userWaypoint = Waypoint(location: mapView?.userLocation!.location, allowsArrivingOnOppositeSide: false)
Include multiple stops
The Mapbox Directions API requires at least two waypoints to generate a route. If your route involves several pick-up and drop-off points, you can add up to 25 coordinates (including the origin and destination) using the driving
profile or three coordinates using the driving-traffic
profile. These coordinates are treated as stops between the origin and destination in the order that you add them — the first waypoint is the origin and the second waypoint is the first stop:
let routeOptions = NavigationRouteOptions(waypoints: [
Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.77766, longitude: -122.43199)),
Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.77609, longitude: -122.43292)),
Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.77536, longitude: -122.43494)),
])
Directions.shared.calculate(routeOptions) { [weak self] (session, result) in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let response):
guard let route = response.routes?.first, let strongSelf = self else {
return
}
let navigationService = MapboxNavigationService(route: route, routeOptions: routeOptions,
simulating: simulationIsEnabled ? .always : .onPoorGPS)
let navigationOptions = NavigationOptions(navigationService: navigationService)
let navigationViewController = NavigationViewController(for: route, routeOptions: routeOptions, navigationOptions: navigationOptions)
navigationViewController.delegate = strongSelf
strongSelf.present(navigationViewController, animated: true, completion: nil)
}
}
Silent waypoints
The Waypoint.separatesLegs
property determines if a waypoint will be treated as a stop between legs or influence the route without specifically mentioning it in maneuver instructions.
By default Waypoint.separatesLegs
is equal to true
meaning the waypoint will appear in the resulting routes as a waypoint separating two legs, along with corresponding guidance instructions.
If you want to make sure that the route you request passes through the waypoint without specifically mentioning it, set Waypoint.separatesLegs
equal to false
.