zoukankan      html  css  js  c++  java
  • IOS-CoreLocation

    一、简介

    在移动互联网时代,移动app能解决用户的很多生活琐事,比如
    导航:去任意陌生的地方
    周边:找餐馆、找酒店、找银行、找电影院
     
    在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这2大功能,必须基于2个框架进行开发
    Map Kit :用于地图展示
    Core Location :用于地理定位
     
    2个热门专业术语
    LBS :Location Based Service
    p、SoLoMo :Social Local Mobile(索罗门)
     
     
    CoreLocation框架使用须知
    CoreLocation框架中所有数据类型的前缀都是CL
    CoreLocation中使用CLLocationManager对象来做用户定位
     
     
    二、CLLocationManager
    CLLocationManager的常用操作
    开始用户定位
    - (void)startUpdatingLocation;
     
    停止用户定位
    - (void) stopUpdatingLocation;
     
    当调用了startUpdatingLocation方法后,就开始不断地定位用户的位置,中途会频繁地调用代理的下面方法
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
    locations参数里面装着CLLocation对象
     
    @property(assign, nonatomic) CLLocationDistance distanceFilter;
    每隔多少米定位一次
     
    @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
    定位精确度(越精确就越耗电)
     
    三、CLLocation
    CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等
    @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
    经纬度
     
    @property(readonly, nonatomic) CLLocationDistance altitude;
    海拔
     
    @property(readonly, nonatomic) CLLocationDirection course;
    路线,航向(取值范围是0.0° ~ 359.9°,0.0°代表真北方向)
     
    @property(readonly, nonatomic) CLLocationSpeed speed;
    行走速度(单位是m/s)
     
    用- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location方法可以计算2个位置之间的距离
     
     
    三、CLLocationCoordinate2D
    CLLocationCoordinate2D是一个用来表示经纬度的结构体,定义如下

    typedef struct {

            CLLocationDegrees latitude; // 纬度

            CLLocationDegrees longitude; // 经度

    } CLLocationCoordinate2D;

    一般用CLLocationCoordinate2DMake函数来创建CLLocationCoordinate2D
     
    四、CLGeocoder
    使用CLGeocoder可以完成“地理编码”和“反地理编码”
    地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
    反地理编码:根据给定的经纬度,获得具体的位置信息
     
    地理编码方法
    - (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
     
    反地理编码方法
    - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
     
    CLGeocodeCompletionHandler
    当地理反地理编码完成时,就会调用CLGeocodeCompletionHandler
    typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
    这个block传递2个参数
    error :当编码出错时(比如编码不出具体的信息)有值
    placemarks :里面装着CLPlacemark对象
     
    五、CLPlacemark
    CLPlacemark的字面意思是地标,封装详细的地址位置信息
    @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;
    城市
     
     
    代码:定位、指南针、区域检测
      1 //
      2 //  ViewController.m
      3 //  IOS_0403_导航
      4 //
      5 //  Created by ma c on 16/4/3.
      6 //  Copyright © 2016年 博文科技. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 #import <CoreLocation/CoreLocation.h>
     11 
     12 @interface ViewController ()<CLLocationManagerDelegate>
     13 
     14 @property (nonatomic, strong) CLLocationManager *mgr;
     15 
     16 //上一次位置
     17 @property (nonatomic, strong) CLLocation *previousLocation;
     18 //总路程
     19 @property (nonatomic, assign) CLLocationDistance sumDistance;
     20 //总时间
     21 @property (nonatomic, assign) NSTimeInterval sumTime;
     22 
     23 @property (nonatomic, strong) UIImageView *commpasspointer;
     24 
     25 
     26 @end
     27 
     28 @implementation ViewController
     29 
     30 /*
     31  注意:iOS7只要定位,系统就会自动要求用户对你的应用程序授权,但是从iOS8开始想要定位
     32  必须自己主动要求用户授权,然后在Info.plist文件中配置一项属性才能弹出授权窗口
     33  NSLocationWhenInUseDescription,允许在前台获取GPS的描述
     34  NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述
     35  
     36  CLLocation
     37  location.coordinate; 坐标, 包含经纬度
     38  location.altitude; 设备海拔高度 单位是米
     39  location.course; 设置前进方向 0表示北 90东 180南 270西
     40  location.horizontalAccuracy; 水平精准度
     41  location.verticalAccuracy; 垂直精准度
     42  location.timestamp; 定位信息返回的时间
     43  location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
     44  
     45  CLHeading
     46  magneticHeading 设备与磁北的相对角度
     47  trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
     48  真北始终指向地理北极点
     49  磁北对应随着时间变化的地球磁场北极
     50  
     51  CLRegion   代表一个区域
     52  >CLCircularRegion  圆形区域
     53  >CLBeaconRegion 蓝牙信号区域
     54  */
     55 
     56 - (void)viewDidLoad {
     57     [super viewDidLoad];
     58     self.view.backgroundColor = [UIColor cyanColor];
     59     
     60     [self test];
     61     
     62     //添加指南针图片
     63     UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg_compasspointer"]];
     64     imgView.center = self.view.center;
     65     [self.view addSubview:imgView];
     66     self.commpasspointer = imgView;
     67 }
     68 
     69 - (void)test
     70 {
     71     //1.创建管理者
     72 //    CLLocationManager *mgr = [[CLLocationManager alloc] init];
     73     //2.设置代理
     74     self.mgr.delegate = self;
     75     
     76     //设置获取位置精确度
     77     self.mgr.desiredAccuracy = kCLLocationAccuracyBest;
     78     //设置多久获取一次
     79     self.mgr.distanceFilter = 10;
     80 
     81     if ([[UIDevice currentDevice].systemVersion doubleValue] > 8.0) {
     82         //主动请求授权
     83         [self.mgr requestAlwaysAuthorization];
     84     }
     85     
     86     //3.开始定位
     87     [self.mgr startUpdatingLocation];
     88     
     89     //3.开始获取用户方向
     90     [self.mgr startUpdatingHeading];
     91     
     92     //3.开始区域检测
     93     //创建中心点
     94     CLLocationCoordinate2D center = CLLocationCoordinate2DMake(41, 116);
     95     //创建圆形区域
     96     CLCircularRegion *circularRegion = [[CLCircularRegion alloc] initWithCenter:center radius:500 identifier:@"北京"];
     97     [self.mgr startMonitoringForRegion:circularRegion];
     98     
     99 }
    100 
    101 
    102 #pragma mark - CLLocationManagerDelegate
    103 //当获取到位置时调用
    104 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    105 {
    106     //获取当前位置
    107     CLLocation *newLocation = [locations lastObject];
    108     
    109     NSLog(@"%f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
    110 
    111     if (self.previousLocation == nil) {
    112         
    113         //计算两次之间的位置(单位为米)
    114         CLLocationDistance distance = [newLocation distanceFromLocation:self.previousLocation];
    115         //计算两次之间的时间(单位为秒)
    116         NSTimeInterval dTime = [newLocation.timestamp timeIntervalSinceDate:self.previousLocation.timestamp];
    117         //计算速度
    118         CGFloat speed = distance / dTime;
    119         
    120         //累加时间
    121         self.sumTime += dTime;
    122         //累加路程
    123         self.sumDistance += distance;
    124         //计算平均速度
    125         CGFloat averSpeed = self.sumDistance / self.sumTime;
    126     }
    127     //记录上一次位置
    128     self.previousLocation = newLocation;
    129     
    130 }
    131 
    132 //当获取到用户方向时调用
    133 - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    134 {
    135     //1.将角度转换成弧度
    136     CGFloat angle = newHeading.magneticHeading * M_PI / 180;
    137     //2.旋转图片
    138     self.commpasspointer.transform = CGAffineTransformIdentity;
    139     self.commpasspointer.transform = CGAffineTransformMakeRotation(-angle);
    140 }
    141 
    142 //进入监听区域时调用
    143 - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    144 {
    145     NSLog(@"didEnterRegion");
    146 }
    147 
    148 //离开监听区域时调用
    149 - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    150 {
    151     NSLog(@"didExitRegion");
    152 }
    153 
    154 #pragma mark - 懒加载
    155 - (CLLocationManager *)mgr
    156 {
    157     if(!_mgr){
    158         _mgr = [[CLLocationManager alloc] init];
    159         
    160     }
    161     return _mgr;
    162 }
    163 
    164 
    165 @end

    地理编码

      1 //
      2 //  ViewController.m
      3 //  IOS_0403_地理编码
      4 //
      5 //  Created by ma c on 16/4/3.
      6 //  Copyright © 2016年 博文科技. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 #import <CoreLocation/CoreLocation.h>
     11 
     12 @interface ViewController ()
     13 //-------------------正向地理编码----------------//
     14 /**
     15  *  监听地理编码点击事件
     16  */
     17 - (IBAction)geocodeBtnClick;
     18 /**
     19  *  需要编码的地址容器
     20  */
     21 @property (weak, nonatomic) IBOutlet UITextField *addressField;
     22 /**
     23  *  经度容器
     24  */
     25 @property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;
     26 /**
     27  *  纬度容器
     28  */
     29 @property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;
     30 /**
     31  *  详情容器
     32  */
     33 @property (weak, nonatomic) IBOutlet UILabel *detailAddressLabel;
     34 /**
     35  *  地理编码对象
     36  */
     37 
     38 //-------------------反向地理编码----------------//
     39 - (IBAction)reverseGeocode;
     40 @property (weak, nonatomic) IBOutlet UITextField *longtitudeField;
     41 @property (weak, nonatomic) IBOutlet UITextField *latitudeField;
     42 @property (weak, nonatomic) IBOutlet UILabel *reverseDetailAddressLabel;
     43 
     44 
     45 @property (nonatomic ,strong) CLGeocoder *geocoder;
     46 
     47 @end
     48 
     49 @implementation ViewController
     50 
     51 - (void)viewDidLoad {
     52     [super viewDidLoad];
     53 }
     54 //正向地理编码
     55 - (IBAction)geocodeBtnClick
     56 {
     57     // 0.获取用户输入的位置
     58     NSString *addressStr = self.addressField.text;
     59     if (addressStr == nil || addressStr.length == 0) {
     60         NSLog(@"请输入地址");
     61         return;
     62     }
     63     
     64     
     65     // 1.创建地理编码对象
     66     
     67     // 2.利用地理编码对象编码
     68     // 根据传入的地址获取该地址对应的经纬度信息
     69     [self.geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) {
     70         
     71         if (placemarks.count == 0 || error != nil) {
     72             return ;
     73         }
     74         // placemarks地标数组, 地标数组中存放着地标, 每一个地标包含了该位置的经纬度以及城市/区域/国家代码/邮编等等...
     75         // 获取数组中的第一个地标
     76         CLPlacemark *placemark = [placemarks firstObject];
     77         //        for (CLPlacemark  *placemark in placemarks) {
     78         //            NSLog(@"%@ %@ %f %f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
     79         self.latitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
     80         self.longitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
     81         NSArray *address = placemark.addressDictionary[@"FormattedAddressLines"];
     82         NSMutableString *strM = [NSMutableString string];
     83         for (NSString *str in address) {
     84             [strM appendString:str];
     85         }
     86         self.detailAddressLabel.text = strM;
     87         //        }
     88         
     89         
     90         
     91     }];
     92 }
     93 //反向地理编码
     94 - (IBAction)reverseGeocode
     95 {
     96     // 1.获取用户输入的经纬度
     97     NSString *longtitude = self.longtitudeField.text;
     98     NSString *latitude = self.latitudeField.text;
     99     if (longtitude.length == 0 ||
    100         longtitude == nil ||
    101         latitude.length == 0 ||
    102         latitude == nil) {
    103         NSLog(@"请输入经纬度");
    104         return;
    105     }
    106     
    107     // 2.根据用户输入的经纬度创建CLLocation对象
    108     CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue]  longitude:[longtitude doubleValue]];
    109     
    110     // 3.根据CLLocation对象获取对应的地标信息
    111     [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
    112         
    113         for (CLPlacemark *placemark in placemarks) {
    114             NSLog(@"%@ %@ %f %f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
    115             self.reverseDetailAddressLabel.text = placemark.locality;
    116         }
    117     }];
    118 }
    119 
    120 #pragma mark - 懒加载
    121 - (CLGeocoder *)geocoder
    122 {
    123     if(!_geocoder){
    124         _geocoder = [[CLGeocoder alloc] init];
    125         
    126     }
    127     return _geocoder;
    128 }
    129 
    130 
    131 @end
     
  • 相关阅读:
    找回Android studio的帮助文档
    adb shell 命令详解
    Android 获取Activity当前view
    下载网络文件HttpURLConnection.getContentLength()大小为 0
    Android设置屏幕旋转后保存数据
    解决TextView drawableRight左侧图片大小不可控的问题
    Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
    人生苦短,我用Python(目录)
    爬虫学习目录
    Django-jet自定义菜单
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5350181.html
Copyright © 2011-2022 走看看