高德地图持续定位与单次定位简谈(持续更新)
2019-01-21 本文已影响0人
愿红尘作伴
概述
高德 iOS 定位 SDK 提供了不依赖于地图定位的定位功能,开发者可以无地图显示的场景中便捷地为应用程序添加定位功能。iOS定位SDK提供了单次定位、连续定位、逆地理信息、地理围栏等功能
关于定位的一些环境配置自行参考高德定位 这篇文章就不多讨论了,只奔主题
单次定位与持续定位
1.单次定位,顾名思义,就是只执行一次的定位.高德的API并不会持续更新您的位置信息,只有在您调用的时候查询您此时位置的经纬度信息和逆地理编码信息
1.头文件引入
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
2.高德地图key配置
[AMapServices sharedServices].apiKey =@"您的key"; //需要您在appDelegate中配置
3.定位配置
#pragma - mark 高德地图单次定位
- (void)configLocationManager{
self.locationManager = [[AMapLocationManager alloc] init];
[self.locationManager setDelegate:self];
//设置期望定位精度
注意:高德提供了 kCLLocationAccuracyBest 参数,设置该参数可以获取到精度在10m左右的定位结果,但是相应的需要付出比较长的时间(10s左右),越高的精度需要持续定位时间越长
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
//设置不允许系统暂停定位
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
//设置定位超时时间
[self.locationManager setLocationTimeout:DefaultLocationTimeout];
//设置逆地理超时时间
[self.locationManager setReGeocodeTimeout:DefaultReGeocodeTimeout];
}
4.在下面方法中请求
注意:若您配置了持续定位,单次定位的方法就不会再调用了
[self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
if (error)
{
NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
if (error.code == AMapLocationErrorLocateFailed)
{
return;
}
}
NSLog(@"location:%@", location);
if (regeocode)
{
NSLog(@"reGeocode:%@", regeocode);
}
}];
细节说明:您在WIFI下的定位的位置会和您在移动网络下定位的位置信息有偏差!!!,这点很重要
1)我的手机定位为什么有时候会不准确?
一方面,网络定位依赖于周边监测到的基站和wifi信息,而这些信息有受各种因素的影响发生变化或者采集有误,导致定位的偏差。
另一方面,定位本身也有一定精度范围随机误差,从几十米到上公里都是正常的情况,所以有时候看到定位结果有一定偏差,这也是为什么有时候您会看到您的位置并没有变化,但是定位位置却总在小范围的跳动的原因。
如果使用GPS定位,相对来说是定位比较精确的方式,但受限制一般只能在室外使用,且卫星信号容易受气象,遮挡等因素影响,而且手机自身GPS芯片的质量,也会对最终定位的的精准度有直接的影响。
2.持续定位,你可以在app启动期间不断的监控此刻使用者的位置,那么如何使用呢?
参考如下
1.头文件引入
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
2.高德地图key配置
[AMapServices sharedServices].apiKey =@"您的key"; //需要您在appDelegate中配置
3.持续定位配置
- (void)configLocationManager{
self.locationManager = [[AMapLocationManager alloc] init];
[self.locationManager setDelegate:self];
//设置不允许系统暂停定位--------这些话加上就会后台定位,就会出现您将程序进入后台,但是会在屏幕顶部出现小蓝条的现象
// [self.locationManager setPausesLocationUpdatesAutomatically:NO];
//iOS 9(不包含iOS 9) 之前设置允许后台定位参数,保持不会被系统挂起
// [self.locationManager setPausesLocationUpdatesAutomatically:NO];
// //iOS 9(包含iOS 9)之后新特性:将允许出现这种场景,同一app中多个locationmanager:一些只能在前台定位,另一些可在后台定位,并可随时禁止其后台定位。
// if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
// self.locationManager.allowsBackgroundLocationUpdates = YES;
// }
//设置定位超时时间
[self.locationManager setLocationTimeout:DefaultLocationTimeout];
//设置逆地理超时时间
[self.locationManager setReGeocodeTimeout:DefaultReGeocodeTimeout];
self.locationManager.distanceFilter = 200;//设置定位精度200米 200米去查询一次
self.locationManager.locatingWithReGeocode = YES;//
}
//仅供参考
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{
GSNSLog(@"0000000000-------------------reGeocode:%@", reGeocode);
GSNSLog(@"0000000000-------------------location:%@", location);
if (location) {//当定位成功的情况
self.errorView.hidden = YES;
if (reGeocode) {//当逆地理编码查询到的时候
CGFloat longitude = location.coordinate.longitude;
CGFloat latitude = location.coordinate.latitude;
NSString *province = reGeocode.province;
NSString *citycode = reGeocode.citycode;
NSString *adcode = reGeocode.adcode;
NSString *city = reGeocode.city;
NSString *district = reGeocode.district;
NSString *address = reGeocode.formattedAddress;
//放在模型里 存储经纬度和逆地理编码
self.currentLocationModel.longitude = longitude;
self.currentLocationModel.latitude = latitude;
self.currentLocationModel.province = province;
self.currentLocationModel.citycode = citycode;
self.currentLocationModel.adcode = adcode;
self.currentLocationModel.city = city;
self.currentLocationModel.district = district;
self.currentLocationModel.detailAddress = address;
if (self.firstLocationFlag == YES) {//当是第一次加载的情况
//记录首次加载
[self.locationBtn setTitle:city forState:UIControlStateNormal];
[self.listTableView.mj_header beginRefreshing];
self.firstLocationFlag = NO;
}else{//若非首次加载的话 需要判断上次加载的城市是否发生了改变
GSNSLog(@"上次加载的城市self.regecode.city%@",self.regecode.city);
GSNSLog(@"此次定位的城市reGeocode.city%@",reGeocode.city);
if (![reGeocode.city isEqualToString:self.regecode.city]) {//当城市发生改变的时候 弹窗提示
[self createAlertViewWithReGeocode:reGeocode andLocation:location];
}
}
self.regecode = reGeocode;
}else{//没查到不做任何事情
}
}else{
[CSToast showWithText:@"定位失败"];
[self.locationBtn setTitle:@"定位失败" forState:UIControlStateNormal];
}
}
//选择性添加,是否监听进入后台或者从后台进入前台是否重新开启或者关闭持续定位
- (void)addNotifacations{
//MARK:监听进入前后台
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationBecomeActive) name:UIApplicationWillEnterForegroundNotification object:nil];//监听进入前台
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];//从活动状态过度到不活动状态
}
- (void)applicationBecomeActive{//后台到前台要开启持续定位
[self.locationManager startUpdatingLocation];
}
- (void)applicationWillResignActive{//变成不活跃状态关闭定位 省电
[self.locationManager stopUpdatingLocation];
}
注意:
1.持续定位后单次定位方法不生效
2.持续定位开启后,push到其他页面持续定位是不关闭的,需要你手动关闭
3.手动关闭持续定位后,单次定位依旧可以使用