亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

IOS CoreLocation實現(xiàn)系統(tǒng)自帶定位的方法

 更新時間:2017年02月23日 10:22:21   作者:低調學者  
本篇文章主要介紹了IOS Core Location實現(xiàn)系統(tǒng)自帶定位的方法,非常具有實用價值,需要的朋友可以參考下。

Core Location是iOS SDK中一個提供設備位置的框架??梢允褂萌N技術來獲取位置:GPS、蜂窩或WiFi。在這些技術中,GPS最為精準,如果有GPS硬件,Core Location將優(yōu)先使用它。如果設備沒有GPS硬件(如WiFi iPad)或使用GPS獲取當前位置時失敗,Core Location將退而求其次,選擇使用蜂窩或WiFi。

Core Location的大多數功能是由位置管理器(CLLocationManager)提供的,可以使用位置管理器來指定位置更新的頻率和精度,以及開始和停止接收這些更新。

要使用位置管理器,必須首先將框架Core Location加入到項目中,再導入其接口文件:

#import <CoreLocation/CoreLocation.h>

并初始化位置管理器,指定更新代理,以及一些更新設置,然后更新

CLLocationManager *locManager = [[CLLocationManager alloc] init];

locManager.delegate = self;

[locManager startUpdatingLocation]; 

位置管理器委托(CLLocationManagerDelegate)有兩個與位置相關的方法:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{ 

 CLLocation *curLocation = [locations lastObject];
  
  if(curLocation.horizontalAccuracy > 0)
  {
    NSLog(@"當前位置:%.0f,%.0f +/- %.0f meters",curLocation.coordinate.longitude,
       curLocation.coordinate.latitude,
       curLocation.horizontalAccuracy);
  }
  
  if(curLocation.verticalAccuracy > 0)
  {
    NSLog(@"當前海拔高度:%.0f +/- %.0f meters",curLocation.altitude,curLocation.verticalAccuracy);
  }

}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{ //此方法為定位失敗的時候調用。并且由于會在失敗以后重新定位,所以必須在末尾停止更新 

 if(error.code == kCLErrorLocationUnknown)
  {
    NSLog(@"Currently unable to retrieve location.");
  }
  else if(error.code == kCLErrorNetwork)
  {
    NSLog(@"Network used to retrieve location is unavailable.");
  }
  else if(error.code == kCLErrorDenied)
  {
    NSLog(@"Permission to retrieve location is denied.");
    [manager stopUpdatingLocation];
  }


} 


第一個方法處理定位成功,manager參數表示位置管理器實例;locations為一個數組,是位置變化的集合,它按照時間變化的順序存放。如果想獲得設備的當前位置,只需要訪問數組的最后一個元素即可。集合中每個對象類型是CLLocation,它包含以下屬性:

coordinate — 坐標。一個封裝了經度和緯度的結構體。

altitude — 海拔高度。正數表示在海平面之上,而負數表示在海平面之下。

horizontalAccuracy — 位置的精度(半徑)。位置精度通過一個圓表示,實際位置可能位于這個圓內的任何地方。這個圓是由coordinate(坐標)和horizontalAccuracy(半徑)共同決定的,horizontalAccuracy的值越大,那么定義的圓就越大,因此位置精度就越低。如果horizontalAccuracy的值為負,則表明coordinate的值無效。

verticalAccuracy — 海拔高度的精度。為正值表示海拔高度的誤差為對應的米數;為負表示altitude(海拔高度)的值無效。

speed — 速度。該屬性是通過比較當前位置和前一個位置,并比較它們之間的時間差異和距離計算得到的。鑒于Core Location更新的頻率,speed屬性的值不是非常精確,除非移動速度變化很小。

應用程序開始跟蹤用戶的位置時,將在屏幕上顯示一個是否允許定位的提示框。如果用戶禁用定位服務,iOS不會禁止應用程序運行,但位置管理器將生成錯誤。

第二個方法處理這種定位失敗,該方法的參數指出了失敗的原因。如果用戶禁止應用程序定位,error參數將為kCLErrorDenied;如果Core Location經過努力后無法確認位置,error參數將為kCLErrorLocationUnknown;如果沒有可供獲取位置的源,error參數將為kCLErrorNetwork。

通常,Core Location將在發(fā)生錯誤后繼續(xù)嘗試確定位置,但如果是用戶禁止定位,它就不會這樣做;在這種情況下,應使用方法stopUpdatingLocation停止位置管理器。

可根據實際情況來指定位置精度。例如,對于只需確定用戶在哪個國家的應用程序,沒有必要要求Core Location的精度為10米。要指定精度,可在啟動位置更新前設置位置管理器的desiredAccuracy。有6個表示不同精度的枚舉值:

extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;

extern const CLLocationAccuracy kCLLocationAccuracyBest;

extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;

extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;

extern const CLLocationAccuracy kCLLocationAccuracyKilometer;

extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers; 

對位置管理器啟動更新后,更新將不斷傳遞給位置管理器委托,直到停止更新。您無法直接控制這些更新的頻率,但可使用位置管理器的屬性distanceFilter進行間接控制。在啟動更新前設置屬性distanceFilter,它指定設備(水平或垂直)移動多少米后才將另一個更新發(fā)送給委托。下面的代碼使用適合跟蹤長途跋涉者的設置啟動位置管理器:

CLLocationManager *locManager = [[CLLocationManager alloc] init];

locManager.delegate = self;

locManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;//定位精度百米以內

locManager.distanceFilter = 200;//水平或者垂直移動200米調用代理更新位置

[locManager startUpdatingLocation];//啟動位置更新 

P.s. 定位要求的精度越高、屬性distanceFilter的值越小,應用程序的耗電量就越大。

位置管理器有一個headingAvailable屬性,它指出設備是否裝備了磁性指南針。如果該屬性為YES,就可以使用Core Location來獲取航向(heading)信息。接收航向更新與接收位置更新極其相似,要開始接收航向更新,可指定位置管理器委托,設置屬性headingFilter以指定要以什么樣的頻率(以航向變化的度數度量)接收更新,并對位置管理器調用方法startUpdatingHeading:

位置管理器委托協(xié)議定義了用于接收航向更新的方法。該協(xié)議有兩個與航向相關的方法:

- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
{
  return YES;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
  
}

第一個方法指定位置管理器是否向用戶顯示校準提示。該提示將自動旋轉設備360°。由于指南針總是自我校準,因此這種提示僅在指南針讀數劇烈波動時才有幫助。當設置為YES后,提示可能會分散用戶的注意力,或影響用戶的當前操作。

第二個方法的參數newHeading是一個CLHeading對象。CLHeading通過一組屬性來提供航向讀數:magneticHeading和trueHeading。這些值的單位為度,類型為CLLocationDirection,即雙精度浮點數。這意味著:

如果航向為0.0,則前進方向為北;

如果航向為90.0,則前進方向為東;

如果航向為180.0,則前進方向為南;

如果航向為270.0,則前進方向為西。

CLHeading對象還包含屬性headingAccuracy(精度)、timestamp(讀數的測量時間)和description(這種描述更適合寫入日志而不是顯示給用戶)。下面演示了利用這個方法處理航向更新:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
  if(newHeading.headingAccuracy >=0)
  {
    NSString *headingDesc = [NSString stringWithFormat:@"%.0f degrees (true), %.0f degrees (magnetic)",newHeading.trueHeading,newHeading.magneticHeading];
    
    NSLog(@"%@",headingDesc);
  }
}

trueHeading和magneticHeading分別表示真實航向和磁性航向。如果位置服務被關閉了,GPS和wifi就只能獲取magneticHeading(磁場航向)。只有打開位置服務,才能獲取trueHeading(真實航向)。

下面的代碼演示了,當存在一個確定了經緯度的地點,當前位置離這個地點的距離及正確航向:

#import "ViewController.h"

#define kDestLongitude 113.12 //精度
#define kDestLatitude 22.23 //緯度
#define kRad2Deg 57.2957795 // 180/π
#define kDeg2Rad 0.0174532925 // π/180

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UILabel *lblMessage;
@property (strong, nonatomic) IBOutlet UIImageView *imgView;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *recentLocation;

-(double)headingToLocation:(CLLocationCoordinate2D)desired current:(CLLocationCoordinate2D)current;
@end

@implementation ViewController

- (void)viewDidLoad
{
  [super viewDidLoad];

  self.locationManager = [[CLLocationManager alloc] init];
  self.locationManager.delegate = self;
  self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
  self.locationManager.distanceFilter = 1609; //1英里≈1609米
  [self.locationManager startUpdatingLocation];
  
  if([CLLocationManager headingAvailable])
  {
    self.locationManager.headingFilter = 10; //10°
    [self.locationManager startUpdatingHeading];
  }
}

/*
 * According to Movable Type Scripts
 * http://mathforum.org/library/drmath/view/55417.html
 *
 * Javascript:
 *
 * var y = Math.sin(dLon) * Math.cos(lat2);
 * var x = Math.cos(lat1)*Math.sin(lat2) -
 * Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
 * var brng = Math.atan2(y, x).toDeg();
 */
-(double)headingToLocation:(CLLocationCoordinate2D)desired current:(CLLocationCoordinate2D)current
{
  double lat1 = current.latitude*kDeg2Rad;
  double lat2 = desired.latitude*kDeg2Rad;
  double lon1 = current.longitude;
  double lon2 = desired.longitude;
  double dlon = (lon2-lon1)*kDeg2Rad;
  
  double y = sin(dlon)*cos(lat2);
  double x = cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(dlon);
  
  double heading=atan2(y,x);
  heading=heading*kRad2Deg;
  heading=heading+360.0;
  heading=fmod(heading,360.0);
  return heading;
}

//處理航向 
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
  if(self.recentLocation!=nil && newHeading.headingAccuracy>=0)
  {
    CLLocation *destLocation = [[CLLocation alloc] initWithLatitude:kDestLatitude longitude:kDestLongitude];
    
    double course = [self headingToLocation:destLocation.coordinate current:self.recentLocation.coordinate];
    
    double delta = newHeading.trueHeading - course;
    
    if (abs(delta) <= 10)
    {
      self.imgView.image = [UIImage imageNamed:@"up_arrow.png"];
    }
    else
    {
      if (delta > 180)
      {
        self.imgView.image = [UIImage imageNamed:@"right_arrow.png"];
      }
      else if (delta > 0)
      {
        self.imgView.image = [UIImage imageNamed:@"left_arrow.png"];
      }
      else if (delta > -180)
      {
        self.imgView.image = [UIImage imageNamed:@"right_arrow.png"];
      }
      else
      {
        self.imgView.image = [UIImage imageNamed:@"left_arrow.png"];
      }
    }
    self.imgView.hidden = NO;
  }
  else
  {
    self.imgView.hidden = YES;
  }
}

//處理定位成功
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
  CLLocation *curLocation = [locations lastObject];
  
  if(curLocation.horizontalAccuracy >= 0)
  {
    self.recentLocation = curLocation;
    
    CLLocation *destLocation = [[CLLocation alloc] initWithLatitude:kDestLatitude longitude:kDestLongitude];
    
    CLLocationDistance distance = [destLocation distanceFromLocation:curLocation];
    
    if(distance<500)
    {
      [self.locationManager stopUpdatingLocation];
      [self.locationManager stopUpdatingHeading];
      self.lblMessage.text = @"您已經到達目的地!";
    }
    else
    {
      self.lblMessage.text = [NSString stringWithFormat:@"距離目的地還有%f米",distance];
    }
  }
}

//處理定位失敗
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
  if(error.code == kCLErrorLocationUnknown)
  {
    NSLog(@"Currently unable to retrieve location.");
  }
  else if(error.code == kCLErrorNetwork)
  {
    NSLog(@"Network used to retrieve location is unavailable.");
  }
  else if(error.code == kCLErrorDenied)
  {
    NSLog(@"Permission to retrieve location is denied.");
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
  }
}


- (void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

@end

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • ios 服務器端推送證書生成的方法

    ios 服務器端推送證書生成的方法

    這篇文章主要介紹了ios 服務器端推送證書生成的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 百度地圖PC端判斷用戶是否在配送范圍內

    百度地圖PC端判斷用戶是否在配送范圍內

    在pc端設置商家的配送范圍,用戶在下單時,根據用戶設置的配送地點判斷是否在可配送范圍內,并給用戶相應的提示,下面通過本文給大家分享具有實現(xiàn)代碼,感興趣的朋友一起學習吧
    2016-01-01
  • Objective-C中類和方法的定義以及協(xié)議的使用

    Objective-C中類和方法的定義以及協(xié)議的使用

    這篇文章主要介紹了Objective-C中類和方法的定義以及協(xié)議的使用,配合Mac下的Xcode IDE進行講解,需要的朋友可以參考下
    2016-01-01
  • 配置mac啟動項的3種方式總結

    配置mac啟動項的3種方式總結

    這篇文章主要給大家介紹了關于配置mac啟動項的3種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-02-02
  • LRecyclerView側滑iOS阻塞效果不完整的解決辦法

    LRecyclerView側滑iOS阻塞效果不完整的解決辦法

    這篇文章主要介紹了LRecyclerView側滑iOS阻塞效果不完整的解決辦法,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2016-12-12
  • iOS Tabbar中間添加凸起可旋轉按鈕功能

    iOS Tabbar中間添加凸起可旋轉按鈕功能

    最近的項目中有需求在tabbar中間添加凸起按鈕,并且點擊時按鈕要旋轉,看了仿斗魚的凸起,點擊后是present出來View,這篇文章主要介紹了iOS Tabbar中間添加凸起可旋轉按鈕,需要的朋友可以參考下
    2017-12-12
  • 淺談iOS應用中的相關正則及驗證

    淺談iOS應用中的相關正則及驗證

    下面小編就為大家?guī)硪黄獪\談iOS應用中的相關正則及驗證。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • IOS代碼筆記之下拉選項cell

    IOS代碼筆記之下拉選項cell

    這篇文章主要為大家詳細介紹了IOS代碼筆記之下拉選項cell的相關資料,需要的朋友可以參考下
    2016-07-07
  • iOS判斷身份證號碼是否正確的方法

    iOS判斷身份證號碼是否正確的方法

    本篇文章主要介紹了iOS判斷身份證號碼是否正確的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • IOS代碼筆記之下拉菜單效果

    IOS代碼筆記之下拉菜單效果

    這篇文章主要為大家詳細介紹了IOS實現(xiàn)下拉菜單效果的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-07-07

最新評論