ios - gmsgeocoder - ¿Cómo obtener país, estado, ciudad de reverseGeocodeCoordinate?
maps for ios (3)
GMSReverseGeocodeResponse
contiene
- (GMSReverseGeocodeResult *)firstResult;
cuya definición es como
@interface GMSReverseGeocodeResult : NSObject<NSCopying>
/** Returns the first line of the address. */
- (NSString *)addressLine1;
/** Returns the second line of the address. */
- (NSString *)addressLine2;
@end
¿Hay alguna forma de obtener el país, el código de país ISO, el estado (administrative_area_1 o el correspondiente) de esas dos cadenas (válido para todos los países y todas las direcciones )?
NOTA: Intenté ejecutar este fragmento de código.
[[GMSGeocoder geocoder] reverseGeocodeCoordinate:CLLocationCoordinate2DMake(40.4375, -3.6818) completionHandler:^(GMSReverseGeocodeResponse *resp, NSError *error)
{
NSLog( @"Error is %@", error) ;
NSLog( @"%@" , resp.firstResult.addressLine1 ) ;
NSLog( @"%@" , resp.firstResult.addressLine2 ) ;
} ] ;
Pero por alguna razón el manejador nunca fue llamado. Agregué la clave de la aplicación y también agregué la ID del paquete de iOS a la clave de la aplicación. No se imprime ningún error en la consola. Con esto quiero decir que no estoy al tanto del contenido de las líneas.
En Swift 4.0, la función obtiene CLLocation y dirección postal de retorno
func geocodeCoordinates(location : CLLocation)->String{
var postalAddress = ""
let geocoder = GMSGeocoder()
geocoder.reverseGeocodeCoordinate(location.coordinate, completionHandler: {response,error in
if let gmsAddress = response!.firstResult(){
for line in gmsAddress.lines! {
postalAddress += line + " "
}
return postalAddress
}
})
return ""
}
La forma más sencilla es actualizar a la versión 1.7 del SDK de Google Maps para iOS (lanzado en febrero de 2014).
De las notas de publicación :
GMSGeocoder
ahora proporciona direcciones estructuradas a través deGMSAddress
, en desusoGMSReverseGeocodeResult
.
Desde GMSAddress
Class Reference , puede encontrar estas propiedades :
coordinate
Ubicación okLocationCoordinate2DInvalid
si se desconoce.
thoroughfare
Número y nombre de la calle.
locality
Localidad o ciudad.
subLocality
Subdivisión de localidad, distrito o parque.
administrativeArea
Región / Estado / Área administrativa.
postalCode
Código postal / postal.
country
El nombre del país.
lines
Una matriz deNSString
contiene líneas con formato de la dirección.
Sin embargo, no hay código ISO de país.
También tenga en cuenta que algunas propiedades pueden devolver nil
.
Aquí hay un ejemplo completo:
[[GMSGeocoder geocoder] reverseGeocodeCoordinate:CLLocationCoordinate2DMake(40.4375, -3.6818) completionHandler:^(GMSReverseGeocodeResponse* response, NSError* error) {
NSLog(@"reverse geocoding results:");
for(GMSAddress* addressObj in [response results])
{
NSLog(@"coordinate.latitude=%f", addressObj.coordinate.latitude);
NSLog(@"coordinate.longitude=%f", addressObj.coordinate.longitude);
NSLog(@"thoroughfare=%@", addressObj.thoroughfare);
NSLog(@"locality=%@", addressObj.locality);
NSLog(@"subLocality=%@", addressObj.subLocality);
NSLog(@"administrativeArea=%@", addressObj.administrativeArea);
NSLog(@"postalCode=%@", addressObj.postalCode);
NSLog(@"country=%@", addressObj.country);
NSLog(@"lines=%@", addressObj.lines);
}
}];
y su salida:
coordinate.latitude=40.437500
coordinate.longitude=-3.681800
thoroughfare=(null)
locality=(null)
subLocality=(null)
administrativeArea=Community of Madrid
postalCode=(null)
country=Spain
lines=(
"",
"Community of Madrid, Spain"
)
Como alternativa, puede considerar utilizar la geocodificación inversa en la API de geocodificación de Google ( example ).
Respuesta en Swift
Con el SDK de iOS de Google Maps (actualmente con la V1.9.2, no puede especificar el idioma en el que desea devolver los resultados):
@IBAction func googleMapsiOSSDKReverseGeocoding(sender: UIButton) {
let aGMSGeocoder: GMSGeocoder = GMSGeocoder()
aGMSGeocoder.reverseGeocodeCoordinate(CLLocationCoordinate2DMake(self.latitude, self.longitude)) {
(let gmsReverseGeocodeResponse: GMSReverseGeocodeResponse!, let error: NSError!) -> Void in
let gmsAddress: GMSAddress = gmsReverseGeocodeResponse.firstResult()
print("/ncoordinate.latitude=/(gmsAddress.coordinate.latitude)")
print("coordinate.longitude=/(gmsAddress.coordinate.longitude)")
print("thoroughfare=/(gmsAddress.thoroughfare)")
print("locality=/(gmsAddress.locality)")
print("subLocality=/(gmsAddress.subLocality)")
print("administrativeArea=/(gmsAddress.administrativeArea)")
print("postalCode=/(gmsAddress.postalCode)")
print("country=/(gmsAddress.country)")
print("lines=/(gmsAddress.lines)")
}
}
Utilizando Google Reverse Geocoding API V3 (actualmente puede especificar el idioma en el que desea devolver los resultados):
@IBAction func googleMapsWebServiceGeocodingAPI(sender: UIButton) {
self.callGoogleReverseGeocodingWebservice(self.currentUserLocation())
}
// #1 - Get the current user''s location (latitude, longitude).
private func currentUserLocation() -> CLLocationCoordinate2D {
// returns current user''s location.
}
// #2 - Call Google Reverse Geocoding Web Service using AFNetworking.
private func callGoogleReverseGeocodingWebservice(let userLocation: CLLocationCoordinate2D) {
let url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=/(userLocation.latitude),/(userLocation.longitude)&key=/(self.googleMapsiOSAPIKey)&language=/(self.googleReverseGeocodingWebserviceOutputLanguageCode)&result_type=country"
AFHTTPRequestOperationManager().GET(
url,
parameters: nil,
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
println("GET user''s country request succeeded !!!/n")
// The goal here was only for me to get the user''s iso country code +
// the user''s Country in english language.
if let responseObject: AnyObject = responseObject {
println("responseObject:/n/n/(responseObject)/n/n")
let rootDictionary = responseObject as! NSDictionary
if let results = rootDictionary["results"] as? NSArray {
if let firstResult = results[0] as? NSDictionary {
if let addressComponents = firstResult["address_components"] as? NSArray {
if let firstAddressComponent = addressComponents[0] as? NSDictionary {
if let longName = firstAddressComponent["long_name"] as? String {
println("long_name: /(longName)")
}
if let shortName = firstAddressComponent["short_name"] as? String {
println("short_name: /(shortName)")
}
}
}
}
}
}
},
failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
println("Error GET user''s country request: /(error.localizedDescription)/n")
println("Error GET user''s country request: /(operation.responseString)/n")
}
)
}
Espero que este fragmento de código y su explicación ayuden a los futuros lectores.