zoukankan      html  css  js  c++  java
  • IOS CoreLocation框架的使用(用于地理定位)

    ●  在移动互联网时代,移动app能解决用户的很多生活琐事,比如

     ●  导航:去任意陌生的地方

    ●  周边:找餐馆、找酒店、找银行、找电影院

    ●  在上述应用中,都用到了地图定位功能,在iOS开发中,要想加入这大功 能,必须基于2个框架进行开发

    ●  Map Kit :用于地图展示

    ●  Core Location :用于地理定位

    ●  2个热门专业术语

    ●  LBS :Location Based Service

    ●  SoLoMo :Social Local Mobile(索罗门)

    CoreLocation框架的使用

    CoreLocation框架使用前提
    导入框架
    导入主头文件
    #import <CoreLocation/CoreLocation.h>

    CoreLocation框架使用须知
    CoreLocation框架中所有数据类型的前缀都是CL
    CoreLocation中使用CLLocationManager对象来做用户定位

    CLLocationManager

    CLLocationManager的常用操作
    开始用户定位
    - (void)startUpdatingLocation;

     

    停止用户定位
    - (void) stopUpdatingLocation;

    当调用了startUpdatingLocation方法后,就开始不断地定位用户的位 置,中途会频繁地调用代理的下面方法

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

    locations参数里面装着CLLocation对象

    CLLocation

    CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等
    @property(readonly,nonatomic)CLLocationCoordinate2D
    coordinate;

    经纬度
    @property(readonly,nonatomic)CLLocationDistancealtitude;

    海拔
    @property(readonly,nonatomic)CLLocationDirectioncourse;

    路线,航向(取值范围是0.0°~359.9°,0.0°代表真北方向)
    @property(readonly,nonatomic)CLLocationSpeedspeed;

    行走速度(单位是m/s)
    - (CLLocationDistance)distanceFromLocation:(const CLLocation
    *)location

    方法可以计算2个位置之间的距离

    CLLocationManager

    @property(assign, nonatomic) CLLocationDistance distanceFilter;

     

    每隔多少米定位一次
    @property(assign, nonatomic) CLLocationAccuracy
    desiredAccuracy;

    定位精确度(越精确就越耗电)

    CLLocationCoordinate2D

    CLLocationCoordinate2D是一个用来表示经纬度的结构体,定义如下
    typedef struct {

     CLLocationDegrees latitude; // 纬度

    CLLocationDegrees longitude; // 经度

    }CLLocationCoordinate2D;

     

    一般用CLLocationCoordinate2DMake函数来创建CLLocationCoordinate2D

     

    用户隐私的保护

     iOS 6开始,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经 过用户批准授权

     ● 要想获得用户的位置
    想访问用户的通讯录、日历、相机、相册等等

    当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权

     

    开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的 (Privacy - Location Usage Description)

      

     

    一旦用户选择了Don’t Allow,意味着你的应用以后就无法使用定位功能
    为了严谨起见,最好在使用定位功能之前判断当前应用的定位功能是否可用
    CLLocationManager有个类方法可以判断当前应用的定位功能是否可用
    + (BOOL)locationServicesEnabled;

     

    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;

    城市

     实例:Core Location :用于地理定位

    #import "HMViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface HMViewController () <CLLocationManagerDelegate>
    @property (nonatomic, strong) CLLocationManager *locMgr;
    @end
    
    @implementation HMViewController
    
    - (CLLocationManager *)locMgr
    {
        if (!_locMgr) {
            // 1.创建位置管理器(定位用户的位置)
            self.locMgr = [[CLLocationManager alloc] init];
            
            // 2.设置代理
            self.locMgr.delegate = self;
        }
        return _locMgr;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        if ([CLLocationManager locationServicesEnabled]) {
            // 开始定位用户的位置
            [self.locMgr startUpdatingLocation];
            
    //        [self.locMgr startMonitoringForRegion:<#(CLRegion *)#>];
            
    //        self.locMgr.purpose
            
    //        self.locMgr.distanceFilter = kCLDistanceFilterNone;
    //        self.locMgr.desiredAccuracy = kcllocationac
        } else { // 不能定位用户的位置
            // 1.告诉用户检查网络状况
            // 2.提醒用户打开定位开关
        }
        
        [self countDistance];
    }
    
    - (void)countDistance
    {
        CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:40 longitude:116];
        CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:41 longitude:116];
        
        CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
        NSLog(@"(%@)和(%@)的距离:%f", loc1, loc2, distance);
    }
    
    #pragma mark - CLLocationManagerDelegate
    /**
     *  当定位到用户的位置时,就会调用(调用比较频繁)
     */
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        // 数组里面存放的是CLLocation对象, 一个CLLocation就代表一个位置
        CLLocation *loc = [locations lastObject];
        
        // 纬度:loc.coordinate.latitude
        // 经度:loc.coordinate.longitude
        NSLog(@"纬度=%f, 经度=%f", loc.coordinate.latitude, loc.coordinate.longitude);
        
        // 停止更新位置(不用定位服务,应当马上停止定位,非常耗电)
        [manager stopUpdatingLocation];
    }
    
    //- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    //{
    //
    //}
    //
    //- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    //{
    //    
    //}
    
    @end
    View Code

    实例:地理编码 and 反地理编码

    #import "HMViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface HMViewController ()
    @property (nonatomic, strong) CLGeocoder *geocoder;
    
    #pragma mark - 地理编码
    - (IBAction)geocode;
    @property (weak, nonatomic) IBOutlet UITextField *addressField;
    @property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;
    @property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;
    @property (weak, nonatomic) IBOutlet UILabel *detailAddressLabel;
    
    #pragma mark - 反地理编码
    - (IBAction)reverseGeocode;
    @property (weak, nonatomic) IBOutlet UITextField *longtitudeField;
    @property (weak, nonatomic) IBOutlet UITextField *latitudeField;
    @property (weak, nonatomic) IBOutlet UILabel *reverseDetailAddressLabel;
    @end
    
    @implementation HMViewController
    
    - (CLGeocoder *)geocoder
    {
        if (!_geocoder) {
            self.geocoder = [[CLGeocoder alloc] init];
        }
        return _geocoder;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
    }
    
    /**
     *  地理编码:地名 -> 经纬度
     */
    - (void)geocode
    {
        // 1.获得输入的地址
        NSString *address = self.addressField.text;
        if (address.length == 0) return;
        
        // 2.开始编码
        [self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
            if (error || placemarks.count == 0) {
                self.detailAddressLabel.text = @"你输入的地址找不到,可能在火星上";
            } else { // 编码成功(找到了具体的位置信息)
                // 输出查询到的所有地标信息
                for (CLPlacemark *placemark in placemarks) {
                    NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@", placemark.name, placemark.locality, placemark.country, placemark.postalCode);
                }
                
                // 显示最前面的地标信息
                CLPlacemark *firstPlacemark = [placemarks firstObject];
                self.detailAddressLabel.text = firstPlacemark.name;
                
                CLLocationDegrees latitude = firstPlacemark.location.coordinate.latitude;
                CLLocationDegrees longitude = firstPlacemark.location.coordinate.longitude;
                self.latitudeLabel.text = [NSString stringWithFormat:@"%.2f", latitude];
                self.longitudeLabel.text = [NSString stringWithFormat:@"%.2f", longitude];
            }
        }];
    }
    
    /**
     *  反地理编码:经纬度 -> 地名
     */
    - (void)reverseGeocode
    {
        NSString *longtitudeText = self.longtitudeField.text;
        NSString *latitudeText = self.latitudeField.text;
        if (longtitudeText.length == 0 || latitudeText.length == 0) return;
        
        CLLocationDegrees latitude = [latitudeText doubleValue];
        CLLocationDegrees longtitude = [longtitudeText doubleValue];
        
        // 开始反向编码
        CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longtitude];
        [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
            if (error || placemarks.count == 0) {
                self.reverseDetailAddressLabel.text = @"你输入的经纬度找不到,可能在火星上";
            } else { // 编码成功(找到了具体的位置信息)
                // 输出查询到的所有地标信息
                for (CLPlacemark *placemark in placemarks) {
                    NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@", placemark.name, placemark.locality, placemark.country, placemark.postalCode);
                }
                
                // 显示最前面的地标信息
                CLPlacemark *firstPlacemark = [placemarks firstObject];
                self.reverseDetailAddressLabel.text = firstPlacemark.name;
                
                CLLocationDegrees latitude = firstPlacemark.location.coordinate.latitude;
                CLLocationDegrees longitude = firstPlacemark.location.coordinate.longitude;
                self.latitudeField.text = [NSString stringWithFormat:@"%.2f", latitude];
                self.longtitudeField.text = [NSString stringWithFormat:@"%.2f", longitude];
            }
        }];
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.view endEditing:YES];
    }
    
    @end
    View Code

     

  • 相关阅读:
    三分 例题
    设计模式学习笔记(十九):迭代器模式
    设计模式学习笔记(十八):解释器模式
    设计模式学习笔记(十七):命令模式
    设计模式学习笔记(十六):职责链模式
    设计模式学习笔记(十五):代理模式
    设计模式学习笔记(十四):享元模式
    设计模式学习笔记(十三):外观模式
    设计模式学习笔记(十二):装饰模式
    设计模式学习笔记(十一):组合模式
  • 原文地址:https://www.cnblogs.com/liuwj/p/6894659.html
Copyright © 2011-2022 走看看