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
     
  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5350181.html
Copyright © 2011-2022 走看看