web-dev-qa-db-fra.com

Comment géocoder les adresses avec Google Maps API iOS?

J'ai trouvé un moyen d'envoyer une demande:

Une demande d'API de géocodage de Google Maps se présente comme suit:

https://maps.googleapis.com/maps/api/geocode/outputFormat?parameters où outputFormat peut être l'une des valeurs suivantes:

json (recommandé) indique la sortie dans la notation d'objet JavaScript (JSON); ou xml indique une sortie en XML Pour accéder à Google Maps API de géocodage sur HTTP, utilisez:

Mais c'est vraiment gênant, y a-t-il une manière indigène dans rapide?

J'ai examiné l'interface GMSGeocoder et seul l'API permet de réaliser un géocodage inversé.

8
Jurasic

Comme d'autres l'ont souligné, il n'existe pas de méthode prédéfinie pour effectuer la recherche, mais vous pouvez utiliser la requête réseau pour accéder à la API de géocodage de Google vous-même:

func performGoogleSearch(for string: String) {
    strings = nil
    tableView.reloadData()

    var components = URLComponents(string: "https://maps.googleapis.com/maps/api/geocode/json")!
    let key = URLQueryItem(name: "key", value: "...") // use your key
    let address = URLQueryItem(name: "address", value: string)
    components.queryItems = [key, address]

    let task = URLSession.shared.dataTask(with: components.url!) { data, response, error in
        guard let data = data, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, error == nil else {
            print(String(describing: response))
            print(String(describing: error))
            return
        }

        guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else {
            print("not JSON format expected")
            print(String(data: data, encoding: .utf8) ?? "Not string?!?")
            return
        }

        guard let results = json["results"] as? [[String: Any]],
            let status = json["status"] as? String,
            status == "OK" else {
                print("no results")
                print(String(describing: json))
                return
        }

        DispatchQueue.main.async {
            // now do something with the results, e.g. grab `formatted_address`:
            let strings = results.compactMap { $0["formatted_address"] as? String }
            ...
        }
    }

    task.resume()
}
15
Rob

Non, il n’existe pas de méthode native dans le SDK Google Maps pour iOS.

Ceci est une demande de fonctionnalité très populaire, voir: Issue 5170: Demande de fonctionnalité: Géocodage en aval (de l'adresse aux coordonnées)

5
miguev

Si vous cherchez simplement une solution de géocodage, vous pouvez vous lancer dans un petit projet open source que j'ai construit. Il est très léger et utilise l’API de géocodage d’OpenStreetMap appelée Nominatim. Découvrez-le ici: https://github.com/caloon/NominatimSwift

Vous pouvez même rechercher des points de repère.

Adresses de géocodage et repères:

Nominatim.getLocation(fromAddress: "The Royal Palace of Stockholm", completion: {(error, location) -> Void in
  print("Geolocation of the Royal Palace of Stockholm:")
  print("lat = " + (location?.latitude)! + "   lon = " + (location?.longitude)!)
})
3
Josef Moser

Malheureusement, il n’ya aucun moyen de le faire en tant qu’indigène. J'espère que cette fonction aidera.

    func getAddress(address:String){

    let key : String = "YOUR_GOOGLE_API_KEY"
    let postParameters:[String: Any] = [ "address": address,"key":key]
    let url : String = "https://maps.googleapis.com/maps/api/geocode/json"

    Alamofire.request(url, method: .get, parameters: postParameters, encoding: URLEncoding.default, headers: nil).responseJSON {  response in

        if let receivedResults = response.result.value
        {
            let resultParams = JSON(receivedResults)
            print(resultParams) // RESULT JSON
            print(resultParams["status"]) // OK, ERROR
            print(resultParams["results"][0]["geometry"]["location"]["lat"].doubleValue) // approximately latitude
            print(resultParams["results"][0]["geometry"]["location"]["lng"].doubleValue) // approximately longitude
        }
    }
}
2
Fırat Yenidünya

Vous pouvez envoyer une demande via une session URL de l'adresse à l'aide de Placer une recherche de l'API Google Adresses, puis analyser le résultat json. Ce n'est peut-être pas parfait, mais vous pouvez obtenir plus d'informations que les coordonnées. 

1
Gamz Rs

Il n’existe pas de méthode native dans le SDK iOS iOS de Google Maps. Comme cela a été mentionné dans d'autres réponses, il s'agit d'une fonctionnalité demandée depuis des années .

Une chose à garder à l'esprit est que les API de Google Maps sont principalement axées sur la création de cartes: c'est un objectif primordial.

Vous devez utiliser les appels d'API basés sur une URL ou un autre service. Par exemple, un service différent appelé SmartyStreets possède un SDK iOS prenant en charge de manière native le géocodage à terme. Voici l'exemple de code pour Swift from leur page de documentation sur le SDK iOS }:

// Swift: Sending a Single Lookup to the US Zip Code API

package examples;

import Foundation
import SmartystreetsSDK

class ZipCodeSingleLookupExample {

    func run() -> String {
        let mobile = SSSharedCredentials(id: "SMARTY WEBSITE KEY HERE", hostname: "Host HERE")
        let client = SSZipCodeClientBuilder(signer: mobile).build()
//        Uncomment the following line to use Static Credentials
//        let client = SSZipCodeClientBuilder(authId: "YOUR AUTH-ID HERE", authToken: "YOUR AUTH-TOKEN HERE").build()

        let lookup = SSZipCodeLookup()
        lookup.city = "Mountain View"
        lookup.state = "California"

        do {
            try client?.send(lookup)
        } catch let error as NSError {
            print(String(format: "Domain: %@", error.domain))
            print(String(format: "Error Code: %i", error.code))
            print(String(format: "Description: %@", error.localizedDescription))
            return "Error sending request"
        }

        let result: SSResult = lookup.result
        let zipCodes = result.zipCodes
        let cities = result.cities

        var output: String = String()

        if (cities == nil && zipCodes == nil) {
            output += "Error getting cities and Zip codes."
            return output
        }

        for city in cities! {
            output += "\nCity: " + (city as! SSCity).city
            output += "\nState: " + (city as! SSCity).state
            output += "\nMailable City: " + ((city as! SSCity).mailableCity ? "YES" : "NO") + "\n"
        }

        for Zip in zipCodes! {
            output += "\nZIP Code: " + (Zip as! SSZipCode).zipCode
            output += "\nLatitude: " + String(format:"%f", (Zip as! SSZipCode).latitude)
            output += "\nLongitude: " + String(format:"%f", (Zip as! SSZipCode).longitude) + "\n"
        }

        return output
    }
}

Divulgation complète: j'ai travaillé pour SmartyStreets.

0
Joseph Hansen

Alamofire et API Google Geodecode

Swift 4

func getAddressFromLatLong(latitude: Double, longitude : Double) {
    let url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)&key=YOUR_API_KEY_HERE"

    Alamofire.request(url).validate().responseJSON { response in
        switch response.result {
        case .success:

            let responseJson = response.result.value! as! NSDictionary

            if let results = responseJson.object(forKey: "results")! as? [NSDictionary] {
                if results.count > 0 {
                    if let addressComponents = results[0]["address_components"]! as? [NSDictionary] {
                        self.address = results[0]["formatted_address"] as? String
                        for component in addressComponents {
                            if let temp = component.object(forKey: "types") as? [String] {
                                if (temp[0] == "postal_code") {
                                    self.pincode = component["long_name"] as? String
                                }
                                if (temp[0] == "locality") {
                                    self.city = component["long_name"] as? String
                                }
                                if (temp[0] == "administrative_area_level_1") {
                                    self.state = component["long_name"] as? String
                                }
                                if (temp[0] == "country") {
                                    self.country = component["long_name"] as? String
                                }
                            }
                        }
                    }
                }
            }
        case .failure(let error):
            print(error)
        }
    }
}
0
Sathish Kumar