Tev*_*ung 46 mapkit ios clgeocoder swift clplacemark
如何使用MapKit从坐标获取地址?
当我在地图上长按它获取坐标时,我有这个代码:
func didLongPressMap(sender: UILongPressGestureRecognizer) {
    if sender.state == UIGestureRecognizerState.Began {
        let touchPoint = sender.locationInView(self.mapView)
        let touchCoordinate = self.mapView.convertPoint(touchPoint, toCoordinateFromView: self.mapView)
        var annotation = MKPointAnnotation()
        annotation.coordinate = touchCoordinate
        annotation.title = "Your position"
        self.mapView.addAnnotation(annotation) //drops the pin
        println("lat:  \(touchCoordinate.latitude)")
        var num = (touchCoordinate.latitude as NSNumber).floatValue
        var formatter = NSNumberFormatter()
        formatter.maximumFractionDigits = 4
        formatter.minimumFractionDigits = 4
        var str = formatter.stringFromNumber(num)
        println("long: \(touchCoordinate.longitude)")
        var num1 = (touchCoordinate.longitude as NSNumber).floatValue
        var formatter1 = NSNumberFormatter()
        formatter1.maximumFractionDigits = 4
        formatter1.minimumFractionDigits = 4
        var str1 = formatter1.stringFromNumber(num1)
        self.adressLoLa.text = "\(num),\(num1)"
                }
}
我想在annotation.title完整的地址(街道,城市,邮编,国家)打印.
Kam*_*pai 72
MapKit 框架确实提供了一种从坐标获取地址详细信息的方法. 
您需要使用地图工具包的反向地理编码.CLGeocoderclass用于从位置(坐标)获取地址和地址的位置.该方法reverseGeocodeLocation将从坐标返回地址详细信息.
此方法接受CLLocation作为参数并返回CLPlacemark,其中包含地址字典.
所以现在上面的方法将更新为:
@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)
                }
        })
    }
}
Dav*_*eek 36
对于Swift 3:和Swift 4
首先,您需要设置容差以接收用户的GPS info.plist.
设置:NSLocationWhenInUseUsageDescription使用随机字符串.和/或:NSLocationAlwaysUsageDescription使用随机字符串.
然后我建立了一个类来获得所需的数据,如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)
                }
            }
        }
    }
}
被称为:
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 {
               //
            }
        }
    }
}
完成
Isl*_* Q. 27
更新:
import Foundation
import CoreLocation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let location = CLLocation(latitude: 37.3321, longitude: -122.0318)
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
    guard let placemark = placemarks?.first else {
        let errorString = error?.localizedDescription ?? "Unexpected Error"
        print("Unable to reverse geocode the given location. Error: \(errorString)")
        return
    }
    let reversedGeoLocation = ReversedGeoLocation(with: placemark)
    print(reversedGeoLocation.formattedAddress)
    // Apple Inc.,
    // 1 Infinite Loop,
    // Cupertino, CA 95014
    // United States
}
struct ReversedGeoLocation {
    let name: String            // eg. Apple Inc.
    let streetName: String      // eg. Infinite Loop
    let streetNumber: String    // eg. 1
    let city: String            // eg. Cupertino
    let state: String           // eg. CA
    let zipCode: String         // eg. 95014
    let country: String         // eg. United States
    let isoCountryCode: String  // eg. US
    var formattedAddress: String {
        return """
        \(name),
        \(streetNumber) \(streetName),
        \(city), \(state) \(zipCode)
        \(country)
        """
    }
    // Handle optionals as needed
    init(with placemark: CLPlacemark) {
        self.name           = placemark.name ?? ""
        self.streetName     = placemark.thoroughfare ?? ""
        self.streetNumber   = placemark.subThoroughfare ?? ""
        self.city           = placemark.locality ?? ""
        self.state          = placemark.administrativeArea ?? ""
        self.zipCode        = placemark.postalCode ?? ""
        self.country        = placemark.country ?? ""
        self.isoCountryCode = placemark.isoCountryCode ?? ""
    }
}
旧/不赞成的答案:
感谢@ Kampai的回答,这里是Swift 3兼容且更安全的方式(无强制!):
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: touchCoordinate.latitude, longitude: touchCoordinate.longitude)
geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in
    guard let addressDict = placemarks?[0].addressDictionary else {
        return
    }
    // Print each key-value pair in a new row
    addressDict.forEach { print($0) }
    // Print fully formatted address
    if let formattedAddress = addressDict["FormattedAddressLines"] as? [String] {
        print(formattedAddress.joined(separator: ", "))
    }
    // Access each element manually
    if let locationName = addressDict["Name"] as? String {
        print(locationName)
    }
    if let street = addressDict["Thoroughfare"] as? String {
        print(street)
    }
    if let city = addressDict["City"] as? String {
        print(city)
    }
    if let zip = addressDict["ZIP"] as? String {
        print(zip)
    }
    if let country = addressDict["Country"] as? String {
        print(country)
    }
})
不要忘记NSLocationWhenInUseUsageDescription和Swift 3中的NSLocationAlwaysUsageDescription键
Agg*_*sor 21
感谢@Kampi.这是一个更新的Swift 2.0(Xcode 7)版本:
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)
        }
    }
}
sup*_*org 10
谢谢@Kampai的回答,我修改了一下,所以它适用于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)
        }
结果:
[SubLocality:Sydney,Street:141 Harrington Street,State:NSW,SubThoroughfare:141,CountryCode:AU,ZIP:2000,Thoroughfare:Harrington Street,Name:141 Harrington Street,国家:Australia,FormattedAddressLines:("141 Harrington Street" ,"The Rocks NSW 2000",澳大利亚),城市:The Rocks]
更新Swift 4
addressDictionary在 iOS 11.0 中被弃用
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: 37.769193, longitude: -122.426512)
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
// Complete address as PostalAddress
print(placeMark.postalAddress as Any)  //  Import Contacts
// Location name
if let locationName = placeMark.name  {
    print(locationName)
}
// Street address
if let street = placeMark.thoroughfare {
   print(street)
}
// Country
if let country = placeMark.country {
   print(country)
}
})
可以检索更多数据
名称、大道、subThoroughfare、locality、subLocality、administrativeArea、subAdministrativeArea、邮政编码、isoCountryCode、国家、内陆水域、areaOfInterest
Swift 4.2 使其尽可能简单,查看Apple 文档并根据需要进行修改:
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)
     })
}
| 归档时间: | 
 | 
| 查看次数: | 53029 次 | 
| 最近记录: |