Map定位
定位功能:
定位是一个很常用的功能,如一些地图软件打开之后如果用户允许软件定位的话,那么打开软件后就会自动锁定到当前位置,如果用户手机移动,那么当前位置也会随着变化。要实现功能需要使用CoreLocation中的CLLocationManager类,首先看一下这个来的一些主要方法和属性:
类方法:
1.+(BOOL)locationServicesEnabled;
说明:是否启用定位服务,通常如果用户没有启用定位服务,可以提醒用户打开定位服务。
2.+(CLAuthorizationStatus)authorizationStatus;
说明:定位服务授权状态,返回枚举类型
kCLAuthorizationStatusNotDetermined:用户尚未作出决定是否启用定位服务
kCLAuthorizationStatusRestricted:没有获得用户授权使用定位服务,可能用户没有自己禁止访问权限
kCLAuthorizationStatusDenied:用户已经明确禁止应用定位服务或者当前系统定位服务处于关闭状态
kCLAuthorizationStatusAuthorizedAlways:应用获得授权可以一直使用定位服务,即使应用不在关闭状态
kCLAuthorizationStatusAuthorizedWhenInUse:使用此应用过程中允许访问定位服务
属性:
1.distanceFilter
说明:位置信息更新最小距离,只有移动大于这个距离才更新位置信息,默认为KCLDistanceFilterNone:不进行距离限制
2.desiredAccruacy
说明:定位精度,枚举类型:
kCLLocationAccuracyBest:最精确定位
CLLocationAccuracy kCLLocationAccuracyNearestTenMeters:十米误差范围
kCLLocationAccuracyHundredMeters:百米误差范围
kCLLocationAccuracyKilometer:千米误差范围
kCLLocationAccuracyThreeKilometers:三千米误差范围
对象方法:
1.startUpdatingLocation
说明:开始定位追踪,开始定位后将按照用户设置的更新频率执行-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;方法反馈定位信息
2.stopUpdatingLocation
说明:停止定位追踪
3.startUpdatingHeading
说明:开始导航方向追踪
4.stopUpdatingHeading
说明:停止导航方向追踪
5.startMonitoringForRegion 说明:开始对某个区域进行定位追踪,开始对某个区域进行定位后。如果用户进入或者走出某个区域会调用- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region和- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion*)region代理方法反馈相关信息
6.stopMonitoringForRegion
说明:停止对某个区域进行定位追踪
7.requestWhenInUseAuthorization
说明:请求获得应用使用时的定位服务授权,注意使用此方法前要在info.plist中配置NSLocationWhenInUseUsageDescription
8.requestAlwaysAuthorization
说明:请求获得应用一直使用定位服务授权,注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription
代理方法:
1.-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
说明:位置发生改变后执行(第一次定位到某个位置之后也会执行)
2.- (void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading;
说明:导航方向发生变化后执行
3.- (void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region
说明:进入某个区域之后执行
4.- (void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLRegion *)region
说明:走出某个区域之后执行
源代码:
//第一步:引入库的头文件
#import <CoreLocation/CoreLocation.h>
//遵守协议:<CLLocationManagerDelegate>
//CoreLocation框架中的CLLocationManager用于管理定位的管理器
@property (nonatomic,strong) CLLocationManager *manager;
//CoreLocation框架中的CLGeoCOder能进行编码和反编码
//编码与反编码的类
@property (nonatomic,strong) CLGeocoder *gencoder;
- (void) viewDidLoad {
[super viewDidLoad];
//定位的步骤
//第一步:初始化定位管理器
self.manager = [[CLLocationManager alloc] init];
//第二步:进行隐私的判断并授权
if(![CLLocationManger locationServicesEnabled]){
NSLog(@"是否前往隐私进行设置允许定位");
}
//当状态是不允许访问定位服务的时候,打开
if([CLLocationManager authorizationStatus] != KCLAuthorizationStatusAuthorizedWhenInUse){
//请求授权
[self.manager requestWhenInUseAuthorization];
}
//第三步:设置管理器的代理和相关属性
self.manager.delegate = self;
//设置精度(有误差100米)
self.manager.desiredAccuracy = 100;
//设置最小更新距离
self.manager.distanceFilter = 100;
//第四步:开启定位
[self.manager startUpdatingLocation];
#################编码和反编码##################
//初始化对象
self.gencoder = [[CLGencoder alloc] init];
//根据地名获取经纬度
[self getCoordinateByAddress:@"北京"];
//根据经纬度反编码出地名
[self getAddressByLongitude : 113 latitude : 23];
//计算两个地方之间的距离
[self distance];
}
#pragma mark - 距离
- (void) distance {
//创建位置1
CLLocation *locationBeijing = [[CLLocation alloc] initWithLatitude : 40 longitude :116];
//创建位置2
CLLocation *locationDalian = [[CLLocation alloc] initWithLatitude : 39 longitude:121];
CLLocation distance = [locationBeijing distanceFromLocation:locationDalian];
NSLog(@"北京到大连的距离:%f",distance);
}
#pragma mark -根据地名获取相关的信息
- (void) getCoordinateByAddress :(NSString *) address {
//编码方法
[self.geocoder geocodeAddressString:address completionHandler : ^(NSArray <CLPlacemark *>*_Nullable placemarks,NSError *_Nullable error){
//根据返回的地标,取出第一个位置(地标的位置)
CLPlacemark *mark = placemarks.firstObject;
//根据地标得到location
CLLocation *location = mark.location;
//根据location获取区域
CLRegin *region = mark.region;
//获取字典信息
NSDictionary *addressDic = mark.addressDictionary;
// NSString *name=placemark.name;//地名
// NSString *thoroughfare=placemark.thoroughfare;//街道
// NSString *subThoroughfare=placemark.subThoroughfare; //街道相关信息,例如门牌等
// NSString *locality=placemark.locality; // 城市
// NSString *subLocality=placemark.subLocality; // 城市相关信息,例如标志性建筑
// NSString *administrativeArea=placemark.administrativeArea; // 州
// NSString *subAdministrativeArea=placemark.subAdministrativeArea; //其他行政区域信息
// NSString *postalCode=placemark.postalCode; //邮编
// NSString *ISOcountryCode=placemark.ISOcountryCode; //国家编码
// NSString *country=placemark.country; //国家
// NSString *inlandWater=placemark.inlandWater; //水源、湖泊
// NSString *ocean=placemark.ocean; // 海洋
// NSArray *areasOfInterest=placemark.areasOfInterest; //关联的或利益相关的地标
NSLog(@"地标位置%@,区域%@,地理位置信息%@",location,mark,addressDic);
}];
}
#pragma mark - 进行反编码
- (void)getAddressByLongitude:(CLLoctionDegrees)longitude latitude:(CLLocationDegrees)latitude {
//反编码
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
[self.geocoder reverGeocoderLocation:location completionHandle:^(NSArray <CLPlacemark *>*_Nulable placemarks,NSError *_Nullable error){
NSDictionary *dic = placemarks.firstObject.addressDictionary;
NSLog(@"反编码地理位置信息:%@",dic);
}];
}
#pragma mark - CLLocationManagerDelegate的代理方法
//这个代理方法搜定位成功之后开始更新位置信息,只要移动设置的最小距离之后就开始执行这个方法
- (void) locationManager:(CLLocationManager *)manager didUpdatingLocations:(NSArray <CLLocation *>*)locations {
//获取最后一次的位置
CLLocation *location = locations.lastObject;
//获取位置坐标
CLLocationCoordinate2D coordinate = location.coordinate;
/*注意:
1.定位频率和定位精度并不应当越精确越好,需要视实际情况而定,因为越精确越耗性能,也就越费电。
2.定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法,这个方法返回一组地理位置对象数组,每个元素一个CLLocation代表地理位置信息(包含经度、纬度、海报、行走速度等信息),之所以返回数组是因为有些时候一个位置点可能包含多个位置。
3.使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源。
4.除了提供定位功能,CLLocationManager还可以调用startMonitoringForRegion:方法对指定区域进行监控。
*/
NSLog(@"经度%f,纬度%f,海拔%f,航海方向%f,速度%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);
//为了节省电源,如果不适用定位,需要把定位关掉
[self.manager stopUpdatingLocation];
}
//定位失败
- (void) locationManager:(CLLoctionManager *)manager didFailWithError:(NSError *)error {
}