How to geocode address by google maps iOS API?

大憨熊 提交于 2019-12-18 13:23:29

问题


I found one way to send request:

A Google Maps Geocoding API request takes the following form:

https://maps.googleapis.com/maps/api/geocode/outputFormat?parameters where outputFormat may be either of the following values:

json (recommended) indicates output in JavaScript Object Notation (JSON); or xml indicates output in XML To access the Google Maps Geocoding API over HTTP, use:

But it's really inconvenient, is there any native way in swift?

I looked into GMSGeocoder interface and only reverse geocoding can be done by it's API.


回答1:


As others have pointed out, there is not a predefined method to do the search, but you can use network request to access the Google Geocoding API yourself:

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



回答2:


No, there is no native way in the Google Maps SDK for iOS.

This is a very popular feature request though, see: Issue 5170: Feature request: Forward geocoding (from address to coordinates)




回答3:


If you are just looking for a Geocoding solution you could look into a little open source project I built. It is very lightweight and uses OpenStreetMap's geocoding API called Nominatim. Check it out here: https://github.com/caloon/NominatimSwift

You can even search for landmarks.

Geocoding addresses and landmarks:

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



回答4:


Unfortunately, there is no way to do that as native. I hope that function will help.

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



回答5:


Alamofire and Google's Geodecode API

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



回答6:


You can send a request through URL session of the address using Place Search of Google Places API and then parse the json result. It may not be perfect but you can get more information other than coordinates.




回答7:


There is no native way in the Google Maps API iOS SDK. As has been mentioned in other answers, it's been a requested feature for years.

One thing to remember is that Google Maps APIs are mostly focused on creating maps: that's a primary goal.

You have to use the URL-based API calls or some other service. For instance, a different service called SmartyStreets has an iOS SDK that has native support for forward geocoding. Here's the example code for Swift from their iOS SDK documentation page:

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

Full disclosure: I have worked for SmartyStreets.



来源:https://stackoverflow.com/questions/40971633/how-to-geocode-address-by-google-maps-ios-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!