4中的反向地理编码

4中的反向地理编码

本文介绍了Swift 4中的反向地理编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一种简单的方法,该方法可以填充 CLLocationDegrees 并返回 CLPlacemark 。查看,这似乎很简单。 p>

以下是我扔到操场上的东西:

  import CoreLocation 
//这对于游乐场中的异步代码是必需的
import PlaygroundSupport

//这对于游乐场中的异步代码是必需的
PlaygroundPage.current.needsIndefiniteExecution = true

功能地理编码(纬度:CLLocationDegrees,经度:CLLocationDegrees)-> CLPlacemark? {
let location = CLLocation(纬度:纬度,经度:经度)
let geocoder = CLGeocoder()

var地标:CLPlacemark?

geocoder.reverseGeocodeLocation(location){(地标,错误)在
中,如果出现错误!= nil {
print(发生了严重错误)
} $如果让地标=地标{
地标=地标,则

.first
}
}

返回地标
}

让myPlacemark =地理编码(纬度:37.3318,经度:122.0312)

,我的方法返回nil。我不确定我的错误在哪里,但我可以放心,这对我来说是愚蠢的。谢谢您的阅读。

解决方案
  import UIKit 
import CoreLocation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true






  func地理编码(纬度:双倍,经度:双倍,完成:@转义(_地标:[CLPlacemark]?,_错误:错误?)->无效){
CLGeocoder()。reverseGeocodeLocation(CLLocation(纬度:纬度,经度:经度)){地标,
中的错误警卫队让地标=地标,错误==零,否则{
完成(零,错误)
返回
}
完成(地标,无)
}
}

或简单地:

  func地理编码(纬度:Double,经度:Double,完成度: @转义(_地标:[CLPlacemark]?,_错误:错误?)->无效){
CLGeocoder()。reverseGeocodeLocation(CLLocation(latitude:latitud e,经度:longitude),completionHandler:完成)
}

或扩展CLLocation:

 扩展名CLLocation {
func geocode(完成:@转义(_地标:[CLPlacemark]?,_错误:错误?)->无效){
CLGeocoder()。reverseGeocodeLocation(self,completeHandler:完成)
}
}






要将地标格式化为邮件地址,可以使用联系人框架 CNPostalAddressFormatter

  import联系人

扩展Formatter {
static let mailingAddress:CNPostalAddressFormatter = {
let formatter = CNPostalAddressFormatter()
formatter.style = .mailingAddress
返回格式化程序
}()
}

扩展CLPlacemark {
var mailingAddress:字符串? {
return postalAddress?.mailingAddress
}
}

扩展名CNPostalAddress {
var mailingAddress:字符串{
return Formatter.mailingAddress.string (来自:自我)
}
}






有关CLPlacemark属性的更多信息,可以检查此






用法:

 让位置= CLLocation(纬度:-22.963451,经度:-43.198242)
location.geocode {地标,如果让error = error as,则
中存在错误? CLError {
print( CLError:,error)
return
}否则,如果let placemark = placemark?.first {
//您应该始终在主界面中更新UI线程
DispatchQueue.main.async {
//在此处更新UI
print( name:,placemark.name ?? unknown)

print( address1:,placemark.thoroughfare ??未知)
print( address2:,placemark.subThoroughfare ?? unknown)
print( neighborhood:,placemark.subLocality ?? 未知)
print( city:,placemark.locality ??未知)

print( state:,placemark.administrativeArea ??未知)
print( subAdministrativeArea:,placemark.subAdministrativeArea ??未知)
print(邮政编码:,placemark.postalCode ??未知)
print( country:, placemark.country ?? unknown,终止符: \n\n)

print( isoCountry代码:,placemark.isoCountryCode? unknown)
print( region identifier:,placemark.region?.identifier ?? unknown)

print( timezone:,placemark.timeZone ?? unknown ,终止符: \n\n)

// Mailind地址
print(placemark.mailingAddress ??未知)
}
}
}






这将打印

 名称:Morro da Saudade 
地址1:Rua Casuarina
地址2:597
社区:Lagoa
城市:Rio de Janeiro
省:RJ
subAdministrativeArea:不明
邮政编码:22011-040
国家:巴西

isoCountryCode:BR
区域标识符:< -22.96345100,-43.19824200>半径141.83
时区:America / Sao_Paulo(当前)




I'm attempting to write a simple method that's fed CLLocationDegrees and returns a CLPlacemark. Looking at Apple's documentation, it seems like a simple task.

Below is what I've dumped into a playground:

import CoreLocation
// this is necessary for async code in a playground
import PlaygroundSupport

// this is necessary for async code in a playground
PlaygroundPage.current.needsIndefiniteExecution = true

func geocode(latitude: CLLocationDegrees, longitude: CLLocationDegrees) -> CLPlacemark? {
  let location = CLLocation(latitude: latitude, longitude: longitude)
  let geocoder = CLGeocoder()

  var placemark: CLPlacemark?

  geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
    if error != nil {
      print("something went horribly wrong")
    }

    if let placemarks = placemarks {
      placemark = placemarks.first
    }
  }

  return placemark
}

let myPlacemark = geocode(latitude: 37.3318, longitude: 122.0312)

As it stands, my method is returning nil. I'm not sure where my error lies, but I rest assured it's something starlingly stupid on my part. Thank you for reading.

解决方案
import UIKit
import CoreLocation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true


func geocode(latitude: Double, longitude: Double, completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)  {
    CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude)) { placemark, error in
        guard let placemark = placemark, error == nil else {
            completion(nil, error)
            return
        }
        completion(placemark, nil)
    }
}

or simply:

func geocode(latitude: Double, longitude: Double, completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)  {
    CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), completionHandler: completion)
}

or extending CLLocation:

extension CLLocation {
    func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)  {
        CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion)
    }
}


To format your place mark as a mailing address you can use Contacts framework CNPostalAddressFormatter:

import Contacts

extension Formatter {
    static let mailingAddress: CNPostalAddressFormatter = {
        let formatter = CNPostalAddressFormatter()
        formatter.style = .mailingAddress
        return formatter
    }()
}

extension CLPlacemark {
    var mailingAddress: String? {
        return postalAddress?.mailingAddress
    }
}

extension CNPostalAddress {
    var mailingAddress: String {
        return Formatter.mailingAddress.string(from: self)
    }
}


For more information about the CLPlacemark properties you can check this CLPlacemark


Usage:

let location = CLLocation(latitude: -22.963451, longitude: -43.198242)
location.geocode { placemark, error in
    if let error = error as? CLError {
        print("CLError:", error)
        return
    } else if let placemark = placemark?.first {
        // you should always update your UI in the main thread
        DispatchQueue.main.async {
            //  update UI here
            print("name:", placemark.name ?? "unknown")

            print("address1:", placemark.thoroughfare ?? "unknown")
            print("address2:", placemark.subThoroughfare ?? "unknown")
            print("neighborhood:", placemark.subLocality ?? "unknown")
            print("city:", placemark.locality ?? "unknown")

            print("state:", placemark.administrativeArea ?? "unknown")
            print("subAdministrativeArea:", placemark.subAdministrativeArea ?? "unknown")
            print("zip code:", placemark.postalCode ?? "unknown")
            print("country:", placemark.country ?? "unknown", terminator: "\n\n")

            print("isoCountryCode:", placemark.isoCountryCode ?? "unknown")
            print("region identifier:", placemark.region?.identifier ?? "unknown")

            print("timezone:", placemark.timeZone ?? "unknown", terminator:"\n\n")

            // Mailind Address
            print(placemark.mailingAddress ?? "unknown")
        }
    }
}


This will print

name: Morro da Saudade
address1: Rua Casuarina
address2: 597
neighborhood: Lagoa
city: Rio de Janeiro
state: RJ
subAdministrativeArea: unknown
zip code: 22011-040
country: Brazil

isoCountryCode: BR
region identifier: <-22.96345100,-43.19824200> radius 141.83
timezone: America/Sao_Paulo (current)

这篇关于Swift 4中的反向地理编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-12 21:23