项目作者: mapbox

项目描述 :
Address search and reverse geocoding in Swift or Objective-C on iOS, macOS, tvOS, and watchOS
高级语言: Swift
项目地址: git://github.com/mapbox/MapboxGeocoder.swift.git
创建时间: 2014-08-18T00:45:13Z
项目社区:https://github.com/mapbox/MapboxGeocoder.swift

开源协议:ISC License

下载


MapboxGeocoder

CircleCI
Carthage compatible
SPM compatible
CocoaPods

MapboxGeocoder.swift makes it easy to connect your iOS, macOS, tvOS, or watchOS application to the Mapbox Geocoding API. MapboxGeocoder.swift exposes the power of the Carmen geocoder through a simple API similar to Core Location’s CLGeocoder.

Note that use of the Geocoding API via MapboxGeocoder.swift is billed by API requests. For more information, see the Geocoding API pricing documentation.

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

Getting started

Specify the following dependency in your Carthage Cartfile:

  1. github "mapbox/MapboxGeocoder.swift" ~> 0.15

Or in your CocoaPods Podfile:

  1. pod 'MapboxGeocoder.swift', '~> 0.15'

Or in your Swift Package Manager Package.swift:

  1. .package(url: "https://github.com/mapbox/MapboxGeocoder.swift.git", from: "0.15.0")

Then import MapboxGeocoder or @import MapboxGeocoder;.

For Objective-C targets, it may be necessary to enable the ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES build setting.

This repository includes example applications written in both Swift and Objective-C showing use of the framework (as well as a comparison of writing apps in either language). The Mapbox API Documentation explains the underlying HTTP request and response format, as well as relevant limits that also apply when using this library.

System requirements

  • One of the following package managers:
    • CocoaPods 1.10 or above
    • Carthage 0.38 or above
    • Swift Package Manager 5.3 or above
  • Xcode 12 or above
  • One of the following operating systems:
    • iOS 12.0 or above
    • macOS 10.14 or above
    • tvOS 12.0 or above
    • watchOS 5.0 or above

Usage

You will need a Mapbox access token in order to use the API. If you’re already using the Mapbox Maps SDK for iOS or Mapbox Maps SDK for macOS, MapboxGeocoder.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) and Objective-C (main.m). For further details about each class and method, use the Quick Help feature inside Xcode.

Basics

The main geocoder class is Geocoder in Swift or MBGeocoder in Objective-C. Create a geocoder object using your access token:

  1. // main.swift
  2. import MapboxGeocoder
  3. let geocoder = Geocoder(accessToken: "<#your access token#>")
  1. // main.m
  2. @import MapboxGeocoder;
  3. MBGeocoder *geocoder = [[MBGeocoder alloc] initWithAccessToken:@"<#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 geocoder object:

  1. // main.swift
  2. let geocoder = Geocoder.shared
  1. // main.m
  2. MBGeocoder *geocoder = [MBGeocoder sharedGeocoder];

With the geocoder in hand, construct a geocode options object and pass it into the Geocoder.geocode(_:completionHandler:) method.

Forward geocoding

Forward geocoding takes a human-readable query, such as a place name or address, and produces any number of geographic coordinates that correspond to that query. To perform forward geocoding, use ForwardGeocodeOptions in Swift or MBForwardGeocodeOptions in Objective-C.

  1. // main.swift
  2. #if canImport(Contacts)
  3. import Contacts
  4. #endif
  5. let options = ForwardGeocodeOptions(query: "200 queen street")
  6. // To refine the search, you can set various properties on the options object.
  7. options.allowedISOCountryCodes = ["CA"]
  8. options.focalLocation = CLLocation(latitude: 45.3, longitude: -66.1)
  9. options.allowedScopes = [.address, .pointOfInterest]
  10. let task = geocoder.geocode(options) { (placemarks, attribution, error) in
  11. guard let placemark = placemarks?.first else {
  12. return
  13. }
  14. print(placemark.name)
  15. // 200 Queen St
  16. print(placemark.qualifiedName)
  17. // 200 Queen St, Saint John, New Brunswick E2L 2X1, Canada
  18. let coordinate = placemark.location.coordinate
  19. print("\(coordinate.latitude), \(coordinate.longitude)")
  20. // 45.270093, -66.050985
  21. #if canImport(Contacts)
  22. let formatter = CNPostalAddressFormatter()
  23. print(formatter.string(from: placemark.postalAddress!))
  24. // 200 Queen St
  25. // Saint John New Brunswick E2L 2X1
  26. // Canada
  27. #endif
  28. }
  1. // main.m
  2. #if !TARGET_OS_TV
  3. @import Contacts;
  4. #endif
  5. MBForwardGeocodeOptions *options = [[MBForwardGeocodeOptions alloc] initWithQuery:@"200 queen street"];
  6. // To refine the search, you can set various properties on the options object.
  7. options.allowedISOCountryCodes = @[@"CA"];
  8. options.focalLocation = [[CLLocation alloc] initWithLatitude:45.3 longitude:-66.1];
  9. options.allowedScopes = MBPlacemarkScopeAddress | MBPlacemarkScopePointOfInterest;
  10. NSURLSessionDataTask *task = [geocoder geocodeWithOptions:options
  11. completionHandler:^(NSArray<MBGeocodedPlacemark *> * _Nullable placemarks,
  12. NSString * _Nullable attribution,
  13. NSError * _Nullable error) {
  14. MBPlacemark *placemark = placemarks[0];
  15. NSLog(@"%@", placemark.name);
  16. // 200 Queen St
  17. NSLog(@"%@", placemark.qualifiedName);
  18. // 200 Queen St, Saint John, New Brunswick E2L 2X1, Canada
  19. CLLocationCoordinate2D coordinate = placemark.location.coordinate;
  20. NSLog(@"%f, %f", coordinate.latitude, coordinate.longitude);
  21. // 45.270093, -66.050985
  22. #if !TARGET_OS_TV
  23. CNPostalAddressFormatter *formatter = [[CNPostalAddressFormatter alloc] init];
  24. NSLog(@"%@", [formatter stringFromPostalAddress:placemark.postalAddress]);
  25. // 200 Queen St
  26. // Saint John New Brunswick E2L 2X1
  27. // Canada
  28. #endif
  29. }];

Reverse geocoding

Reverse geocoding takes a geographic coordinate and produces a hierarchy of places, often beginning with an address, that describes the coordinate’s location. To perform reverse geocoding, use ReverseGeocodeOptions in Swift or MBReverseGeocodeOptions in Objective-C.

  1. // main.swift
  2. let options = ReverseGeocodeOptions(coordinate: CLLocationCoordinate2D(latitude: 40.733, longitude: -73.989))
  3. // Or perhaps: ReverseGeocodeOptions(location: locationManager.location)
  4. let task = geocoder.geocode(options) { (placemarks, attribution, error) in
  5. guard let placemark = placemarks?.first else {
  6. return
  7. }
  8. print(placemark.imageName ?? "")
  9. // telephone
  10. print(placemark.genres?.joined(separator: ", ") ?? "")
  11. // computer, electronic
  12. print(placemark.administrativeRegion?.name ?? "")
  13. // New York
  14. print(placemark.administrativeRegion?.code ?? "")
  15. // US-NY
  16. print(placemark.place?.wikidataItemIdentifier ?? "")
  17. // Q60
  18. }
  1. // main.m
  2. MBReverseGeocodeOptions *options = [[MBReverseGeocodeOptions alloc] initWithCoordinate: CLLocationCoordinate2DMake(40.733, -73.989)];
  3. // Or perhaps: [[MBReverseGeocodeOptions alloc] initWithLocation:locationManager.location]
  4. NSURLSessionDataTask *task = [geocoder geocodeWithOptions:options
  5. completionHandler:^(NSArray<MBGeocodedPlacemark *> * _Nullable placemarks,
  6. NSString * _Nullable attribution,
  7. NSError * _Nullable error) {
  8. MBPlacemark *placemark = placemarks[0];
  9. NSLog(@"%@", placemark.imageName);
  10. // telephone
  11. NSLog(@"%@", [placemark.genres componentsJoinedByString:@", "]);
  12. // computer, electronic
  13. NSLog(@"%@", placemark.administrativeRegion.name);
  14. // New York
  15. NSLog(@"%@", placemark.administrativeRegion.code);
  16. // US-NY
  17. NSLog(@"%@", placemark.place.wikidataItemIdentifier);
  18. // Q60
  19. }];

Batch geocoding

With batch geocoding, you can perform up to 50 distinct forward or reverse geocoding requests simultaneously and store the results in a private database. Create a ForwardBatchGeocodingOptions or ReverseBatchGeocodingOptions object in Swift, or an MBForwardBatchGeocodingOptions or MBReverseBatchGeocodingOptions object in Objective-C, and pass it into the Geocoder.batchGeocode(_:completionHandler:) method.

  1. // main.swift
  2. let options = ForwardBatchGeocodeOptions(queries: ["skyline chili", "gold star chili"])
  3. options.focalLocation = locationManager.location
  4. options.allowedScopes = .pointOfInterest
  5. let task = geocoder.batchGeocode(options) { (placemarksByQuery, attributionsByQuery, error) in
  6. guard let placemarksByQuery = placemarksByQuery else {
  7. return
  8. }
  9. let nearestSkyline = placemarksByQuery[0][0].location
  10. let distanceToSkyline = nearestSkyline.distance(from: locationManager.location)
  11. let nearestGoldStar = placemarksByQuery[1][0].location
  12. let distanceToGoldStar = nearestGoldStar.distance(from: locationManager.location)
  13. let distance = LengthFormatter().string(fromMeters: min(distanceToSkyline, distanceToGoldStar))
  14. print("Found a chili parlor \(distance) away.")
  15. }
  1. // main.m
  2. MBForwardBatchGeocodeOptions *options = [[MBForwardBatchGeocodeOptions alloc] initWithQueries:@[@"skyline chili", @"gold star chili"]];
  3. options.focalLocation = locationManager.location;
  4. options.allowedScopes = MBPlacemarkScopePointOfInterest;
  5. NSURLSessionDataTask *task = [geocoder batchGeocodeWithOptions:options
  6. completionHandler:^(NSArray<NSArray<MBGeocodedPlacemark *> *> * _Nullable placemarksByQuery,
  7. NSArray<NSString *> * _Nullable attributionsByQuery,
  8. NSError * _Nullable error) {
  9. if (!placemarksByQuery) {
  10. return;
  11. }
  12. MBPlacemark *nearestSkyline = placemarksByQuery[0][0].location;
  13. CLLocationDistance distanceToSkyline = [nearestSkyline distanceFromLocation:locationManager.location];
  14. MBPlacemark *nearestGoldStar = placemarksByQuery[1][0].location;
  15. CLLocationDistance distanceToGoldStar = [nearestGoldStar distanceFromLocation:locationManager.location];
  16. NSString *distance = [NSLengthFormatter stringFromMeters:MIN(distanceToSkyline, distanceToGoldStar)];
  17. NSLog(@"Found a chili parlor %@ away.", distance);
  18. }];

Batch geocoding is available to Mapbox enterprise accounts. See the Mapbox Geocoding website for more information.

Tests

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

  1. carthage bootstrap
  2. open MapboxGeocoder.xcodeproj
  3. Switch to the “MapboxGeocoder iOS” scheme and go to Product ‣ Test.

Alternatively, open Package.swift in Xcode and go to Product ‣ Test, or run swift test on the command line.