MapboxDirections 2.14.0

MapboxDirections 2.14.0

Victor KononovMapbox 维护。



 
依赖
Polyline~> 5.0
Turf~> 2.8.0
 

Mapbox Directions for Swift

CircleCI Carthage compatible CocoaPods SPM compatible codecov

Mapbox Directions for Swift(之前名为 MapboxDirections.swift)使您能够轻松地将 iOS、macOS、tvOS、watchOS 或 Linux 应用程序连接到 Mapbox DirectionsMap Matching API。快速获取驾驶、骑行或步行路线,无论是单程还是多程,都使用类似 MapKit 的 MKDirections API 的简单界面。将 GPX 轨迹与 OpenStreetMap 道路网络匹配。Mapbox Directions 和 Map Matching API 由 OSRMValhalla 路由引擎提供支持。更多信息,请查看 Mapbox Navigation 主页。

Mapbox Directions 与 MapboxGeocoder.swiftMapboxStatic.swift、iOS 的 Mapbox Navigation SDK 以及 iOS 的 Mapbox Maps SDK 或 macOS SDK 结合得很好。

入门

在您的 Carthage Cartfile 中指定以下依赖项

# Latest stable release
github "mapbox/mapbox-directions-swift" ~> 2.10
# Latest prerelease
github "mapbox/mapbox-directions-swift" "v2.10.0-rc.2"

或您的 CocoaPods Podfile 中

# Latest stable release
pod 'MapboxDirections', '~> 2.10'
# Latest prerelease
pod 'MapboxDirections', :git => 'https://github.com/mapbox/mapbox-directions-swift.git', :tag => 'v2.10.0-rc.2'

或您的 Swift Package Manager Package.swift 中

// Latest stable release
.package(name: "MapboxDirections", url: "https://github.com/mapbox/mapbox-directions-swift.git", from: "2.10.0")
// Latest prerelease
.package(name: "MapboxDirections", url: "https://github.com/mapbox/mapbox-directions-swift.git", .exact("2.10.0-rc.2"))

然后 import MapboxDirections

该存储库包含一个示例应用程序,演示了如何使用该框架。要运行它,您需要使用 0.19 或更高版本的 Carthage 安装依赖项。详细的文档可在 Mapbox API 文档 中找到。

系统需求

  • 以下包管理器之一
    • CocoaPods 1.10 或更高版本
    • Carthage 0.38 或更高版本
    • Swift Package Manager 5.5 或更高版本
  • Xcode 13 或更高版本
  • 以下操作系统之一
    • iOS 12.0 或更高版本
    • macOS 10.14 或更高版本
    • tvOS 12.0 或更高版本
    • watchOS 5.0 或更高版本
    • 支持 Swift 的任何 Linux 发行版

v0.30.0 是 MapboxDirections.swift 支持最低部署目标为 iOS 9.x、macOS 10.11.x、tvOS 9.x 或 watchOS 2.x 的最后一个版本。v0.30.0 同样是该版本最后一个与 Objective-C 或 AppleScript 代码相兼容的版本。

使用方法

API 参考

为了使用 API,您需要一个 Mapbox 访问令牌。如果您已在使用 Mapbox Maps SDK for iOSmacOS SDK,只要您已经将访问令牌放置在应用程序的 Info.plist 文件中的 MBXAccessToken 键,Mapbox Directions 会自动识别您的访问令牌。

以下示例均使用 Swift 提供的代码(标记为 main.swift)。有关更多详细信息,请参阅 发行版 中提供的文档。

计算地点间路径

主要方向类是 Directions. 使用您的访问令牌创建一个方向对象

// main.swift
import MapboxDirections

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

或者,您可以将访问令牌放置在应用程序的 Info.plist 文件中的 MBXAccessToken 键,然后使用共享的方向对象

// main.swift
let directions = Directions.shared

准备好方向对象后,构造一个 RouteOptions 对象并将其传递到 Directions.calculate(_:completionHandler:) 方法。

// 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) { (session, result) in
    switch result {
    case .failure(let error):
        print("Error calculating directions: \(error)")
    case .success(let response):
        guard let route = response.routes?.first, let leg = route.legs.first else {
            return
        }

        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)")
        }
    }
}

此库默认使用 Mapbox Directions API 版本 5。

将轨迹匹配到道路网络

如果您有GPX轨迹或其他GPS导出的位置数据,可以使用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) { (session, result) in
    switch result {
    case .failure(let error):
        print("Error matching coordinates: \(error)")
    case .success(let response):
        guard let match = response.matches?.first, let leg = match.legs.first else {
            return
        }

        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)")
        }
    }
}

您还可以使用Directions.calculateRoutes(matching:completionHandler:)方法获取适合在任何地方使用标准Directions API响应的路线对象。

创建等时线地图

使用Isochrone API告诉用户他们可以在特定距离或时间内从给定位置旅行多远。等时线使用与Directions相同的访问令牌初始化。一旦配置了这些,您需要填写IsochronesOptions参数来计算所需的GeoJSON。

let isochrones = Isochrones(credentials: Credentials(accessToken: "<#your access token#>"))

let isochroneOptions = IsochroneOptions(centerCoordinate: CLLocationCoordinate2D(latitude: 45.52, longitude: -122.681944),
                                        contours: .byDistances([
                                            .init(value: 500, unit: .meters,     color: .orange),
                                            .init(value: 1,   unit: .kilometers, color: .red)
                                        ]))

isochrones.calculate(isochroneOptions) { session, result in
    if case .success(let response) = result {
         print(response)
    }
}

检索距离或时长矩阵

使用Matrix API查看许多点之间的旅行时间或距离。Matrix使用与Directions相同的访问令牌初始化。一旦配置了这些,您需要填写MatrixOptions参数来计算所需的矩阵。

let matrix = Matrix(credentials: Credentials(accessToken: "<#your access token#>")
let waypoints = [
    Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.751668, longitude: -122.418408), name: "Mission Street"),
    Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.755184, longitude: -122.422959), name: "22nd Street"),
    Waypoint(coordinate: CLLocationCoordinate2D(latitude: 37.759695, longitude: -122.426911))
]
let matrixOptions = MatrixOptions(sources: waypoints, destinations: waypoints, profileIdentifier: .automobile)
matrix.calculate(matrixOptions) { session, result in
    if case .success(let response) = result,
       let expectedTravelTime = response.travelTime(from: 0, to: 1) {
        print("Expected route duration from '\(waypoints[0].name)' to '\(waypoints[1].name)' is \(expectedTravelTime / 60) minutes.")
    }
}

与其他Mapbox库一起使用

在地图上绘制路线

使用Mapbox Maps SDK for iOSmacOS SDK,您可以在地图上轻松地绘制路线。

// 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)
}

展示实时导航界面

Mapbox Navigation SDK for iOS 提供了一个完整的用户界面,用于显示由 MapboxDirections 提供的路线路径的实时导航。

在地图快照中绘制同心圆轮廓

MapboxStatic.swift 提供了一种简单的方法,在地图上画同心圆轮廓。

// main.swift
import MapboxStatic
import MapboxDirections

let centerCoordinate = CLLocationCoordinate2D(latitude: 45.52, longitude: -122.681944)
let accessToken = "<#your access token#>"

// Setup snapshot parameters
let camera = SnapshotCamera(
    lookingAtCenter: centerCoordinate,
    zoomLevel: 12)
let options = SnapshotOptions(
    styleURL: URL(string: "<#your mapbox: style URL#>")!,
    camera: camera,
    size: CGSize(width: 200, height: 200))

// Request Isochrone contour to draw on a map
let isochrones = Isochrones(credentials: Credentials(accessToken: accessToken))
isochrones.calculate(IsochroneOptions(centerCoordinate: centerCoordinate,
                                      contours: .byDistances([.init(value: 500, unit: .meters)]))) { session, result in
    if case .success(let response) = result {
        // Serialize the geoJSON
        let encoder = JSONEncoder()
        let data = try! encoder.encode(response)
        let geoJSONString = String(data: data, encoding: .utf8)!
        let geoJSONOverlay = GeoJSON(objectString: geoJSONString)

        // Feed resulting geoJSON to snapshot options
        options.overlays.append(geoJSONOverlay)

        let snapshot = Snapshot(
            options: options,
            accessToken: accessToken)

        // Display the result!
        drawImage(snapshot.image)
    }
}

Directions CLI

MapboxDirectionsCLI 是一个命令行工具,旨在将任意的、JSON 格式的 Directions 或 Map Matching API 响应通过模型对象来回传递,并回到 JSON。这在各种场景下都很有用,包括测试目的和设计更复杂的 API 响应处理管道。它作为 Swift 包提供。

使用 SPM 构建 MapboxDirectionsCLI

  1. swift build

要运行(如果尚未构建)并查看 MapboxDirectionsCLI 的用法

  1. swift run mapbox-directions-swift -h

有关详细信息,请参阅 MapboxDirectionsCLI 文档

定价

调用 Directions API 的 API 调用按请求单独计费。请参阅当前费率的信息 定价信息定价页面