Mapbox Directions for Swift
Mapbox Directions for Swift(之前名为 MapboxDirections.swift)使您能够轻松地将 iOS、macOS、tvOS、watchOS 或 Linux 应用程序连接到 Mapbox Directions 和 Map Matching API。快速获取驾驶、骑行或步行路线,无论是单程还是多程,都使用类似 MapKit 的 MKDirections
API 的简单界面。将 GPX 轨迹与 OpenStreetMap 道路网络匹配。Mapbox Directions 和 Map Matching API 由 OSRM 和 Valhalla 路由引擎提供支持。更多信息,请查看 Mapbox Navigation 主页。
Mapbox Directions 与 MapboxGeocoder.swift、MapboxStatic.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,您需要一个 Mapbox 访问令牌。如果您已在使用 Mapbox Maps SDK for iOS 或 macOS 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 iOS或macOS 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
swift build
要运行(如果尚未构建)并查看 MapboxDirectionsCLI
的用法
swift run mapbox-directions-swift -h
有关详细信息,请参阅 MapboxDirectionsCLI 文档。