Convert coordinates to City name?

后端 未结 9 1155
Happy的楠姐
Happy的楠姐 2020-12-02 07:41

How to get an address from coordinates using MapKit?

I have this code when long press on the map it gets the coordinates:

func didLongPressMap(sender         


        
相关标签:
9条回答
  • 2020-12-02 08:05

    SWIFT 4.2 : EDIT


    MapKit framework does provide a way to get address details from coordinates.

    You need to use reverse geocoding of map kit. CLGeocoder class is used to get the location from address and address from the location (coordinates). The method reverseGeocodeLocation will returns the address details from coordinates.

    This method accepts CLLocation as a parameter and returns CLPlacemark, which contains address dictionary.

    So now above method will be updated as:

    @objc func didLongPressMap(sender: UILongPressGestureRecognizer) {
    
        if sender.state == UIGestureRecognizer.State.began {
            let touchPoint = sender.location(in: mapView)
            let touchCoordinate = mapView.convert(touchPoint, toCoordinateFrom: self.mapView)
            let annotation = MKPointAnnotation()
            annotation.coordinate = touchCoordinate
            annotation.title = "Your position"
            mapView.addAnnotation(annotation) //drops the pin
            print("lat:  \(touchCoordinate.latitude)")
            let num = touchCoordinate.latitude as NSNumber
            let formatter = NumberFormatter()
            formatter.maximumFractionDigits = 4
            formatter.minimumFractionDigits = 4
            _ = formatter.string(from: num)
            print("long: \(touchCoordinate.longitude)")
            let num1 = touchCoordinate.longitude as NSNumber
            let formatter1 = NumberFormatter()
            formatter1.maximumFractionDigits = 4
            formatter1.minimumFractionDigits = 4
            _ = formatter1.string(from: num1)
            self.adressLoLa.text = "\(num),\(num1)"
    
            // Add below code to get address for touch coordinates.
            let geoCoder = CLGeocoder()
            let location = CLLocation(latitude: touchCoordinate.latitude, longitude: touchCoordinate.longitude)
            geoCoder.reverseGeocodeLocation(location, completionHandler:
                {
                    placemarks, error -> Void in
    
                    // Place details
                    guard let placeMark = placemarks?.first else { return }
    
                    // Location name
                    if let locationName = placeMark.location {
                        print(locationName)
                    }
                    // Street address
                    if let street = placeMark.thoroughfare {
                        print(street)
                    }
                    // City
                    if let city = placeMark.subAdministrativeArea {
                        print(city)
                    }
                    // Zip code
                    if let zip = placeMark.isoCountryCode {
                        print(zip)
                    }
                    // Country
                    if let country = placeMark.country {
                        print(country)
                    }
            })
        }
    }
    
    0 讨论(0)
  • 2020-12-02 08:05

    Thanks @Kampai for his answer, I revised a bit so it works with Swift 1.2:

            var geocoder = CLGeocoder()
            var location = CLLocation(latitude: IC.coordinate!.latitude, longitude: IC.coordinate!.longitude)
            geocoder.reverseGeocodeLocation(location) {
                (placemarks, error) -> Void in
                if let placemarks = placemarks as? [CLPlacemark] where placemarks.count > 0 {
                    var placemark = placemarks[0]
                    println(placemark.addressDictionary)
            }
    

    Result:

    [SubLocality: Sydney, Street: 141 Harrington Street, State: NSW, SubThoroughfare: 141, CountryCode: AU, ZIP: 2000, Thoroughfare: Harrington Street, Name: 141 Harrington Street, Country: Australia, FormattedAddressLines: ( "141 Harrington Street", "The Rocks NSW 2000", Australia ), City: The Rocks]

    0 讨论(0)
  • 2020-12-02 08:09
    func placePicker(_ viewController: GMSPlacePickerViewController, didPick place: GMSPlace) {
    
        viewController.dismiss(animated: true, completion: nil)
        let geoCoder = CLGeocoder()
        let location = CLLocation(latitude: place.coordinate.latitude, longitude: place.coordinate.longitude)
        geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
    
            // Place details
            var placeMark: CLPlacemark!
            placeMark = placemarks?[0]
    
            // Address dictionary
            print(placeMark.addressDictionary as Any)
       // 
    
        print("Place name \(place.name)")
        print("Place address \(String(describing: place.formattedAddress))")
        print("Place attributions \(String(describing: place.attributions))")
    
    
    
    })
    }
    

    use this code this will resolve the issue.

    0 讨论(0)
  • 2020-12-02 08:13

    For Swift 3: and Swift 4

    First you need to set allowance to receive User's GPS in the info.plist.

    Set: NSLocationWhenInUseUsageDescription with a random String. And/or: NSLocationAlwaysUsageDescription with a random String.

    Then I have set up a class to get the desired data like zip, town, country...:

    import Foundation
    import MapKit
    
    typealias JSONDictionary = [String:Any]
    
    class LocationServices {
    
        let shared = LocationServices()
        let locManager = CLLocationManager()
        var currentLocation: CLLocation!
    
        let authStatus = CLLocationManager.authorizationStatus()
        let inUse = CLAuthorizationStatus.authorizedWhenInUse
        let always = CLAuthorizationStatus.authorizedAlways
    
        func getAdress(completion: @escaping (_ address: JSONDictionary?, _ error: Error?) -> ()) {
    
            self.locManager.requestWhenInUseAuthorization()
    
            if self.authStatus == inUse || self.authStatus == always {
    
                self.currentLocation = locManager.location
    
                let geoCoder = CLGeocoder()
    
                geoCoder.reverseGeocodeLocation(self.currentLocation) { placemarks, error in
    
                    if let e = error {
    
                        completion(nil, e)
    
                    } else {
    
                        let placeArray = placemarks as? [CLPlacemark]
    
                        var placeMark: CLPlacemark!
    
                        placeMark = placeArray?[0]
    
                        guard let address = placeMark.addressDictionary as? JSONDictionary else {
                            return
                        }
    
                        completion(address, nil)
    
                    }
    
                }
    
            }
    
        }
    
    }
    

    Called by:

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            LocationServices.shared.getAdress { address, error in
    
                if let a = address, let city = a["City"] as? String {
                   //
                }
    
            }
    
        }
    
    }
    

    Done

    0 讨论(0)
  • 2020-12-02 08:14

    Thanks to @Kampi for this. This is an updated Swift 2.0 (Xcode 7) Version:

    func setUsersClosestCity()
    {
        let geoCoder = CLGeocoder()
        let location = CLLocation(latitude: _point1.coordinate.latitude, longitude: _point1.coordinate.longitude)
        geoCoder.reverseGeocodeLocation(location)
        {
            (placemarks, error) -> Void in
    
            let placeArray = placemarks as [CLPlacemark]!
    
            // Place details
            var placeMark: CLPlacemark!
            placeMark = placeArray?[0]
    
            // Address dictionary
            print(placeMark.addressDictionary)
    
            // Location name
            if let locationName = placeMark.addressDictionary?["Name"] as? NSString
            {
                print(locationName)
            }
    
            // Street address
            if let street = placeMark.addressDictionary?["Thoroughfare"] as? NSString
            {
                print(street)
            }
    
            // City
            if let city = placeMark.addressDictionary?["City"] as? NSString
            {
                print(city)
            }
    
            // Zip code
            if let zip = placeMark.addressDictionary?["ZIP"] as? NSString
            {
                print(zip)
            }
    
            // Country
            if let country = placeMark.addressDictionary?["Country"] as? NSString
            {
                print(country)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 08:14

    Swift 4.2 Keep it as simple as possible, look at the Apple doc and modify it as you need:

    func retreiveCityName(lattitude: Double, longitude: Double, completionHandler: @escaping (String?) -> Void)
    {
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), completionHandler:
        {
            placeMarks, error in
    
            completionHandler(placeMarks?.first?.locality)
         })
    }
    
    0 讨论(0)
提交回复
热议问题