二十四桥明月夜

一个没有名字的网工

地图定位CoreLocation框架,地理位置编码与反编码

在现代互联网时代,越来越多的应用,都用到了地图定位功能,在iOS开发中,想要加入这种功能,必须基于两个框架进行开发:

1.Map Kit:用于显示地图, 2.CoreLocation:用于显示地理位置

这里我们简单了解一下CoreLocation,用于显示地理位置,坐标信息.

一、相关类介绍

  • CLLocationManager。用于定位服务管理类,它能够给我们提供位置信息和高度信息,也可以监控设备进入或离开某个区域,还可以获得设备的运行方向。
  • CLLocation。封装了位置和高度信息。
  • CLLocationManagerDelegate。CLLocationManager类的委托协议.

    CLLocationManager 定位的基础信息
    CLLocation  某个位置的地理信息
    CLLocationCoordinate2D  存放经纬度的结构体
    CLGeocoder 地理位置编码与反编码的类
    CLPlacemark 地标.

二、CLLocationManager相关属性介绍

  1. @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;//定位的精度设置
  2. @property(assign, nonatomic) CLLocationDistance distanceFilter;///设备移动后获得位置信息的最小距离
  3. @property(assign, nonatomic, nullable)id delegate;
  4. - (void)requestWhenInUseAuthorization;//弹出用户授权对话框,使用程序期间授权
  5. - (void)requestAlwaysAuthorization;//始终授权
  6. - (void)startUpdatingLocation;//开始定位,每次要使用的时候都要打开一下.
  7. - (void)stopUpdatingLocation;//停止定位,每次定位完后,建议关闭,这样更加省电,用户体验更好.
    desiredAccuracy是一个很重要的属性,它的取值有6个常量,具体如下:

    CLLocationAccuracy 是一个枚举值
    /*
    最佳导航:kCLLocationAccuracyBestForNavigation //一般有外接电源的时候使用,车载的时候可以用导航,比较费电.
    最精准:kCLLocationAccuracyBest;  //设备使用电池供电时的最高精度
    精确到10米:kCLLocationAccuracyNearestTenMeters;
    精确到百米:kCLLocationAccuracyHundredMeters;
    精确到千米:kCLLocationAccuracyKilometer;
    精确到3千米: kCLLocationAccuracyThreeKilometers;     
    */

对于授权属性使用之前,需要对Info.plist属性列表文件进行配置,这点不要忘了.

注意:从iOS 7之后,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经过用户批准授权:
①要想获得用户的位置和访问用户的通讯录、日历、相机、相册等等都需要用户来手动授权。
②当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权.

随便点个+就行了,然后将授权添加进Info.plist文件中.

这样,我们用代码来更好的说明定位:

  1 #import "ViewController.h"
  2 //第一步:引入头文件
  3 #import <CoreLocation/CoreLocation.h>
  4 @interface ViewController ()<CLLocationManagerDelegate>
  5 //CoreLocation框架中的CLLocationManager用于管理定位的管理器.是主要的操作对象<需要执行代理>
  6 @property (nonatomic, strong)CLLocationManager *manager;
  7 //地理位置反编码
  8 @property (nonatomic, strong)CLGeocoder *geocoder;
  9 @end
 10 
 11 @implementation ViewController
 12 
 13 - (void)viewDidLoad {
 14     [super viewDidLoad];
 15     //定位的步骤:
 16     
 17     //第一步:初始化定位管理器
 18     self.manager = [[CLLocationManager alloc] init];
 19     //第二步:进行隐私的判断和授权
 20     //进行隐私的判断
 21     if (![CLLocationManager locationServicesEnabled]) {
 22         NSLog(@"是否前往隐私,设置定位权限");
 23     }
 24      //根据状态进行授权
 25     //判断当前系统版本,是否是8.0以上
 26     if ([[[UIDevice currentDevice] systemVersion] integerValue] >= 8.0) {
 27         //状态进行判断(此应用使用过程中允许访问定位服务)
 28         if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) {
 29             /*
 30              定位服务授权状态,返回枚举类型:
 31             kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务
 32             kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
 33             kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
 34             kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态
 35             kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务
 36              */
 37             //在授权请求之前需要在infoPlist中设置允许定位的内容:NSLocationWhenInUseUsageDescription
 38             //请求授权,弹出用户授权框,使用程序期间授权
 39             [self.manager requestWhenInUseAuthorization];
 40             //始终授权
 41             //[self.manager requestAlwaysAuthorization];
 42         }
 43     }
 44     
 45     //第三步:设置定位管理器代理
 46     self.manager.delegate = self;
 47     //设置精确度(单位是米)(越精确越耗电)
 48     self.manager.desiredAccuracy = 100;
 49     //设置最小更新距离
 50     self.manager.distanceFilter = 100;
 51     
 52     //第四步:开启定位
 53     [self.manager startUpdatingLocation];
 54     
 55     
 56     
 57     /*****************编码与反编码********************/
 58     
 59     //初始化
 60     self.geocoder = [[CLGeocoder alloc] init];
 61     
 62     //根据地名获取经纬度
 63 //    [self getCoordinateByAddress:@"北京"];
 64     
 65     //根据经纬度反编码取出地名
 66     [self getAddressByLongitude:113 Latitude:23];
 67     
 68     //计算两点之间的距离
 69     [self distance];
 70     
 71   
 72 }
 73 
 74 #pragma mark - 计算两个点之间的距离
 75 - (void)distance {
 76     //北京到大连的距离
 77     //创建位置一:北京
 78     CLLocation *locationBJ = [[CLLocation alloc] initWithLatitude:40 longitude:116];
 79     //创建位置二:大连
 80     CLLocation *locationDL = [[CLLocation alloc] initWithLatitude:39 longitude:121];
 81     //北京到大连的距离
 82     CLLocationDistance distance = [locationBJ distanceFromLocation:locationDL];
 83     
 84     NSLog(@"北京到大连的距离%f", distance);
 85 
 86 }
 87 
 88 
 89 
 90 #pragma mark - 根据经纬度获取地址
 91 - (void)getAddressByLongitude:(CLLocationDegrees)longitude Latitude:(CLLocationDegrees)latitude {
 92     
 93     //反编码
 94     //创建CLLocation
 95     CLLocation *locations = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
 96     [_geocoder reverseGeocodeLocation:locations completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
 97         
 98         if (error == nil) {
 99             NSDictionary *dic = placemarks.firstObject.addressDictionary;
100             NSLog(@"反编码地理位置信息%@", dic);
101         } else {
102              NSLog(@"%@", error);
103         }
104        
105     }];
106     
107 }
108 
109 
110 #pragma mark - 根据地名获取相关信息
111 - (void)getCoordinateByAddress:(NSString *)address {
112    // CLPlacemark中所包含的地理位置信息
113     //        NSString *name=placemark.name;//地名
114     //        NSString *thoroughfare=placemark.thoroughfare;//街道
115     //        NSString *subThoroughfare=placemark.subThoroughfare; //街道相关信息,例如门牌等
116     //        NSString *locality=placemark.locality; // 城市
117     //        NSString *subLocality=placemark.subLocality; // 城市相关信息,例如标志性建筑
118     //        NSString *administrativeArea=placemark.administrativeArea; //119     //        NSString *subAdministrativeArea=placemark.subAdministrativeArea; //其他行政区域信息
120     //        NSString *postalCode=placemark.postalCode; //邮编
121     //        NSString *ISOcountryCode=placemark.ISOcountryCode; //国家编码
122     //        NSString *country=placemark.country; //国家
123     //        NSString *inlandWater=placemark.inlandWater; //水源、湖泊
124     //        NSString *ocean=placemark.ocean; // 海洋
125     //        NSArray *areasOfInterest=placemark.areasOfInterest; //关联的或利益相关的地标
126     //编码方法
127     [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
128         
129        //error:出错时,错误信息,placemarks地标的意思,封装这详细的地址位置信息
130         CLPlacemark *mark = placemarks.firstObject;
131         //根据地标得到location
132         CLLocation *location = mark.location;
133         //a根据location获取区域
134         CLRegion *region = mark.region;
135         //获取字典信息
136         NSDictionary *addressDic = mark.addressDictionary;
137         
138         NSLog(@"地理位置%@, 区域%@, 详细地址%@", location, region, addressDic);
139     }];
140 }
141 
142 
143 
144 #pragma mark - 代理方法
145 //定位成功之后,开始更新位置信息(只要移动了最小距离就会开始执行这个代理方法)
146 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
147     
148     //获取最后一次的位置
149     CLLocation *location = locations.lastObject;
150     
151     //获取位置坐标
152     CLLocationCoordinate2D coordinate = location.coordinate;
153     
154     //longitude经度,latitude纬度
155     NSLog(@"经度%f, 纬度%f, 海拔%f, 航向%f, 行走速度%f", coordinate.longitude, coordinate.latitude, location.altitude, location.course, location.speed);
156     
157     //为了节省电源,如果不适用定位,需要把定位关掉
158     [self.manager stopUpdatingLocation];
159     
160 }
161 
162 //定位失败
163 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
164     NSLog(@"定位失败%@", error);
165 }

 

posted @ 2016-05-31 20:39  24桥明月夜  阅读(431)  评论(0编辑  收藏  举报