美文网首页
IOS基础:定位

IOS基础:定位

作者: 时光啊混蛋_97boy | 来源:发表于2020-11-06 15:00 被阅读0次

原创:知识点总结性文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容

目录

  • 一、CoreLocation
    • 1、用户授权
    • 2、设置定位管理者
    • 3、获取用户当前的位置
    • 4、磁力感应
    • 5、区域检测
    • 6、地理编码与反地理编码

1、用户授权

a、运行效果
用户授权
2020-11-06 11:12:32.676599+0800 LocationDemo[52957:5777093] 等待用户授权
2020-11-06 11:13:28.432218+0800 LocationDemo[52957:5777093] 授权成功,开始定位
b、Info.plist添加定位权限

Privacy - Location When In Use Usage Description:需要使用定位权限
Privacy - Location Always and When In Use Usage Description:需要使用定位权限

c、CLAuthorizationStatus
kCLAuthorizationStatusNotDetermined //用户从未选择过权限,无法使用定位服务,该状态用户无法改变
kCLAuthorizationStatusRestricted //用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
kCLAuthorizationStatusDenied //用户允许该程序无论何时都可以使用地理信息
kCLAuthorizationStatusAuthorizedAlways //用户同意程序在可见时使用地理位置
kCLAuthorizationStatusAuthorizedWhenInUse //用户同意使用时应用使用定位服务
d、授权状态发生改变时调用
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager
{

    if (manager.authorizationStatus == kCLAuthorizationStatusNotDetermined)
    {
        NSLog(@"等待用户授权");
    }
    else if (manager.authorizationStatus == kCLAuthorizationStatusAuthorizedAlways || manager.authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse)
    {
        NSLog(@"授权成功,开始定位");
        [self.mgr startUpdatingLocation];
    }
    else
    {
        NSLog(@"授权失败");
    }
}

2、设置定位管理者

a、引入定位头文件
#import <CoreLocation/CoreLocation.h>

@interface CoreLocationViewController ()<CLLocationManagerDelegate>

@property (nonatomic ,strong) CLLocationManager *locationManager;// 定位管理者

@end
b、设置定位管理者的属性
- (void)configLocationManager
{
    self.place = @"";
    
    // 判断定位权限是否打开
    if ([CLLocationManager locationServicesEnabled])
    {
        _locationManager = [[CLLocationManager alloc] init];
        // 成为CoreLocation管理者的代理监听获取到的位置
        _locationManager.delegate = self;
        
        // 设置寻址精度
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        
        // 设置多远获取一次
        _locationManager.distanceFilter = 100.0f;
        
        // 开始定位
        [_locationManager startUpdatingLocation];
    }
    else
    {
        // 必须再info.plist文件中配置一项属性才能弹出授权窗口
        // 要主动请求授权定位权限 授权状态改变就会通知代理
        [_locationManager requestAlwaysAuthorization];
    }
}

3、获取用户当前的位置

a、运行效果
2020-11-06 11:30:33.256619+0800 LocationDemo[926:133009] 纬度:24.477126,经度:118.183663,速度:-1.000000
2020-11-06 11:30:33.492373+0800 LocationDemo[926:133009] 在下当前所在位置位:省:福建省,市:厦门市,街道:思明区 展鸿路81号
b、位置信息

可以设置模拟器模拟速度

bicycle ride// 骑车移动
run// 跑动
freeway drive// 高速公路驾车

可以获取到的位置信息

location.coordinate; //坐标, 包含经纬度
location.altitude; //设备海拔高度 单位是米
location.course; //设置前进方向 0表示北 90东 180南 270西
location.horizontalAccuracy; //水平精准度
location.verticalAccuracy; //垂直精准度
location.timestamp; //定位信息返回的时间
location.speed; //设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
c、获取到位置信息之后就会调用(调用频率非常高)
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // 如果只需要获取一次, 可以获取到位置之后就停止
    [_locationManager stopUpdatingHeading];
    [_locationManager stopUpdatingLocation];
    
    // 获取最后一次的位置
    CLLocation *location = [locations lastObject];
    NSLog(@"纬度:%f,经度:%f,速度:%f", location.coordinate.latitude, location.coordinate.longitude, location.speed);
    
    CLLocation *currentLocation = [locations lastObject];
    CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
    // 利用经纬度进行反编译获取位置信息
    [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0)
        {
            // 获取当前定位信息
            CLPlacemark *placeMark = [placemarks firstObject];
            if (placeMark)
            {
                //省、市、县、街
                self.place = [NSString stringWithFormat:@"省:%@,市:%@,街道:%@ %@",placeMark.administrativeArea,placeMark.locality,placeMark.subLocality,placeMark.thoroughfare];
                NSLog(@"在下当前所在位置位:%@",self.place);
            }
        }
    }];
}
d、定位失败时调用
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    [_locationManager startUpdatingLocation];
}

4、磁力感应

a、运行效果
磁力感应
2020-11-06 13:51:35.295963+0800 LocationDemo[1309:196044] 设备支持则开启磁力感应
2020-11-06 13:51:35.364536+0800 LocationDemo[1309:196044] 设备与磁北的相对角度:232.313324
b、判断设备是否支持则开启磁力感应
if ([CLLocationManager headingAvailable])
{
    self.mgr.headingFilter = kCLHeadingFilterNone;
    [self.mgr startUpdatingHeading];
    
    NSLog(@"设备支持则开启磁力感应");
}
else
{
    NSLog(@"设备不支持则开启磁力感应");
}
c、当获取到用户方向时就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    // magneticHeading: 设备与磁北的相对角度
    // trueHeading:设置与真北的相对角度,真北始终指向地理北极点,必须和定位一起使用,iOS需要设置的位置来计算真北
    NSLog(@"设备与磁北的相对角度:%f",newHeading.magneticHeading);

    // 将获取到的角度转为弧度 = (角度 * π) / 180;
    CGFloat angle = newHeading.magneticHeading * M_PI / 180;

    // 如果需要根据角度来旋转图片如指南针等,可以这样调用
    // 顺时针 正  逆时针 负
    self.compasspointer.transform = CGAffineTransformMakeRotation(-angle);
}

5、区域检测

a、监听区域
- (void)areaDetection
{
    // 创建中心点
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(24.477117, 118.183691);
    // 创建圆形区域, 指定区域中心点的经纬度, 以及半径
    CLCircularRegion *circular = [[CLCircularRegion alloc] initWithCenter:center radius:0.1 identifier:@"厦门"];
    [_locationManager startMonitoringForRegion:circular];
}
b、进入监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"进入监听区域时调用");
}
c、进入监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"离开监听区域时调用");
}

6、地理编码与反地理编码

a、运行效果
2020-11-06 14:55:09.540017+0800 LocationDemo[1463:228984] name=福建省厦门市思明区岭兜南片区156号楼 locality=厦门市 country=中国 postalCode=(null)
2020-11-06 14:55:09.540113+0800 LocationDemo[1463:228984] 地理编码,获取到的详细地址名称:福建省厦门市思明区岭兜南片区156号楼,纬度:24.48,经度:118.18
2020-11-06 14:55:09.480586+0800 LocationDemo[1463:228984] 反地理编码获取到的位置名称为: 岭兜南片区156号楼
b、地理编码: 地名—>经纬度坐标
- (void)geocoding
{
    // 根据传入的地址获取该地址对应的经纬度信息
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:@"岭兜南片区156号楼" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        
        // 如果有错误信息,或者是数组中获取的地名元素数量为0,那么说明没有找到
        if (error || placemarks.count == 0)
        {
            NSLog(@"你输入的地址没找到,可能在月球上");
        }
        else
        {
            // 打印查看找到的所有的位置信息
            // locality:城市  country:国家 postalCode:邮政编码
            for (CLPlacemark *placemark in placemarks)
            {
                NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@",placemark.name, placemark.locality, placemark.country, placemark.postalCode);
            }
            
            // 取出获取的地理信息数组中的第一个显示在界面上
            CLPlacemark *firstPlacemark = [placemarks firstObject];
            
            // 详细地址名称
            NSString *latitude = [NSString stringWithFormat:@"%.2f",firstPlacemark.location.coordinate.latitude];
            NSString *longitude = [NSString stringWithFormat:@"%.2f",firstPlacemark.location.coordinate.longitude];
            NSLog(@"地理编码,获取到的详细地址名称:%@,纬度:%@,经度:%@",firstPlacemark.name,latitude,longitude);
        }
    }];
}
c、反地理编码:经纬度坐标—>地名
- (void)antiGeocoding
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    
    // 1.获得输入的经纬度
    CLLocationDegrees latitude = [@"24.477139" doubleValue];
    CLLocationDegrees longitude = [@"118.183671" doubleValue];
    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
    
    // 2.反地理编码
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
     {
        if (error||placemarks.count==0)
        {
            NSLog(@"你输入的地址没找到,可能在月球上");
        }
        else
        {
            // 显示最前面的地标信息
            CLPlacemark *firstPlacemark= [placemarks firstObject];
            // 详细地址名称
            NSLog(@"反地理编码获取到的位置名称为: %@",firstPlacemark.name);
        }
    }];
}

Demo

Demo在我的Github上,欢迎下载。
LocationDemo

参考文献

相关文章

  • 定位及耗电

    iOS-GPS定位基础知识 iOS -GPS定位服务和地图应用是两套完全不同的API iOS7 的四种定位服务-G...

  • IOS基础:定位

    原创:知识点总结性文章创作不易,请珍惜,之后会持续更新,不断完善个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈...

  • IOS后台定位以及位置上传方案

    IOS后台定位以及位置上传方案 iOS定位原理和使用建议 iOS后台持续定位并定时上传 iOS 通过定位获取常驻后...

  • iOS开发之定位

    一、介绍 1、定位使用CoreLocation框架2、主要功能(1)基础定位(2)地理编码反编码3、IOS8 IO...

  • iOS开发之定位

    iOS开发之定位 iOS开发之定位

  • 百度地图之定位

    iOS中三种定位方式 ioS开发之CoreLocation(GPS定位) iOS自带的GPS 定位 iOS开发 C...

  • iOS-CoreLocation文集目录

    CoreLocation应用场景:定位iOS8.0之前的定位iOS8.0定位iOS9.0定位定位总结指南针效果区域...

  • iOS 端定位「网络问题」

    iOS 端定位「网络问题」 iOS 端定位「网络问题」

  • iOS监控-野指针定位

    iOS监控-野指针定位 iOS监控-野指针定位

  • iOS 地图

    iOS 地图 基础 一 :定位 在 iOS 程序开发中 地图功能是普遍存在的,刚好最近都在研究地图的功能。总结一下...

网友评论

      本文标题:IOS基础:定位

      本文链接:https://www.haomeiwen.com/subject/rfozvktx.html