Как получить страну, штат, город из reverseGeocodeCoordinate?

GMSReverseGeocodeResponse содержит

- (GMSReverseGeocodeResult *)firstResult;

чье определение похоже:

@interface GMSReverseGeocodeResult : NSObject<NSCopying>

/** Returns the first line of the address. */
- (NSString *)addressLine1;

/** Returns the second line of the address. */
- (NSString *)addressLine2;

@end

Есть ли способ получить страну, код страны ISO, штат (административная_райя_1 или соответствующая) из этих двух строк (действительных для всех стран и всех адресов)?

ПРИМЕЧАНИЕ: я пытался выполнить этот фрагмент кода

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

Но почему-то обработчик так и не был вызван. Я добавил ключ приложения, а также добавил идентификатор пакета iOS к ключу приложения. В консоли ошибки не выводятся. Я имею в виду, что я не осведомлен о содержании строк.


person user2101384    schedule 23.02.2013    source источник


Ответы (4)


Самый простой способ - обновить до версии 1.7 SDK Google Maps для iOS (выпущена в феврале 2014 г.).
Из версии -_feb February_2014" rel="noreferrer"> примечания:

GMSGeocoder теперь предоставляет структурированные адреса через GMSAddress, исключая GMSReverseGeocodeResult.

В GMSAddress Справочнике по классам можно найти эти свойства:

coordinate
Местоположение или kLocationCoordinate2DInvalid, если неизвестно.

thoroughfare
Номер и название улицы.

locality
Населенный пункт или город.

subLocality
Подразделение населенного пункта, района или парка.

administrativeArea
Регион / Штат / Административный район.

postalCode
Почтовый индекс.

country
Название страны.

lines
Массив NSString, содержащий отформатированные строки адреса.

Код страны ISO отсутствует.
Также обратите внимание, что некоторые свойства могут возвращать nil.

Вот полный пример:

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

и его вывод:

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

В качестве альтернативы вы можете рассмотреть возможность использования обратного геокодирования в API геокодирования Google (example).

person Pang    schedule 17.02.2014

Ответьте в Swift

Использование SDK Google Maps для iOS (в настоящее время используется версия 1.9.2, вы не можете указать язык, на котором будут возвращаться результаты):

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

Используя Google Reverse Geocoding API V3 (в настоящее время вы можете указать язык, на котором следует вернуть результаты):

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

}

Я надеюсь, что этот фрагмент кода и объяснение помогут будущим читателям.

person King-Wizard    schedule 15.04.2015

Версия Swift 5 для адресов в США:

import Foundation
import GoogleMaps

extension GMSAddress {

    var formattedAddress: String {
        let addressComponents = [
            thoroughfare,        // One Infinite Loop
            locality,            // Cupertino
            administrativeArea,  // California
            postalCode           // 95014
        ]
        return addressComponents
            .compactMap { $0 }
            .joined(separator: ", ")
    }

}
person Chris Chute    schedule 23.11.2019

В swift 4.0 функция получает CLLocation и возвращает почтовый адрес

  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 ""
    }
person Mujahid Latif    schedule 24.07.2018