(七十七)地理编码与反地理编码

所谓地理编码。指的是通过地名获取位置信息。比如经纬度、具体地址等。

所谓反地理编码,指的是通过经纬度、海拔等信息获取地理位置信息。

在iOS上使用地理编码和反地理编码,假设是手动输入经纬度,是不须要获取用户授权的,可是通常是获取用户的经纬度,然后再通过地理编码实现精确定位,因此须要授权。本文由于是单独解说地理编码的相关知识,因此採用手动输人经纬度。不再赘述授权的代码。

①导入框架:

#import <CoreLocation/CoreLocation.h>

②新建CLGeocoder对象:

@property (strong, nonatomic) CLGeocoder *gcoder;
CLGeocoder *coder = [[CLGeocoder alloc] init];
self.gcoder = coder;

【地理编码】

③调用对象的geocodeAddressString:completionHandler方法。传入一个字符串地名,返回的对象为地标数组。

普通情况下。地标数组中仅仅有一个元素。通过firstObject或者lastObject得到一个地标。

每一个地标都有很多个属性,打印一个地标,能够发现当中的属性过于复杂,当中比較实用的属性还是通过地标类CLPlacemark的头文件,比較重要的列举例如以下:

location:位置信息。能够得到经纬度、海拔等,上节有介绍。

city:城市名

name:完整地名

addressDictionary:这是一个字典,数据例如以下

{
    City = "U5317U4eacU5e02U5e02U8f96U533a";
    Country = "U4e2dU56fd";
    CountryCode = CN;
    FormattedAddressLines =     (
        "U4e2dU56fdU5317U4eacU5e02"
    );
    Name = "U5317U4eacU5e02";
    State = "U5317U4eacU5e02";
}
当中的FormatterAddressLines是格式化的地址。圆括号表示的数组,当中的元素是字符串。

以下的代码把经纬度和格式化的地址获取并输出。self开头的那些成员属性是TextField,用于显示。

    NSString *addressStr = self.addressView.text;
    if(addressStr == nil || addressStr.length == 0){
        NSLog(@"请输入地址");
    }
    [self.gcoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) {
       // 地标数组中存放地标。每个地标,包括了当前位置的一系列信息。
        CLPlacemark *placemark = [placemarks firstObject];
        NSLog(@"%@ %@ %f %f",placemark.name, placemark.addressDictionary,placemark.location.coordinate.latitude,placemark.location.coordinate.longitude);
        self.latiView.text = [NSString stringWithFormat:@"%f",placemark.location.coordinate.latitude];
        self.longtiView.text = [NSString stringWithFormat:@"%f",placemark.location.coordinate.longitude];
        
        // addressDictionary中的FormattedAddressLines是一个数组。内部存放的是字符串
        NSMutableString *strM = [NSMutableString string];
        NSArray *addressLines = placemark.addressDictionary[@"FormattedAddressLines"];
        for (NSString *str in addressLines) {
            [strM appendString:str];
        }
        self.detailView.text = strM;
        if (error) {
            NSLog(@"%@",error);
        }
        
    }];

【反地理编码】

④调用reverseGeocodeLocation方法,传入一个CLLocation就可以,得到了仍然是地标,和前面一样处理,须要注意的是,CLLocation假设要输入值,要在初始化时设定。由于经纬度、海拔等都是仅仅读属性,因此应当在初始化时赋值。以下的代码通过获取TextField获取经纬度,然后反地理编码得到位置信息:

    CLLocationDegrees latitude = [self.latiView.text doubleValue];
    CLLocationDegrees longtitude = [self.longtiView.text doubleValue];
    
    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longtitude];
    [self.gcoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        for (CLPlacemark *placemark in placemarks) {
            
            NSLog(@"%@ %@ %f %f",placemark.name, placemark.addressDictionary,placemark.location.coordinate.latitude,placemark.location.coordinate.longitude);
            
            self.addressView.text = placemark.addressDictionary[@"City"];
            
            NSMutableString *strM = [NSMutableString string];
            NSArray *addressLines = placemark.addressDictionary[@"FormattedAddressLines"];
            for (NSString *str in addressLines) {
                [strM appendString:str];
            }
            self.detailView.text = strM;
            
            
        }
        if (error) {
            NSLog(@"%@",error);
        }
    }];

原文地址:https://www.cnblogs.com/brucemengbm/p/6772429.html