iOS學習筆記19-地圖(一)定位CoreLocation

來源:互聯網
上載者:User

iOS學習筆記19-地圖(一)定位CoreLocation
一、定位介紹

現在很多社交、電商、團購應用都引入了地圖和定位功能,似乎地圖功能不再是地圖應用和導航應用所特有的。的確,有了地圖和定位功能確實讓我們的生活更加豐富多彩,極大的改變了我們的生活。要實現地圖、導航功能,往往需要先熟悉定位功能

在iOS中通過 CoreLocation架構進行定位操作。

CoreLocation自身可以單獨使用,和地圖開發架構MapKit完全是獨立的,但是往往地圖開發要配合定位架構使用。

CoreLocation可以實現的功能:定位功能地理編碼與逆地理編碼

二、定位核心類

定位是一個很常用的功能,如一些地圖軟體開啟之後如果使用者允許軟體定位的話,那麼開啟軟體後就會自動鎖定到當前位置,如果使用者手機移動那麼當前位置也會跟隨著變化。要實現這個功能需要使用CoreLoactionCLLocationManager類,下面是這個類的使用說明:

1. 類方法:
+ (BOOL)locationServicesEnabled;/* 返回使用者是否啟用定位服務 */+ (CLAuthorizationStatus)authorizationStatus;/* 定位服務授權狀態,返回枚舉類型 */typedefNS_ENUM(int,CLAuthorizationStatus){    kCLAuthorizationStatusNotDetermined = 0, /* 使用者尚未決定是否啟用定位服務 */    kCLAuthorizationStatusRestricted, /* 沒有獲得使用者授權 */    kCLAuthorizationStatusDenied, /* 使用者禁止使用定位或者定位服務處於關閉狀態 */    kCLAuthorizationStatusAuthorizedAlways, /*前台、後台定位授權 */    kCLAuthorizationStatusAuthorizedWhenInUse, /* 前台定位授權 */};
2. 對象屬性:定位精度 desiredAccuracy
枚舉類型:
位置資訊更新最小距離 distanceFilter
浮點數,預設為 kCLDistanceFilterNone,表示不進行距離限制3. 對象方法:
#pragma mark - 定位追蹤-(void)startUpdatingLocation;/* 開始定位追蹤 */-(void)stopUpdatingLocation;/* 停止定位追蹤 */#pragma mark - 導航追蹤-(void)startUpdatingHeading;/* 開始導航方向追蹤 */-(void)stopUpdatingHeading;/* 停止導航方向追蹤 */#pragma mark - 地區定位追蹤-(void)startMonitoringForRegion:(CLRegion *)region;/* 開始對某個地區進行定位追蹤 */-(void)stopMonitoringForRegion:(CLRegion *)region;/* 停止對某個地區進行定位追蹤 */#pragma mark - 授權請求-(void)requestWhenInUseAuthorization;/* 請求獲得應用前台定位授權 */-(void)requestAlwaysAuthorization;/* 請求獲得應用前後台定位授權 */
4. 常用代理方法 CLLocationManagerDelegate
/* 位置發生改變後調用,第一次定位也會調用 */-(void)locationManager:(CLLocationManager *)manager     didUpdateLocations:(NSArray *)locations;/* 導航方向發生變化後調用 */-(void)locationManager:(CLLocationManager *)manager       didUpdateHeading:(CLHeading *)newHeading;/* 進入某個地區後調用 */-(void)locationManager:(CLLocationManager *)manager         didEnterRegion:(CLRegion *)region;/* 走出某個地區後調用 */-(void)locationManager:(CLLocationManager *)manager          didExitRegion:(CLRegion *)region;/* 當使用者授權狀態發生變化時調用 */-(void)locationManager:(CLLocationManager *)manager        didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
三、定位簡單使用先要在項目匯入CoreLocation架構,然後再匯入標頭檔:
#import 
iOS版本不同,使用也有一些區別,主要區分為:iOS8.0之前的定位使用iOS8.0之後的定位使用1. iOS8.0之前的定位使用:1.1 前台定位:
- (void)viewDidLoad{    [super viewDidLoad];    if (![CLLocationManager locationServicesEnabled]) {        NSLog(@"定位服務當前可能尚未開啟,請設定開啟!");        return;    }    [self initLocationManager];    //調用方法,開始更新使用者位置資訊    [self.locationM startUpdatingLocation];}//建立CLLocationManager並啟動定位- (void)initLocationManager{    //建立CLLocationManager對象並設定代理    self.locationM = [[CLLocationManager alloc] init];    self.locationM.delegate = self;    //設定定位精度和位置更新最小距離    self.locationM.distanceFilter = 100;    self.locationM.desiredAccuracy = kCLLocationAccuracyBest;}//在對應的代理方法中擷取位置資訊- (void)locationManager:(CLLocationManager *)manager      didUpdateLocations:(NSArray *)locations{    CLLocation *location = [locations firstObject];//取出第一個位置    /*         使用位置前, 務必判斷當前擷取的位置是否有效        如果水平精確度小於零, 代表雖然可以擷取位置對象, 但是資料錯誤, 不可用     */    if (location.horizontalAccuracy < 0)        return;    CLLocationCoordinate2D coordinate = location.coordinate;//位置座標     CGFloat longitude = coordinate.longitude;//經度    CGFloat latitude = coordinate.latitude;//緯度    CGFloat altitude = location.altitude;//海拔    CGFloat course = location.course;//方向    CGFloat speed = location.speed;//速度    NSLog(@"經度:%f,緯度:%f",longitude,latitude);       NSLog(@"海拔:%f,方向:%f,速度:%f",altitude,course,speed);    //如果不需要即時定位,使用完即使關閉定位服務    [self.locationM stopUpdatingLocation];   }
定位頻率和定位精度並不是越精確越好,需要視實際情況而定,因為越精確越耗效能,也就越費電。定位成功後會根據設定情況頻繁調用 locationManager:didUpdateLocations:方法每個元素一個 CLLocation代表地理位置資訊,之所以返回數組是因為有些時候一個位置點可能包含多個位置。使用完定位服務後,如果不需要即時監控應該立即關閉定位服務,以節省資源。除了提供定位功能,還可以調用 startMonitoringForRegion:方法對指定地區進行監控。1.2 後台定位:

在前台的基礎上,勾選後台模式Location updates

2. iOS8之後的定位使用iOS8開始,需要請求定位授權:前台授權:
在Info.plist檔案中配置 NSLocationWhenInUseUsageDescriptionYES
前後台授權:
在Info.plist檔案中配置 NSLocationAlwaysUsageDescriptionYES
- (void)viewDidLoad{    [super viewDidLoad];    if (![CLLocationManager locationServicesEnabled]) {        NSLog(@"定位服務當前可能尚未開啟,請設定開啟!");        return;    }    [self initLocationManager];    //如果沒有授權,則請求使用者授權    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];    if (status == kCLAuthorizationStatusNotDetermined){        //請求前台定位授權        //[self.locationM requestWhenInUseAuthorization];        //請求前後台定位授權        [self.locationM requestAlwaysAuthorization];    }}//建立CLLocationManager並啟動定位- (void)initLocationManager{    //建立CLLocationManager對象並設定代理    self.locationM = [[CLLocationManager alloc] init];    self.locationM.delegate = self;    //設定定位精度和位置更新最小距離    self.locationM.distanceFilter = 100;    self.locationM.desiredAccuracy = kCLLocationAccuracyBest;}// 當使用者授權狀態發生變化時調用- (void)locationManager:(CLLocationManager *)manager         didChangeAuthorizationStatus:(CLAuthorizationStatus)status{    switch (status) {        case kCLAuthorizationStatusNotDetermined://使用者還未決定        {            NSLog(@"使用者還未決定");            break;        }        case kCLAuthorizationStatusRestricted://訪問受限        {            NSLog(@"訪問受限");            break;        }        case kCLAuthorizationStatusDenied://定位關閉時或使用者APP授權為永不授權時調用        {            NSLog(@"定位關閉或者使用者未授權");            break;        }        case kCLAuthorizationStatusAuthorizedAlways://擷取前後台定位授權        {            NSLog(@"擷取前後台定位授權");            [self.locationM startUpdatingLocation];            break;        }        case kCLAuthorizationStatusAuthorizedWhenInUse://獲得前台定位授權        {            NSLog(@"獲得前台定位授權");            [self.locationM startUpdatingLocation];            break;        }        default:break;    }}//在對應的代理方法中擷取位置資訊- (void)locationManager:(CLLocationManager *)manager      didUpdateLocations:(NSArray *)locations{    CLLocation *location = [locations firstObject];//取出第一個位置    /*         使用位置前, 務必判斷當前擷取的位置是否有效        如果水平精確度小於零, 代表雖然可以擷取位置對象, 但是資料錯誤, 不可用     */    if (location.horizontalAccuracy < 0)        return;    CLLocationCoordinate2D coordinate = location.coordinate;//位置座標    CGFloat longitude = coordinate.longitude;//經度    CGFloat latitude = coordinate.latitude;//緯度    CGFloat altitude = location.altitude;//海拔    CGFloat course = location.course;//方向    CGFloat speed = location.speed;//速度    NSLog(@"經度:%f,緯度:%f",longitude,latitude);    NSLog(@"海拔:%f,方向:%f,速度:%f",altitude,course,speed);    //如果不需要即時定位,使用完即使關閉定位服務    [self.locationM stopUpdatingLocation];}

四、地理編碼

定位服務中還包含CLGeocoder類,用於處理地理編碼和逆地理編碼功能。
* 地理編碼:根據給定的位置(通常是地名)確定地理座標(經、緯度)。
【位置 -> 地理座標】
* 逆地理編碼:可以根據地理座標(經、緯度)確定位置資訊(街道、門牌等)。
【地理座標 -> 位置】

- (void)viewDidLoad {    [super viewDidLoad];    self.geocoder = [[CLGeocoder alloc] init];    [self getCoordinateByAddress:@"北京"];    [self getAddressByLatitude:39.54 longitude:116.28];}#pragma mark 根據地名確定地理座標-(void)getCoordinateByAddress:(NSString *)address{    //地理編碼    [self.geocoder geocodeAddressString:address                       completionHandler:^(NSArray *placemarks, NSError *error) {        //取得第一個地標,地標中儲存了詳細的地址資訊,注意:一個地名可能搜尋出多個地址        CLPlacemark *placemark = [placemarks firstObject];        CLLocation *location = placemark.location;//位置        CLRegion *region = placemark.region;//地區        NSDictionary *addressDic = placemark.addressDictionary;//詳細地址資訊字典        NSLog(@"位置:%@,地區:%@,詳細資料:%@",location,region,addressDic);    }];}#pragma mark 根據座標取得地名-(void)getAddressByLatitude:(CLLocationDegrees)latitude                   longitude:(CLLocationDegrees)longitude{    //反地理編碼    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude                                                       longitude:longitude];    [self.geocoder reverseGeocodeLocation:location                         completionHandler:^(NSArray *placemarks, NSError *error) {        CLPlacemark *placemark = [placemarks firstObject];        NSLog(@"詳細資料:%@",placemark.addressDictionary);    }];}
地標類 CLPlacemark還包含以下資訊:
NSString *name = placemark.name;//地名NSString *thoroughfare = placemark.thoroughfare;//街道NSString *subThoroughfare = placemark.subThoroughfare; //街道相關資訊,例如門牌等NSString *locality = placemark.locality; // 城市NSString *subLocality = placemark.subLocality; // 城市相關資訊,例如標誌性建築NSString *administrativeArea = placemark.administrativeArea; // 州NSString *subAdministrativeArea = placemark.subAdministrativeArea; //其他行政地區資訊NSString *postalCode = placemark.postalCode; //郵編NSString *ISOcountryCode = placemark.ISOcountryCode; //國家編碼NSString *country = placemark.country; //國家NSString *inlandWater = placemark.inlandWater; //水源、湖泊NSString *ocean = placemark.ocean; // 海洋NSArray *areasOfInterest = placemark.areasOfInterest; //關聯的或利益相關的地標
下一節我會寫地圖類MapKit的相關筆記,敬請期待吧!有什麼問題可以在下方評論區提出,O(∩_∩)O哈!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.