iOS筆記-地圖的基本使用

地圖的基本使用

  • 1.設置地圖顯示類型

    // 1.設置地圖顯示類型
            /**
                MKMapTypeStandard = 0,  // 標準
                MKMapTypeSatellite,     // 衛星
                MKMapTypeHybrid,        // 混合(標準+衛星)
                MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0), // 3D立體衛星
                MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0), // 3D立體混合
             */
            self.customMapView.mapType = MKMapTypeStandard;
    
  • 設置地圖的其他屬性(操作項)

    • 注意:設置對應屬性時,注意該屬性是從哪個系統版本開始引入的,做好不同系統版本的適配
      // 是否可以縮放
          self.customMapView.zoomEnabled = NO;
          // 是否可以滾動
          self.customMapView.scrollEnabled = NO;
          // 是否可以旋轉
          self.customMapView.rotateEnabled = NO;
          // 是否顯示3D
          self.customMapView.pitchEnabled = NO;
      
  • 設置地圖其他屬性

        // 是否顯示指南針
            self.customMapView.showsCompass = YES;
            // 是否顯示比例尺
            self.customMapView.showsScale = YES;
            // 是否顯示交通
            self.customMapView.showsTraffic = YES;
            // 是否顯示建筑物
            self.customMapView.showsBuildings = YES;
    
  • 設置地圖的用戶追蹤模式

    • 1.創建CLLocationManager對象請求授權

-(CLLocationManager *)locationM
{
if (!_locationM) {
_locationM = [[CLLocationManager alloc] init];
if ([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationM requestAlwaysAuthorization];
}
}
return _locationM;
}
```

- 2.設置地圖的用戶追蹤模式
```objc
    /**
                    MKUserTrackingModeNone = 0, // 不跟隨
                    MKUserTrackingModeFollow, // 跟隨用戶位置
                    MKUserTrackingModeFollowWithHeading, // 跟隨用戶位置,并跟隨用戶方向
                 */
                [self locationM];
                self.customMapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;

```

地圖中級使用

  • 查看當前用戶位置信息
    • 1.設置地圖代理,并實現代理方法,在代理方法中獲取用戶當前位置(注意iOS8.0之后要請求授權)
    • 2.將地圖顯示中心調整為用戶當前所在位置(iOS之前,地圖不會自動移動到用戶所在位置)
    • 3.調整當前地圖顯示的區域(可使用對應代理方法查看當前地圖跨度然后調整到合適的跨度即可)

-(void)mapView:(MKMapView )mapView didUpdateUserLocation:(MKUserLocation )userLocation
{
/

MKUserLocation : 被稱作“大頭針模型”,其實喊什么都行,本質就是一個數據模型,只不過此模型遵循了大頭針要遵循的協議(MKAnnotation)
location: 用戶當前所在位置信息(CLLocation對象)
title: 大頭針標注要顯示的標題(NSString對象)
subtitle: 大頭針標注要顯示的子標題(NSString對象)
/
// 根據用戶當前位置的經緯度,設置地圖顯示中心
/
*
存在弊端:地圖顯示比例過大,無法調整
解決方案:直接使用對應的調整地圖“顯示區域”的API
/
// [mapView setCenterCoordinate:userLocation.coordinate animated:YES];
/
*
MKCoordinateSpan 跨度解釋:
latitudeDelta:緯度跨度,因為南北緯各90度,所以此值的范圍是(0---180);此值表示,整個地圖視圖寬度,顯示多大跨度
longitudeDelta:經度跨度,因為東西經各180度,所以此值范圍是(0---360):此值表示,整個地圖視圖高度,顯示多大跨度
注意:地圖視圖顯示,不會更改地圖的比例,會以地圖視圖高度或寬度較小的那個為基準,按比例調整
*/
// MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
// MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.coordinate, span);
// [mapView setRegion:region animated:YES];
}

    // 當地圖區域(跨度)改變時調用
    -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
    {
        NSLog(@"%f---%f", mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta);
    }

```

大頭針基本使用

  • 在地圖上操作大頭針,實際上就是操作大頭針數據模型
  • 添加大頭針就是添加大頭針數據模型
  • 刪除大頭針就是刪除大頭針模型
  • 實現步驟
    • 添加一個/多個大頭針

      • 1.自定義大頭針模型(需要遵循MKAnnotation協議)
        #import <MapKit/MapKit.h>
        
        

      @interface XMGAnnotation : NSObject <MKAnnotation>

      @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
      @property (nonatomic, copy, nullable) NSString *title;
      @property (nonatomic, copy, nullable) NSString *subtitle;

      @end
      ```

      • 2.創建自定義大頭針模型,并添加到地圖上
        -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
        

      {
      // 如果我們僅僅添加大頭針數據模型,地圖上會自動添加系統默認的大頭針視圖
      CYXAnnotation *annotation = [[CYXAnnotation alloc] init];
      // annotation.coordinate = self.mapView.centerCoordinate;
      // 1. 獲取當前點的位置
      UITouch *touch = [touches anyObject];
      CGPoint point = [touch locationInView:self.mapView];
      // 把點轉換成對應的經緯度
      CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
      // TODO:使用反地理編碼,獲取對應大頭針的所在的位置信息,通過標注顯示出來
      annotation.coordinate = coordinate;
      annotation.title = @"荔灣區";
      annotation.subtitle = @"和業廣場";

        // 添加單個大頭針
        [self.mapView addAnnotation:annotation];
        // 添加多個大頭針
      

      // [self.mapView addAnnotations:@[]];
      }
      ```

      • 移除1個/多個大頭針
        [self.mapView removeAnnotations:self.mapView.annotations];
        
        

自定義大頭針

  • 添加大頭針數據時,其實地圖會調用代理方法查找對應的大頭針視圖,如果沒有找到,就會使用系統默認的大頭針視圖
    • 1.模擬系統大頭針實現方案,并對大頭針進行部分自定義
    • (彈出標注, 修改大頭針顏色, 設置大頭針從天而降, 設置大頭針可以被拖拽)
      - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
      {
          if ([annotation isKindOfClass:[MKUserLocation class]]) {
              return nil;
          }
          // 如果此方法返回nil, 就會使用系統自帶的大頭針視圖
          // 模擬下,返回nil,系統的解決方案
          static NSString *pinId = @"pinID";
          MKPinAnnotationView *pinView = ( MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinId];
          if (pinView == nil) {
              pinView  = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinId];
          }
          pinView.annotation = annotation;
          // 是否顯示標注
          pinView.canShowCallout = YES;
          // 設置大頭針顏色
          pinView.pinColor = MKPinAnnotationColorPurple;
          // 設置大頭針是否有下落動畫
          pinView.animatesDrop = YES;
          return pinView;
      }
      
    • 2.自定義大頭針
      - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
      {
          if ([annotation isKindOfClass:[MKUserLocation class]]) {
              return nil;
          }
          /**  自定義大頭針-------*/
          static NSString *pinId = @"pinID";
          MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:pinId];
          if (annoView == nil) {
              annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinId];
          }
          annoView.annotation = annotation;
          annoView.image = [UIImage imageNamed:@"category_5"];
          annoView.canShowCallout = YES;
          UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"huba.jpeg"]];
          imageView.bounds = CGRectMake(0, 0, 44, 44);
          annoView.leftCalloutAccessoryView = imageView;
          imageView.userInteractionEnabled  = YES;
          UIImageView *imageView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"eason.jpg"]];
          imageView2.bounds = CGRectMake(0, 0, 44, 44);
          annoView.rightCalloutAccessoryView = imageView2;
          annoView.detailCalloutAccessoryView = [UISwitch new];
          annoView.draggable = YES;
          return annoView;
      }
      

大頭針圖標,大頭針標注,左側視圖,右側視圖,詳情視圖,等;

    ```
- 選中和取消選中大頭針時的代理方法
    ```objc
    // 點擊標注
    - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
    {
        NSLog(@"點擊標注");
    }
    // 選中大頭針
    - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
    {
        NSLog(@"選中大頭針");
    }
    // 取消選中大頭針
    -(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
    {
        NSLog(@"取消選中大頭針");
    }
    ```

利用系統App導航

// 根據兩個地標對象進行調用系統導航
- (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark
{

    // 根據 CLPlacemark 地標對象創建 MKPlacemark 地標對象
    MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark];
    MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1];


    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];

}

數字版街景地圖

    /**
        補充1:類似于地圖街景,增強用戶體驗
     */
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(23.132931, 113.375924);
    MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001) eyeAltitude:1];
    self.mapView.camera = camera;

地圖快照截圖

    /**
        補充2:地圖截圖
     */
    // 截圖附加選項
    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/chenyanxiang/Desktop/snap.png" atomically:YES];
        }
    }];

獲取導航路線信息

// 根據兩個地標,向蘋果服務器請求對應的行走路線信息
- (void)directionsWithBeginPlackmark:(CLPlacemark *)beginP andEndPlacemark:(CLPlacemark *)endP
{

    // 創建請求
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];

    // 設置開始地標
    MKPlacemark *beginMP = [[MKPlacemark alloc] initWithPlacemark:beginP];
    request.source = [[MKMapItem alloc] initWithPlacemark:beginMP];

    // 設置結束地標
    MKPlacemark *endMP = [[MKPlacemark alloc] initWithPlacemark:endP];
    request.destination = [[MKMapItem alloc] initWithPlacemark:endMP];


    // 根據請求,獲取實際路線信息
    MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {

        /**
         MKDirectionsResponse對象解析
            source :開始位置
            destination :結束位置
            routes : 路線信息 (MKRoute對象)

         MKRoute對象解析
            name : 路的名稱
            advisoryNotices : 注意警告信息
            distance : 路線長度(實際物理距離,單位是m)
            polyline : 路線對應的在地圖上的幾何線路(由很多點組成,可繪制在地圖上)
            steps : 多個行走步驟組成的數組(例如“前方路口左轉”,“保持直行”等等, MKRouteStep 對象)

        MKRouteStep對象解析
            instructions : 步驟說明(例如“前方路口左轉”,“保持直行”等等)
            transportType : 通過方式(駕車,步行等)
            polyline : 路線對應的在地圖上的幾何線路(由很多點組成,可繪制在地圖上)

        注意:
            MKRoute是一整條長路;MKRouteStep是這條長路中的每一截;

         */
        [response.routes enumerateObjectsUsingBlock:^(MKRoute * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"%@--", obj.name);
            [obj.steps enumerateObjectsUsingBlock:^(MKRouteStep * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSLog(@"%@", obj.instructions);
            }];
        }];

    }];

}

繪制導航路線

  • 路線也是一個覆蓋層

  • 理論指導:在地圖上操作覆蓋層,其實就是操作覆蓋層的數據模型

  • 添加覆蓋層:在地圖上添加覆蓋層數據模型

  • 刪除覆蓋層:在地圖上移除覆蓋層數據模型

    • 1.創建路線覆蓋層模型,并添加到地圖上

      // 繪制線路
      - (void)drawMapLine:(id <MKOverlay>)overlay
      {
          /**
           注意:這里不像添加大頭針那樣,只要我們添加了大頭針模型,默認就會在地圖上添加系統的大頭針視圖
           添加覆蓋層,需要我們實現對應的代理方法,在代理方法中返回對應的覆蓋層
           */
          [self.mapView addOverlay:overlay];
      
          /** 補充測試:添加一個圓形覆蓋層 */
      //    MKCircle *circle = [MKCircle circleWithCenterCoordinate:self.mapView.centerCoordinate radius:1000000];
      //    [self.mapView addOverlay:circle];
      }
      
    • 2.利用地圖的代理方法,返回對應的圖層渲染

      -(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
          // 創建折線渲染對象
          if ([overlay isKindOfClass:[MKPolyline class]]) {
               MKPolylineRenderer *lineRenderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
              // 設置線寬
              lineRenderer.lineWidth = 6;
              // 設置線顏色
              lineRenderer.strokeColor = [UIColor redColor];
              return lineRenderer;
          }
          // 創建圓形區域渲染對象
          //    if ([overlay isKindOfClass:[MKCircle class]]) {
          //        MKCircleRenderer *circleRender = [[MKCircleRenderer alloc] initWithOverlay:overlay];
          //        circleRender.fillColor = [UIColor cyanColor];
          //        circleRender.alpha = 0.6;
          //        return circleRender;
          //    }
          return nil;
      
      }
      
      
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容