> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/ios/navigation/v2/llms.txt)

# Route generation

The routes used in the Navigation SDK are generated by the [Mapbox Directions API](https://docs.mapbox.com/api/navigation/#directions). 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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Route.html) object using [`RoutingProvider`](https://docs.mapbox.com/ios/navigation/api/2.21.0/Protocols/RoutingProvider.html) with its default implementation [`MapboxRoutingProvider`](https://docs.mapbox.com/ios/navigation/api/2.21.0/Classes/MapboxRoutingProvider.html). In most cases, you'll also use the [`NavigationRouteOptions`](https://docs.mapbox.com/ios/navigation/api/2.21.0/Classes/NavigationRouteOptions.html) class (a subclass of Mapbox Directions for Swift's [`RouteOptions`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/RouteOptions.html) 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](https://docs.mapbox.com/api/navigation/#retrieve-directions) 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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)headingAccuracy) in more detail.

> **Note: Default heading**
> 
> The system sets the default value for `heading` to −1°, meaning it will not take the heading into account 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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)heading) to use [`CLHeading.trueHeading`](https://developer.apple.com/documentation/corelocation/clheading/1423568-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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)headingAccuracy) to specify the range of degrees by which a route can deviate from the `Waypoint.heading` angle. Though `Waypoint.headingAccuracy` and [`CLHeading.headingAccuracy`](https://developer.apple.com/documentation/corelocation/clheading/1423705-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.

```swift
if let latestLocation = navigationMapView.mapView.location.latestLocation,
   let heading = latestLocation.heading {
    let location = latestLocation.internalLocation
    let userWaypoint = Waypoint(location: location)
    userWaypoint.heading = heading.trueHeading
    userWaypoint.headingAccuracy = 90.0
}
```

### 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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)heading%3E) to use [`CLLocation.course`](https://developer.apple.com/documentation/corelocation/cllocation/1423832-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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)headingAccuracy).

This can be applied to any waypoint including the origin, stops along the route, and the destination.

```swift
if let location = navigationMapView.mapView.location.latestLocation?.internalLocation {
    let userWaypoint = Waypoint(location: location)
    userWaypoint.heading = location.course
    userWaypoint.headingAccuracy = 90.0
}
```

## 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`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)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](https://docs.mapbox.com/api/navigation/#retrieve-directions) query parameter in the Mapbox Directions and Map Matching APIs.

```swift
if let location = navigationMapView.mapView.location.latestLocation?.internalLocation {
    let userWaypoint = Waypoint(location: location)
    userWaypoint.allowsArrivingOnOppositeSide = false
}
```

## Include multiple stops

To request a route, create a property with a [`MapboxRoutingProvider`](https://docs.mapbox.com/ios/navigation/api/2.21.0/Classes/MapboxRoutingProvider.html) instance:

```swift
let routeProvider = MapboxRoutingProvider()
```

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:

```swift
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)),
])

routeProvider.calculateRoutes(options: routeOptions) { [weak self] 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(
            indexedRouteResponse: indexedRouteResponse,
            credentials: NavigationSettings.shared.directions.credentials,
            simulating: .always
        )
        let navigationOptions = NavigationOptions(navigationService: navigationService)
        let navigationViewController = NavigationViewController(for: indexedRouteResponse, navigationOptions: navigationOptions)
        navigationViewController.delegate = strongSelf

        strongSelf.present(navigationViewController, animated: true, completion: nil)
    }
}
```

### Silent waypoints

The [`Waypoint.separatesLegs`](https://docs.mapbox.com/ios/directions/api/2.14.4/Classes/Waypoint.html#/c:@M@MapboxDirections@objc(cs)MBWaypoint(py)separatesLegs) property determines if a waypoint will be treated as a stop between [legs](https://docs.mapbox.com/ios/navigation/v2/guides/turn-by-turn-navigation/route-progress/#information-about-progress) 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`.

### Optimized routes

If you want to generate a route that will arrive at the waypoints in the fastest order (not necessarily in a specific order), see the [Optimization API documentation](https://docs.mapbox.com/api/navigation/#optimization).

### Route generation in offline mode

`MapboxRoutingProvider` can be configured by [`Source`](https://docs.mapbox.com/ios/navigation/api/2.21.0/Classes/MapboxRoutingProvider/Source.html) to load online only, offline only, and online with fallback to offline routes. By default, the `hybrid` code is used.

```swift
let routeProvider = MapboxRoutingProvider(.offline)
```

## More about route generation

-   [Localization](https://docs.mapbox.com/ios/navigation/v2/guides/system-integration/localization-and-internationalization/): Customize the language and units of measurement returned for both text and voice instructions or use the language preferences set on the device.
-   [Free-drive navigation](https://docs.mapbox.com/ios/navigation/v2/guides/free-drive/): Accurately display the user's location outside of turn-by-turn navigation.