地圖相關(guān) CoreLocation框架

介紹

1.導(dǎo)入主頭文件 #import <CoreLocation/CoreLocation.h>

2.地圖和定位功能基于2個框架進行開發(fā):
(1)Map Kit :用于地圖展示
(2)CoreLocation:用于地理定位,有時只用定位,比如外賣,只有需要顯示地圖才用map kit

3.2個熱門專業(yè)術(shù)語:
(1)LBS :Location Based Service 位置服務(wù),又稱定位服務(wù)
LBS的服務(wù)歸納為四類:定位(個人位置定位)、導(dǎo)航(路徑導(dǎo)航)、查詢(查詢某個人或某個對象)、識別(識別某個人或?qū)ο?、事件檢查(當出現(xiàn)特殊情況下向相關(guān)機構(gòu)發(fā)送帶求救或查詢的個人位置信息)。
(2)SoLoMo :Social Local Mobile(索羅門) 移動社交

4.天朝的經(jīng)緯度范圍:緯度范圍:N 3°51′ ~ N 53°33′ 經(jīng)度范圍:E 73°33′ ~ E 135°05′


1、如果定位方法不走原因:
(1)沒有配置 plist 鍵值
(2)模擬器 bug
(3)沒有使用 strong 的屬性

2、邏輯結(jié)構(gòu)

邏輯結(jié)構(gòu)

請求用戶授權(quán)方法

注意:
  1. 一步代碼,一步plist配置
  2. 請求授權(quán)iOS8以后才有,一定注意版本適配!
  3. 如果同時實現(xiàn)兩個請求, 第一次運行會彈出第一個, 第二次運行會彈出第二個,大部分應(yīng)用程序只需要使用用戶使用期間授權(quán)即可
  4. 如果程序列表中出現(xiàn)了3行(即永不定位,使用應(yīng)用期間,始終定位),說明實現(xiàn)了2種授權(quán)


    設(shè)置界面
  5. plist添加的用戶提示信息可以不寫值,表示空白提示,一般寫上需要定位的原因,提高用戶打開的幾率
1. 代碼:
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        // 永久授權(quán)
        [self.locationManager requestAlwaysAuthorization];
        //用戶使用時授權(quán),大部分的應(yīng)用應(yīng)該使用此種授權(quán)方式,當能看見程序時才能定位
        [self.locationManager requestWhenInUseAuthorization];
    }
}
2. plist文件配置

① 使用期間授權(quán):添加該鍵,值是用戶提示信息
NSLocationWhenInUseUsageDescription


plist配置

② 永久始終授權(quán):添加該鍵,值是用戶提示信息
NSLocationAlwaysUsageDescription


plist配置

③ iOS9.0新特性:臨時獲取后臺定位權(quán)限(永久授權(quán))
注意:該方式進入后臺后會有提示
iOS 9 新特性

代碼:iOS9 臨時開啟后臺定位, allowsBackgroundLocationUpdates屬性設(shè)置為YES

if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
    self.locationManager.allowsBackgroundLocationUpdates = YES;
}

plist:需要配置Plist,不然會崩潰,是一個數(shù)組,值添加到一個數(shù)組的對象當中
鍵 :Required background modes 數(shù)組值:App registers for location updates

iOS 9 plist配置


CLLocationManager 屬性和方法

注意:

  1. 想要使用定位, 必須使用CLLocationManager(位置管理器)創(chuàng)建一個對象
  2. iOS8以后, 要定位, 必須使用位置管理器授權(quán),并配置plist
  3. 使用期間授權(quán):APP退到后臺就不進行定位了
    始終授權(quán):后臺也會進行定位,例如記錄跑步,持續(xù)定位需要對電量做些優(yōu)化(設(shè)置兩個屬性)


    設(shè)置界面
  4. 一般請求定位放在appDelegate中,在加載頁面之前就定位好
下面兩個屬性設(shè)置后可以降低代理方法調(diào)用頻率(默認大約一秒調(diào)用一次),以此省電,始終持續(xù)定位時候建議使用

屬性:

  1. 距離篩選器,每隔多少米定位一次,單位:米,當用戶發(fā)生一定位置的改變時, 再去調(diào)用代理方法, 以此實現(xiàn)省電
@property(assign, nonatomic) CLLocationDistance distanceFilter;

例子:每隔十米定位一次

self.locationManager.distanceFilter = 10;
  1. 定位精確度(越精確就越耗電)
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

降低精準度,實際上降低了與衛(wèi)星之間的計算,以此節(jié)省電量

Iphone的定位方式:(1)GPS(2)wifi定位(3)移動基站定位(流量)

例子:設(shè)置定位精度誤差一千米
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
枚舉值:iOS9以前默認kCLLocationAccuracyBest
kCLLocationAccuracyBestForNavigation 最精確的定位
kCLLocationAccuracyBest; 最好的
kCLLocationAccuracyNearestTenMeters; 十米誤差
kCLLocationAccuracyHundredMeters; 一百米
kCLLocationAccuracyKilometer; 一千米
kCLLocationAccuracyThreeKilometers; 三千米

方法:

1.開始用戶定位

- (void) startUpdatingLocation;

2.停止用戶定位

- (void) stopUpdatingLocation;

代理方法

當調(diào)用了startUpdatingLocation方法后,就開始不斷地調(diào)用該代理方法定位用戶的位置,locations參數(shù)里面裝著一組CLLocation對象,持續(xù)定位需要設(shè)置 distanceFilter 和 desiredAccuracy 屬性

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

CLLocation 位置對象介紹

CLLocation用來表示某個位置的地理信息,比如經(jīng)緯度、海拔等等,創(chuàng)建一個 CLLocation對象只需要兩個參數(shù):緯度和經(jīng)度

屬性:

(1)2D位置坐標,經(jīng)緯度

@property(readonly, nonatomic) CLLocationCoordinate2D coordinate;

CLLocationDegrees latitude 緯度
CLLocationDegrees longitude 經(jīng)度

(2)海拔

@property(readonly, nonatomic) CLLocationDistance altitude;

(3)速度(單位是m/s)

@property(readonly, nonatomic) CLLocationSpeed speed;

(4)水平 垂直精準度

@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;

(5)航向(取值范圍是0.0° ~ 359.9°,0.0°代表真北方向)

@property(readonly, nonatomic) CLLocationDirection course;

(6)時間戳,什么時間進行的定位

@property(readonly, nonatomic, copy) NSDate *timestamp;

方法:
(1)創(chuàng)建一個 CLLocation對象只需要兩個參數(shù):緯度和經(jīng)度

- (instancetype)initWithLatitude:(CLLocationDegrees)latitude
longitude:(CLLocationDegrees)longitude;

(2)計算2個位置之間的距離,比較的是直線距離,單位是米,除以1000可以換算成千米

- (CLLocationDistance)distanceFromLocation:(constCLLocation *)location;

例子:計算北京和西安的位置直線距離

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:40.06 longitude:116.39];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:34.27 longitude:108.93];
CGFloat distance = [location2 distanceFromLocation:location1];
NSLog(@"distance: %f",distance / 1000);

例子:定位功能實現(xiàn)

1、 創(chuàng)建位置管理器
self.locationManager = [CLLocationManager new];

2、 請求用戶授權(quán)(iOS8以后才有) 同時配置 plist 列表,注意:必須使用版本判斷,建議結(jié)合使用
-----------------------------
有兩種授權(quán)方式,還有一種始終 requestAlwaysAuthorization
if([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [self.locationManager requestWhenInUseAuthorization];
}

3、 設(shè)置 <CLLocationManagerDelegate>代理, 來獲取用戶位置數(shù)據(jù)
self.locationManager.delegate = self;

4、調(diào)用開始定位方法
[self.locationManager startUpdatingLocation];

5、實現(xiàn)代理方法拿到數(shù)據(jù),當用戶更新位置的時候調(diào)用此方法,頻繁調(diào)用, 非常耗電
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    //CLLocation 位置對象 --> 經(jīng)緯度
    //CLLocationCoordinate2D coordinate 經(jīng)緯度

    //獲取最后一次位置信息
    CLLocation *location = locations.lastObject;
    //輸出緯度和經(jīng)度
    NSLog(@"latitude: %f,longitude: %f",location.coordinate.latitude, location.coordinate.longitude);
    // 停止定位
    [self.locationManager stopUpdatingLocation];
}

三、地理編碼的實現(xiàn)

  1. 正地理編碼:將地名轉(zhuǎn)換成經(jīng)緯度的過程
    步驟:
    (1)創(chuàng)建一個GLGeocoder對象

(2)實現(xiàn)地理編碼方法
(3)遍歷數(shù)組,獲取數(shù)據(jù)(可能返回多個相同地名),如果對象大于1,應(yīng)該給用戶一個列表選擇

  1. 反地理編碼:將經(jīng)緯度轉(zhuǎn)換成地名的過程
    步驟:
    (1)創(chuàng)建一個GLGeocoder對象
    (2)創(chuàng)建一個CLLoction對象(經(jīng)緯度)
    (3)實現(xiàn)反地理編碼方法
    (4)遍歷數(shù)組,獲取數(shù)組

CLGeocoder地理編碼對象

一個屬性:
@property (nonatomic, readonly, getter=isGeocoding) BOOL geocoding;
方法:

1、三個正地理編碼方法

(1)
- (void)geocodeAddressDictionary:(NSDictionary *)addressDictionary completionHandler:(CLGeocodeCompletionHandler)completionHandler;

(2)最簡單的,填入要搜索的位置,回調(diào)出搜索信息
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

(3)
- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region completionHandler:(CLGeocodeCompletionHandler)completionHandler;

2、一個反地理編碼方法

- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

3、取消編碼

- (void)cancelGeocode;

回調(diào)的block參數(shù)CLGeocodeCompletionHandler
typedef void (^CLGeocodeCompletionHandler)(NSArray< CLPlacemark *> * __nullable placemarks, NSError * __nullable error);

block參數(shù):
  1. placemarks:CLPlacemark 地標對象,里面封裝各種詳細地址信息,如街道名,城市名,國家名等
  2. error :當編碼出錯時有值(比如編碼不出具體的信息)
CLPlacemark 地標對象:

- (instancetype)initWithPlacemark:(CLPlacemark *) placemark;
1、主要獲取的屬性,位置對象,能獲取到經(jīng)緯度信息
@property (nonatomic, readonly, copy, nullable) CLLocation *location;

@property (nonatomic, readonly, copy, nullable) CLRegion *region;

@property (nonatomic, readonly, copy, nullable) NSTimeZone *timeZone ( 9_0))
@property (nonatomic, readonly, copy, nullable) NSDictionary *addressDictionary;
詳細地址名(包括等到門牌等)
@property (nonatomic, readonly, copy, nullable) NSString *name;
街道名
@property (nonatomic, readonly, copy, nullable) NSString *thoroughfare;
子街道名
@property (nonatomic, readonly, copy, nullable) NSString *subThoroughfare;
城市
@property (nonatomic, readonly, copy, nullable) NSString *locality;
子城市
@property (nonatomic, readonly, copy, nullable) NSString *subLocality;
行政區(qū)域
@property (nonatomic, readonly, copy, nullable) NSString *administrativeArea;
子行政區(qū)域
@property (nonatomic, readonly, copy, nullable) NSString *subAdministrativeArea;
@property (nonatomic, readonly, copy, nullable) NSString *postalCode;
@property (nonatomic, readonly, copy, nullable) NSString *ISOcountryCode;
國家
@property (nonatomic, readonly, copy, nullable) NSString *country;
@property (nonatomic, readonly, copy, nullable) NSString *inlandWater;
@property (nonatomic, readonly, copy, nullable) NSString *ocean;
@property (nonatomic, readonly, copy, nullable) NSArray<NSString *> *areasOfInterest;

正地理編碼例子

//1. 創(chuàng)建 Geocoder
CLGeocoder *geocoder = [CLGeocoder new];
//2. 調(diào)用方法
[geocoder geocodeAddressString:self.addressTF.text completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //3.1 防錯處理
    if (placemarks.count == 0 || error) {
        NSLog(@"沒有數(shù)據(jù)或數(shù)據(jù)解析出錯");
        return;
    }
    //3.2 遍歷地標數(shù)組placemarks,地理編碼容易出現(xiàn)多個地標,應(yīng)該給用戶一個列表去選擇
    for (CLPlacemark *pm in placemarks) {
        //3.3 設(shè)置緯度
        self.latitudeLabel.text = [NSString stringWithFormat:@"%f",pm.location.coordinate.latitude];
        //3.4 設(shè)置經(jīng)度
        self.longitudeLabel.text = [NSString stringWithFormat:@"%f",pm.location.coordinate.longitude];
        //3.5 設(shè)置地址
        self.detailAddressLabel.text = pm.name;
    }
}];

反地理編碼例子

//1. 創(chuàng)建 Geocoder 對象
CLGeocoder *geocoder = [CLGeocoder new];
//2. 創(chuàng)建 CLLocation對象,輸入經(jīng)緯度信息
CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text floatValue] longitude:[self.longitudeTF.text floatValue]];
//3. 調(diào)用反地理編碼方法
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //3.1 防錯處理
    if (placemarks.count == 0 || error) {
        NSLog(@"沒有數(shù)據(jù)或數(shù)據(jù)解析出錯");
        return;
    }
    //3.2 遍歷數(shù)據(jù)
    for (CLPlacemark *pm in placemarks) {
        //3.3. 獲取城市信息, 如果有城市信息就顯示, 否則可以顯示行政區(qū)域
        if (pm.locality) {
            //locality : 城市
            self.cityLabel.text = pm.locality;
        } else {
            //administrativeArea : 行政區(qū)域
            self.cityLabel.text = pm.administrativeArea;
        }
    }
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容