Skip to content

Optimind-llc/MapboxDirections.swift

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,006 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MapboxDirections

CircleCI Carthage compatible CocoaPods codecov

MapboxDirections.swift makes it easy to connect your iOS, macOS, tvOS, or watchOS application to the Mapbox Directions and Map Matching APIs. Quickly get driving, cycling, or walking directions, whether the trip is nonstop or it has multiple stopping points, all using a simple interface reminiscent of MapKit’s MKDirections API. Fit a GPX trace to the OpenStreetMap road network. The Mapbox Directions and Map Matching APIs are powered by the OSRM and Valhalla routing engines. For more information, see the Mapbox Navigation homepage.

MapboxDirections.swift pairs well with MapboxGeocoder.swift, MapboxStatic.swift, the Mapbox Navigation SDK for iOS, and the Mapbox Maps SDK for iOS or macOS SDK.

Getting started

Specify the following dependency in your Carthage Cartfile:

github "mapbox/MapboxDirections.swift" ~> 0.30

Or in your CocoaPods Podfile:

pod 'MapboxDirections.swift', '~> 0.30'

Or in your Swift Package Manager Package.swift:

.package(url: "https://github.com/mapbox/MapboxDirections.swift.git", from: "0.30.0")

Then import MapboxDirections.

This library supports a minimum deployment target of iOS 10.0 or above, macOS 10.12.0 or above, tvOS 10.0 or above, or watchOS 2.0 or above. v0.30.0 is the last release of MapboxDirections.swift that supports a minimum deployment target of iOS 9.x, macOS 10.11.x, tvOS 9.x, or watchOS 2.x.

This repository contains an example application that demonstrates how to use the framework. To run it, you need to use Carthage 0.19 or above to install the dependencies. Detailed documentation is available in the Mapbox API Documentation.

Usage

API reference

You’ll need a Mapbox access token in order to use the API. If you’re already using the Mapbox Maps SDK for iOS or macOS SDK, MapboxDirections.swift automatically recognizes your access token, as long as you’ve placed it in the MGLMapboxAccessToken key of your application’s Info.plist file.

The examples below are each provided in Swift (denoted with main.swift), For further details, see the MapboxDirections.swift API reference.

Calculating directions between locations

The main directions class is Directions. Create a directions object using your access token:

// main.swift
import MapboxDirections

let directions = Directions(accessToken: "<#your access token#>")

Alternatively, you can place your access token in the MGLMapboxAccessToken key of your application’s Info.plist file, then use the shared directions object:

// main.swift
let directions = Directions.shared

With the directions object in hand, construct a RouteOptions object and pass it into the Directions.calculate(_:completionHandler:) method.

// main.swift

let waypoints = [
    Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.9131752, longitude: -77.0324047), name: "Mapbox"),
    Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.8977, longitude: -77.0365), name: "White House"),
]
let options = RouteOptions(waypoints: waypoints, profileIdentifier: .automobileAvoidingTraffic)
options.includesSteps = true

let task = directions.calculate(options) { (waypoints, routes, error) in
    guard error == nil else {
        print("Error calculating directions: \(error!)")
        return
    }

    if let route = routes?.first, let leg = route.legs.first {
        print("Route via \(leg):")

        let distanceFormatter = LengthFormatter()
        let formattedDistance = distanceFormatter.string(fromMeters: route.distance)

        let travelTimeFormatter = DateComponentsFormatter()
        travelTimeFormatter.unitsStyle = .short
        let formattedTravelTime = travelTimeFormatter.string(from: route.expectedTravelTime)

        print("Distance: \(formattedDistance); ETA: \(formattedTravelTime!)")

        for step in leg.steps {
            print("\(step.instructions)")
            let formattedDistance = distanceFormatter.string(fromMeters: step.distance)
            print("\(formattedDistance)")
        }
    }
}

This library uses version 5 of the Mapbox Directions API by default. To use version 4 instead, replace RouteOptions with RouteOptionsV4.

Matching a trace to the road network

If you have a GPX trace or other GPS-derived location data, you can clean up the data and fit it to the road network using the Map Matching API:

// main.swift

let coordinates = [
    CLLocationCoordinate2D(latitude: 32.712041, longitude: -117.172836),
    CLLocationCoordinate2D(latitude: 32.712256, longitude: -117.17291),
    CLLocationCoordinate2D(latitude: 32.712444, longitude: -117.17292),
    CLLocationCoordinate2D(latitude: 32.71257,  longitude: -117.172922),
    CLLocationCoordinate2D(latitude: 32.7126,   longitude: -117.172985),
    CLLocationCoordinate2D(latitude: 32.712597, longitude: -117.173143),
    CLLocationCoordinate2D(latitude: 32.712546, longitude: -117.173345)
]

let options = MatchOptions(coordinates: coordinates)
options.includesSteps = true

let task = directions.calculate(options) { (matches, error) in
    guard error == nil else {
        print("Error matching coordinates: \(error!)")
        return
    }

    if let match = matches?.first, let leg = match.legs.first {
        print("Match via \(leg):")

        let distanceFormatter = LengthFormatter()
        let formattedDistance = distanceFormatter.string(fromMeters: match.distance)

        let travelTimeFormatter = DateComponentsFormatter()
        travelTimeFormatter.unitsStyle = .short
        let formattedTravelTime = travelTimeFormatter.string(from: match.expectedTravelTime)

        print("Distance: \(formattedDistance); ETA: \(formattedTravelTime!)")

        for step in leg.steps {
            print("\(step.instructions)")
            let formattedDistance = distanceFormatter.string(fromMeters: step.distance)
            print("\(formattedDistance)")
        }
    }
}

You can also use the Directions.calculateRoutes(matching:completionHandler:) method to get Route objects suitable for use anywhere a standard Directions API response would be used.

Usage with other Mapbox libraries

Drawing the route on a map

With the Mapbox Maps SDK for iOS or macOS SDK, you can easily draw the route on a map:

// main.swift

if var routeCoordinates = route.shape?.coordinates, routeCoordinates.count > 0 {
    // Convert the route’s coordinates into a polyline.
    let routeLine = MGLPolyline(coordinates: &routeCoordinates, count: UInt(routeCoordinates.count))

    // Add the polyline to the map.
    mapView.addAnnotation(routeLine)
    
    // Fit the viewport to the polyline.
    let camera = mapView.cameraThatFitsShape(routeLine, direction: 0, edgePadding: .zero)
    mapView.setCamera(camera, animated: true)
}

Displaying a turn-by-turn navigation interface

See the Mapbox Navigation SDK for iOS documentation for usage examples.

Tests

To run the included unit tests, you need to use Carthage 0.19 or above to install the dependencies.

  1. carthage build --platform iOS
  2. open MapboxDirections.xcodeproj
  3. Go to Product ‣ Test.

About

Traffic-aware directions and map matching in Swift on iOS, macOS, tvOS, and watchOS

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Swift 98.6%
  • Other 1.4%