美文网首页iOS开发iOS开发资料收集
iOS怎样获取当前手机的地理位置和经纬度

iOS怎样获取当前手机的地理位置和经纬度

作者: 辛小二 | 来源:发表于2017-02-17 17:00 被阅读6503次
目录
  • app常见需求(获取当前手机经纬度 地址 精确到省市和街道)并且需要通过经纬度计算出当前位置距离某个商店(确认经纬度的商店)距离是多少?
解答如下:

1、导入coreLocation库

导入CoreLocation

2、需要在info.plist里设置权限
//允许在前台使用时获取GPS的描述
NSLocationAlwaysUsageDescription=YES
//允许永久使用GPS的描述
NSLocationWhenInUseUsageDescription=YES


info.plist设置

3、导入头文件和设置代理

导入头文件和设置代理

4、初始化CLLocationManager


初始化CLLocationManager

5、设置代理方法

#pragma mark CoreLocation deleagte (定位失败)
/*定位失败则执行此代理方法*/
/*定位失败弹出提示窗,点击打开定位按钮 按钮,会打开系统设置,提示打开定位服务*/
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    /*设置提示提示用户打开定位服务*/
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"允许\"定位\"提示" message:@"请在设置中打开定位" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * ok =[UIAlertAction actionWithTitle:@"打开定位" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        /*打开定位设置*/
        NSURL * settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication]openURL:settingsURL];
    }];
    UIAlertAction * cacel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
       
    }];
    [alert addAction:ok];
    [alert addAction:cacel];
    [self presentViewController:alert animated:YES completion:nil];
}
/*定位成功后则执行此代理方法*/
#pragma mark 定位成功
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    [_locationManager stopUpdatingLocation];
    /*旧值*/
    CLLocation * currentLocation = [locations lastObject];
    CLGeocoder * geoCoder = [[CLGeocoder alloc]init];
    /*打印当前经纬度*/
    NSLog(@"%f%f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
    /*地理反编码 -- 可以根据地理位置(经纬度)确认位置信息 (街道、门牌)*/
    [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count >0) {
            CLPlacemark * placeMark = placemarks[0];
            currentCity = placeMark.locality;
            if (!currentCity) {
                currentCity = @"无法定位当前城市";
            }
            /*看需求定义一个全局变量来接受赋值*/
            NSLog(@"%@",placeMark.country);/*当前国家*/
            NSLog(@"%@",currentCity);/*当前城市*/
            NSLog(@"%@",placeMark.subLocality);/*当前位置*/
            NSLog(@"%@",placeMark.thoroughfare)/*当前街道*/
            NSLog(@"%@",placeMark.name);/*具体地址 ** 市 ** 区** 街道*/
            /*根据经纬度判断当前距离*/
            /*这个地方需要double转字符串赋值到label上面*/
            self.headView.Distance.text =HZString(@"距您%.1fkm",[self getDistance:currentLocation.coordinate.latitude lng1:currentLocation.coordinate.longitude lat2:weiDouble lng2:jingDouble]);
        }
        else if (error == nil&&placemarks.count == 0){
            NSLog(@"没有地址返回");
        }
        else if (error){
            NSLog(@"location error:%@",error);
        }
    }];
}
}
下面开始通过经纬度计算当前手机位置和接口获取到的经纬度两者之间计算距离的方法

答:首先上面这个需求你需要知道四个属性,分别是当前位置的经度纬度以及接口获取的精度纬度,上面解析出来当前的经纬度就是

//将经度显示到label上
      /*打印当前经纬度*/
    NSLog(@"%f%f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);

那么接口获取到的一般都是字符串类型的,那么其实经度和纬度是无法用字符串来识别的,我们只能用字符串转换成double来让系统识别

double类型 转换截图

好了到现在为止我们将需要的四个属性都找到了,下面我们开始计算,需要声明两个实例方法,然后进行计算

调用实例方法

[self getDistance:newLocation.coordinate.latitude lng1:newLocation.coordinate.longitude lat2:weiDouble lng2:jingDouble];

实现部分

#pragma mark 通过经纬度计算两地距离
- (float)getDistance:(float)lat1 lng1:(float)lng1 lat2:(float)lat2 lng2:(float)lng2
{
    //地球半径
    int R = 6378137;
    //将角度转为弧度
    float radLat1 = [self radians:lat1];
    float radLat2 = [self radians:lat2];
    float radLng1 = [self radians:lng1];
    float radLng2 = [self radians:lng2];
    //结果
    float s = acos(cos(radLat1)*cos(radLat2)*cos(radLng1-radLng2)+sin(radLat1)*sin(radLat2))*R;
    //精度
    s = round(s* 10000)/10000;
    return  round(s);
}
- (float)radians:(float)degrees{
    return (degrees*3.14159265)/180.0;
}

以上代码就能实现获取当前位置(省市街道和经纬度)以及计算经纬度和经纬度之前的距离的方法,喜欢的可以点赞。谢谢。

本人个人微信公众号地址(喜欢记得关注😯)


辛小二个人微信公众号地址

相关文章

网友评论

  • _君莫笑_:怎么做才能让代理方法执行
    _君莫笑_:@辛小二 我之前是这么写的但是没好使,下面的就好使了
    //判断定位功能是否打开
    if ([CLLocationManager locationServicesEnabled]) {
    locationmanager = [[CLLocationManager alloc]init];
    locationmanager.delegate = self;
    [locationmanager requestAlwaysAuthorization];
    currentCity = [NSString new];
    [locationmanager requestWhenInUseAuthorization];

    //设置寻址精度
    locationmanager.desiredAccuracy = kCLLocationAccuracyBest;
    locationmanager.distanceFilter = 5.0;
    [locationmanager startUpdatingLocation];
    }
    辛小二:@JustinKoala 1、你需要写<CLLocationManagerDelegate>2、你需要对所创建的CLLocationManager对象添加代理,也就是eg:
    //创建位置管理器(定位用户的位置)
    self.locMgr=[[CLLocationManager alloc]init];
    //2.设置代理
    self.locMgr.delegate=self;
  • 呵呵哈哈嘿嘿:你好,为什么我获取到经纬度数据,调用
    - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler

    这个方法反地理编码,获取就提城市信息的时候,有时很长时间拿不到地理信息,而且会输出一个
    Geocode error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x17064e9d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://dispatcher.is.autonavi.com/dispatcher, NSErrorFailingURLKey=https://dispatcher.is.autonavi.com/dispatcher, _kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4, NSLocalizedDescription=The request timed out.}
    这样的错误?
    呵呵哈哈嘿嘿:@辛小二 偶尔,有的时候会出现,有的时候不会出现
    辛小二:@辛小二 如果你想实现更多地图定位功能。请看http://www.jianshu.com/p/f1cc0b661d04文章。
    辛小二:@呵呵哈哈嘿嘿 你是一直都是反编码编译错误。还是有时会出现这个问题?如果偶尔的话,你检查下当前网络连接是否正常。
  • Hunter琼:你这算出来 单位是什么??
    辛小二:@7bf276a81417 高德经纬度,还有百度经纬度会有偏差,个人用百度经纬度比较准确:stuck_out_tongue:
    Hunter琼:@辛小二 你好 我没有移动 就好几米 似乎不对啊
    辛小二:@7bf276a81417 米
  • 瑛伟达:加油
    瑛伟达:@辛小二 :relaxed:
    辛小二:@NIUXINGJIAN 谢谢
  • 夜不知枫:加油,继续
    辛小二:@夜不知枫 加油:stuck_out_tongue:

本文标题:iOS怎样获取当前手机的地理位置和经纬度

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