1.地圖的簡介
在移動互聯網時代,移動app能解決用戶的很多生活瑣事,比如
??? 導航:去任意陌生的地方
??? 周邊:找餐館、找酒店、找銀行、找電影院
??? 手機軟件:微信搖一搖、QQ附近的人、微博、支付寶等
在上述應用中,都用到了地圖和定位功能,在iOS開發中,要想加入這兩大功能,必須基于兩個框架進行開發
??? Map Kit :用于地圖展示
??? Core Location :用于地理定位
地圖定位(CoreLocation框架,地理編碼與反地理編碼)
地圖顯示(MapKit框架)
自定義大頭針
2.地圖的定位
1 CLLocationManager的常用操作
2 // 開始用戶定位
3 - (
void)startUpdatingLocation;
4 // 停止用戶定位
5 - (
void) stopUpdatingLocation;
6
7 // 當調用了startUpdatingLocation方法后,就開始不斷地定位用戶的位置,中途會頻繁地調用下面的代理方法
8 - (
void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *
)locations;
9 // 參數locations中的元素對象是CLLocation對象 1 // 每隔多少米定位一次
2 @property(assign, nonatomic) CLLocationDistance distanceFilter;
3
4 // 定位精確度(越精確就越耗電)
5 @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
6
7 CLLocationAccuracy 是一個枚舉值
8 /*
9 最佳導航
10 kCLLocationAccuracyBestForNavigation
11 最精準
12 kCLLocationAccuracyBest;
13 10米
14 kCLLocationAccuracyNearestTenMeters;
15 百米
16 kCLLocationAccuracyHundredMeters;
17 千米
18 kCLLocationAccuracyKilometer;
19 3千米
20 kCLLocationAccuracyThreeKilometers;
21 */
22
23 實現定位只需要下面幾步:
24 1. 創建管理者對象
25 self.manager =
[[CLLocationManager alloc] init];
26 2. 設置代理
27 self.manager.
delegate =
self;
28 3. 開啟定位
29 [self.manager startUpdatingLocation];
30 注意:從iOS 7之后,蘋果在保護用戶隱私方面做了很大的加強,以下操作都必須經過用戶批準授權:
31 ①要想獲得用戶的位置和訪問用戶的通訊錄、日歷、相機、相冊等等都需要用戶來手動授權。
32 ②當想訪問用戶的隱私信息時,系統會自動彈出一個對話框讓用戶授權
33
34 4 、請求授權 (授權方式根據實際情況進行選擇)
35
36 // 請求授權
37
38 [self.manager requestAlwaysAuthorization];
// 請求前臺和后臺定位
39
40 [self.manager requestWhenInUseAuthorization];
// 請求后臺定位
定位服務授權狀態,返回枚舉類型:
kCLAuthorizationStatusNotDetermined: 用戶尚未做出決定是否啟用定位服務
kCLAuthorizationStatusRestricted: 沒有獲得用戶授權使用定位服務,可能用戶沒有自己禁止訪問授權
kCLAuthorizationStatusDenied :用戶已經明確禁止應用使用定位服務或者當前系統定位服務處于關閉狀態
kCLAuthorizationStatusAuthorizedAlways: 應用獲得授權可以一直使用定位服務,即使應用不在使用狀態
kCLAuthorizationStatusAuthorizedWhenInUse: 使用此應用過程中允許訪問定位服務
用戶隱私的保護
NSLocationWhenInUseUsageDescription(當打開APP應用的時候會觸發這個方法)
NSLocationAlwaysUsageDescription(總是處于打開的狀態)
?
模擬位置:(如果是模擬器,需要設置模擬位置(經緯度))======點擊模擬器---->Debug---->Location----->CustomLocation更改經緯度
北京的經緯度是:北緯40°,東經116°
大連的經緯度是:北緯39°,東經121°
鄭州的經緯度是:北緯34°,東經113°
上海的經緯度是:北緯31°,東經121°
廣州的經緯度是:北緯23°,東經113°
西安的經緯度是:北緯34°,東經108°
?
使用CLGeocoder可以完成"地理編碼"和"反地理編碼"
地理編碼:根據給定的地名,獲得具體的位置信息(比如經緯度、地址的全稱等)
反地理編碼:根據給定的經緯度,獲得具體的位置信息
1 // 地理編碼方法
2 - (
void)geocodeAddressString:(NSString *
)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
3
4 // 反地理編碼方法
5 - (
void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
1 當地理編碼/
反地理編碼完成時,就會調用CLGeocodeCompletionHandler
2 typedef
void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *
error);
3
4 block包含2個參數
5 error:當編碼出錯時(比如編碼不出具體的信息),2其錯誤信息會包含在error中
6 placemarks:里面裝著CLPlacemark對象
7
8 CLPlacemark的字面意思是地標,封裝詳細的地址位置信息
9
10 // 地理位置
11 @property (nonatomic,
readonly) CLLocation *
location;
12
13 // 區域
14 @property (nonatomic,
readonly) CLRegion *
region;
15
16 // 詳細的地址信息
17 @property (nonatomic,
readonly) NSDictionary *
addressDictionary;
18
19 // 地址名稱
20 @property (nonatomic,
readonly) NSString *
name;
21
22 // 地點名稱
23 @property (nonatomic,
readonly) NSString *locality;
總結:
CLLocationManager 定位的基礎信息
CLLocation? 某個位置的地理信息
CLLocationCoordinate2D? 存放經緯度的結構體
CLGeocoder 地理位置編碼與反編碼的類
CLPlacemark 地標.
1 #import "ViewController.h"
2 // 第一步: 引入庫的頭文件
3 #import <CoreLocation/CoreLocation.h>
4
5 @interface ViewController ()<CLLocationManagerDelegate>
6
7 // 定位管理器
8 // CoreLocation框架中的CLLocationManager用于管理定位的管理器
9 // CoreLocation框架中的CLGeocoder能進行編碼和反編碼
10 @property (nonatomic, strong) CLLocationManager *
manager;
11
12 // 編碼反編碼的類
13 @property (nonatomic, strong) CLGeocoder *
geocoder;
14
15
16 @end
17
18 @implementation ViewController
19
20 - (
void)viewDidLoad {
21 [super viewDidLoad];
22 // Do any additional setup after loading the view, typically from a nib.
23 // 定位步驟
24 // 第一步: 初始化定位管理器
25 self.manager =
[[CLLocationManager alloc] init];
26 // 第二步: 進行隱私的判斷并授權
27 // 如何跳轉隱私界面
28 // 進行隱私的判斷
29 if (!
[CLLocationManager locationServicesEnabled]) {
30 NSLog(
@"是否前往隱私進行設置允許定位");
31 }
32
33 // 根據狀態進行授權
34 // 進行版本的判斷
35 if ([[[UIDevice currentDevice] systemVersion] integerValue] >=
8.0) {
36
37 if ([CLLocationManager authorizationStatus] !=
kCLAuthorizationStatusAuthorizedWhenInUse) {
38
39 /*
40 定位服務授權狀態,返回枚舉類型:
41 kCLAuthorizationStatusNotDetermined: 用戶尚未做出決定是否啟用定位服務
42 kCLAuthorizationStatusRestricted: 沒有獲得用戶授權使用定位服務,可能用戶沒有自己禁止訪問授權
43 kCLAuthorizationStatusDenied :用戶已經明確禁止應用使用定位服務或者當前系統定位服務處于關閉狀態
44 kCLAuthorizationStatusAuthorizedAlways: 應用獲得授權可以一直使用定位服務,即使應用不在使用狀態
45 kCLAuthorizationStatusAuthorizedWhenInUse: 使用此應用過程中允許訪問定位服務
46
47 */
48
49
50 // 在授權請求之前需要在info.plist中設置允許定位的內容:NSLocationWhenInUseUsageDescription ? NSLocationAlwaysUsageDescription
51 // 請求授權
52 [self.manager requestWhenInUseAuthorization];
53 }
54 }
55 // 第三步: 設置管理器的代理和相關屬性
56 self.manager.
delegate =
self;
57 // 設置經度
58 self.manager.desiredAccuracy =
100;
59 // 設置最小更新距離
60 self.manager.distanceFilter =
100;
61 // 第四步: 開啟定位
62 [self.manager startUpdatingLocation];
63
64 //====================編碼和反編碼===========================\\
65
66 // 初始化編碼和反編碼對象
67 self.geocoder =
[[CLGeocoder alloc] init];
68
69 // 根據地名獲取經緯度
70 [self getCoordinateByAddress:
@"平安村"];
71
72 // 根據經緯度反編碼取出地名
73 [self getAddressByLongitude:
113 Latitude:
34];
74
75 // 計算兩點之間的距離
76 [self distence];
77
78 }
79
80 #pragma mark - 計算兩個地方的距離
81
82 - (
void)distence
83 {
84 // 創建位置1北京
85 CLLocation *locationBJ = [[CLLocation alloc] initWithLatitude:
40 longitude:
116];
86 // 位置2大連
87 CLLocation *locationDL = [[CLLocation alloc] initWithLatitude:
39 longitude:
121];
88 CLLocationDistance distance =
[locationBJ distanceFromLocation:locationDL];
89 NSLog(
@"北京到大連的距離:%f", distance);
90
91 }
92
93 #pragma mark - 根據經緯度獲取地名
94 - (
void)getAddressByLongitude:(CLLocationDegrees)longitude Latitude:(CLLocationDegrees)latitude
95 {
96 // 反編碼
97 // 創建CLLocation
98 CLLocation *location =
[[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
99 //反編碼
100 [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError *
_Nullable error) {
101
102 NSDictionary *dic =
placemarks.firstObject.addressDictionary;
103
104 NSLog(
@"反編碼地理位置信息:%@", dic);
105 }];
106 }
107
108
109 #pragma mark - 根據地名獲取相關的信息
110 - (
void)getCoordinateByAddress:(NSString *
)address
111 {
112 // 編碼方法
113 [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError *
_Nullable error) {
114
115 // 根據返回的地標,取出第一個位置(地標的位置很多)
116 CLPlacemark *mark =
placemarks.firstObject;
117 // 根據地標得到location
118 CLLocation *location =
mark.location;
119 // 根據location獲取區域
120 CLRegion *region =
mark.region;
121 // 獲取字典信息
122 NSDictionary *addressDictionary =
mark.addressDictionary;
123
124 NSLog(
@"地標位置:%@,區域:%@,地理位置信息:%@",location,region,addressDictionary);
125
126
127 // NSString *name=placemark.name;//地名
128 // NSString *thoroughfare=placemark.thoroughfare;//街道
129 // NSString *subThoroughfare=placemark.subThoroughfare; //街道相關信息,例如門牌等
130 // NSString *locality=placemark.locality; // 城市
131 // NSString *subLocality=placemark.subLocality; // 城市相關信息,例如標志性建筑
132 // NSString *administrativeArea=placemark.administrativeArea; // 州
133 // NSString *subAdministrativeArea=placemark.subAdministrativeArea; //其他行政區域信息
134 // NSString *postalCode=placemark.postalCode; //郵編
135 // NSString *ISOcountryCode=placemark.ISOcountryCode; //國家編碼
136 // NSString *country=placemark.country; //國家
137 // NSString *inlandWater=placemark.inlandWater; //水源、湖泊
138 // NSString *ocean=placemark.ocean; // 海洋
139 // NSArray *areasOfInterest=placemark.areasOfInterest; //關聯的或利益相關的地標
140
141 }];
142 }
143
144 #pragma mark - CLLocationManagerDelegate的代理方法
145 // 這個代理方法是定位成功之后開始更新位置信息,只要移動設置的最小距離之后也開始走這個方法
146 - (
void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *
)locations
147 {
148 // 獲取最后一次的位置
149 CLLocation *location =
locations.lastObject;
150 // 獲取位置坐標
151 CLLocationCoordinate2D coordinate =
location.coordinate;
152 // latitude(緯度) longitude(經度) altitude(海拔) course(航線) speed(速度)
153 NSLog(
@"%f,%f, %f, %f,%f",coordinate.latitude,coordinate.longitude,location.altitude,location.course,location.speed);
154 /*
155 注意:
156
157 1.定位頻率和定位精度并不應當越精確越好,需要視實際情況而定,因為越精確越耗性能,也就越費電。
158
159 2.定位成功后會根據設置情況頻繁調用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法,這個方法返回一組地理位置對象數組,每個元素一個CLLocation代表地理位置信息(包含經度、緯度、海報、行走速度等信息),之所以返回數組是因為有些時候一個位置點可能包含多個位置。
160
161 3.使用完定位服務后如果不需要實時監控應該立即關閉定位服務以節省資源。
162
163 4.除了提供定位功能,CLLocationManager還可以調用startMonitoringForRegion:方法對指定區域進行監控。
164 */
165
166 // 為了節省電源,如果不適用定位,需要把定位關掉
167 [self.manager stopUpdatingLocation];
168
169 }
170
171 // 定位失敗
172 - (
void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *
)error
173 {
174 NSLog(
@"定位失敗");
175 }
?
轉載于:https://www.cnblogs.com/leikun1113/p/5547885.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的iOS地图定位(Map)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。