备注:本教程只考虑iOS 8.0+,测试切勿忘了权限
2.区域位置监听
3.地理位置编码
。。。。比较懒不想写文字,而且写这就是当个笔记用
iOS开发中CoreLocation是一个与定位有关的类,本教程将利用CoreLocation来实现三个小功能,获取经纬度、区域位置监听、地理位置编码。
1.获取经纬度
//
// LocationController.m
// CoreLocation
//
// Created by LouKit on 2017/2/17.
// Copyright © 2017年 LouKit. All rights reserved.
//
#import "LocationController.h"
#import <CoreLocation/CoreLocation.h>
@interface LocationController ()<CLLocationManagerDelegate>
@property (nonatomic,strong) CLLocationManager *locMgr;
@property (nonatomic, strong) CLLocation *lastLoc;
@end
@implementation LocationController
-(CLLocationManager *)locMgr{
if(![CLLocationManager locationServicesEnabled]){
NSLog(@"定位服务没有开启不可用");
return nil;
}
if (!_locMgr) {
_locMgr = [[CLLocationManager alloc]init];
_locMgr.delegate = self;
//ios9 以上才有
//_locMgr.allowsBackgroundLocationUpdates = YES;
//前台定位
//[_locMgr requestWhenInUseAuthorization];
//前后台定位
[_locMgr requestAlwaysAuthorization];
//一些属性设置
//定位精度
/**
kCLLocationAccuracyBestForNavigation
CLLocationAccuracy kCLLocationAccuracyBest;
CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
CLLocationAccuracy kCLLocationAccuracyHundredMeters;
CLLocationAccuracy kCLLocationAccuracyKilometer;
CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
**/
_locMgr.desiredAccuracy = kCLLocationAccuracyBest;
//定位频率
_locMgr.distanceFilter = 100;//每隔100米定位一次
}
return _locMgr;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
// 开始定位用户的位置
if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
//doing
}else{
//一次定位
//[self.locMgr requestLocation];
[self.locMgr startUpdatingLocation];
}
[self countLineDistance];
}
#pragma mark - CLLocationManagerDelegate
//当前位置授权状态的改变
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
/**
用户未决定
kCLAuthorizationStatusNotDetermined = 0,
//受限制
kCLAuthorizationStatusRestricted,
//拒绝
kCLAuthorizationStatusDenied,
//前后台定位授权
kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),
//前台定位
kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
**/
}
//定位到位置时调用 (调用频率特别高)
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *loc = [locations firstObject];
CLLocationCoordinate2D coordinate = loc.coordinate;
NSLog(@"经纬度:------%f %f", coordinate.latitude, coordinate.longitude);
/**
altitude : 海拔
horizontalAccuracy : 如果是负值, 代表当前位置数据不可用
verticalAccuracy : 海拔 -- 如果是负值, 代表当前海拔数据不可用
course : 航向 (0.0----359.9)
speed : 速度
floor : 楼层
方法:
distanceFromLocation : 计算两个坐标之间的物理直线距离
*/
/
// >场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
// 例如:”北偏东 30度 方向,移动了 8米”
if (loc.horizontalAccuracy < 0) {
return;
}
// 1. 确定当前航向
NSInteger index = (int)loc.course / 90;
NSArray *courseStrArray = @[@"北偏东", @"东偏南", @"南偏西", @"西偏北"];
NSString *courseStr = courseStrArray[index];
// 2. 确定偏离角度
NSInteger angle = (int)loc.course % 90;
// 代表是正方向
if (angle == 0) {
courseStr = [@"正" stringByAppendingString:[courseStr substringToIndex:1]];
}
// 3. 确定行走距离
CGFloat distance = 0;
if (_lastLoc) {
distance = [loc distanceFromLocation:_lastLoc];
}
_lastLoc = loc;
// 4. 打印
NSString *noticeStr;
if(angle != 0)
{
noticeStr = [NSString stringWithFormat:@"%@ %zd 度方向, 移动了 %f米", courseStr, angle, distance];
}else
{
noticeStr = [NSString stringWithFormat:@"%@ 方向, 移动了 %f米", courseStr, distance];
}
NSLog(@"%@", noticeStr);
// 停止定位
// [self.locMgr stopUpdatingLocation];
}
//定位失败时调用
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"%s",__func__);
}
//计算两个经纬度之间的直线距离
- (void)countLineDistance
{
// 计算2个经纬度之间的直线距离
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:40 longitude:120];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:41 longitude:120];
CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
NSLog(@"countLineDistance:%f", distance);
}
@end
2.区域位置监听
//
// RegionController.m
// CoreLocation
//
// Created by LouKit on 2017/2/17.
// Copyright © 2017年 LouKit. All rights reserved.
//
#import "RegionController.h"
#import <CoreLocation/CoreLocation.h>
@interface RegionController ()<CLLocationManagerDelegate>
@property (nonatomic,strong) CLLocationManager *locMgr;
@property (nonatomic, strong) CLLocation *lastLoc;
@end
@implementation RegionController
-(CLLocationManager *)locMgr{
if(![CLLocationManager locationServicesEnabled]){
NSLog(@"定位服务没有开启不可用");
return nil;
}
if (!_locMgr) {
_locMgr = [[CLLocationManager alloc]init];
_locMgr.delegate = self;
//前后台定位
[_locMgr requestAlwaysAuthorization];
}
return _locMgr;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
// 判断当前设备是否支持区域监听(区域类型)
if (![CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
return;
}
// 创建区域
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(37.78,-122.40);//测试时在模拟器外部需要设置好经纬度
CLLocationDistance distance = 1000.0;
if(distance > self.locMgr.maximumRegionMonitoringDistance)
{
distance = self.locMgr.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:distance identifier:@"lk_identifier"];
// 监听一个区域(只有用户有进入区域, 或者离开区域时才会调用代理)
[self.locMgr startMonitoringForRegion:region];
// 请求某个区域的状态
// 获取到指定区域的状态, 而且当状态发生变化时也会调用对应的代理方法
[self.locMgr requestStateForRegion:region];
}
#pragma mark - CLLocationManagerDelegate
/**
* 当前请求指定区域状态时, 回调的代理方法
* @param manager 位置管理者
* @param state 状态
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
//state
//CLRegionStateUnknown, // 不知道
//CLRegionStateInside, // 在区域内部
//CLRegionStateOutside // 在区域外部
if(state == CLRegionStateInside)
{
NSLog(@"区域内部");
}else if (state == CLRegionStateOutside)
{
NSLog(@"区域外部");
}
NSLog(@"%s;%@",__func__,region.identifier);
}
/**
* 进入指定区域时调用
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(@"%s;%@",__func__,region.identifier);
}
/**
* 离开指定区域时调用
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(@"%s;%@",__func__,region.identifier);
}
@end
3.地理位置编码
//
// GeocoderController.m
// CoreLocation
//
// Created by LouKit on 2017/2/17.
// Copyright © 2017年 LouKit. All rights reserved.
//
#import "GeocoderController.h"
#import <CoreLocation/CoreLocation.h>
@interface GeocoderController ()
@property (nonatomic,strong) CLGeocoder *geocoder;
@end
@implementation GeocoderController
-(CLGeocoder *)geocoder{
if (!_geocoder) {
_geocoder = [[CLGeocoder alloc]init];
}
return _geocoder;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor yellowColor];
//[self geocode];
[self reverseGeocode];
}
//地理编码
-(void)geocode{
[self.geocoder geocodeAddressString:@"北京" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error) {
NSLog(@"输入的地址有误");
return ;
}
//取出最前面地址
CLPlacemark *pm = [placemarks firstObject];
NSLog(@"lat:%f;lon:%f;addressDictionary:%@",pm.location.coordinate.latitude,pm.location.coordinate.longitude,pm.addressDictionary);
/**
lat:39.904989;lon:116.405285;addressDictionary:{
City = Beijing;
Country = China;
CountryCode = CN;
FormattedAddressLines = (
"Beijing China"
);
Name = Beijing;
State = Beijing;
}**/
}];
}
//反地理编码
-(void)reverseGeocode{
CLLocation *location = [[CLLocation alloc] initWithLatitude:39.904989 longitude:116.405285];
[self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error) {
NSLog(@"输入的地址有误");
return ;
}
//取出最前面地址
CLPlacemark *pm = [placemarks firstObject];
NSLog(@"reverseGeocode CLPlacemark:%@",pm.addressDictionary);
/**
CLPlacemark:{
City = Beijing;
Country = China;
CountryCode = CN;
FormattedAddressLines = (
"East Chang'an Avenue No.14 Dongcheng",
"Beijing China"
);
Name = "Ministry of Public Security";
State = Beijing;
Street = "East Chang'an Avenue No.14";
SubLocality = Dongcheng;
Thoroughfare = "East Chang'an Avenue No.14";
}**/
}];
}
@end
。。。。比较懒不想写文字,而且写这就是当个笔记用
因此一些概念性以及CoreLocation中一些基础方法、代理方面了解可以
参考 Kenshin Cui's Blog iOS开发系列--地图与定位