zoukankan      html  css  js  c++  java
  • iOS定位--CoreLocation框架

    CoreLocation框架的使用

    // 首先导入头文件
    #import <CoreLocation/CoreLocation.h>
    
    • CoreLocation框架中所有数据类型的前缀都是CL
    • CoreLocation中使用CLLocationManager对象来做用户定位

    1.CLLocationManager的使用

    CLLocationManager的常用操作

    /**
     *  定位管理者,全局变量强引用,防止销毁
     */
    @property (nonatomic ,strong) CLLocationManager *mgr;
    

    设代理

    // 2.成为CoreLocation管理者的代理监听获取到的位置
        self.mgr.delegate = self;
    

    ①得到用户授权

    注意:

    iOS7只要开始定位, 系统就会自动要求用户对你的应用程序授权. 但是从iOS8开始, 想要定位必须先"自己""主动"要求用户授权

    • 添加友好提示,在info.plist文件中添加字段
      • Privacy - Location Usage Description

    在iOS8中不仅仅要主动请求授权,而且必须再info.plist文件中配置一项属性才能弹出授权窗口

    • NSLocationWhenInUseDescription,允许在前台获取GPS的描述
    • NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述
     /*
         用户从未选择过权限
         kCLAuthorizationStatusNotDetermined
         无法使用定位服务,该状态用户无法改变
         kCLAuthorizationStatusRestricted
         用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
         kCLAuthorizationStatusDenied
         已经授权(废弃)
         kCLAuthorizationStatusAuthorized
         用户允许该程序无论何时都可以使用地理信息
         kCLAuthorizationStatusAuthorizedAlways
         用户同意程序在可见时使用地理位置
         kCLAuthorizationStatusAuthorizedWhenInUse
         */
    
        // 1.获得用户授权状态
        CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    
        // 2.判断用户是否授权
        if (status == kCLAuthorizationStatusNotDetermined) {
            NSLog(@"等待用户授权");
        }else if (status == kCLAuthorizationStatusAuthorizedAlways ||
                  status == kCLAuthorizationStatusAuthorizedWhenInUse)
    
        {
            NSLog(@"授权成功");
            // 开始定位
            [self.mgr startUpdatingLocation];
    
        }else
        {
            NSLog(@"授权失败");
        }
    

    iOS8请求授权得不到提示的原因

    • 1.没有发送请求
      • 无请求代码
    • 2.CLLocationManager不是全局的成员属性
      • 被提前销毁,没有强引用
    • 3.没有在info.plist文件中添加字段
      • NSLocationAlwaysUsageDescription
      • NSLocationWhenInUseDescription

    ②开始用户定位

    - (void)startUpdatingLocation;
    

    ③停止用户定位

    - (void) stopUpdatingLocation;
    

    ③设置当用户移动多少米,重新定位

    - self.mgr.distanceFilter = 50;
    

    ④设置获取位置的精确度

    • 越精确就越耗电
        /*
          kCLLocationAccuracyBestForNavigation 最佳导航
          kCLLocationAccuracyBest;  最精准
          kCLLocationAccuracyNearestTenMeters;  10米
          kCLLocationAccuracyHundredMeters;  百米
          kCLLocationAccuracyKilometer;  千米
          kCLLocationAccuracyThreeKilometers;  3千米
         */
        self.mgr.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    
    • 当调用了startUpdatingLocation方法后,就开始不断地定位用户的位置,中途会频繁地调用代理的下面方法调用频率非常高

    • 如果只需要获取一次, 可以获取到位置之后就停止

      • [manager stopUpdatingLocation];
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
    //locations参数里面装着CLLocation对象
    

    在startUpdatingLocation 代理方法中可以得到用户的坐标信息

    
        // 1.获取最后一次的位置
     CLLocation *location = [locations lastObject];
        /*
         location.coordinate; 坐标, 包含经纬度
         location.altitude; 设备海拔高度 单位是米
         location.course; 设置前进方向 0表示北 90东 180南 270西
         location.horizontalAccuracy; 水平精准度
         location.verticalAccuracy; 垂直精准度
         location.timestamp; 定位信息返回的时间
         location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
         */
        /*
         可以设置模拟器模拟速度
         bicycle ride 骑车移动
         run 跑动
         freeway drive 高速公路驾车
         */
        CLLocation *location = [locations lastObject];
        NSLog(@"%f, %f speed = %f", location.coordinate.latitude , location.coordinate.longitude, location.speed);
    

    计算两地之间的直线距离

    • (CLLocationDistance)distanceFromLocation:(const CLLocation *)location;
        // 北京:39.6 116.39
        // 广州:23.08 113.15
        CLLocation *BeiJing = [[CLLocation alloc] initWithLatitude:39.6 longitude:116.39];
        CLLocation *GuangZhou = [[CLLocation alloc] initWithLatitude:23.08 longitude:113.15];
    
        // 得到两地之间的距离
        CLLocationDistance distance = [BeiJing distanceFromLocation:GuangZhou];
        NSLog(@"%.2f", distance);
    

    2、CLLocation

    • CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等
    // 属性
        location.coordinate; 坐标, 包含经纬度
         location.altitude; 设备海拔高度 单位是米
         location.course; 设置前进方向 0表示北 90东 180南 270西
         location.horizontalAccuracy; 水平精准度
         location.verticalAccuracy; 垂直精准度
         location.timestamp; 定位信息返回的时间
         location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
    
    // 可以计算2个位置之间的距离
    - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
    

    3、CLGeocoder

    • 使用CLGeocoder可以完成“地理编码”和“反地理编码”

    地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)

    反地理编码:根据给定的经纬度,获得具体的位置信息

    // 地理编码方法
    - geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {};
    
    // 反地理编码方法
    - reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {};
    

    CLPlacemark的字面意思是地标,封装详细的地址位置信息

    1.CLPlacemark的addressDictionary属性 遍历字典数据
    
    addressDictionary enumerateKeysAndObjectsUsingBlock
    
    2.block是在主线程调用,所以可以直接在block刷新UI
    
    name                    :   地名
    thoroughfare            :   街道
    ubThoroughfare          :   街道相关信息,例如门牌等
    locality                :   城市
    subLocality             :   城市相关信息,例如标志性建筑
    administrativeArea      :   直辖市
    subAdministrativeArea   :   其他行政区域信息
    postalCode              :   邮编
    ISOcountryCode          :   国家编码
    country;                :   国家
    inlandWater             :   水源、湖泊
    ocean;                  :   海洋
    areasOfInterest         :   关联的或利益相关的地标
    
    @property (nonatomic, readonly) CLLocation *location;
    // 地理位置
    
    @property (nonatomic, readonly) CLRegion *region;
    // 区域
    
    @property (nonatomic, readonly) NSDictionary *addressDictionary;
    // 详细的地址信息
    
    @property (nonatomic, readonly) NSString *name;
    // 地址名称
    
    @property (nonatomic, readonly) NSString *locality;
    // 城市
    

    错误:使用CoreLocation获取地理位置信息,报错

    Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
    

    解决方法:

    • 1.确定模拟器(手机)已经联网并且允许程序获取地理位置
    • 2.重置地理位置服务或者网络服务

    • PS:如果是模拟器就果断直接重置模拟器吧 IOS Simulator - Reset Content and Settings..。

    中国经纬度

    中国的经纬度范围

    • 纬度范围:N 3°51′ ~ N 53°33′
    • 经度范围:E 73°33′ ~ E 135°05′

    中国部分城市的经纬度

  • 相关阅读:
    Oracle 操作数据库(增删改语句)
    web----框架基础
    js----DOM对象
    易错之for循环
    python调用修改变量新方法
    js----基础
    web----Twisted
    web----Socket
    python----面向对象(2)
    python----面向对象
  • 原文地址:https://www.cnblogs.com/ShaoYinling/p/4696749.html
Copyright © 2011-2022 走看看