iOS_CLLocation定位


   CoreLocation框架可用於定位設備當前經緯度,通過該框架,應用程序可通過附近的蜂窩基站,WIFI信號或者GPS等信息計算用戶位置。
     iOS定位支持的3種模式。
     (1)GPS衛星定位
     (2)基站定位
     (3)WiFi
     iOS開發者使用CoreLocation.framework框架進行定位非常簡單,CoreLocation框架的常用API主要有如下幾個。
     (1)CLLocationManger:定位管理器類。
     (2)CLLocationManagerDelegate:該協議代表定位管理器的delegate協議。實現該協議的對象可負責處理CLLocationManager的定位事件。
     (3)CLLocation:該對象代表位置。該對象包含了當前設備的經度、緯度、高度、速度、路線等信息,還包含了該定位信息的水平精確度,垂直精確度以及時間戳信息。
     (4)CLHeading:該對象代表設備的移動方向。
     (5)CLRegion:該對象代表一個區域。一般程序不會直接使用該類,而是使用它的兩個子類,即CLCircularRegion(圓形區域)和CLBeaconRegion(藍牙信號區)。
  
   1.獲取位置信息
     (1)創建CLLocationManager對象,該對象負責獲取定位相關信息。並為該對象設置一些必要的屬性。
     (2)為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
     (3)調用CLLocationManager的startUpdatingLocation方法獲取定位信息。定位結束時,可調用stopUpdatingLocation方法結束獲取定位信息。
  
  案例:
  第一步:在CoreLocation.framework添加到項目中去
  第二步:在iOS8中需要在info.plist中添加兩個字段。
  代碼如下:
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
@property (weak, nonatomic) IBOutlet UITextField *longitude;
@property (weak, nonatomic) IBOutlet UITextField *latitude;
@property (weak, nonatomic) IBOutlet UITextField *height;
@property (weak, nonatomic) IBOutlet UITextField *speed;
@property (weak, nonatomic) IBOutlet UITextField *direction;
@property(strong,nonatomic)CLLocationManager *locationManager;
@end

@implementation ViewController
- (IBAction)beginLocation:(UIButton *)sender
{
    if ([CLLocationManager locationServicesEnabled]) {
        NSLog(@"開始執行定位服務");
        //設定定位精度:最佳精度
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        //設置距離過濾器為50米,表示每移動50米更新一次位置
        self.locationManager.distanceFilter = 50;
        //將視圖控制器自身設置為CLLocationManager的delegate
        //因此該視圖控制器需要實現CLLocationManagerDelegate協議
        self.locationManager.delegate = self;
    }
    else
    {
        NSLog(@"無法使用定位服務");
    }
}
-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    //開啟定位
    [_locationManager startUpdatingLocation];
}
-(void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    //結束定位
    [_locationManager stopUpdatingLocation];
}
#pragma mark - CLLocationDelegate代理協議
//成功獲取定位數據后將會激發該方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    //獲取最后一個定位數據
    CLLocation *location = [locations lastObject];
    //依次獲取CLLocation中封裝的經度、緯度、高度、速度、方向等信息
    self.longitude.text = [NSString stringWithFormat:@"%g",location.coordinate.longitude];//緯度
    NSLog(@"%f",location.coordinate.longitude);
    self.latitude.text = [NSString stringWithFormat:@"%g",location.coordinate.latitude];//經度
    self.height.text = [NSString stringWithFormat:@"%g",location.altitude];
    self.speed.text = [NSString stringWithFormat:@"%g",location.speed];
    self.direction.text = [NSString stringWithFormat:@"%g",location.course];
    
}
//定位失敗執行的操作
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"定位失敗:%@",error);
}
- (void)viewDidLoad {
    [super viewDidLoad];
    //創建CLLocationManager對象
    self.locationManager = [[CLLocationManager alloc]init];
}

@end

  運行效果圖,如下:

   方向監測
     擁有GPS硬件的設備可以生成設備的當前方向(course屬性)和速度信息。iPhone設備攜帶的定位管理器可以返回一個已經計算好的course值,通過這個值我們可以獲得當前前進的方向,course值是0~360之間的浮點數,0°值表示正北方向,90°表示正東方向,180°值表示正南方向,270°值表示正西方向,程序可以通過course值來檢測用戶位置的移動方向。除此之外,還可以通過磁力計來獲取設備的真實方向。
     使用CLLocationManager獲取設備方向的步驟如下。
     1.創建CLLocationManager對象,該對象負責獲取定位相關信息,並為該對象設置一些必要的屬性。
     2.為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
     3.調用CLLocationManager的startUpdatingHeading方法獲取方向信息。獲取方向結束時,可調用stopUpdatingHeading方法結束時獲取方向信息。
     當設備的方向改變時,iOS系統就會自動激發CLLocationManager的delegate對象的locationManager:didUpdateHeading:方法,而程序可通過重寫該方法來獲取設備方向。
     iOS允許為檢測方向改變設置如下屬性。
     1)CLLocationDegress headingFilter:設置只有當設備方向的改變值超過該屬性值時才激發delegate的方法。
     2)CLDeviceOrientation headingOrientation:設置設備當前方向。
     監聽方向時返回的是一個CLHeading對象,該對象包含以下屬性。
     1)magnticHeading:該屬性返回設備與磁北的相對方向。
     2)trueHeading:該屬性返回設備與真北的相對方向。
     3)headingAccuracy:該屬性返回方向值的誤差范圍。
     4)timestamp:該屬性返回方向值的生成時間。

 

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
{
    CALayer *znzLayer;
}
@property(strong,nonatomic)CLLocationManager *locationManager;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //如果磁力計可用,則開始監聽方向改變
    if ([CLLocationManager headingAvailable]) {
        //創建顯示方向的指南針圖片Layer;
        znzLayer = [[CALayer alloc]init];
        NSInteger screenHeight = [UIScreen mainScreen].bounds.size.height;
        NSInteger y = (screenHeight - 320)/2;
        znzLayer.frame = CGRectMake(0, y, 320, 320);
        //設置znzLayer顯示的圖片
        znzLayer.contents = (id)[[UIImage imageNamed:@"1.png"]CGImage];
        //將znzLayer添加到系統的UIView中
        [self.view.layer addSublayer:znzLayer];
        //創建CLLocationManager對象
        self.locationManager = [[CLLocationManager alloc]init];
        self.locationManager.delegate = self;
        [self.locationManager startUpdatingHeading];
        
    }
    else
    {
        [[[UIAlertView alloc]initWithTitle:@"提醒" message:@"您的設備不支持磁力計" delegate:self cancelButtonTitle:@"確定" otherButtonTitles: nil]show];
    }
}
#pragma mark - CLLocationManagerDelegate代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    //將設備的方向換算成弧度
    CGFloat headings = -1.0f *M_PI * newHeading.magneticHeading / 180.0f;
    //創建不斷改變CALayer的transform屬性的屬性動畫
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    CATransform3D fromValue = znzLayer.transform;
    //設置動畫開始的屬性值
    anim.fromValue = [NSValue valueWithCATransform3D:fromValue];
    //繞Z軸旋轉heading弧度的變換矩陣
    CATransform3D toValue = CATransform3DMakeRotation(headings, 0, 0, 1);
    //設置動畫結束時的屬性
    anim.toValue = [NSValue valueWithCATransform3D:toValue];
    anim.duration = 0.5;
    anim.removedOnCompletion = YES;
    //設置動畫結束后znzLayer的變換矩陣
    znzLayer.transform = toValue;
    //為znzLayer添加動畫
    [znzLayer addAnimation:anim forKey:nil];
    
}
-(BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
{
    return YES;
}

@end

  區域監測

     如果希望iOS設備進入某個區域發出通知,那么這種區域監測的功能也被稱為臨近警告。所謂臨近警告的示意圖如下:
  用戶設備不斷地臨近指定固定點,當與該固定點的距離小於指定范圍時,系統可以觸發相應的處理。用戶設備離開指定固定點,當與該固定點的距離大於指定范圍時,系統也可以觸發相應的處理。
     iOS的區域監測同樣可以使用CLLocationManager來實現,監聽設備是否進入/離開某個區域的步驟如下:
     1)創建CLLocationManager對象,該對象負責獲取定位相關信息,並未該對象設置一些必要的屬性。對於區域監測而言,CLLocationManager對象需要設置monitoredRegions屬性,該屬性值用於設置該設備監聽的多個區域。
     2)為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
     3)調用CLLocationManager的startMonitoringForRegion:方法進行區域監測。區域監測結束時,可調用stopMonitoringForRegion:方法結束區域監測。
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
@property(strong,nonatomic)CLLocationManager *locationManager;
@end

@implementation ViewController
-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.locationManager startUpdatingLocation];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    //判斷是否開啟定位服務
    if ([CLLocationManager locationServicesEnabled]) {
        self.locationManager = [[CLLocationManager alloc]init];
        
        //定義一個CLLocationCoordinate2D作為區域的圓心
        CLLocationCoordinate2D companyCenter;
        companyCenter.latitude = 23.126272;
        companyCenter.longitude = 113.395568;
        //使用CLCircularRegion創建一個圓形區域,半徑為500米
        CLRegion *fkit = [[CLCircularRegion alloc]initWithCenter:companyCenter radius:500 identifier:@"fkit"];
        //開始監聽fkit區域
        [self.locationManager startMonitoringForRegion:fkit];
        self.locationManager.delegate = self;
        [self.locationManager requestAlwaysAuthorization];
    }
    else
    {
        [[[UIAlertView alloc]initWithTitle:@"提醒" message:@"您的設備不支持定位" delegate:self cancelButtonTitle:@"確定" otherButtonTitles: nil]show];
    }
    [self.locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate代理方法
//進入指定區域以后彈出提示框提示用戶
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    [[[UIAlertView alloc]initWithTitle:@"區域檢測提示" message:@"您已經【進入】中關園區域" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]show];
}
//離開指定區域以后將彈出提示框提示用戶
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    [[[UIAlertView alloc]initWithTitle:@"區域檢測提示" message:@"您已經【離開】中關園區域" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]show];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM