您的位置:首页 > 移动开发 > IOS开发

ios 定位 航向检测

2015-09-15 16:15 627 查看
//  ViewController.m
//  CoreLocation框架的基本使用—定位
// 注意 点:  1.设置地位可用 2. 设置允许本程序定位(对弹出的框,允许即可) 3. 为模拟器  设置位置移动方式, 比如 Freeway Drive(自由驾车模式)

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

#define isIOS(version) ([[UIDevice currentDevice].systemVersion floatValue] >= version)

@interface ViewController ()<CLLocationManagerDelegate>
{
CLLocation *_lastLoc;
}
/** 位置管理者*/
@property (nonatomic, strong) CLLocationManager *locM;

@end

@implementation ViewController

#pragma mark - 懒加载
/** locM属性的懒加载 */
-(CLLocationManager *)locM
{
if (!_locM) {
// 1. 创建位置管理者
_locM = [[CLLocationManager alloc] init];
// 1.1 block , 代理, 通知
_locM.delegate = self;

// 精确度越高, 越好点, 而且, 定位时间越长
// 精确度
_locM.desiredAccuracy = kCLLocationAccuracyBest;

/** ----------iOS8.0+定位适配-------------- */

//  如果两个授权请求,同时发送, 那么先执行第一个

if(isIOS(8.0))
{

// 请求前后台定位授权
// 无论是在前台还是后台, 都可以获取用户位置,而且不会出现蓝条
// 无论是否勾选后台模式
// 如果当前的授权状态 != 用户未选择状态, 那么这个方法不会有效
// 如果当前授权状态 == 前台定位授权时, 这个方法也会有效
//            [_locM requestAlwaysAuthorization];

// 请求前台定位授权
// 在前台授权下, 默认只能在前台获取用户位置信息, 如果想要在后台获取用户位置, 那么 勾选后台模式 Location updates (会出现蓝条)
// 如果当前的授权状态 != 用户未选择状态, 那么这个方法不会有效
[_locM requestWhenInUseAuthorization];

// 在前台授权下, 默认只能在前台获取用户位置信息, 如果想要在后台获取用户位置, 那么 勾选后台模式 Location updates (会出现蓝条), 需要额外的设置一下属性为YES
if (isIOS(9.0)) {
//                _locM.allowsBackgroundLocationUpdates = YES;
}

}

}
return _locM;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

// 2. 开始更新用户位置
// start 开始某个服务  stop 停止某个服务
// 一旦我们调用了这个方法, 那么就会在后台不断的获取用户位置, 然后告诉外界
// 标准化定位(gps/ 基站 / WiFi)
//
[self.locM startUpdatingLocation];

// 显著位置变化(基站)(要求设备必须由电话模块)
// 当app 被杀死时也可以接收到位置通知(app -- 后台  )
//    [self.locM startMonitoringSignificantLocationChanges];

/**
*   ———————————应用场景—————————————
1) 如果要求定位及时,精度较高,并且运行时间较短,可使用标准定位;
2) 如果长时间监控用户位置,用户移动速度比较快(例如打车软件),可使用后者
*
*/

/**
*  extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;ß
*/

//    [self.locM requestLocation];

}

#pragma mark - CLLocationManagerDelegate

/**
*  获取到位置信息时调用
*
*  @param manager   位置管理者
*  @param locations 位置数组
*/
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//    NSLog(@"获取到位置");

CLLocation *loc = [locations lastObject];

NSLog(@"%lf",loc.horizontalAccuracy);
// 代表当前位置  horizontalAccuracy>0 才是有效的
if(loc.horizontalAccuracy > 0)
{

/**
*  CLLocation
* coordinate : 经纬度
altitude :海拔
course : 航向
speed : 速度
distanceFromLocation : 计算两个点之间的直线物理距离
*/

/**
*  场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
例如:”北偏东 30度  方向,移动了 8米  ”
*/

// 确定航向
NSString *angleStr = nil;
switch ((int)loc.course / 90) {
case 0:
angleStr = @"北偏东";
break;
case 1:
angleStr = @"东偏南";
break;
case 2:
angleStr = @"南偏西";
break;
case 3:
angleStr = @"西偏北";
break;

default:
angleStr = @"掉沟里去了";
break;
}

// 确定偏离角度
int angle = 0;
angle = (int)loc.course % 90;
// 正方向
if (angle == 0) {
angleStr = [angleStr substringToIndex:1];
}

// 移动了多少
CLLocationDistance distance = 0;
if (_lastLoc) {
distance = [loc distanceFromLocation:_lastLoc];
}
_lastLoc = loc;

// 拼串
// 例如:”北偏东 30度  方向,移动了 8米  ”

NSString *str ;
if (angle == 0) {
str = [NSString stringWithFormat:@"正%@方向, 移动了%f米", angleStr, distance];
}else
{
str = [NSString stringWithFormat:@"%@%zd度方向, 移动了%f米", angleStr , angle, distance];
}

NSLog(@"%@", str);

}

// 如果我们想要定位一次

// 停止位置更新
//    [manager stopUpdatingLocation];
}

/**
*  当前授权状态发生变化时调用
*
*  @param manager 位置管理者
*  @param status  状态
*/
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
{
NSLog(@"用户未选择");
break;
}
case kCLAuthorizationStatusRestricted:
{
NSLog(@"受限制");
break;
}
case kCLAuthorizationStatusDenied:
{

// 确定当前设备, 是否支持定位,或者定位服务是否开启
if([CLLocationManager locationServicesEnabled])
{
NSLog(@"拒绝");

// 我们可以调用代码, 打开设置界面
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}

}else
{
NSLog(@"服务关闭");
}

break;
}
case kCLAuthorizationStatusAuthorizedAlways:
{
NSLog(@"前后台定位授权");
break;
}
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"前台定位授权");
break;
}

default:
break;
}
}

/**
*  定位失败
*
*  @param manager 位置管理者
*  @param error   错误
*/
-(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error
{
NSLog(@"fail%@",error);

}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: