美文网首页程序员
iOS开发-CoreLocation地图基本知识示例

iOS开发-CoreLocation地图基本知识示例

作者: 037e3257fa3b | 来源:发表于2017-02-21 17:36 被阅读0次

    可先建项目直接运行学习

    info.plist文件设置:


    CoreLocation.png

    模拟器模拟运动场景:


    5FFFC80F-43EA-4728-9648-7E9CB54EE0B2.png

    .m文件代码

    //
    //  ViewController.m
    //  CoreLocation
    //
    //  Created by admin on 17/2/21.
    //  Copyright © 2017年 zengchunjun. All rights reserved.
    //
    
    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    
    #define IOS7_Later [[UIDevice currentDevice].systemVersion floatValue] >= 7.0
    #define IOS8_Later [[UIDevice currentDevice].systemVersion floatValue] >= 8.0
    #define IOS9_Later [[UIDevice currentDevice].systemVersion floatValue] >= 9.0
    #define IOS10_Later [[UIDevice currentDevice].systemVersion floatValue] >= 10.0
    
    @interface ViewController ()<CLLocationManagerDelegate>
    
    @property (nonatomic,strong)CLLocationManager *locationManager;
    
    @property (nonatomic,strong)CLLocation *lastLoc;
    
    @end
    
    @implementation ViewController
    
    
    - (CLLocationManager *)locationManager
    {
        if (_locationManager == nil) {
            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.delegate = self;
            
            // 如果是ios8.0以后, 在想请求用户的位置信息, 需要主动的请求授权
            
            // 使用时授权
            [_locationManager requestWhenInUseAuthorization];
            
            // 前后台定位授权
    //        [_locationManager requestAlwaysAuthorization];
            // 如果当前的授权状态是前后台定位授权, 那么默认情况下, 就可以在后台获取用户位置信息, 不需要勾选后台模式location updates
            
            // 使用时授权 + 勾选后台模式location  updates
    //        [_locationManager requestWhenInUseAuthorization];
            // 效果 在后台确实可以获取到位置信息, 但是屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
            // 对于这个在后台使用定位的方式,在iOS 9之后需要加一句代码
    //        _locationManager.allowsBackgroundLocationUpdates = YES;
            
            
        }
        
        // 设置过滤距离
        // 每隔100米定位一次
        // 1 111KM/100M
        // 如果最新的位置距离上一次的位置之间的物理距离, 大于这个值, 就会通过代理来告诉我们最新的位置数据
        _locationManager.distanceFilter = 10;
        
        
        // 定位精确度
        //         kCLLocationAccuracyBestForNavigation // 最适合导航
        //         kCLLocationAccuracyBest; // 最好的
        //         kCLLocationAccuracyNearestTenMeters; // 附近10米
        //         kCLLocationAccuracyHundredMeters; // 附近100米
        //         kCLLocationAccuracyKilometer; // 附近1000米
        //         kCLLocationAccuracyThreeKilometers; // 附近3000米
        // 经验: 如果定位的精确度越高, 那么越耗电, 而且定位时间越长
        //
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        
        return _locationManager;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        // 标准定位服务 (gps/wifi/蓝牙/基站)
        [self.locationManager startUpdatingLocation];
        
        //  不能与 startUpdatingLocation同时使用
        // 必须实现代理的定位失败的方法 iOS 9以后的方法
    //    [self.locationManager requestLocation];
        
        // 显著位置变化的服务(基站进行定位, 电话模块)
    //    [self.locationManager startMonitoringSignificantLocationChanges];
        
        
        if ([CLLocationManager headingAvailable]) {// 判断 "磁力计"传感器 是否可用
            
            [self.locationManager startUpdatingHeading];
            
        }else
        {
            NSLog(@"当前磁力计设备不可用");
        }
        
        
        // CLLocation属性详解
        // coordinate: 经纬度信息
        // altitude: 海拔信息
        // horizontalAccuracy: 如果整个数字是负数, 就代表位置数据无效
        // verticalAccuracy:  如果整个数字是负数, 就代表海拔数据无效
        // course: 航向
        // speed: 速度
        // distanceFromLocation: 计算两个经纬度坐标之间的物理指向距离
        // 计算两点之间的距离
        CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:21.123 longitude:121.345];
        CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:22.123 longitude:121.345];
        CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
        NSLog(@"%.2f",distance);
        
        
    }
    
    
    #pragma mark CLLocationManagerDelegate
    // 检查磁力计朝向
    - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    {
        // 1. 拿到当前设备朝向
        /// 0- 359.9 角度
        
        CLLocationDirection angle = newHeading.magneticHeading;
        
        // 1.1 把角度转换成为弧度
        CGFloat hudu = (angle / 180 * M_PI);
        
        
        // 2. 反向旋转图片(弧度)
    //    UIView.animateWithDuration(0.5) {
    //        self.compassView.transform = CGAffineTransformMakeRotation(-hudu)
    //    }
        [UIView animateWithDuration:0.5 animations:^{
            
        }];
    }
    // 位置信息改变
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    {
        NSLog(@"获取到位置信息");
        CLLocation *newLocation = locations.lastObject;
    //    guard let newLocation = locations.last else {return}
        if (newLocation.horizontalAccuracy < 0)  return;
        // CLLocation
        // coordinate: 经纬度信息
        // altitude: 海拔信息
        // horizontalAccuracy: 如果整个数字是负数, 就代表位置数据无效
        // verticalAccuracy:  如果整个数字是负数, 就代表海拔数据无效
        // course: 航向
        // speed: 速度
        // distanceFromLocation: 计算两个经纬度坐标之间的物理指向距离
        
        //        场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
        //        例如:”北偏东 30度 方向,移动了 8米”
        
        // 1. 获取当前的行走航向
        NSArray *angleStrs = @[@"北偏东", @"东偏南", @"南偏西", @"西偏北"];
        int index = (int)(newLocation.course) / 90;
        NSString *angleStr = angleStrs[index];
        
        
        // 2. 行走的偏离角度
        int angle = (int)(newLocation.course) % 90;
        
        if (angle == 0) {
            
            angleStr = [@"正" stringByAppendingString:[angleStr substringToIndex:1]];
        }
        
        
        // 3. 移动了多少米
        CLLocation *lastLocation = _lastLoc ? _lastLoc : newLocation;
        CLLocationDistance distance = [newLocation distanceFromLocation:lastLocation];
        _lastLoc = newLocation;
        
        // 4. 合并字符串, 打印
        //        例如:”北偏东 30度 方向,移动了 8米”
        if (angle == 0) {
    //        print(angleStr + "方向, 移动了\(distance)米")
            NSLog(@"%@",[NSString stringWithFormat:@"%@方向,移动了%.2f米",angleStr,distance]);
        }else
        {
    //        print(angleStr + "\(angle)" + "方向, 移动了\(distance)米")
            NSLog(@"%@",[NSString stringWithFormat:@"%@%d方向,移动了%.2f米",angleStr,angle,distance]);
        }
    
    }
    
    // 定位失败
    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        NSLog(@"定位失败");
    }
    
    // 授权状态改变
    - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    {
    //    kCLAuthorizationStatusNotDetermined = 0,
    //    
    //    kCLAuthorizationStatusRestricted,
    //    
    //    kCLAuthorizationStatusDenied,
    //    
    //    kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),
    //    
    //    kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
    //
    //    kCLAuthorizationStatusAuthorized
        
        switch (status) {
                
        case kCLAuthorizationStatusNotDetermined:
                printf("用户没有决定");
                break;
        case kCLAuthorizationStatusRestricted:
                printf("受限制");
                break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
                printf("前台定位授权");
                break;
        case kCLAuthorizationStatusAuthorizedAlways:
                printf("前后台定位授权");
                break;
        case kCLAuthorizationStatusDenied:
            //            print("拒绝")
            // 判断当前设备是否支持定位, 并且定位服务是否开启
            if ([CLLocationManager locationServicesEnabled]) {
                printf("真正被拒绝");
                // 手动通过代码, 来跳转到设置界面
                if (IOS8_Later) {
                    
                    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                    if ([[UIApplication sharedApplication] canOpenURL:url]) {
                        [[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@""} completionHandler:nil];
                    }
                }
                
                
            }else {
                // 当我们在app内部想要访问用户位置, 但是当前的定位服务是关闭状态, 那么系统会自动弹出一个窗口, 快捷跳转到设置界面, 让用户设置
                printf("定位服务应该打开");
            }
                break;
        default:
                printf("none");
                break;
        }
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    
    

    demo分享链接

    相关文章

      网友评论

        本文标题:iOS开发-CoreLocation地图基本知识示例

        本文链接:https://www.haomeiwen.com/subject/xlmuwttx.html