地图相关 CoreLocation框架介绍请求用户授权方法CLLocationManager 属性和方法CLLocation 位置对象介绍三、地理编码的实现

介绍

1.导入主头文件 #import <CoreLocation/CoreLocation.h>

2.地图和定位功能基于2个框架进行开发: (1)Map Kit :用于地图展示 (2)CoreLocation:用于地理定位,有时只用定位,比如外卖,只有需要显示地图才用map kit

3.2个热门专业术语: (1)LBS :Location Based Service 位置服务,又称定位服务 LBS的服务归纳为四类:定位(个人位置定位)、导航(路径导航)、查询(查询某个人或某个对象)、识别(识别某个人或对象)、事件检查(当出现特殊情况下向相关机构发送带求救或查询的个人位置信息)。 (2)SoLoMo :Social Local Mobile(索罗门) 移动社交

4.天朝的经纬度范围:纬度范围:N 3°51′ ~ N 53°33′ 经度范围:E 73°33′ ~ E 135°05′


1、如果定位方法不走原因: (1)没有配置 plist 键值 (2)模拟器 bug (3)没有使用 strong 的属性

2、逻辑结构

逻辑结构


请求用户授权方法

注意:

  1. 一步代码,一步plist配置
  2. 请求授权iOS8以后才有,一定注意版本适配!
  3. 如果同时实现两个请求, 第一次运行会弹出第一个, 第二次运行会弹出第二个,大部分应用程序只需要使用用户使用期间授权即可
  4. 如果程序列表中出现了3行(即永不定位,使用应用期间,始终定位),说明实现了2种授权

设置界面

  1. plist添加的用户提示信息可以不写值,表示空白提示,一般写上需要定位的原因,提高用户打开的几率
1. 代码:
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        // 永久授权
        [self.locationManager requestAlwaysAuthorization];
        //用户使用时授权,大部分的应用应该使用此种授权方式,当能看见程序时才能定位
        [self.locationManager requestWhenInUseAuthorization];
    }
}
2. plist文件配置

① 使用期间授权:添加该键,值是用户提示信息 NSLocationWhenInUseUsageDescription

plist配置

② 永久始终授权:添加该键,值是用户提示信息 NSLocationAlwaysUsageDescription

plist配置

③ iOS9.0新特性:临时获取后台定位权限(永久授权) 注意:该方式进入后台后会有提示

iOS 9 新特性

代码:iOS9 临时开启后台定位, allowsBackgroundLocationUpdates属性设置为YES

if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
    self.locationManager.allowsBackgroundLocationUpdates = YES;
}

plist:需要配置Plist,不然会崩溃,是一个数组,值添加到一个数组的对象当中 键 :Required background modes 数组值:App registers for location updates

iOS 9 plist配置


CLLocationManager 属性和方法

注意:

  1. 想要使用定位, 必须使用CLLocationManager(位置管理器)创建一个对象
  2. iOS8以后, 要定位, 必须使用位置管理器授权,并配置plist
  3. 使用期间授权:APP退到后台就不进行定位了 始终授权:后台也会进行定位,例如记录跑步,持续定位需要对电量做些优化(设置两个属性)

设置界面

  1. 一般请求定位放在appDelegate中,在加载页面之前就定位好
下面两个属性设置后可以降低代理方法调用频率(默认大约一秒调用一次),以此省电,始终持续定位时候建议使用

属性:

  1. 距离筛选器,每隔多少米定位一次,单位:米,当用户发生一定位置的改变时, 再去调用代理方法, 以此实现省电
@property(assign, nonatomic) CLLocationDistance distanceFilter;

例子:每隔十米定位一次

self.locationManager.distanceFilter = 10;
  1. 定位精确度(越精确就越耗电)
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

降低精准度,实际上降低了与卫星之间的计算,以此节省电量

Iphone的定位方式:(1)GPS(2)wifi定位(3)移动基站定位(流量)

例子:设置定位精度误差一千米 self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; 枚举值:iOS9以前默认kCLLocationAccuracyBest kCLLocationAccuracyBestForNavigation 最精确的定位 kCLLocationAccuracyBest; 最好的 kCLLocationAccuracyNearestTenMeters; 十米误差 kCLLocationAccuracyHundredMeters; 一百米 kCLLocationAccuracyKilometer; 一千米 kCLLocationAccuracyThreeKilometers; 三千米

方法:

1.开始用户定位

- (void) startUpdatingLocation;

2.停止用户定位

- (void) stopUpdatingLocation;

代理方法

当调用了startUpdatingLocation方法后,就开始不断地调用该代理方法定位用户的位置,locations参数里面装着一组CLLocation对象,持续定位需要设置 distanceFilter 和 desiredAccuracy 属性

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

CLLocation 位置对象介绍

CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等,创建一个 CLLocation对象只需要两个参数:纬度和经度

属性:

(1)2D位置坐标,经纬度

@property(readonly, nonatomic) CLLocationCoordinate2D coordinate;

CLLocationDegrees latitude 纬度 CLLocationDegrees longitude 经度

(2)海拔

@property(readonly, nonatomic) CLLocationDistance altitude;

(3)速度(单位是m/s)

@property(readonly, nonatomic) CLLocationSpeed speed;

(4)水平 垂直精准度

@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;

(5)航向(取值范围是0.0° ~ 359.9°,0.0°代表真北方向)

@property(readonly, nonatomic) CLLocationDirection course;

(6)时间戳,什么时间进行的定位

@property(readonly, nonatomic, copy) NSDate *timestamp;

方法: (1)创建一个 CLLocation对象只需要两个参数:纬度和经度

- (instancetype)initWithLatitude:(CLLocationDegrees)latitude
longitude:(CLLocationDegrees)longitude;

(2)计算2个位置之间的距离,比较的是直线距离,单位是米,除以1000可以换算成千米

- (CLLocationDistance)distanceFromLocation:(constCLLocation *)location;

例子:计算北京和西安的位置直线距离

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:40.06 longitude:116.39];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:34.27 longitude:108.93];
CGFloat distance = [location2 distanceFromLocation:location1];
NSLog(@"distance: %f",distance / 1000);

例子:定位功能实现

1、 创建位置管理器
self.locationManager = [CLLocationManager new];

2、 请求用户授权(iOS8以后才有) 同时配置 plist 列表,注意:必须使用版本判断,建议结合使用
-----------------------------
有两种授权方式,还有一种始终 requestAlwaysAuthorization
if([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [self.locationManager requestWhenInUseAuthorization];
}

3、 设置 <CLLocationManagerDelegate>代理, 来获取用户位置数据
self.locationManager.delegate = self;

4、调用开始定位方法
[self.locationManager startUpdatingLocation];

5、实现代理方法拿到数据,当用户更新位置的时候调用此方法,频繁调用, 非常耗电
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    //CLLocation 位置对象 --> 经纬度
    //CLLocationCoordinate2D coordinate 经纬度

    //获取最后一次位置信息
    CLLocation *location = locations.lastObject;
    //输出纬度和经度
    NSLog(@"latitude: %f,longitude: %f",location.coordinate.latitude, location.coordinate.longitude);
    // 停止定位
    [self.locationManager stopUpdatingLocation];
}

三、地理编码的实现

  1. 正地理编码:将地名转换成经纬度的过程 步骤: (1)创建一个GLGeocoder对象

(2)实现地理编码方法 (3)遍历数组,获取数据(可能返回多个相同地名),如果对象大于1,应该给用户一个列表选择

  1. 反地理编码:将经纬度转换成地名的过程 步骤: (1)创建一个GLGeocoder对象 (2)创建一个CLLoction对象(经纬度) (3)实现反地理编码方法 (4)遍历数组,获取数组

CLGeocoder地理编码对象

一个属性:
@property (nonatomic, readonly, getter=isGeocoding) BOOL geocoding;
方法:

1、三个正地理编码方法

(1)
- (void)geocodeAddressDictionary:(NSDictionary *)addressDictionary completionHandler:(CLGeocodeCompletionHandler)completionHandler;

(2)最简单的,填入要搜索的位置,回调出搜索信息
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

(3)
- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region completionHandler:(CLGeocodeCompletionHandler)completionHandler;

2、一个反地理编码方法

- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

3、取消编码

- (void)cancelGeocode;

回调的block参数CLGeocodeCompletionHandler typedef void (^CLGeocodeCompletionHandler)(NSArray< CLPlacemark *> * __nullable placemarks, NSError * __nullable error);

block参数:
  1. placemarks:CLPlacemark 地标对象,里面封装各种详细地址信息,如街道名,城市名,国家名等
  2. error :当编码出错时有值(比如编码不出具体的信息)
CLPlacemark 地标对象:
- (instancetype)initWithPlacemark:(CLPlacemark *) placemark;
1、主要获取的属性,位置对象,能获取到经纬度信息
@property (nonatomic, readonly, copy, nullable) CLLocation *location;

@property (nonatomic, readonly, copy, nullable) CLRegion *region;

@property (nonatomic, readonly, copy, nullable) NSTimeZone *timeZone ( 9_0))
@property (nonatomic, readonly, copy, nullable) NSDictionary *addressDictionary;
详细地址名(包括等到门牌等)
@property (nonatomic, readonly, copy, nullable) NSString *name;
街道名
@property (nonatomic, readonly, copy, nullable) NSString *thoroughfare;
子街道名
@property (nonatomic, readonly, copy, nullable) NSString *subThoroughfare;
城市
@property (nonatomic, readonly, copy, nullable) NSString *locality;
子城市
@property (nonatomic, readonly, copy, nullable) NSString *subLocality;
行政区域
@property (nonatomic, readonly, copy, nullable) NSString *administrativeArea;
子行政区域
@property (nonatomic, readonly, copy, nullable) NSString *subAdministrativeArea;
@property (nonatomic, readonly, copy, nullable) NSString *postalCode;
@property (nonatomic, readonly, copy, nullable) NSString *ISOcountryCode;
国家
@property (nonatomic, readonly, copy, nullable) NSString *country;
@property (nonatomic, readonly, copy, nullable) NSString *inlandWater;
@property (nonatomic, readonly, copy, nullable) NSString *ocean;
@property (nonatomic, readonly, copy, nullable) NSArray<NSString *> *areasOfInterest;

正地理编码例子

//1. 创建 Geocoder
CLGeocoder *geocoder = [CLGeocoder new];
//2. 调用方法
[geocoder geocodeAddressString:self.addressTF.text completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //3.1 防错处理
    if (placemarks.count == 0 || error) {
        NSLog(@"没有数据或数据解析出错");
        return;
    }
    //3.2 遍历地标数组placemarks,地理编码容易出现多个地标,应该给用户一个列表去选择
    for (CLPlacemark *pm in placemarks) {
        //3.3 设置纬度
        self.latitudeLabel.text = [NSString stringWithFormat:@"%f",pm.location.coordinate.latitude];
        //3.4 设置经度
        self.longitudeLabel.text = [NSString stringWithFormat:@"%f",pm.location.coordinate.longitude];
        //3.5 设置地址
        self.detailAddressLabel.text = pm.name;
    }
}];

反地理编码例子

//1. 创建 Geocoder 对象
CLGeocoder *geocoder = [CLGeocoder new];
//2. 创建 CLLocation对象,输入经纬度信息
CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text floatValue] longitude:[self.longitudeTF.text floatValue]];
//3. 调用反地理编码方法
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //3.1 防错处理
    if (placemarks.count == 0 || error) {
        NSLog(@"没有数据或数据解析出错");
        return;
    }
    //3.2 遍历数据
    for (CLPlacemark *pm in placemarks) {
        //3.3. 获取城市信息, 如果有城市信息就显示, 否则可以显示行政区域
        if (pm.locality) {
            //locality : 城市
            self.cityLabel.text = pm.locality;
        } else {
            //administrativeArea : 行政区域
            self.cityLabel.text = pm.administrativeArea;
        }
    }
}];

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏wOw的Android小站

[iOS] WSHorizontalPickerView 图片水平滚动封装

之前这篇文章传送门本来是记录自己练手的demo的,后来很多人来问我要代码。今天就抽时间封装了一下,没有考虑太多情况,等我有空再去仔细考虑吧。

841
来自专栏互联网开发者交流社区

Robots协议

1647
来自专栏我杨某人的青春满是悔恨

Kingfisher源码阅读(三)

上一篇地址:Kingfisher源码阅读(二) 第一篇地址:Kingfisher源码阅读(一)

1124
来自专栏飞雪无情的博客

Android布尔型配置存储优化

在Android开发的过程中,我们基本上都会遇到是否开启自动备份、是否保存账号、是否自动登陆、是否开启向导等这样的选项功能,对于这类功能,我们一般的做法是采用S...

1073
来自专栏IMWeb前端团队

React函数式进阶

React让很多人让追捧的一个特性是它的所有的组件都是完全由JavaScript组成的。组件的定义是JavaScript,组件的模板也可以是JavaScript...

2356
来自专栏向治洪

iOS Hybrid 框架

前言 Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”...

4738
来自专栏GIS讲堂

Arcgis for Android解决中文字体乱码的问题

首先,在此感谢Arcgis for Android群里的一位成员,大家可以加进来QQ群号:337469080。

1554
来自专栏点滴积累

Cesium中Clock控件及时间序列瓦片动态加载

前言 前面已经写了两篇博客介绍Cesium,一篇整体上简单介绍了Cesium如何上手,还有一篇介绍了如何将Cesium与分布式地理信息处理框架Geotrelli...

4504
来自专栏有趣的Python和你

Python数据分析之贴吧的问与答读取数据库获取question列分词词云

1253
来自专栏圣杰的专栏

Asp.net mvc 知多少(三)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想...

2126

扫码关注云+社区

领取腾讯云代金券