将坐标转换为城市名称?

如何使用MapKit从坐标获取地址?

我有这个代码,当长按在地图上它获得的坐标:

func didLongPressMap(sender: UILongPressGestureRecognizer) { if sender.state == UIGestureRecognizerState.Began { let touchPoint = sender.locationInView(self.mapView) let touchCoordinate = self.mapView.convertPoint(touchPoint, toCoordinateFromView: self.mapView) var annotation = MKPointAnnotation() annotation.coordinate = touchCoordinate annotation.title = "Your position" self.mapView.addAnnotation(annotation) //drops the pin println("lat: \(touchCoordinate.latitude)") var num = (touchCoordinate.latitude as NSNumber).floatValue var formatter = NSNumberFormatter() formatter.maximumFractionDigits = 4 formatter.minimumFractionDigits = 4 var str = formatter.stringFromNumber(num) println("long: \(touchCoordinate.longitude)") var num1 = (touchCoordinate.longitude as NSNumber).floatValue var formatter1 = NSNumberFormatter() formatter1.maximumFractionDigits = 4 formatter1.minimumFractionDigits = 4 var str1 = formatter1.stringFromNumber(num1) self.adressLoLa.text = "\(num),\(num1)" } } 

我想在annotation.title打印。 annotation.title的完整地址(街道,城市,邮编,国家)。


SWIFT 2.1:编辑


MapKit框架确实提供了一种从坐标获取地址细节的方法。

您需要使用地图工具包的反向地理编码CLGeocoder类用于从位置(坐标)获取地址和地址的位置。 reverseGeocodeLocation方法将从坐标返回地址细节。

此方法接受CLLocation作为参数并返回包含地址字典的CLPlacemark

所以现在上面的方法会更新为:

 func didLongPressMap(sender: UILongPressGestureRecognizer) { if sender.state == UIGestureRecognizerState.began { let touchPoint = sender.location(in: mapView) let touchCoordinate = mapView.convert(touchPoint, toCoordinateFrom: self.mapView) let annotation = MKPointAnnotation() annotation.coordinate = touchCoordinate annotation.title = "Your position" mapView.addAnnotation(annotation) //drops the pin print("lat: \(touchCoordinate.latitude)") let num = touchCoordinate.latitude as NSNumber let formatter = NumberFormatter() formatter.maximumFractionDigits = 4 formatter.minimumFractionDigits = 4 let str = formatter.string(from: num) print("long: \(touchCoordinate.longitude)") let num1 = touchCoordinate.longitude as NSNumber let formatter1 = NumberFormatter() formatter1.maximumFractionDigits = 4 formatter1.minimumFractionDigits = 4 let str1 = formatter1.string(from: num1) adressLoLa.text = "\(num),\(num1)" // Add below code to get address for touch coordinates. let geoCoder = CLGeocoder() let location = CLLocation(latitude: touchCoordinate.latitude, longitude: touchCoordinate.longitude) geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in // Place details var placeMark: CLPlacemark! placeMark = placemarks?[0] // Address dictionary print(placeMark.addressDictionary as Any) // Location name if let locationName = placeMark.addressDictionary!["Name"] as? NSString { print(locationName) } // Street address if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString { print(street) } // City if let city = placeMark.addressDictionary!["City"] as? NSString { print(city) } // Zip code if let zip = placeMark.addressDictionary!["ZIP"] as? NSString { print(zip) } // Country if let country = placeMark.addressDictionary!["Country"] as? NSString { print(country) } }) } } 

欲了解更多地址详情,请浏览CLPlacemark课程。 你会在addressDictionary部分find更多的细节。

Swift 3Swift 4

首先你需要设置津贴来接收用户的GPS在info.plist

在这里输入图像说明

设置: NSLocationWhenInUseUsageDescription与一个随机的string。 和/或: NSLocationAlwaysUsageDescription用一个随机的string。

然后,我build立了一个class,以获得所需的数据,如邮编,城市,国家…:

 import Foundation import MapKit typealias JSONDictionary = [String:Any] class LocationServices { let shared = LocationServices() let locManager = CLLocationManager() var currentLocation: CLLocation! let authStatus = CLLocationManager.authorizationStatus() let inUse = CLAuthorizationStatus.authorizedWhenInUse let always = CLAuthorizationStatus.authorizedAlways func getAdress(completion: @escaping (_ address: JSONDictionary?, _ error: Error?) -> ()) { self.locManager.requestWhenInUseAuthorization() if self.authStatus == inUse || self.authStatus == always { self.currentLocation = locManager.location let geoCoder = CLGeocoder() geoCoder.reverseGeocodeLocation(self.currentLocation) { placemarks, error in if let e = error { completion(nil, e) } else { let placeArray = placemarks as? [CLPlacemark] var placeMark: CLPlacemark! placeMark = placeArray?[0] guard let address = placeMark.addressDictionary as? JSONDictionary else { return } completion(address, nil) } } } } } 

调用人:

 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() LocationServices.shared.getAdress { address, error in if let a = address, let city = a["City"] as? String { // } } } } 

完成

感谢@Kampi。 这是一个更新的Swift 2.0(Xcode 7)版本:

 func setUsersClosestCity() { let geoCoder = CLGeocoder() let location = CLLocation(latitude: _point1.coordinate.latitude, longitude: _point1.coordinate.longitude) geoCoder.reverseGeocodeLocation(location) { (placemarks, error) -> Void in let placeArray = placemarks as [CLPlacemark]! // Place details var placeMark: CLPlacemark! placeMark = placeArray?[0] // Address dictionary print(placeMark.addressDictionary) // Location name if let locationName = placeMark.addressDictionary?["Name"] as? NSString { print(locationName) } // Street address if let street = placeMark.addressDictionary?["Thoroughfare"] as? NSString { print(street) } // City if let city = placeMark.addressDictionary?["City"] as? NSString { print(city) } // Zip code if let zip = placeMark.addressDictionary?["ZIP"] as? NSString { print(zip) } // Country if let country = placeMark.addressDictionary?["Country"] as? NSString { print(country) } } } 

感谢@ Kampai的回答 ,这里有一个Swift 3兼容和更安全的方法(没有强制! ):

 let geoCoder = CLGeocoder() let location = CLLocation(latitude: touchCoordinate.latitude, longitude: touchCoordinate.longitude) geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in guard let addressDict = placemarks?[0].addressDictionary else { return } // Print each key-value pair in a new row addressDict.forEach { print($0) } // Print fully formatted address if let formattedAddress = addressDict["FormattedAddressLines"] as? [String] { print(formattedAddress.joined(separator: ", ")) } // Access each element manually if let locationName = addressDict["Name"] as? String { print(locationName) } if let street = addressDict["Thoroughfare"] as? String { print(street) } if let city = addressDict["City"] as? String { print(city) } if let zip = addressDict["ZIP"] as? String { print(zip) } if let country = addressDict["Country"] as? String { print(country) } }) 

不要忘记NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescriptionSwift 3中的

感谢@Kampai的回答,我修改了一下,所以它适用于Swift 1.2

  var geocoder = CLGeocoder() var location = CLLocation(latitude: IC.coordinate!.latitude, longitude: IC.coordinate!.longitude) geocoder.reverseGeocodeLocation(location) { (placemarks, error) -> Void in if let placemarks = placemarks as? [CLPlacemark] where placemarks.count > 0 { var placemark = placemarks[0] println(placemark.addressDictionary) } 

结果:

澳大利亚,Harrington街141号国家:Harrington街141号邮政编码:141,国家代码:AU,邮编:2000,通道:Harrington Street,名称:141 Harrington Street, ,“The Rocks NSW 2000”,澳大利亚),城市:The Rocks]

在didUpdateToLocation方法中:

 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ CLLocation *location = [locationManager location]; CLLocationCoordinate2D coordinate = [location coordinate]; latitude = [NSString stringWithFormat:@"%.12f", coordinate.latitude]; longitude = [NSString stringWithFormat:@"%.12f", coordinate.longitude]; CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude.floatValue longitude:longitude.floatValue]; self.myGeocoder = [[CLGeocoder alloc] init]; [self.myGeocoder reverseGeocodeLocation:location1 completionHandler:^(NSArray *placemarks, NSError *error) { if (error == nil && [placemarks count] > 0){ placemark = [placemarks lastObject]; NSString* vendorLocation=[NSString stringWithFormat:@"%@ %@", placemark.locality, placemark.subLocality]; NSLog(@"%@",vendorLocation); } }]; }