MapKit之地理编码和反向地理编码(CLGeocoder、CLPlacemark)

来源:互联网 发布:淘宝类目大全2017 编辑:程序博客网 时间:2024/04/29 05:40
地理编码和反向地理编码

   CLGeocoder类主要提供的服务是在具体经纬度信息和用户位置信息之间的转换。
   CLGeocoder将根据请求的所有信息决定返回什么类型的信息。比如:如果用户是在高速上快速移动,可能返回整个区域的名称,而不是用户通过小公园的名称。应用应该明白怎样使用地理编码,因为地理编码对于每一个app都是有频率限制的,如果在较短的时间内进行太多的请求,可能会导致请求失败(当使用超过了最大的限制,地理编码将会返回应该错误对象kCLErrorNetwork)下面有一些相关的使用规则:

 1)
对于任意的用户行为,最多只发送一次请求。
 2)如果用户执行的多次请求涉及到相同的位置,应该重用最初的地理编码请求结果,而不是开始一个新的请求。如:http://stackoverflow.com/questions/32041454/what-is-the-best-way-to-load-static-objects-in-an-ios-app存储到本地,下次直接使用。
 3)当想要自动更新用户的当前位置时(如:用户正在移动),要注意:仅仅是当用户已经移动一段距离并且有一段合理的时间才发起一个新的编码请求。例如:不应该在每分钟发送超过一个的编码请求。
 4)不要每次在用户不能够立马看到结果的时候,又开始一个编码请求。当应用处于后台绘制inactive状态不要进行请求操作。

由于 ios的地图必须根据精度和纬度来完成,因此如果需要让程序根据地址进行定位判断,则需要先把地址解析成精度,纬度.两个基本的概念:

地理编码:把普通用户能够看懂的字符串地址转换成为精度,纬度.
反向地理编码:把精度,纬度转换成普通的字符串地址.

iOS
为我们提供了3个方法来进行地理编码,一个方法进行反向地理编码,如下:

//reverse geocode requests反向地理编码
根据给定的经纬度得到对应的地址。当地理/反地理编码完成时,就会调用CLGeocodeCompletionHandler,可以获取到CLPlacemark对象. CLGeocodeCompletionHandler:这个block传递2个参数:error:当编码出错时(比如编码不出具体的信息)有值,placemarks:里面装着CLPlacemark对象
publicfunc reverseGeocodeLocation(location: CLLocation, completionHandler:CLGeocodeCompletionHandler)

//forward geocode requests地理编码 根据给定的字符串进行请求,解析得到对应字符串地址的经纬度信息。
publicfunc geocodeAddressDictionary(addressDictionary: [NSObject :AnyObject], completionHandler:CLGeocodeCompletionHandler)
publicfunc geocodeAddressString(addressString:String, completionHandler:CLGeocodeCompletionHandler)
//该方法跟前面方法差不多,区别在于多了一个CLRegion参数,该参数代表某个区域,这样可以提高编码解析的准确性。
publicfuncgeocodeAddressString(addressString: String, inRegion region:CLRegion?,completionHandler: CLGeocodeCompletionHandler)

CLPlacemark类CLPlacemark它存储了给定精度和纬度对应的地标数据该对象包含了以下信息:

publicinit(placemark:CLPlacemark)//使用一个CLPlacemark初始化一个CLPlacemark
@NSCopyingpublicvar location: CLLocation? { get }//返回值封装了CLPlacemark对象代表的精度和纬度信息.
@NSCopyingpublicvar region: CLRegion? { get }//对应placemark的地理区域
@available(iOS9.0, *)
@NSCopyingpublicvar timeZone: NSTimeZone? { get }//对应placemark的时区
publicvar addressDictionary: [NSObject : AnyObject]? { get }//返回值封装了CLPlacemark所代表的地址详情信息.

// address dictionary properties
publicvar name:String? { get }//返回CLPlacemark所代表的地址名称.
publicvar thoroughfare:String? { get }//所在地址的道路名
publicvar subThoroughfare:String? { get }//所在地址的下级道路名
publicvar locality:String? { get }//所在地址的城市名,市
publicvar subLocality:String? { get }//下一级城市名,
publicvar administrativeArea:String? { get }//返回CLPlacemark所代表行政区域
publicvar subAdministrativeArea:String? { get }//返回CLPlacemark所代表次级行政区
publicvar postalCode:String? { get }//代表所在地址的邮编
publicvar ISOcountryCode:String? { get }//代表地址所在国家的代码.中国:CN
publicvar country:String? { get }// 代表地址所在国家
publicvar inlandWater:String? { get }//河流名称
publicvar ocean:String? { get }//Placemark相关的海洋
publicvar areasOfInterest: [String]? { get }//Placemark相关区域的兴趣点

Demo,实现地理编码和反向地理编码的基本功能:输入地址字符串得到对应的位置信息,输入给定的经纬度得到对应的地址。代码如下:

import UIKitimport CoreLocationclass FourViewController: UIViewController {        //MARK:地理编码相关    @IBOutletweakvar addressTextField: UITextField!    @IBOutletweakvar longtitudeLabel: UILabel!    @IBOutletweakvar latitudeLabel: UILabel!    @IBOutletweakvar detailAddressLabel: UILabel!         //MARK:反地理编码相关    @IBOutletweakvar longtitudeTextField: UITextField!    @IBOutletweakvar latitudeTextField: UITextField!    @IBOutletweakvar reverseDetailAddressLabel: UILabel!        lazyvar geocoder: CLGeocoder = {         let geocoder: CLGeocoder = CLGeocoder()         return geocoder    }()        overridefunc viewDidLoad() {        super.viewDidLoad()        view.backgroundColor = UIColor.whiteColor()    }    //MARK:地理编码地名 -> 经纬度说白了就是输入地址得到对应的位置信息,包括精度维度.    @IBActionfunc geocode(sender: AnyObject) {               //1:获得输入的地址并进行是否有内容判断        iflet address = self.addressTextField.textwhere address != "" {            //MARK:方法一:直接传入字符串地址            self.geocoder.geocodeAddressString(address, completionHandler: { (placeMarks, error) in                if  (error != nil || (placeMarks?.count == 0)) {                    self.detailAddressLabel.text = "您输入的地址找不到!";                }else{                     //编码成功(找到了具体的位置信息),打印输出查询到的所有地标信息                    for placeMark in placeMarks!{                        print("name = \(placeMark.name),country = \(placeMark.locality),postalCode = \(placeMark.postalCode),ISOcountryCode = \(placeMark.ISOcountryCode)")                    }                    //显示第一个地标信息 CLPlacemark代表了定位的所有信息。                    let firstPlaceMark = placeMarks!.first                    self.detailAddressLabel.text = firstPlaceMark!.name                    iflet location = firstPlaceMark!.location?.coordinate{                        self.latitudeLabel.text = "\(location.latitude)"                        self.longtitudeLabel.text = "\(location.longitude)"                    }                }           })        }    }        //MARK:反地理编码经纬度 -> 地名    @IBActionfunc reverseGeocode(sender: AnyObject) {        ifself.longtitudeTextField.text != "" && self.latitudeTextField.text != ""{            let location = CLLocation(latitude:CLLocationDegrees(self.latitudeTextField.text!)!, longitude: CLLocationDegrees(self.longtitudeTextField.text!)!)             self.geocoder.reverseGeocodeLocation(location, completionHandler: { (placeMarks, error) in                if  (error != nil || (placeMarks?.count == 0)) {                    self.reverseDetailAddressLabel.text = "您输入的地址找不到!";                    print("\(error?.userInfo)")                }else{                    //编码成功,输出查询到的所有地标信息                    for placeMark in placeMarks!{                        print("name = \(placeMark.name),country = \(placeMark.locality),postalCode = \(placeMark.postalCode),ISOcountryCode = \(placeMark.ISOcountryCode)")                    }                    //显示最前面的地标信息 CLPlacemark代表了定位的所有信息。                    let firstPlaceMark = placeMarks!.first                    self.reverseDetailAddressLabel.text = firstPlaceMark!.name                }             })        }    }     overridefunc touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {        self.view.endEditing(true)    }}

功能效果图如下:

  

0 0
原创粉丝点击