美文网首页iOS 开发iOSiOS开发收集
iOS笔记-地图的基本使用

iOS笔记-地图的基本使用

作者: Developer_Yancy | 来源:发表于2016-03-07 00:51 被阅读2557次

    地图的基本使用

    • 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;
        
        }
        
        

    相关文章

      网友评论

      本文标题:iOS笔记-地图的基本使用

      本文链接:https://www.haomeiwen.com/subject/vxorkttx.html