亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

IOS CoreLocation實現系統自帶定位的方法

2020-07-26 02:55:33
字體:
來源:轉載
供稿:網友

Core Location是iOS SDK中一個提供設備位置的框架??梢允褂萌N技術來獲取位置:GPS、蜂窩或WiFi。在這些技術中,GPS最為精準,如果有GPS硬件,Core Location將優先使用它。如果設備沒有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將在發生錯誤后繼續嘗試確定位置,但如果是用戶禁止定位,它就不會這樣做;在這種情況下,應使用方法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,它指定設備(水平或垂直)移動多少米后才將另一個更新發送給委托。下面的代碼使用適合跟蹤長途跋涉者的設置啟動位置管理器:

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:

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

- (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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色七七影院综合| 久久久精品久久久| 亚洲免费伊人电影在线观看av| 国内精品在线一区| 欧美日韩不卡合集视频| 久久免费精品日本久久中文字幕| 欧美限制级电影在线观看| 久久夜色精品国产欧美乱| 久久久亚洲福利精品午夜| 2019日本中文字幕| 精品国产91乱高清在线观看| 97视频人免费观看| 国产一区玩具在线观看| 九九精品视频在线观看| 在线观看欧美日韩| 欧美激情精品久久久久久| 日韩国产欧美精品在线| 亚洲国产日韩一区| 国产噜噜噜噜久久久久久久久| 欧美精品久久一区二区| 国产精品第七十二页| 欧美与欧洲交xxxx免费观看| 亚洲精品www久久久| 正在播放国产一区| 2019中文在线观看| 欧美限制级电影在线观看| 97人人爽人人喊人人模波多| 日本中文字幕不卡免费| 亚洲成人黄色在线| 亚洲2020天天堂在线观看| 久久99久久亚洲国产| 668精品在线视频| 久久视频在线免费观看| 亚洲最新av网址| 亚洲午夜精品视频| 欧美在线性视频| 久久精品99久久香蕉国产色戒| 欧美在线中文字幕| 国内免费久久久久久久久久久| 亚洲情综合五月天| 91精品国产乱码久久久久久蜜臀| 国产精品999999| 97久久久免费福利网址| 成人在线精品视频| 日韩在线中文视频| 欧美肥老妇视频| 国产精品极品尤物在线观看| 亚洲香蕉成视频在线观看| 国产精品稀缺呦系列在线| 黑人与娇小精品av专区| 国产精品视频永久免费播放| 久久精品视频导航| 欧美日韩色婷婷| 欧美成人第一页| 亚洲精品中文字幕女同| 亚洲另类欧美自拍| 国产精品自拍偷拍视频| 午夜精品国产精品大乳美女| 国产精品成人av在线| 性欧美办公室18xxxxhd| 日韩在线欧美在线| 日韩av在线不卡| 亚洲精品视频在线观看视频| 国产69久久精品成人| 欧美高清在线视频观看不卡| 亚洲第一中文字幕| 91精品国产高清久久久久久久久| 欧美日韩国产中字| 琪琪亚洲精品午夜在线| 国产综合久久久久| 国产成人亚洲综合91精品| 精品magnet| 成人精品一区二区三区电影黑人| 久久国产一区二区三区| 亚洲成人三级在线| 亚洲国产小视频| 国产精品免费久久久久影院| 久久亚洲精品国产亚洲老地址| 国产综合久久久久久| 丁香五六月婷婷久久激情| 亚洲精品一区二三区不卡| 在线日韩精品视频| 国产精品露脸av在线| 欧美激情在线观看视频| 日韩av影院在线观看| 91亚洲精品在线| 日韩免费电影在线观看| 国产专区精品视频| 在线不卡国产精品| 国产精自产拍久久久久久| 另类天堂视频在线观看| 欧美国产亚洲精品久久久8v| 欧美精品成人91久久久久久久| 日本精品久久久久久久| 日韩欧美在线视频日韩欧美在线视频| 伊人久久免费视频| 亚洲精品电影在线观看| 97视频在线播放| 久久视频在线看| 91成人性视频| 国产精品中文久久久久久久| 国产精品久久一区主播| 一本色道久久88精品综合| 国产精品高潮呻吟视频| 欧美精品videosex性欧美| 欧美视频在线观看 亚洲欧| 欧美激情视频网| 国产亚洲欧洲在线| 欧美黄色片免费观看| 精品精品国产国产自在线| 久久99青青精品免费观看| 久久久久国产一区二区三区| 91大神福利视频在线| 久久久亚洲国产天美传媒修理工| 国产一区二区美女视频| 欧美又大又硬又粗bbbbb| 国产精品成人av性教育| 俺去亚洲欧洲欧美日韩| 亚洲免费高清视频| 中文字幕亚洲欧美在线| 亚洲高清一区二| 欧美电影免费观看电视剧大全| 久久精品中文字幕| 久久av在线看| 久久伊人精品天天| 亚洲开心激情网| 日韩在线一区二区三区免费视频| 国产精品香蕉在线观看| 国产精品日韩在线一区| 国产日韩欧美日韩大片| 欧美精品情趣视频| 国产精品亚洲激情| 欧美日韩在线视频一区| 日韩美女免费视频| 亚洲免费电影一区| 精品久久久久久中文字幕大豆网| 97在线观看免费高清| 国产精品毛片a∨一区二区三区|国| 欧美特级www| 国产精品网址在线| 欧美巨大黑人极品精男| 九九精品视频在线观看| 久久久精品久久久久| 久久久免费观看视频| 伊人久久久久久久久久久| 亚洲欧美日韩成人| 日韩欧美成人区| 日本精品在线视频| 亚洲国产精品va在线看黑人| 日韩欧美在线网址| 午夜精品一区二区三区视频免费看| 亚洲欧美日韩另类| 精品久久久久久亚洲精品| 国产日韩在线亚洲字幕中文| 亚洲精品资源在线| 伊是香蕉大人久久| 欧美高清视频在线播放| 成人免费网视频| 亚洲伊人久久大香线蕉av| 成人免费网站在线看| 国产欧美精品xxxx另类| 欧美精品电影免费在线观看| 亚洲影影院av| 热re91久久精品国99热蜜臀|