CoreLocation 定位 iOS 地图 反编码
CoreLocation 实现基于 8.0 之后的使用方法, 8.0 前后使用方法是有区别的。
相关框架,类注释 API:
- CoreLocation 框架主要用于地理定位,地理编码等。
- CoreLocation 框架中使用 CLLocationManager 对象来做用户定位
- CLGeocoder 根据地址关键字, 进行地理编码, 通过地址获取经纬度.
- CLPlacemark 存储坐标数据,对于一个给定的经度和纬度。标数据包含的信息,如国家,州,城市,街道地址指定的坐标。它也可以包括点利息和地理位置相关的数据。此类有16个属性、1个实例方法。
创建流程:
- 创建定位管理对象
- 设置定位管理对象(设置过滤、设置定位精度)
- 设置定位管理对象的代理
- 实现<CLLocationManagerDelegate>协议里的代理方法
- 开始定位
首先导入 CoreLocation.framework 框架,并在 VC 中引入头文件,签订协议
#import <CoreLocation/CoreLocation.h>
<CLLocationManagerDelegate>
iOS 8.0 之后要注意,从iOS 8.0开始,苹果进一步加强了对用户隐私的保护。
当app想访问用户的隐私时,系统不再自动弹出一个对话框让用户授
(1) 调用ios8.0的api。主动请求用户授权
-(void)requestAlwaysAuthorization // 请求允许在前后台都能获取用户位置的授权
-(void)requestWhenInUseAuthorization // 请求允许在前台获取用户位置的授权(注意:当设置为前台授权时,通过设置后台模式:location updates后
也可以后台获取定位信息,但是屏幕上方会出现蓝条)
在Info.plist文件中添加如下配置:
(1)NSLocationAlwaysUsageDescription
(2)NSLocationWhenInUseUsageDescription
添加的这两个描述为弹窗的提示内容
代码示例:
desiredAccuracy 属性枚举值: kCLLocationAccuracyBestForNavigation 最适合导航 kCLLocationAccuracyBest 精度最好的 kCLLocationAccuracyNearestTenMeters 附近10米 kCLLocationAccuracyHundredMeters 附近100米 kCLLocationAccuracyKilometer 附近1000米 kCLLocationAccuracyThreeKilometers 附近3000米
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
//位置管理器
@property(nonatomic,strong)CLLocationManager *locMgr;
//位置编码
@property(nonatomic, strong)CLGeocoder *coder;
@end
@implementation ViewController
#pragma mark-懒加载
- (CLLocationManager *)locMgr{
if (!_locMgr ) {
//1.创建位置管理器(定位用户的位置)
self.locMgr=[[CLLocationManager alloc]init];
//2.设置代理
self.locMgr.delegate=self;
}
return _locMgr;
}
// 位置编码
- (CLGeocoder *)coder{
// _coder == nil
if (!_coder) {
self.coder = [[CLGeocoder alloc] init];
}
return _coder;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//判断用户定位服务是否开启
if ([CLLocationManager locationServicesEnabled]) {
// iOS 8 之后添加 始终允许访问位置信息, 请求前台定位授权, 并在Info.Plist文件中配置Key ( Nslocationwheninuseusagedescription )
[self.locMgr requestAlwaysAuthorization];
//当用户使用的时候授权
[locationManager requestWhenInUseAuthorization];
//开始定位用户的位置
[self.locMgr startUpdatingLocation];
//每隔多少米定位一次(这里的设置为任何的移动)
self.locMgr.distanceFilter = kCLDistanceFilterNone;
//设置定位的精准度,一般精准度越高,越耗电(这里设置为精准度最高的,适用于导航应用)
self.locMgr.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
}else
{//不能定位用户的位置
//1.提醒用户检查当前的网络状况
//2.提醒用户打开定位开关
}
//测试方法,计算两个位置之间的距离
[self countDistance];
}
#pragma mark-CLLocationManagerDelegate
/**
* 当定位到用户的位置时,就会调用(调用的频率比较频繁)
*/
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//locations数组里边存放的是CLLocation对象,一个CLLocation对象就代表着一个位置
CLLocation *loc = [locations firstObject];
NSLog(@"定位到了");
//维度:loc.coordinate.latitude
//经度:loc.coordinate.longitude
NSLog(@"纬度=%f,经度=%f",loc.coordinate.latitude,loc.coordinate.longitude);
NSLog(@"%lu",(unsigned long)locations.count);
// 反编码
[self.coder reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error) {
// 包含区,街道等信息的地标对象
CLPlacemark *placemark = [placemarks firstObject];
// 城市名称
NSString *city = placemark.locality;
// 街道名称
NSString *street = placemark.thoroughfare;
// 全称
NSString *name = placemark.name;
NSString *str = [NSString stringWithFormat:@"%@, %@, %@", name,city,street];
NSLog(@"城市信息%@", str);
}];
//停止更新位置(如果定位服务不需要实时更新的话,那么应该停止位置的更新)
[self.locMgr stopUpdatingLocation];
}
// 定位错误的代理方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if ([error code] == kCLErrorDenied)
{
//访问被拒绝
NSLog(@"访问被拒绝");
}
if ([error code] == kCLErrorLocationUnknown) {
//无法获取位置信息
NSLog(@"无法获取位置信息");
}
}
//计算两个位置之间的距离
-(void)countDistance
{
//根据经纬度创建两个位置对象
CLLocation *loc1=[[CLLocation alloc]initWithLatitude:40 longitude:116];
CLLocation *loc2=[[CLLocation alloc]initWithLatitude:41 longitude:116];
//计算两个位置之间的距离
CLLocationDistance distance=[loc1 distanceFromLocation:loc2];
NSLog(@"(%@)和(%@)的距离=%fM",loc1,loc2,distance);
}
感谢:
http://www.jianshu.com/p/964b19ef0225
http://www.jianshu.com/p/ddbb722066f6
Demo 下载地址: