zoukankan      html  css  js  c++  java
  • ios 定位

    ios 定位新功能----在程序中实现定位功能
    Core Location是iOS SDK中一个提供设备位置的框架。可以使用三种技术来获取位置:GPS、蜂窝或WiFi。在这些技术中,GPS最为精准,如果有GPS硬件,Core Location将优先使用它。如果设备没有GPS硬件(如WiFi iPad)或使用GPS获取当前位置时失败,Core Location将退而求其次,选择使用蜂窝或WiFi。

    Core Location的大多数功能是由位置管理器(CLLocationManager)提供的,可以使用位置管理器来指定位置更新的频率和精度,以及开始和停止接收这些更新。

    要使用位置管理器,必须首先将框架Core Location加入到项目中,再导入其接口文件:

     
    1
    #import <corelocation corelocation.h=""></corelocation>

    接下来,需要分配并初始化一个位置管理器实例、指定将接收位置更新的委托并启动更新:

    1
    2
    3
    4
    CLLocationManager *locManager = [[CLLocationManager alloc] init];
    locManager.delegate = self;
    [locManager startUpdatingLocation];
    //[locManager stopUpdatingLocation];


    位置管理器委托(CLLocationManagerDelegate)有两个与位置相关的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
         
    }
     
    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
         
    }

    第一个方法处理定位成功,manager参数表示位置管理器实例;locations为一个数组,是位置变化的集合,它按照时间变化的顺序存放。如果想获得设备的当前位置,只需要访问数组的最后一个元素即可。集合中每个对象类型是CLLocation,它包含以下属性:

    coordinate — 坐标。一个封装了经度和纬度的结构体。

    altitude — 海拔高度。正数表示在海平面之上,而负数表示在海平面之下。

    horizontalAccuracy — 位置的精度(半径)。位置精度通过一个圆表示,实际位置可能位于这个圆内的任何地方。这个圆是由coordinate(坐标)和 horizontalAccuracy(半径)共同决定的,horizontalAccuracy的值越大,那么定义的圆就越大,因此位置精度就越低。如 果horizontalAccuracy的值为负,则表明coordinate的值无效。

    verticalAccuracy — 海拔高度的精度。为正值表示海拔高度的误差为对应的米数;为负表示altitude(海拔高度)的值无效。

    speed — 速度。该属性是通过比较当前位置和前一个位置,并比较它们之间的时间差异和距离计算得到的。鉴于Core Location更新的频率,speed属性的值不是非常精确,除非移动速度变化很小

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation *curLocation = [locations lastObject];
         
        if(curLocation.horizontalAccuracy > 0)
        {
            NSLog(@"当前位置:%.0f,%.0f +/- %.0f meters",curLocation.coordinate.longitude,
                  curLocation.coordinate.latitude,
                  curLocation.horizontalAccuracy);
        }
         
        if(curLocation.verticalAccuracy > 0)
        {
            NSLog(@"当前海拔高度:%.0f +/- %.0f meters",curLocation.altitude,curLocation.verticalAccuracy);
        }
    }

    应用程序开始跟踪用户的位置时,将在屏幕上显示一个是否允许定位的提示框。如果用户禁用定位服务,iOS不会禁止应用程序运行,但位置管理器将生成错误。

    第二个方法处理这种定位失败,该方法的参数指出了失败的原因。如果用户禁止应用程序定位,error参数将为kCLErrorDenied;如果Core Location经过努力后无法确认位置,error参数将为kCLErrorLocationUnknown;如果没有可供获取位置的源,error参 数将为kCLErrorNetwork。

    通常,Core Location将在发生错误后继续尝试确定位置,但如果是用户禁止定位,它就不会这样做;在这种情况下,应使用方法stopUpdatingLocation停止位置管理器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        if(error.code == kCLErrorLocationUnknown)
        {
            NSLog(@"Currently unable to retrieve location.");
        }
        else if(error.code == kCLErrorNetwork)
        {
            NSLog(@"Network used to retrieve location is unavailable.");
        }
        else if(error.code == kCLErrorDenied)
        {
            NSLog(@"Permission to retrieve location is denied.");
            [manager stopUpdatingLocation];
        }
    }

    可根据实际情况来指定位置精度。例如,对于只需确定用户在哪个国家的应用程序,没有必要要求Core Location的精度为10米。要指定精度,可在启动位置更新前设置位置管理器的desiredAccuracy。有6个表示不同精度的枚举值

    1
    2
    3
    4
    5
    6
    extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
    extern const CLLocationAccuracy kCLLocationAccuracyBest;
    extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
    extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
    extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
    extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;


    对位置管理器启动更新后,更新将不断传递给位置管理器委托,直到停止更新。您无法直接控制这些更新的频率,但可使用位置管理器的属性 distanceFilter进行间接控制。在启动更新前设置属性distanceFilter,它指定设备(水平或垂直)移动多少米后才将另一个更新发 送给委托。下面的代码使用适合跟踪长途跋涉者的设置启动位置管理器:

    1
    2
    3
    4
    5
    CLLocationManager *locManager = [[CLLocationManager alloc] init];
    locManager.delegate = self;
    locManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    locManager.distanceFilter = 200;
    [locManager startUpdatingLocation];

    P.s. 定位要求的精度越高、属性distanceFilter的值越小,应用程序的耗电量就越大。

    位置管理器有一个headingAvailable属性,它指出设备是否装备了磁性指南针。如果该属性为YES,就可以使用Core Location来获取航向(heading)信息。接收航向更新与接收位置更新极其相似,要开始接收航向更新,可指定位置管理器委托,设置属性 headingFilter以指定要以什么样的频率(以航向变化的度数度量)接收更新,并对位置管理器调用方法 startUpdatingHeading:

    位置管理器委托协议定义了用于接收航向更新的方法。该协议有两个与航向相关的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
    {
        return YES;
    }
     
    - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    {
         
    }

    第一个方法指定位置管理器是否向用户显示校准提示。该提示将自动旋转设备360°。由于指南针总是自我校准,因此这种提示仅在指南针读数剧烈波动时才有帮助。当设置为YES后,提示可能会分散用户的注意力,或影响用户的当前操作。

    第二个方法的参数newHeading是一个CLHeading对象。CLHeading通过一组属性来提供航向读数:magneticHeading和 trueHeading。这些值的单位为度,类型为CLLocationDirection,即双精度浮点数。这意味着:

    如果航向为0.0,则前进方向为北;

    如果航向为90.0,则前进方向为东;

    如果航向为180.0,则前进方向为南;

    如果航向为270.0,则前进方向为西。

    CLHeading对象还包含属性headingAccuracy(精度)、timestamp(读数的测量时间)和description(这种描述更适合写入日志而不是显示给用户)。下面演示了利用这个方法处理航向更新:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    {
        if(newHeading.headingAccuracy >=0)
        {
            NSString *headingDesc = [NSString stringWithFormat:@"%.0f degrees (true), %.0f degrees (magnetic)",newHeading.trueHeading,newHeading.magneticHeading];
             
            NSLog(@"%@",headingDesc);
        }
    }

    trueHeading和magneticHeading分别表示真实航向和磁性航向。如果位置服务被关闭了,GPS和wifi就只能获取magneticHeading(磁场航向)。只有打开位置服务,才能获取trueHeading(真实航向)。

  • 相关阅读:
    【Codeforces 349B】Color the Fence
    【Codeforces 459D】Pashmak and Parmida's problem
    【Codeforces 467C】George and Job
    【Codeforces 161D】Distance in Tree
    【Codeforces 522A】Reposts
    【Codeforces 225C】Barcode
    【Codeforces 446A】DZY Loves Sequences
    【Codeforces 429B】Working out
    【Codeforces 478C】Table Decorations
    【Codeforces 478C】Table Decorations
  • 原文地址:https://www.cnblogs.com/xiao-xiao-jian/p/4977822.html
Copyright © 2011-2022 走看看