iOS開發——高級篇——地圖 MapKit

1、簡介


一、
在移動互聯網時代,移動app能解決用戶的不少生活雜事,好比
周邊:找餐館、找KTV、找電影院等等
導航:根據用戶設定的起點和終點,進行路線規劃,並指引用戶如何到達git

在上述應用中,都用到了定位和地圖功能,在iOS開發中,要想加入這2大功能,必須基於2個框架進行開發
CoreLocation :用於地理定位,地理編碼,區域監聽等(着重功能實現)
MapKit :用於地圖展現,例如大頭針,路線、覆蓋層展現等(着重界面展現)數組


二、MapKit框架的使用
MapKit框架使用前提
導入框架(Xcode5以後能夠省略,前提:在代碼裏面使用了框架中某個類建立了一個對象)app

導入主頭文件
#import <MapKit/MapKit.h>框架

MapKit框架使用須知
MapKit框架中全部數據類型的前綴都是MK
MapKit有一個比較重要的UI控件 :MKMapView,專門用於地圖顯示ui


2、地圖的基本使用


一、地圖的類型
能夠經過設置MKMapView的 mapType 設置地圖類型
MKMapTypeStandard :普通地圖(左圖)
MKMapTypeSatellite :衛星雲圖 (中圖)
MKMapTypeHybrid :混合模式(普通地圖覆蓋於衛星雲圖之上 )
MKMapTypeSatelliteFlyover: 3D立體衛星 (iOS9.0)
MKMapTypeHybridFlyover: 3D立體混合 (iOS9.0)編碼

 

二、設置地圖的其餘屬性
操做項:
是否可縮放 zoomEnabled
是否可滾動 scrollEnabled
是否可旋轉 rotateEnabled
顯示項:
是否顯示指南針 showsCompass (iOS9.0)
是否顯示比例尺 showsScale (iOS9.0)
是否顯示交通 showsTraffic (iOS9.0)
是否顯示建築 showsBuildingsatom

使用注意
設置對應的屬性時,注意該屬性是從哪一個系統版本開始引入的,作好不一樣系統版本的適配spa


3、跟蹤顯示用戶的位置


一、顯示用戶的位置
設置MKMapView的showsUserLocation屬性能夠顯示用戶的當前位置代理

下圖是顯示效果
藍色發光圓點就是用戶的當前位置
藍色發光圓點,專業術語叫作「大頭針」

注意:iOS8.0以後,顯示用戶位置須要用戶進行定位受權code


二、追蹤用戶的位置
設置MKMapView的userTrackingMode屬性能夠跟蹤顯示用戶的當前位置
MKUserTrackingModeNone :不跟蹤用戶的位置
MKUserTrackingModeFollow :跟蹤並在地圖上顯示用戶的當前位置
MKUserTrackingModeFollowWithHeading :跟蹤並在地圖上顯示用戶的當前位置,地圖會跟隨用戶的前進方向進行旋轉

注意:iOS8.0以後,追蹤用戶位置須要用戶進行定位受權

備註:
iOS8.0-,地圖不會自動滾動到用戶所在位置
iOS8.0+,地圖會自動放大到合適比例,並顯示出用戶位置


4、設置地圖的顯示


一、設置地圖的顯示
經過MKMapView的下列方法,能夠設置地圖顯示的位置和區域
設置地圖的中心點位置
@property (nonatomic) CLLocationCoordinate2D centerCoordinate;
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;

設置地圖的顯示區域
@property (nonatomic) MKCoordinateRegion region;
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

 

二、MKCoordinateRegion
MKCoordinateRegion是一個用來表示區域的結構體,定義以下
typedef struct {
CLLocationCoordinate2D center; // 區域的中心點位置
MKCoordinateSpan span; // 區域的跨度
} MKCoordinateRegion;

MKCoordinateSpan的定義
typedef struct {
CLLocationDegrees latitudeDelta; // 緯度跨度
CLLocationDegrees longitudeDelta; // 經度跨度
} MKCoordinateSpan;


5、MKMapView的代理


MKMapView能夠設置一個代理對象,用來監聽地圖的相關行爲

常見的代理方法有
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
一個位置更改默認只會調用一次,不斷監測用戶的當前位置
每次調用,都會把用戶的最新位置(userLocation參數)傳進來

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
地圖的顯示區域即將發生改變的時候調用

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
地圖的顯示區域已經發生改變的時候調用

 

二、MKUserLocation 大頭針模型
MKUserLocation實際上是個大頭針模型,包括如下屬性
@property (nonatomic, copy) NSString *title;
顯示在大頭針上的標題

@property (nonatomic, copy) NSString *subtitle;
顯示在大頭針上的子標題

@property (readonly, nonatomic) CLLocation *location;
地理位置信息(大頭針釘在什麼地方?)

 

三、位置、地標、大頭針總概覽

 

 

6、大頭針


一、簡介
地圖上的大頭針
釘在某個具體位置,用來標識這個位置上有特定的事物(好比這個位置上有家餐館)

二、大頭針的基本操做
添加一個大頭針
- (void)addAnnotation:(id <MKAnnotation>)annotation;

添加多個大頭針
- (void)addAnnotations:(NSArray *)annotations;

移除一個大頭針
- (void)removeAnnotation:(id <MKAnnotation>)annotation;

移除多個大頭針
- (void)removeAnnotations:(NSArray *)annotations;

(id <MKAnnotation>)annotation參數是什麼東西?
大頭針模型對象:用來封裝大頭針的數據,好比大頭針的位置、標題、子標題等數據

/** 座標位置 */
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
/** 標題 */
@property (nonatomic, copy) NSString *title;
/** 子標題 */
@property (nonatomic, copy) NSString *subtitle;

 

三、大頭針使用實例
MJTuangouAnnotation *anno = [[MJTuangouAnnotation alloc] init];
anno.title = @「廣州小蠻腰";
anno.subtitle = @「哎呦,不錯哦!";
anno.coordinate = CLLocationCoordinate2DMake(23.132, 113.345);
[self.mapView addAnnotation:anno];

 

四、自定義大頭針
不少狀況下,須要自定義大頭針的顯示樣式,好比顯示一張圖片

如何自定義大頭針
設置MKMapView的代理
實現下面的代理方法,返回大頭針控件
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
根據傳進來的(id <MKAnnotation>)annotation參數建立並返回對應的大頭針控件

代理方法的使用注意
若是返回nil,顯示出來的大頭針就採起系統的默認樣式
標識用戶位置的藍色發光圓點,它也是一個大頭針,當顯示這個大頭針時,也會調用代理方法
所以,須要在代理方法中分清楚(id <MKAnnotation>)annotation參數表明自定義的大頭針仍是藍色發光圓點

 

五、自定義大頭針實例
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// 判斷annotation的類型
if (![annotation isKindOfClass:[MJTuangouAnnotation class]]) return nil;

// 建立MKAnnotationView
static NSString *ID = @"tuangou";
MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
if (annoView == nil) {
annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
annoView.canShowCallout = YES;
}
// 傳遞模型數據
annoView.annotation = annotation;

// 設置圖片
MJTuangouAnnotation *tuangouAnnotation = annotation;
annoView.image = [UIImage imageNamed:tuangouAnnotation.icon];

return annoView;
}

 

7、MKAnnotationView


一、地圖上的大頭針控件是MKAnnotationView

MKAnnotationView的屬性
@property (nonatomic, strong) id <MKAnnotation> annotation;
大頭針模型

@property (nonatomic, strong) UIImage *image;
顯示的圖片

@property (nonatomic) BOOL canShowCallout;
是否顯示標註

@property (nonatomic) CGPoint calloutOffset;
標註的偏移量

@property (strong, nonatomic) UIView *rightCalloutAccessoryView;
標註右邊顯示什麼控件

@property (strong, nonatomic) UIView *leftCalloutAccessoryView;
標註左邊顯示什麼控件

@property (nonatomic, strong) UIView *detailCalloutAccessoryView
標註下面顯示什麼控件(iOS9.0)

 

二、MKPinAnnotationView
MKPinAnnotationView是MKAnnotationView的子類
MKPinAnnotationView比MKAnnotationView多了2個屬性

@property (nonatomic) MKPinAnnotationColor pinColor;
大頭針顏色

@property (nonatomic) BOOL animatesDrop;
大頭針第一次顯示時是否從天而降


8、利用系統App導航/數字版街景/地圖快照截圖


一、MKMapItem調用系統APP進行導航 主要方法
[MKMapItem openMapsWithItems:items launchOptions:md];

示例代碼
// 根據兩個地標對象進行調用系統導航
- (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark
{
// 建立起點:根據 CLPlacemark 地標對象建立 MKPlacemark 地標對象
MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark];
MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1];

// 建立終點:根據 CLPlacemark 地標對象建立 MKPlacemark 地標對象
MKPlacemark *itemP2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark];
MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:itemP2];

NSDictionary *launchDic = @{
// 設置導航模式參數
MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,
// 設置地圖類型
MKLaunchOptionsMapTypeKey : @(MKMapTypeHybridFlyover),
// 設置是否顯示交通
MKLaunchOptionsShowsTrafficKey : @(YES),

};
// 根據 MKMapItem 數組 和 啓動參數字典 來調用系統地圖進行導航
[MKMapItem openMapsWithItems:@[item1, item2] launchOptions:launchDic];

 

二、MKMapCamera地圖街景
主要方法
self.mapView.camera = camera;

示例代碼
// 建立視角中心座標
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(23.132931, 113.375924);
// 建立3D視角
MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001) eyeAltitude:1];
// 設置到地圖上顯示
self.mapView.camera = camera;

 

三、MKMapSnapshotter地圖截圖
主要方法
[snapshotter startWithCompletionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) { }];

示例代碼
// 截圖附加選項
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
// 設置截圖區域(在地圖上的區域,做用在地圖)
options.region = self.mapView.region;
// options.mapRect = self.mapView.visibleMapRect;

// 設置截圖後的圖片大小(做用在輸出圖像)
options.size = self.mapView.frame.size;
// 設置截圖後的圖片比例(默認是屏幕比例, 做用在輸出圖像)
options.scale = [[UIScreen mainScreen] scale];

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
if (error) {
NSLog(@"截圖錯誤:%@",error.localizedDescription);
}else
{
// 設置屏幕上圖片顯示
self.snapshootImageView.image = snapshot.image;
// 將圖片保存到指定路徑(此處是桌面路徑,須要根據我的電腦不一樣進行修改)
NSData *data = UIImagePNGRepresentation(snapshot.image);
[data writeToFile:@"/Users/wangshunzi/Desktop/snap.png" atomically:YES];
}
}];

 

四、MapKit框架-獲取導航路線信息
MKDirections獲取導航路線信息
主要方法
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {

}];

 

五、繪製導航路線主要方法 /** 注意:這裏不像添加大頭針那樣,只要咱們添加了大頭針模型,默認就會在地圖上添加系統的大頭針視圖 添加覆蓋層,須要咱們實現對應的代理方法,在代理方法中返回對應的覆蓋層 */ [self.mapView addOverlay:overlay];調用了以上方法後,會調用如下代理方法獲取對應的渲染塗層-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay

相關文章
相關標籤/搜索