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阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容