iOS開發(fā)-地圖開發(fā)(CoreLocation和MapKit))

地圖(CoreLocation和MapKit)

  • CoreLocation框架

    • CoreLocation
    • CLLocation
    • ios地圖開發(fā)的隱私保護(hù)(如何添加授權(quán))
    • CLGeocoder
    • CLPlacemark
  • MapKit框架

    • MKMapView
    • MKCoordinateRegion
    • MKMapView的代理
    • MKUserLocation
    • 大頭針
    • annotation
    • 自定義大頭針
    • MKAnnotationView
    • MKPinAnnotationView
    • MKMapItem調(diào)用系統(tǒng)APP進(jìn)行導(dǎo)航
    • MKMapCamera地圖街景
    • MKMapSnapshotter地圖截圖

2大框架

  • CoreLocation:用于地理定位,地理編碼區(qū)域監(jiān)聽等(著重功能實(shí)現(xiàn))
  • MapKit:用于地圖展示,例如大頭針,路線,覆蓋層展示等(著重界面展示)

CoreLocation框架的使用

CLLocationManager

  • CoreLocation框架中使用CLLocationManager對象來做用戶定位
  • 創(chuàng)建(初始化)
CLLocationManager *lM = [[CLLocationManager alloc] init];

  • 常用屬性
    • 每隔多少米定位一次
      @property(assign, nonatomic) CLLocationDistance distanceFilter;
    • 定位精確度(越精確就越耗電)
      @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
    • 朝向改變時,每隔多少度調(diào)用一次
      @property(assign, nonatomic) CLLocationDegrees headingFilter
         每隔多米定位一次
       _lM.distanceFilter = 100;
       /**
          kCLLocationAccuracyBestForNavigation // 最適合導(dǎo)航
          kCLLocationAccuracyBest; // 最好的
          kCLLocationAccuracyNearestTenMeters; // 10m
          kCLLocationAccuracyHundredMeters; // 100m
          kCLLocationAccuracyKilometer; // 1000m
          kCLLocationAccuracyThreeKilometers; // 3000m
        */
       // 精確度越高, 越耗電, 定位時間越長
       _lM.desiredAccuracy = kCLLocationAccuracyBest;
       

  • 常用方法
    • 開始更新用戶位置- (void)startUpdatingLocation;

      • 當(dāng)調(diào)用了startUpdatingLocation方法后,就開始不斷地請求、刷新用戶的位置,一旦請求到用戶位置就會調(diào)用代理的下面方法
        -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

      • locations參數(shù)里面裝著CLLocation對象

    • 停止更新用戶位置- (void) stopUpdatingLocation;

    • 判斷定位功能是否可用(為了嚴(yán)謹(jǐn)起見,最好在使用定位功能前進(jìn)行判斷)+ (BOOL)locationServicesEnabled;

    • 監(jiān)聽設(shè)備朝向 -(void)startUpdatingHeading(如試?yán)a中的指南針的實(shí)現(xiàn))

    • 區(qū)域監(jiān)聽(監(jiān)聽進(jìn)出某個區(qū)域) -(void)requestStateForRegion:region;

    //使用位置管理者,開始更新用戶位置
    // 默認(rèn)只能在前臺獲取用戶位置,
    // 勾選后臺模式 location updates
    [self.lM startUpdatingLocation];

    //監(jiān)聽設(shè)備朝向
    [self.lM startUpdatingHeading];
   - 區(qū)域監(jiān)聽(監(jiān)聽進(jìn)出某個區(qū)域)
   [self.lM requestStateForRegion:region];
  • 代理方法
    • 跟新位置后調(diào)用- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
    • 授權(quán)狀態(tài)改變時調(diào)用-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    • 獲取手機(jī)朝向時調(diào)用
      -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    • 區(qū)域監(jiān)聽的代理方法
      • 進(jìn)入?yún)^(qū)域時調(diào)用:-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
      • 離開區(qū)域時調(diào)用:-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
      • 監(jiān)聽是否在某個區(qū)域的狀態(tài):-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state
/**
*  更新到位置之后調(diào)用
*
*  @param manager   位置管理者
*  @param locations 位置數(shù)組
*/
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
   NSLog(@"定位到了");
   
   // 拿到位置,做一些業(yè)務(wù)邏輯操作
   
   
   // 停止更新
//    [manager stopUpdatingLocation];
}
/**
 *  授權(quán)狀態(tài)發(fā)生改變時調(diào)用
 *
 *  @param manager 位置管理者
 *  @param status  狀態(tài)
 */
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
            // 用戶還未決定
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用戶還未決定");
            break;
        }
            // 問受限
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"訪問受限");
            break;
        }
            // 定位關(guān)閉時和對此APP授權(quán)為never時調(diào)用
        case kCLAuthorizationStatusDenied:
        {
            // 定位是否可用(是否支持定位或者定位是否開啟)
            if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"定位開啟,但被拒");
            }else
            {
                NSLog(@"定位關(guān)閉,不可用");
            }
//            NSLog(@"被拒");
            break;
        }
            // 獲取前后臺定位授權(quán)
        case kCLAuthorizationStatusAuthorizedAlways:
            //        case kCLAuthorizationStatusAuthorized: // 失效,不建議使用
        {
            NSLog(@"獲取前后臺定位授權(quán)");
            break;
        }
            // 獲得前臺定位授權(quán)
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"獲得前臺定位授權(quán)");
            break;
        }
        default:
            break;
    }
}
/**
 *  簡易指南針的實(shí)現(xiàn)
 *  手機(jī)朝向改變時調(diào)用
 *
 *  @param manager    位置管理者
 *  @param newHeading 朝向?qū)ο? */
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    /**
     *  CLHeading 
     *  magneticHeading : 磁北角度
     *  trueHeading : 真北角度
     */
    
    NSLog(@"%f", newHeading.magneticHeading);
    
    CGFloat angle = newHeading.magneticHeading;
    
    // 把角度轉(zhuǎn)弧度
    CGFloat angleR = angle / 180.0 * M_PI;
    
    // 旋轉(zhuǎn)圖片(指南針圖片)
    [UIView animateWithDuration:0.25 animations:^{
        self.compassView.transform = CGAffineTransformMakeRotation(-angleR);
    }]; 
}

//區(qū)域監(jiān)聽的代理方法
// 進(jìn)入?yún)^(qū)域
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
   NSLog(@"進(jìn)入?yún)^(qū)域--%@", region.identifier);
}

// 離開區(qū)域
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
   NSLog(@"離開區(qū)域--%@", region.identifier);
}

//監(jiān)聽是否在某個區(qū)域的狀態(tài)
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
   //state的值
   //CLRegionStateUnknown,
   //CLRegionStateInside,
   //CLRegionStateOutside
   NSLog(@"%zd", state);   
}

CLLocation

  • CLLocation用來表示某個位置的地理信息,比如經(jīng)緯度,海拔等等
  • 常用屬性
    • @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
      經(jīng)緯度
    • @property(readonly, nonatomic) CLLocationDistance altitude;
      海拔
    • @property(readonly, nonatomic) CLLocationDirection course;
      路線,航向(取值范圍是0.0° ~ 359.9°,0.0°代表真北方向)
    • @property(readonly, nonatomic) CLLocationSpeed speed;
      移動速度(單位是m/s)
  • 常用方法
    • 計(jì)算兩個位置之間的距離:- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location

使用試?yán)?根據(jù)移動方向打印出移動的方向和距離

/**
 *  CLLocationManager對象的代理方法,當(dāng)用戶位置改變的時候調(diào)用
 *  更新到位置之后調(diào)用
 *
 *  @param manager   位置管理者
 *  @param locations 位置數(shù)組
 * is kind of
 */
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
//    NSLog(@"定位到了");
    /**
     *  CLLocation 詳解
     *  coordinate : 經(jīng)緯度
     *  altitude : 海拔
     *  course : 航向
     *  speed ; 速度
     */

    CLLocation *location = [locations lastObject];
    
//    NSLog(@"%@", location);
    
    /**
     *  場景演示:打印當(dāng)前用戶的行走方向,偏離角度以及對應(yīng)的行走距離,
        例如:”北偏東 30度  方向,移動了8米”
     */
    
    // 1. 獲取方向偏向
    NSString *angleStr = nil;
    
    switch ((int)location.course / 90) {
        case 0:
            angleStr = @"北偏東";
            break;
        case 1:
            angleStr = @"東偏南";
            break;
        case 2:
            angleStr = @"南偏西";
            break;
        case 3:
            angleStr = @"西偏北";
            break;
            
        default:
            angleStr = @"跑溝里去了!!";
            break;
    }
    // 2. 偏向角度
    NSInteger angle = 0;
    angle = (int)location.course % 90;
    
    // 代表正方向
    if (angle == 0) {
        NSRange range = NSMakeRange(0, 1);
        angleStr = [NSString stringWithFormat:@"正%@", [angleStr substringWithRange:range]];
    }
    // 3.移動多少米
    double distance = 0;
    if(_oldL)
    {
        distance = [location distanceFromLocation:_oldL];
    }
    _oldL = location;
    // 4. 拼串 打印
    // 例如:”北偏東 30度  方向,移動了8米”
    NSString *noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移動了%f米", angleStr, angle, distance];
    NSLog(@"%@", noticeStr);
}

ios地圖開發(fā)用戶隱私保護(hù)(授權(quán))

ios6+

  • 當(dāng)使用定位時,系統(tǒng)會自動彈出對話框讓用戶授權(quán)。
    - 一旦用戶選擇了不允許,意味著應(yīng)用程序以后都無法使用定位。
  • 開發(fā)者可以在Info.plist中設(shè)置NSLocationUsageDescription說明定位的目的(Privacy - Location Usage Description)

ios8.0+

從ios8.0開始,蘋果進(jìn)一步加強(qiáng)了對用戶隱私的保護(hù)。
  • 當(dāng)app想訪問用戶的隱私時,系統(tǒng)不再自動彈出一個對話框讓用戶授權(quán).
解決方案
  • (1)調(diào)用ios8.0的api。主動請求用戶授權(quán)
    • -(void)requestAlwaysAuthorization // 請求允許在前后臺都能獲取用戶位置的授權(quán)
    • -(void)requestWhenInUseAuthorization // 請求允許在前臺獲取用戶位置的授權(quán)(注意:當(dāng)設(shè)置為前臺授權(quán)時,通過設(shè)置后臺模式:location updates后 也可以后臺獲取定位信息,但是屏幕上方會出現(xiàn)藍(lán)條)
  • (2)務(wù)必在info.plist文件中配置對應(yīng)的鍵值, 否則以上請求授權(quán)的方法不生效
    • NSLocationAlwaysUsageDescription : 允許在前后臺獲取GPS的描述
    • NSLocationWhenInUseDescription : 允許在前臺獲取GPS的描述

ios9.0

  • ios9.0如果當(dāng)前處于前臺授權(quán)狀態(tài),默認(rèn)是不可以后臺獲取用戶位置。但可以設(shè)置以下屬性為YES,就可以繼續(xù)在后臺獲取位置,但是在屏幕上方會出現(xiàn)藍(lán)條
    • @property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates
    • 使用注意:必須設(shè)置對應(yīng)的后臺模式:location updates
  • ios9.0可以單次請求用戶位置
    • -(void)requestLocation
    • -(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations // 成功調(diào)用
    • -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失敗調(diào)用

CLGeocoder

  • 使用CLGeocoder可以完成“地理編碼”和“反地理編碼”
    • 地理編碼:根據(jù)給定的地名,獲得具體的位置信息(比如經(jīng)緯度、地址的全稱等)
    • 反地理編碼:根據(jù)給定的經(jīng)緯度,獲得具體的位置信息
  • 對應(yīng)方法
    • 地理編碼方法-(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
    • 反地理編碼方法-(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
  • CLGeocodeCompletionHandler:反地理編碼完成時,就會調(diào)用CLGeocodeCompletionHandler
    • typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
      • error :當(dāng)編碼出錯時(比如編碼不出具體的信息)有值
      • placemarks :里面裝著CLPlacemark對象

地理編碼的實(shí)現(xiàn)

// 地理編碼
- (IBAction)geoCoder {

    //當(dāng)傳入的值為0時直接返回
    if ([self.addressDetailTV.text length] == 0) {
        return;
    }

    // 地理編碼方案一:直接根據(jù)地址進(jìn)行地理編碼(返回結(jié)果可能有多個,因?yàn)橐粋€地點(diǎn)有重名)
    [self.geoC geocodeAddressString:self.addressDetailTV.text completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        // 包含區(qū),街道等信息的地標(biāo)對象
        CLPlacemark *placemark = [placemarks firstObject];
        // 城市名稱
//        NSString *city = placemark.locality;
        // 街道名稱
//        NSString *street = placemark.thoroughfare;
        // 全稱
        NSString *name = placemark.name;
        self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
    }];
    // 地理編碼方案二:根據(jù)地址和區(qū)域兩個條件進(jìn)行地理編碼(更加精確)
//    [self.geoC geocodeAddressString:self.addressDetailTV.text inRegion:nil completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
//        // 包含區(qū),街道等信息的地標(biāo)對象
//        CLPlacemark *placemark = [placemarks firstObject];
//        self.addressDetailTV.text = placemark.description;
//        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
//    }];

    

    // 地理編碼方案三:
//    NSDictionary *addressDic = @{
//                                 (__bridge NSString *)kABPersonAddressCityKey : @"北京",
//                                 (__bridge NSString *)kABPersonAddressStreetKey : @"棠下街"
//                                 };
//    [self.geoC geocodeAddressDictionary:addressDic completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
//        CLPlacemark *placemark = [placemarks firstObject];
//        self.addressDetailTV.text = placemark.description;
//        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
//    }];
}

反地理編碼的實(shí)現(xiàn)

// 反地理編碼
- (IBAction)decode {
    // 過濾空數(shù)據(jù)
    if ([self.latitudeTF.text length] == 0 || [self.longtitudeTF.text length] == 0) {
        return;
    }
    // 創(chuàng)建CLLocation對象
    CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text doubleValue] longitude:[self.longtitudeTF.text doubleValue]];
    // 根據(jù)CLLocation對象進(jìn)行反地理編碼
    [self.geoC reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        // 包含區(qū),街道等信息的地標(biāo)對象
        CLPlacemark *placemark = [placemarks firstObject];
        // 城市名稱
//        NSString *city = placemark.locality;
        // 街道名稱
//        NSString *street = placemark.thoroughfare;
        // 全稱
        NSString *name = placemark.name;
        self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
    }];

}

CLPlacemark

  • CLPlacemark的字面意思是地標(biāo),封裝詳細(xì)的地址位置信息
  • 常用屬性
    • @property (nonatomic, readonly) CLLocation *location;地理位置
    • @property (nonatomic, readonly) CLRegion *region;
      區(qū)域
    • @property (nonatomic, readonly) NSDictionary *addressDictionary;詳細(xì)的地址信息
    • @property (nonatomic, readonly) NSString *name;
      地址名稱
    • @property (nonatomic, readonly) NSString *locality;
      城市

MapKit框架的使用

MapKit通過MKMapView來顯示地圖

  • 常用屬性
    • 地圖配型:mapType

      • MKMapTypeStandard :普通地圖(左圖)
      • MKMapTypeSatellite :衛(wèi)星云圖 (中圖)
      • MKMapTypeHybrid :混合模式(普通地圖覆蓋于衛(wèi)星云圖之上 )
      • MKMapTypeSatelliteFlyover: 3D立體衛(wèi)星 (iOS9.0)
      • MKMapTypeHybridFlyover: 3D立體混合 (iOS9.0)
    • 操作項(xiàng)

      • 是否可縮放 zoomEnabled
      • 是否可滾動 scrollEnabled
      • 是否可旋轉(zhuǎn) rotateEnabled
    • 顯示項(xiàng)

      • 是否顯示指南針 showsCompass (iOS9.0)
      • 是否顯示比例尺 showsScale (iOS9.0)
      • 是否顯示交通 showsTraffic (iOS9.0)
      • 是否顯示建筑 showsBuildings
    • 跟蹤顯示用戶的位置(ios8-地圖不會自動滾到用戶所在的位置,ios8+地圖會自動放大到合適比例,并顯示出用戶位置)

      • MKUserTrackingModeNone :不跟蹤用戶的位置
      • MKUserTrackingModeFollow :跟蹤并在地圖上顯示用戶的當(dāng)前位置
      • MKUserTrackingModeFollowWithHeading :跟蹤并在地圖上顯示用戶的當(dāng)前位置,地圖會跟隨用戶的前進(jìn)方向進(jìn)行旋轉(zhuǎn)
    • 設(shè)置地圖顯示的區(qū)域和位置

      • 設(shè)置地圖的中心點(diǎn)位置
        • @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
        • -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
      • 設(shè)置地圖的顯示區(qū)域
        • @property (nonatomic) MKCoordinateRegion region;
        • -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

MKCoordinateRegion

  • MKCoordinateRegion是一個用來表示區(qū)域的結(jié)構(gòu)體
typedef struct {
         CLLocationCoordinate2D center; // 區(qū)域的中心點(diǎn)位置
        MKCoordinateSpan span; // 區(qū)域的跨度
} MKCoordinateRegion;
  • MKCoordinateSpan
typedef struct {
    CLLocationDegrees latitudeDelta; // 緯度跨度
    CLLocationDegrees longitudeDelta; // 經(jīng)度跨度
} MKCoordinateSpan;

MKMapView的代理

  • -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
    • 一個位置更改默認(rèn)只會調(diào)用一次,不斷監(jiān)測用戶的當(dāng)前位置
    • 每次調(diào)用,都會把用戶的最新位置(userLocation參數(shù))傳進(jìn)來
  • -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
    • 地圖的顯示區(qū)域即將發(fā)生改變的時候調(diào)用
  • -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
    • 地圖的顯示區(qū)域已經(jīng)發(fā)生改變的時候調(diào)用

MKUserLocation

  • @property (nonatomic, copy) NSString *title;
    顯示在大頭針上的標(biāo)題

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

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

大頭針

  • 添加大頭針

    • 添加一個大頭針
      -(void)addAnnotation:(id <MKAnnotation>)annotation;
    • 添加多個大頭針
      -(void)addAnnotations:(NSArray *)annotations;
  • 移除大頭針

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

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

annotation

  • 大頭針模型對象
#import <MapKit/MapKit.h>

@interface TestAnnotation : NSObject <MKAnnotation>
/** 坐標(biāo)位置 */
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
/** 標(biāo)題 */
@property (nonatomic, copy) NSString *title; 
/** 子標(biāo)題 */
@property (nonatomic, copy) NSString *subtitle; 
@end

自定義大頭針

  • 設(shè)置MKMapView代理
    • -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
      根據(jù)傳進(jìn)來的(id <MKAnnotation>)annotation參數(shù)創(chuàng)建并返回對應(yīng)的大頭針控件
    • 注意:如果返回nil,顯示出來的大頭針就采取系統(tǒng)的默認(rèn)樣式
      標(biāo)識用戶位置的藍(lán)色發(fā)光圓點(diǎn),它也是一個大頭針,當(dāng)顯示這個大頭針時,也會調(diào)用代理方法
      因此,需要在代理方法中分清楚(id <MKAnnotation>)annotation參數(shù)代表自定義的大頭針還是藍(lán)色發(fā)光圓點(diǎn)
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 判斷annotation的類型
    if (![annotation isKindOfClass:[TestAnnotation class]]) return nil;
    
    // 創(chuàng)建MKAnnotationView
    static NSString *ID = @"tuangou";
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (annoView == nil) {
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        annoView.canShowCallout = YES;
    }

MKAnnotationView

地圖上的大頭針控件是MKAnnotationView
  • 屬性
    • @property (nonatomic, strong) id <MKAnnotation> annotation;
      大頭針模型
    • @property (nonatomic, strong) UIImage *image;
      顯示的圖片
    • @property (nonatomic) BOOL canShowCallout;
      是否顯示標(biāo)注
    • @property (nonatomic) CGPoint calloutOffset;
      標(biāo)注的偏移量
    • @property (strong, nonatomic) UIView *rightCalloutAccessoryView;
      標(biāo)注右邊顯示什么控件
    • @property (strong, nonatomic) UIView *leftCalloutAccessoryView;
      標(biāo)注左邊顯示什么控件
    • @property (nonatomic, strong) UIView *detailCalloutAccessoryView
      標(biāo)注下面顯示什么控件(iOS9.0)

MKPinAnnotationView

MKPinAnnotationView是MKAnnotationView的子類

MKPinAnnotationView比MKAnnotationView多了2個屬性

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

MKMapItem調(diào)用系統(tǒng)APP進(jìn)行導(dǎo)航

// 根據(jù)兩個地標(biāo)對象進(jìn)行調(diào)用系統(tǒng)導(dǎo)航
- (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark
{
    // 創(chuàng)建起點(diǎn):根據(jù) CLPlacemark 地標(biāo)對象創(chuàng)建 MKPlacemark 地標(biāo)對象
    MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark];
    MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1];

    // 創(chuàng)建終點(diǎn):根據(jù) CLPlacemark 地標(biāo)對象創(chuàng)建 MKPlacemark 地標(biāo)對象
    MKPlacemark *itemP2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark];
    MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:itemP2];

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

                                };
    // 根據(jù) MKMapItem 數(shù)組 和 啟動參數(shù)字典 來調(diào)用系統(tǒng)地圖進(jìn)行導(dǎo)航
    [MKMapItem openMapsWithItems:@[item1, item2] launchOptions:launchDic];
}

MKMapCamera地圖街景

    // 創(chuàng)建視角中心坐標(biāo)
     CLLocationCoordinate2D center = CLLocationCoordinate2DMake(23.132931, 113.375924);
    // 創(chuàng)建3D視角
    MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001) eyeAltitude:1];
    // 設(shè)置到地圖上顯示
    self.mapView.camera = camera;

MKMapSnapshotter地圖截圖

// 截圖附加選項(xiàng)
    MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
    // 設(shè)置截圖區(qū)域(在地圖上的區(qū)域,作用在地圖)
    options.region = self.mapView.region;
//    options.mapRect = self.mapView.visibleMapRect;

    // 設(shè)置截圖后的圖片大小(作用在輸出圖像)
    options.size = self.mapView.frame.size;
    // 設(shè)置截圖后的圖片比例(默認(rèn)是屏幕比例, 作用在輸出圖像)
    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
        {
            // 設(shè)置屏幕上圖片顯示
            self.snapshootImageView.image = snapshot.image;
            // 將圖片保存到指定路徑(此處是桌面路徑,需要根據(jù)個人電腦不同進(jìn)行修改)
            NSData *data = UIImagePNGRepresentation(snapshot.image);
            [data writeToFile:@"/Users/wangshunzi/Desktop/snap.png" atomically:YES];
        }
    }];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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