获取当前经纬度、当前位置省市区(工具类)

//
//  YALocationInfo.h
//  YATestFramework
//
//  Created by MacDev1 on 15/6/25.
//  Copyright (c) 2015年 yanan. All rights reserved.
//

/*
 * 需要导入 CoreLocation.framework
 */

#import <Foundation/Foundation.h>

#import <CoreLocation/CoreLocation.h>

@class YALocationInfor;

typedef NS_ENUM(NSInteger, LocationResult) {
    FAIL    = 0,
    SUCCESS    ,
};

typedef void(^LocBlock)(YALocationInfor *locInforModel, LocationResult locRes, NSError *error);

@interface YALocationInfor : NSObject

/**
 *	@brief	YES 有定位的信息可以使用(可以自行决定是否再次调用 getUserCurrentLocationInfo 定位);NO 还没有进行定位或者定位尚未成功过
 */
@property (assign, nonatomic, readonly) BOOL isHaveLocInfor;

/**
 *	@brief	用户当前的纬度
 */
@property (assign, nonatomic, readonly) CLLocationDegrees uLatitude;

/**
 *	@brief	用户当前的经度
 */
@property (assign, nonatomic, readonly) CLLocationDegrees uLongitude;

/**
 *	@brief	国家
 */
@property (strong, nonatomic, readonly) NSString *uCounty;

/**
 *	@brief	国家码
 */
@property (strong, nonatomic, readonly) NSString *uCountryCode;

/**
 *	@brief	省或直辖市
 */
@property (strong, nonatomic, readonly) NSString *uProvince;

/**
 *	@brief	城市
 */
@property (strong, nonatomic, readonly) NSString *uCity;

/**
 *	@brief	完整的详细信息
 */
@property (strong, nonatomic, readonly) NSString *uAddress;

/**
 *	@brief	街道
 */
@property (strong, nonatomic, readonly) NSString *uStreet;

/**
 *	@brief	区 e.g. 昌平区
 */
@property (strong, nonatomic, readonly) NSString *uSubLocality;

/**
 *	@brief	门牌号
 */
@property (strong, nonatomic, readonly) NSString *uSubThoroughfare;

/**
 *	@brief	路名
 */
@property (strong, nonatomic, readonly) NSString *uThoroughfare;

/**
 *	@brief	地址详情
 */
@property (strong, nonatomic, readonly) NSString *uDetailLocString;

/**
 *	@brief	单例
 *
 *	@return
 */
+ (YALocationInfor *)shareLocationInforModel;

/**
 *	@brief	定位(或重新定位)获取用户当前位置信息
 *
 *	@return
 */
- (void)getUserCurrentLocationInfo:(LocBlock)LocationBlock;

/**
 *  根据2个经纬度计算距离
 */
+(double) LantitudeLongitudeDist:(double)lon1 other_Lat:(double)lat1 self_Lon:(double)lon2 self_Lat:(double)lat2;

@end


//
//  YALocationInfo.m
//  YATestFramework
//
//  Created by MacDev1 on 15/6/25.
//  Copyright (c) 2015年 yanan. All rights reserved.
//

#import "YALocationInfor.h"

@interface YALocationInfor ()<CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *mLocationManager;

@property (copy, nonatomic) LocBlock mLocationBlock;



@end

@implementation YALocationInfor

#pragma mark - 单例
static YALocationInfor *single = nil;
+ (YALocationInfor *)shareLocationInforModel {
    @synchronized(self) {
        if (!single) {
            single = [[YALocationInfor alloc]init];
            // 调用获取位置信息的方法
            [single getUserCurrentLocationInfo:NULL];
        }
        return single;
    }
}

#pragma mark - 开始获取用户当前的位置信息
- (void)getUserCurrentLocationInfo:(LocBlock)LocationBlock {
    _mLocationBlock = LocationBlock;
    if (!_mLocationManager) {
        _mLocationManager = [[CLLocationManager alloc]init];
        _mLocationManager.distanceFilter = kCLDistanceFilterNone; // meters
        _mLocationManager.delegate = self;
        _mLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        if (IS_IOS8_LATER) {
            
            /* 需要在info中新增两个key NSLocationAlwaysUsageDescription 和 NSLocationWhenInUseUsageDescription  */
            
            //使用期间
            [_mLocationManager requestWhenInUseAuthorization];
            //始终
//             [self.locationManage requestAlwaysAuthorization]
        }
    }
    if (_mLocationManager)
        [_mLocationManager startUpdatingLocation];
}

#pragma mark - 成功获取定位数据后
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations {
    
    CLLocation *currentLocation = [locations lastObject];
    
    _uLatitude = currentLocation.coordinate.latitude;
    _uLongitude = currentLocation.coordinate.longitude;
    
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:currentLocation
                   completionHandler:^(NSArray *array, NSError *error) {
                       if (array.count > 0) {
                           CLPlacemark *placemark = [array objectAtIndex:0];
                           [self locSuccessSet:placemark];
                           if (_mLocationBlock)
                               _mLocationBlock(self, SUCCESS, error);
                       } else if (error == nil && [array count] == 0) {
                           if (_mLocationBlock)
                               _mLocationBlock(self, FAIL, error);
                       } else if (error != nil) {
                           if (_mLocationBlock)
                               _mLocationBlock(self, FAIL, error);
                       }
                   }];
    
    [_mLocationManager stopUpdatingLocation];
}


#pragma mark - 定位失败时回调
- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error {
    if (_mLocationBlock) {
        _mLocationBlock(self, FAIL, error);
    }
    
}


#pragma mark - 处理定位成功后,反向地理编码得到的信息
- (void)locSuccessSet:(CLPlacemark *)placemark {
    _isHaveLocInfor = YES;
    
    //获取城市
    NSString *city = placemark.locality;
    if (!city) {
        // 四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)
        city = placemark.administrativeArea;
    }
    _uCity = city;
    
    _uCounty          = [placemark.addressDictionary objectForKey:@"Country"];
    _uCountryCode     = [placemark.addressDictionary objectForKey:@"CountryCode"];
    _uProvince        = [placemark.addressDictionary objectForKey:@"State"];
    _uAddress         = [placemark.addressDictionary objectForKey:@"FormattedAddressLines"];
    _uStreet          = [placemark.addressDictionary objectForKey:@"Street"];
    _uSubLocality     = [placemark.addressDictionary objectForKey:@"SubLocality"];
    _uSubThoroughfare = [placemark.addressDictionary objectForKey:@"SubThoroughfare"];
    _uThoroughfare    = [placemark.addressDictionary objectForKey:@"Thoroughfare"];
    
    _uDetailLocString = [[NSString alloc]initWithFormat:@"%@%@%@",_uProvince?_uProvince:@"",_uSubLocality?_uSubLocality:@"",_uStreet?_uStreet:@""];
//    FIXLog(@"\n\n\n\nplacemark.addressDictionary = %@\n\n\n\n",placemark.addressDictionary);
}

#pragma mark - iOS8 新增回调方法
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
            if ([_mLocationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
                [_mLocationManager requestWhenInUseAuthorization];
            }
            break;
        default:
            break;
    }
    
}
/**
 *  根据2个经纬度计算距离
 */
//+(NSString *) LantitudeLongitudeDist:(double)lon1 other_Lat:(double)lat1 self_Lon:(double)lon2 self_Lat:(double)lat2
//{
//    
//    CLLocation *orig=[[CLLocation alloc] initWithLatitude:lat2  longitude:lon2] ;
//    CLLocation* dist=[[CLLocation alloc] initWithLatitude:lat1 longitude:lon1];
//    
//    CLLocationDistance kilometers=[orig distanceFromLocation:dist] / 1000;
//    
//    
//   return [NSString stringWithFormat:@"%0.2f",kilometers];
//}




#define PI 3.1415926
+(double) LantitudeLongitudeDist:(double)lon1 other_Lat:(double)lat1 self_Lon:(double)lon2 self_Lat:(double)lat2{
    double er = 6378137; // 6378700.0f;
    //ave. radius = 6371.315 (someone said more accurate is 6366.707)
    //equatorial radius = 6378.388
    //nautical mile = 1.15078
    double radlat1 = PI*lat1/180.0f;
    double radlat2 = PI*lat2/180.0f;
    //now long.
    double radlong1 = PI*lon1/180.0f;
    double radlong2 = PI*lon2/180.0f;
    if( radlat1 < 0 ) radlat1 = PI/2 + fabs(radlat1);// south
    if( radlat1 > 0 ) radlat1 = PI/2 - fabs(radlat1);// north
    if( radlong1 < 0 ) radlong1 = PI*2 - fabs(radlong1);//west
    if( radlat2 < 0 ) radlat2 = PI/2 + fabs(radlat2);// south
    if( radlat2 > 0 ) radlat2 = PI/2 - fabs(radlat2);// north
    if( radlong2 < 0 ) radlong2 = PI*2 - fabs(radlong2);// west
    //spherical coordinates x=r*cos(ag)sin(at), y=r*sin(ag)*sin(at), z=r*cos(at)
    //zero ag is up so reverse lat
    double x1 = er * cos(radlong1) * sin(radlat1);
    double y1 = er * sin(radlong1) * sin(radlat1);
    double z1 = er * cos(radlat1);
    double x2 = er * cos(radlong2) * sin(radlat2);
    double y2 = er * sin(radlong2) * sin(radlat2);
    double z2 = er * cos(radlat2);
    double d = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
    //side, side, side, law of cosines and arccos
    double theta = acos((er*er+er*er-d*d)/(2*er*er));
    double dist  = theta*er;
    return dist / 1000;
}
@end




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值