Swift 4中的反向地理编码 [英] Reverse geocoding in Swift 4

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

问题描述

我正在尝试编写一种简单的方法,该方法可以填充 CLLocationDegrees 并返回 CLPlacemark 。查看 Apple的文档,这似乎很简单。 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对象。对于大多数地理编码请求,此数组
只能包含一个条目。但是,在
指定地址无法解析到单个位置的情况下,前向地理编码
请求可能返回多个地标对象。如果
请求被取消或获取地标
信息时出错,则此参数为nil。


有关CLPlacemark属性的更多信息,可以检查此 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(当前)




Rua Casuarina,597



拉各斯



里约热内卢RJ



22011-040



巴西



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


placemark

Contains an array of CLPlacemark objects. For most geocoding requests, this array should contain only one entry. However, forward-geocoding requests may return multiple placemark objects in situations where the specified address could not be resolved to a single location. If the request was canceled or there was an error in obtaining the placemark information, this parameter is nil.

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)

Rua Casuarina, 597

Lagoa

Rio de Janeiro RJ

22011-040

Brazil

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆