geocoder ios swift mapkit clgeocoder clplacemark

ios - geocoder - Convertir coordenadas al nombre de la ciudad?



geocoder swift (8)

¿Cómo obtener una dirección de coordenadas usando MapKit?

Tengo este código cuando presiono largo en el mapa obtiene las coordenadas:

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)" } }

y quiero imprimir en annotation.title la dirección completa (calle, ciudad, código postal, país).


SWIFT 4.0: EDITAR

MapKit framework proporciona una forma de obtener detalles de direcciones a partir de las coordenadas.

Necesita usar geocodificación inversa del kit de mapas. CLGeocoder clase CLGeocoder se usa para obtener la ubicación de la dirección y la dirección desde la ubicación (coordenadas). El método reverseGeocodeLocation devolverá los detalles de la dirección de las coordenadas.

Este método acepta CLLocation como parámetro y devuelve CLPlacemark , que contiene el diccionario de direcciones.

Entonces el método anterior se actualizará como:

@objc 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 _ = formatter.string(from: num) print("long: /(touchCoordinate.longitude)") let num1 = touchCoordinate.longitude as NSNumber let formatter1 = NumberFormatter() formatter1.maximumFractionDigits = 4 formatter1.minimumFractionDigits = 4 _ = formatter1.string(from: num1) self.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] // Location name if let locationName = placeMark.location { print(locationName) } // Street address if let street = placeMark.thoroughfare { print(street) } // City if let city = placeMark.subAdministrativeArea { print(city) } // Zip code if let zip = placeMark.isoCountryCode { print(zip) } // Country if let country = placeMark.country { print(country) } }) } }


Actualiza Swift 4

addressDictionary quedó en deprecated en iOS 11.0

let geoCoder = CLGeocoder() let location = CLLocation(latitude: 37.769193, longitude: -122.426512) geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in // Place details var placeMark: CLPlacemark! placeMark = placemarks?[0] // Complete address as PostalAddress print(placeMark.postalAddress as Any) // Import Contacts // Location name if let locationName = placeMark.name { print(locationName) } // Street address if let street = placeMark.thoroughfare { print(street) } // Country if let country = placeMark.country { print(country) } })

Más datos pueden ser recuperados

nombre, vía, subThoroughfare, localidad, subLocality, administrativeArea, subAdministrativeArea, código postal, isoCountryCode, country, inlandWater, areaOfInterest


En el método 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); } }]; }


Gracias a @Kampai por su respuesta, la revisé un poco para que funcione con 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) }

Resultado:

[SubLocality: Sydney, calle: 141 Harrington Street, estado: NSW, SubThoroughfare: 141, CountryCode: AU, ZIP: 2000, calle: Harrington Street, nombre: 141 Harrington Street, país: Australia, líneas de dirección formateadas: ("141 Harrington Street" , "The Rocks NSW 2000", Australia), Ciudad: The Rocks]


Gracias a @Kampi por esto. Esta es una versión actualizada de 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) } } }


Gracias a la respuesta de @ Kampai , aquí hay una forma compatible y segura de Swift 3 (¡sin forzar ! ):

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) } })

No se olvide de NSLocationWhenInUseUsageDescription y NSLocationAlwaysUsageDescription claves de NSLocationAlwaysUsageDescription en Swift 3


Para Swift 3: y Swift 4

Primero, debe establecer la asignación para recibir el GPS del usuario en info.plist .

Set: NSLocationWhenInUseUsageDescription con una cadena aleatoria. Y / o: NSLocationAlwaysUsageDescription con una cadena aleatoria.

Luego configuré una clase para obtener los datos deseados, como zip, ciudad, país ...:

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) } } } } }

Llamado por:

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 { // } } } }

Hecho


func placePicker(_ viewController: GMSPlacePickerViewController, didPick place: GMSPlace) { viewController.dismiss(animated: true, completion: nil) let geoCoder = CLGeocoder() let location = CLLocation(latitude: place.coordinate.latitude, longitude: place.coordinate.longitude) geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in // Place details var placeMark: CLPlacemark! placeMark = placemarks?[0] // Address dictionary print(placeMark.addressDictionary as Any) // print("Place name /(place.name)") print("Place address /(String(describing: place.formattedAddress))") print("Place attributions /(String(describing: place.attributions))") }) }

use este código, esto resolverá el problema.