将坐标转换为城市名称?
如何使用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 3和Swift 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) } })
不要忘记NSLocationWhenInUseUsageDescription
和NSLocationAlwaysUsageDescription
在Swift 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); } }]; }