地图定位CLLocation详解

1.CLLocation主要有一下几个重要的属性

 /**

     *  CLLocation 详解

     *  coordinate : 经纬度

     *  altitude : 海拔

     *  course : 航向

     *  speed ; 速度

     */

1.1 distanceFromLocation: 方法

/*
 *  distanceFromLocation:
 *
 *  Discussion:
 *    Returns the lateral distance between two locations.
 */
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_2);


可以这样一小段代码计算

   
    CLLocation *l1 = [[CLLocation alloc] initWithLatitude:21.123 longitude:123.456];
    CLLocation *l2 = [[CLLocation alloc] initWithLatitude:22.123 longitude:123.456];
    
   CLLocationDistance distance = [l1 distanceFromLocation:l2];
    NSLog(@"distance=%f", distance);

结果:
[3308:176001] distance=110725.220969

2.course :航向

/**

     *  场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,

        例如:”北偏东 30 方向,移动了8

     */

<pre name="code" class="objc">#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>
{
    // 老位置
    CLLocation *_oldL;
}
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *lM;
@end

@implementation ViewController

#pragma mark - 懒加载
- (CLLocationManager *)lM
{
    if (!_lM) {
        
    
        // 1. 创建位置管理者
        _lM = [[CLLocationManager alloc] init];
        // 1.1 代理, 通知, block
        _lM.delegate = self;
        
        // 每隔多米定位一次
//        _lM.distanceFilter = 100;
        /**
           kCLLocationAccuracyBestForNavigation // 最适合导航
           kCLLocationAccuracyBest; // 最好的
           kCLLocationAccuracyNearestTenMeters; // 10m
           kCLLocationAccuracyHundredMeters; // 100m
           kCLLocationAccuracyKilometer; // 1000m
           kCLLocationAccuracyThreeKilometers; // 3000m
         */
        // 精确度越高, 越耗电, 定位时间越长
        _lM.desiredAccuracy = kCLLocationAccuracyBest;
        
        
        /** -------iOS8.0+定位适配-------- */
        
        if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
        {
            // 前台定位授权(默认情况下,不可以在后台获取位置, 勾选后台模式 location update, 但是 会出现蓝条)
            [_lM requestWhenInUseAuthorization];
            
            
            // 前后台定位授权(请求永久授权)
            // +authorizationStatus != kCLAuthorizationStatusNotDetermined
            // 这个方法不会有效
            // 当前的授权状态为前台授权时,此方法也会有效
//            [_lM requestAlwaysAuthorization];

        }
        // 允许后台获取用户位置(iOS9.0)
         if([[UIDevice currentDevice].systemVersion floatValue] >= 9.0)
         {
             // 一定要勾选后台模式 location updates
             _lM.allowsBackgroundLocationUpdates = YES;
         }
        
//        if ([_lM respondsToSelector:@selector(requestAlwaysAuthorization)])
//        {
//            [_lM requestAlwaysAuthorization];
//        }
        
    }
    return _lM;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.lM startUpdatingLocation];
    
//    CLLocation *l1 = [[CLLocation alloc] initWithLatitude:21.123 longitude:123.456];
//    CLLocation *l2 = [[CLLocation alloc] initWithLatitude:22.123 longitude:123.456];
//    
//   CLLocationDistance distance = [l1 distanceFromLocation:l2];
//    NSLog(@"distance=%f", distance);
    
}


#pragma mark - CLLocationManagerDelegate
/**
 *  更新到位置之后调用
 *
 *  @param manager   位置管理者
 *  @param locations 位置数组
 * is kind of
 */
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
//    NSLog(@"定位到了");
    /**
     *  CLLocation 详解
     *  coordinate : 经纬度
     *  altitude : 海拔
     *  course : 航向
     *  speed ; 速度
     */

    CLLocation *location = [locations lastObject];
    
//    NSLog(@"%@", location);
    
    /**
     *  场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
        例如:”北偏东 30度  方向,移动了8米”
     */
    
    // 1. 获取方向偏向
    NSString *angleStr = nil;
    
    switch ((int)location.course / 90) {
        case 0:
            angleStr = @"北偏东";
            break;
        case 1:
            angleStr = @"东偏南";
            break;
        case 2:
            angleStr = @"南偏西";
            break;
        case 3:
            angleStr = @"西偏北";
            break;
            
        default:
            angleStr = @"跑沟里去了!!";
            break;
    }
    // 2. 偏向角度
    NSInteger angle = 0;
    angle = (int)location.course % 90;
    
    // 代表正方向
    if (angle == 0) {
        NSRange range = NSMakeRange(0, 1);
        angleStr = [NSString stringWithFormat:@"正%@", [angleStr substringWithRange:range]];
    }
    // 3.移动多少米
    double distance = 0;
    if(_oldL)
    {
        distance = [location distanceFromLocation:_oldL];
    }
    _oldL = location;
    
    // 4. 拼串 打印
    // 例如:”北偏东 30度  方向,移动了8米”
    NSString *noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移动了%f米", angleStr, angle, distance];
    NSLog(@"%@", noticeStr);
    
    
    
    
}

/**
 *  授权状态发生改变时调用
 *
 *  @param manager 位置管理者
 *  @param status  状态
 */
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
            // 用户还未决定
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用户还未决定");
            break;
        }
            // 问受限
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"访问受限");
            break;
        }
            // 定位关闭时和对此APP授权为never时调用
        case kCLAuthorizationStatusDenied:
        {
            // 定位是否可用(是否支持定位或者定位是否开启)
            if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"定位开启,但被拒");
            }else
            {
                NSLog(@"定位关闭,不可用");
            }
//            NSLog(@"被拒");
            break;
        }
            // 获取前后台定位授权
        case kCLAuthorizationStatusAuthorizedAlways:
            //        case kCLAuthorizationStatusAuthorized: // 失效,不建议使用
        {
            NSLog(@"获取前后台定位授权");
            break;
        }
            // 获得前台定位授权
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"获得前台定位授权");
            break;
        }
        default:
            break;
    }

    
    
}

// 定位失败
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"定位失败");
}

@end

3.指南针

3.1.磁北角度

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  CLHeading  
  3.  *  magneticHeading : 磁北角度 
  4.  *  trueHeading : 真北角度 
  5.  */  


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import "ViewController.h"  
  2. #import <CoreLocation/CoreLocation.h>  
  3.   
  4.   
  5. @interface ViewController ()<CLLocationManagerDelegate>  
  6.   
  7. /** 位置管理者 */  
  8. @property (nonatomicstrongCLLocationManager *lM;  
  9.   
  10. @property (weak, nonatomic) IBOutlet UIImageView *compassView;  
  11.   
  12.   
  13.   
  14. @end  
  15.   
  16. @implementation ViewController  
  17.   
  18.   
  19. - (CLLocationManager *)lM  
  20. {  
  21.     if (!_lM) {  
  22.         _lM = [[CLLocationManager alloc] init];  
  23.         _lM.delegate = self;  
  24.           
  25.         // 每隔多少度更新一次  
  26.         _lM.headingFilter = 2;  
  27.           
  28.     }  
  29.     return _lM;  
  30. }  
  31.   
  32. - (void)viewDidLoad {  
  33.     [super viewDidLoad];  
  34.      
  35.       
  36.     // 开始监听设备朝向  
  37.     [self.lM startUpdatingHeading];  
  38.       
  39. }  
  40.   
  41.   
  42. #pragma mark - CLLocationManagerDelegate  
  43. /** 
  44.  *  获取到手机朝向时调用 
  45.  * 
  46.  *  @param manager    位置管理者 
  47.  *  @param newHeading 朝向对象 
  48.  */  
  49. -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading  
  50. {  
  51.     /** 
  52.      *  CLHeading  
  53.      *  magneticHeading : 磁北角度 
  54.      *  trueHeading : 真北角度 
  55.      */  
  56.       
  57.     NSLog(@"%f", newHeading.magneticHeading);  
  58.       
  59.     CGFloat angle = newHeading.magneticHeading;  
  60.       
  61.     // 把角度转弧度  
  62.     CGFloat angleR = angle / 180.0 * M_PI;  
  63.       
  64.     // 旋转图片  
  65.     [UIView animateWithDuration:0.25 animations:^{  
  66.         self.compassView.transform = CGAffineTransformMakeRotation(-angleR);  
  67.     }];  
  68.       
  69.       
  70. }  
  71.   
  72.   
  73.   
  74. @end  

4.区域监听

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>

/**  位置管理者 */
@property (nonatomic, strong) CLLocationManager *lM;

@end

@implementation ViewController

- (CLLocationManager *)lM
{
    if (!_lM) {
        _lM = [[CLLocationManager alloc] init];
        _lM.delegate = self;
        //请求用户定位授权
        if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
        {
            [_lM requestAlwaysAuthorization];
        }
        
    }
    return _lM;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

    // 区域监听
    CLLocationCoordinate2D center = {21.13, 123.456};
    CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:1000 identifier:@"walden"];
    
//    [self.lM startMonitoringForRegion:region];
    
//    CLLocationCoordinate2D center2 = {21.13, 123.456};
//    CLCircularRegion *region2 = [[CLCircularRegion alloc] initWithCenter:center2 radius:1000 identifier:@"walden"];
//    
//    [self.lM startMonitoringForRegion:region2];

    // 请求区域状态
    [self.lM requestStateForRegion:region];

}

#pragma mark - CLLocationManagerDelegate
// 进入区域
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"进入区域--%@", region.identifier);
}

// 离开区域
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"离开区域--%@", region.identifier);
}


-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    NSLog(@"%zd", state); //这个state是个枚举值
    
    /**
     * CLRegionState
     *
     * Discussion:
     *    Represents the current state of the device with reference to a region.
     *
     *
    typedef NS_ENUM(NSInteger, CLRegionState){
        CLRegionStateUnknown,
        CLRegionStateInside,
        CLRegionStateOutside
    } NS_ENUM_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED __WATCHOS_PROHIBITED;
     */
}



@end

5.地理编码与反地理编码

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextView *addressTV;
@property (weak, nonatomic) IBOutlet UITextField *laTF;
@property (weak, nonatomic) IBOutlet UITextField *longTF;


/** 地理编码 */
@property (nonatomic, strong) CLGeocoder *geoC;


@end

@implementation ViewController

- (CLGeocoder *)geoC
{
    if (!_geoC) {
        _geoC = [[CLGeocoder alloc] init];
    }
    return _geoC;
}

- (IBAction)geoCoder {
    
    
    NSString *addr  = self.addressTV.text;
    
//    if ([addr length] == 0) {
//        return;
//    }
    
    [self.geoC geocodeAddressString:@"重庆" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        /**
         *  CLPlacemark
         location : 位置对象
         addressDictionary : 地址字典
         name : 地址全称
         */

        if(error == nil)
        {
            NSLog(@"%@", placemarks);
            [placemarks enumerateObjectsUsingBlock:^(CLPlacemark * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSLog(@"%@", obj.name);
                self.addressTV.text = obj.name;
                self.laTF.text = @(obj.location.coordinate.latitude).stringValue;
                self.longTF.text = @(obj.location.coordinate.longitude).stringValue;
            }];
        }else
        {
            NSLog(@"cuowu--%@", error.localizedDescription);
        }
   
    }];
    
}
- (IBAction)reverseGeoCoder {
    
    
    double lati = [self.laTF.text doubleValue];
    double longi = [self.longTF.text doubleValue];
    
    // TODO: 容错
    
    CLLocation *loc = [[CLLocation alloc] initWithLatitude:lati longitude:longi];
    [self.geoC reverseGeocodeLocation:loc completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if(error == nil)
        {
            NSLog(@"%@", placemarks);
            [placemarks enumerateObjectsUsingBlock:^(CLPlacemark * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSLog(@"%@", obj.name);
                self.addressTV.text = obj.name;
                self.laTF.text = @(obj.location.coordinate.latitude).stringValue;
                self.longTF.text = @(obj.location.coordinate.longitude).stringValue;
            }];
        }else
        {
            NSLog(@"cuowu");
        }
        
    }];
    
    
    
}



@end

效果:



 

6. INTULocationManager框架的使用

#import "ViewController.h"
#import "INTULocationManager.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
#warning 注意要在info.plist中配置请求用户隐私权限的key
    //精确度 超时  是否一直获取位置信息
//    INTULocationManager *locMgr = [INTULocationManager sharedInstance];
//    INTULocationRequestID requestID =  [locMgr requestLocationWithDesiredAccuracy:INTULocationAccuracyCity
//                                       timeout:5.0
//                          delayUntilAuthorized:YES
//                                         block:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
//                                             if (status == INTULocationStatusSuccess) {
//                                                 NSLog(@"%@", currentLocation);
//                                             }
//                                             else
//                                             {
//                                                 NSLog(@"cuowu--%zd", status);
//                                             }
//                                         }];
//    
    INTULocationManager *locMgr = [INTULocationManager sharedInstance];
    INTULocationRequestID requestID =  [locMgr subscribeToLocationUpdatesWithBlock:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
        if (status == INTULocationStatusSuccess) {
            NSLog(@"%@", currentLocation);
        }
        else
        {
            NSLog(@"cuowu--%zd", status);
        }
    }];
    
    
    // Force the request to complete early, like a manual timeout (will execute the block)
//    [[INTULocationManager sharedInstance] forceCompleteLocationRequest:requestID];
    
    // Cancel the request (won't execute the block)
//    [[INTULocationManager sharedInstance] cancelLocationRequest:requestID];


}

@end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值