MapboxDirections-pre 2.11.0-rc.1

MapboxDirections-pre 2.11.0-rc.1

MapboxVictor KononovAlexander AzarovAliaksandr Bialiauski 维护。



 
依赖项
Polyline~> 5.0
Turf~> 2.6.1
 

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.swiftiOS 的 Mapbox Navigation SDK 以及 iOS 的 Mapbox Maps SDKmacOS SDK 一起使用效果良好。

入门

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

# Latest stable release
github "mapbox/mapbox-directions-swift" ~> 2.9
# Latest prerelease
github "mapbox/mapbox-directions-swift" "v2.11.0-rc.1"

或者在你的 CocoaPods Podfile 中

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

或者在你的 Swift Package Manager Package.swift 中

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

然后 import MapboxDirections

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

系统需求

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

0.30.0 是 MapboxDirections.swift 最后一个支持最小部署目标为 iOS 9.x、macOS 10.11.x、tvOS 9.x 或 watchOS 2.x 的版本。0.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

拿着 directions 对象,构造一个 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 响应类似的路由对象。

创建等时线地图

使用等时线 API 告诉用户,他们可以在给定位置一定距离或时间内走多远。 Isochrone 使用与 Directions 相同的访问令牌初始化。设置好后,需要填写 IsochroneOptions 参数来计算所需的 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 的一一请求进行计费。请查阅 价格信息价格页面 了解当前费用。