MapboxGeocoder
MapboxGeocoder.swift 可以轻松地将您的 iOS、macOS、tvOS 或 watchOS 应用程序连接到 Mapbox 地理编码 API。MapboxGeocoder.swift 通过类似于 Core Location 的 CLGeocoder 的简单 API 提供了 Carmen 地理编码器的功能。
请注意,通过 MapboxGeocoder.swift 使用地理编码 API 会按 API 请求计费。有关更多信息,请参阅 地理编码 API 定价文档。
MapboxGeocoder.swift 与 Mapbox Directions for Swift、MapboxStatic.swift 以及 iOS 或 macOS 的 Mapbox Maps SDK 或 Mapbox Maps SDK for macOS 互相配合良好。
入门
在您的 Carthage Cartfile 中指定以下依赖项
github "mapbox/MapboxGeocoder.swift" ~> 0.14
或在您的 CocoaPods Podfile 中
pod 'MapboxGeocoder.swift', '~> 0.14'
或在您的 Swift 包管理器 Package.swift 中
.package(url: "https://github.com/mapbox/MapboxGeocoder.swift.git", from: "0.14.0")
然后使用 import MapboxGeocoder
或 @import MapboxGeocoder;
。
对于 Objective-C 目标,可能需要启用 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
编译设置。
该仓库包含了以 Swift 和 Objective-C 编写的示例应用程序,展示了如何使用该框架(以及两种语言编写应用程序的比较)。Mapbox API 文档解释了底层的 HTTP 请求和响应格式,以及当使用这个库时也适用的相关限制。
系统需求
- 以下任意一个包管理器
- CocoaPods(如果使用 Xcode 12,则 CocoaPods 1.10 或以上版本)
- Carthage 0.19 或以上(如果使用 Xcode 12,请运行此脚本代替
carthage
) - Swift Package Manager 5.3 或以上
- Xcode 11 或以上(使用 Swift Package Manager 的话则需要 Xcode 12 或以上版本)
- 以下任意一个操作系统
- iOS 10.0 或以上
- macOS 10.12.0 或以上
- tvOS 10.0 或以上
- watchOS 3.0 或以上
使用方法
您需要一个Mapbox 访问令牌才能使用该 API。如果您已经使用Mapbox Maps SDK for iOS 或 Mapbox Maps SDK for macOS,则 MapboxGeocoder.swift 会自动识别您的访问令牌,只要您已将其放置在应用程序的 Info.plist 文件中的 MGLMapboxAccessToken
键中。
下面的示例都是 Swift(以 main.swift
标识)和 Objective-C(以 main.m
标识)。有关每个类和方法的详细信息,请使用 Xcode 中的快速帮助功能。
基础知识
主地理编码类在 Swift 中为 Geocoder,在 Objective-C 中为 MBGeocoder。使用您的访问令牌创建地理编码对象
// main.swift
import MapboxGeocoder
let geocoder = Geocoder(accessToken: "<#your access token#>")
// main.m
@import MapboxGeocoder;
MBGeocoder *geocoder = [[MBGeocoder alloc] initWithAccessToken:@"<#your access token#>"];
或者,您也可以将访问令牌放置在应用程序 Info.plist 文件中的 MGLMapboxAccessToken
键中,然后使用共享的地理编码对象
// main.swift
let geocoder = Geocoder.shared
// main.m
MBGeocoder *geocoder = [MBGeocoder sharedGeocoder];
有了地理编码对象后,构建一个地理编码选项对象,并将其传递给 Geocoder.geocode(_:completionHandler:)
方法。
正向地理编码
正向地理编码接收一个人可读的查询,例如地名或地址,并生成与该查询相对应的任意数量的地理坐标。为了执行正向地理编码,请使用Swift中的ForwardGeocodeOptions或Objective-C中的MBForwardGeocodeOptions。
// main.swift
#if canImport(Contacts)
import Contacts
#endif
let options = ForwardGeocodeOptions(query: "200 queen street")
// To refine the search, you can set various properties on the options object.
options.allowedISOCountryCodes = ["CA"]
options.focalLocation = CLLocation(latitude: 45.3, longitude: -66.1)
options.allowedScopes = [.address, .pointOfInterest]
let task = geocoder.geocode(options) { (placemarks, attribution, error) in
guard let placemark = placemarks?.first else {
return
}
print(placemark.name)
// 200 Queen St
print(placemark.qualifiedName)
// 200 Queen St, Saint John, New Brunswick E2L 2X1, Canada
let coordinate = placemark.location.coordinate
print("\(coordinate.latitude), \(coordinate.longitude)")
// 45.270093, -66.050985
#if canImport(Contacts)
let formatter = CNPostalAddressFormatter()
print(formatter.string(from: placemark.postalAddress!))
// 200 Queen St
// Saint John New Brunswick E2L 2X1
// Canada
#endif
}
// main.m
#if !TARGET_OS_TV
@import Contacts;
#endif
MBForwardGeocodeOptions *options = [[MBForwardGeocodeOptions alloc] initWithQuery:@"200 queen street"];
// To refine the search, you can set various properties on the options object.
options.allowedISOCountryCodes = @[@"CA"];
options.focalLocation = [[CLLocation alloc] initWithLatitude:45.3 longitude:-66.1];
options.allowedScopes = MBPlacemarkScopeAddress | MBPlacemarkScopePointOfInterest;
NSURLSessionDataTask *task = [geocoder geocodeWithOptions:options
completionHandler:^(NSArray<MBGeocodedPlacemark *> * _Nullable placemarks,
NSString * _Nullable attribution,
NSError * _Nullable error) {
MBPlacemark *placemark = placemarks[0];
NSLog(@"%@", placemark.name);
// 200 Queen St
NSLog(@"%@", placemark.qualifiedName);
// 200 Queen St, Saint John, New Brunswick E2L 2X1, Canada
CLLocationCoordinate2D coordinate = placemark.location.coordinate;
NSLog(@"%f, %f", coordinate.latitude, coordinate.longitude);
// 45.270093, -66.050985
#if !TARGET_OS_TV
CNPostalAddressFormatter *formatter = [[CNPostalAddressFormatter alloc] init];
NSLog(@"%@", [formatter stringFromPostalAddress:placemark.postalAddress]);
// 200 Queen St
// Saint John New Brunswick E2L 2X1
// Canada
#endif
}];
反向地理编码
反向地理编码接收地理坐标并生成一个描述坐标位置的地方层次结构,通常从地址开始。为了执行反向地理编码,请使用Swift中的ReverseGeocodeOptions或Objective-C中的MBReverseGeocodeOptions。
// main.swift
let options = ReverseGeocodeOptions(coordinate: CLLocationCoordinate2D(latitude: 40.733, longitude: -73.989))
// Or perhaps: ReverseGeocodeOptions(location: locationManager.location)
let task = geocoder.geocode(options) { (placemarks, attribution, error) in
guard let placemark = placemarks?.first else {
return
}
print(placemark.imageName ?? "")
// telephone
print(placemark.genres?.joined(separator: ", ") ?? "")
// computer, electronic
print(placemark.administrativeRegion?.name ?? "")
// New York
print(placemark.administrativeRegion?.code ?? "")
// US-NY
print(placemark.place?.wikidataItemIdentifier ?? "")
// Q60
}
// main.m
MBReverseGeocodeOptions *options = [[MBReverseGeocodeOptions alloc] initWithCoordinate: CLLocationCoordinate2DMake(40.733, -73.989)];
// Or perhaps: [[MBReverseGeocodeOptions alloc] initWithLocation:locationManager.location]
NSURLSessionDataTask *task = [geocoder geocodeWithOptions:options
completionHandler:^(NSArray<MBGeocodedPlacemark *> * _Nullable placemarks,
NSString * _Nullable attribution,
NSError * _Nullable error) {
MBPlacemark *placemark = placemarks[0];
NSLog(@"%@", placemark.imageName);
// telephone
NSLog(@"%@", [placemark.genres componentsJoinedByString:@", "]);
// computer, electronic
NSLog(@"%@", placemark.administrativeRegion.name);
// New York
NSLog(@"%@", placemark.administrativeRegion.code);
// US-NY
NSLog(@"%@", placemark.place.wikidataItemIdentifier);
// Q60
}];
批量地理编码
使用批量地理编码,您可以同时执行最多50个不同的正向或反向地理编码请求并将结果存储在私有数据库中。在Swift中创建ForwardBatchGeocodingOptions对象,或在Objective-C中创建MBForwardBatchGeocodingOptions或MBReverseBatchGeocodingOptions对象,并将其传递给Geocoder.batchGeocode(_:completionHandler:)
方法。
// main.swift
let options = ForwardBatchGeocodeOptions(queries: ["skyline chili", "gold star chili"])
options.focalLocation = locationManager.location
options.allowedScopes = .pointOfInterest
let task = geocoder.batchGeocode(options) { (placemarksByQuery, attributionsByQuery, error) in
guard let placemarksByQuery = placemarksByQuery else {
return
}
let nearestSkyline = placemarksByQuery[0][0].location
let distanceToSkyline = nearestSkyline.distance(from: locationManager.location)
let nearestGoldStar = placemarksByQuery[1][0].location
let distanceToGoldStar = nearestGoldStar.distance(from: locationManager.location)
let distance = LengthFormatter().string(fromMeters: min(distanceToSkyline, distanceToGoldStar))
print("Found a chili parlor \(distance) away.")
}
// main.m
MBForwardBatchGeocodeOptions *options = [[MBForwardBatchGeocodeOptions alloc] initWithQueries:@[@"skyline chili", @"gold star chili"]];
options.focalLocation = locationManager.location;
options.allowedScopes = MBPlacemarkScopePointOfInterest;
NSURLSessionDataTask *task = [geocoder batchGeocodeWithOptions:options
completionHandler:^(NSArray<NSArray<MBGeocodedPlacemark *> *> * _Nullable placemarksByQuery,
NSArray<NSString *> * _Nullable attributionsByQuery,
NSError * _Nullable error) {
if (!placemarksByQuery) {
return;
}
MBPlacemark *nearestSkyline = placemarksByQuery[0][0].location;
CLLocationDistance distanceToSkyline = [nearestSkyline distanceFromLocation:locationManager.location];
MBPlacemark *nearestGoldStar = placemarksByQuery[1][0].location;
CLLocationDistance distanceToGoldStar = [nearestGoldStar distanceFromLocation:locationManager.location];
NSString *distance = [NSLengthFormatter stringFromMeters:MIN(distanceToSkyline, distanceToGoldStar)];
NSLog(@"Found a chili parlor %@ away.", distance);
}];
批量地理编码适用于Mapbox企业账户。更多详细信息,请参阅Mapbox地理编码网站。
测试
要运行包含的单元测试,您需要使用0.19或以上版本的Carthage安装依赖项。
carthage bootstrap
在Xcode中打开MapboxGeocoder.xcodeproj
- 切换到“MapboxGeocoder iOS”方案,然后转到Product -> Test。
或者,在Xcode中打开Package.swift,然后转到Product -> Test,或者在命令行上运行swift test
。