Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain country, state, city from reverseGeocodeCoordinate?

Tags:

GMSReverseGeocodeResponse contains

- (GMSReverseGeocodeResult *)firstResult; 

whose definition is like:

@interface GMSReverseGeocodeResult : NSObject<NSCopying>  /** Returns the first line of the address. */ - (NSString *)addressLine1;  /** Returns the second line of the address. */ - (NSString *)addressLine2;  @end 

Is there any way to obtain the country, ISO country code, state (administrative_area_1 or corresponding one) from those two strings (valid for all the countries and all the addresses)?

NOTE: I tried to execute this piece of code

[[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 ) ;  } ] ; 

But for some reason the handler was never called. I did add the app key, and also added the iOS bundle id to the app key. No error is printed in the console. With this I mean I am not aware of the content of the lines.

like image 697
user2101384 Avatar asked Feb 23 '13 01:02

user2101384


2 Answers

The simplest way is to upgrade to Version 1.7 of the Google Maps SDK for iOS (released February 2014).
From the release notes:

GMSGeocoder now provides structured addresses via GMSAddress, deprecating GMSReverseGeocodeResult.

From GMSAddress Class Reference, you can find these properties:

coordinate
Location, or kLocationCoordinate2DInvalid if unknown.

thoroughfare
Street number and name.

locality
Locality or city.

subLocality
Subdivision of locality, district or park.

administrativeArea
Region/State/Administrative area.

postalCode
Postal/Zip code.

country
The country name.

lines
An array of NSString containing formatted lines of the address.

No ISO country code though.
Also note that some properties may return nil.

Here's a full example:

[[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);     } }]; 

and its output:

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

Alternatively, you may consider using Reverse Geocoding in the The Google Geocoding API (example).

like image 162
Pang Avatar answered Sep 23 '22 11:09

Pang


Answer in Swift

Using Google Maps iOS SDK (currently using the V1.9.2 you cannot specify the language in which to return results):

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

Using Google Reverse Geocoding API V3 (currently you can specify the language in which to return results):

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

I hope this code snippet and explanation will help future readers.

like image 23
King-Wizard Avatar answered Sep 19 '22 11:09

King-Wizard