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;
      
      }
      
      
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容