zoukankan      html  css  js  c++  java
  • IOS 地图的开发(MapKit)

    概述

    API

    MKMapView

    常用属性
    
    地图配型:mapType
    
    MKMapTypeStandard :普通地图(左图)
    MKMapTypeSatellite :卫星云图 (中图)
    MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 )
    MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0)
    MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0)
    操作项
    
    是否可缩放 zoomEnabled
    是否可滚动 scrollEnabled
    是否可旋转 rotateEnabled
    显示项
    
    是否显示指南针 showsCompass (iOS9.0)
    是否显示比例尺 showsScale (iOS9.0)
    是否显示交通 showsTraffic (iOS9.0)
    是否显示建筑 showsBuildings
    跟踪显示用户的位置(ios8-地图不会自动滚到用户所在的位置,ios8+地图会自动放大到合适比例,并显示出用户位置)
    
    MKUserTrackingModeNone :不跟踪用户的位置
    MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
    MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
    设置地图显示的区域和位置
    
    设置地图的中心点位置
    @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
    -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
    设置地图的显示区域
    @property (nonatomic) MKCoordinateRegion region;
    -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
    mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
        [self.view addSubview:mapView];
        
        
        mapView.mapType = MKMapTypeStandard;
        
        
        mapView.showsBuildings = false;
        mapView.showsScale = true;
        mapView.showsTraffic = false;
        mapView.showsCompass = false;
        
        mapView.zoomEnabled = true;//缩放
        mapView.scrollEnabled = true;//滚动
        mapView.rotateEnabled = true;//旋转
        
       
        mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;//是否显示用户的位置
        
        mapView.delegate = self;
    -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
    一个位置更改默认只会调用一次,不断监测用户的当前位置
    每次调用,都会把用户的最新位置(userLocation参数)传进来
    -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
    地图的显示区域即将发生改变的时候调用
    -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
    地图的显示区域已经发生改变的时候调用
    

      

    大头针

     anno = [[MKPointAnnotation alloc] init];
     anno.title = @"我是一个大头针";
     anno.subtitle = @"我有一个小弟叫小头";
     anno.coordinate = CLLocationCoordinate2DMake(22.568694, 113.87023);
     [mapView addAnnotation:anno];

    1.自定义大头针可以继承大头针类

    2.添加多个大头针可以使用Array

    一.自定大头针模型MKAnnotation
    二.自定义大头针控件MKAnnotationView

      ①MKAnnotationView 类似cell
      ②MKAnnotation 类似表视图里面的model
      ③- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 类似初始化cell的地方
      ④如果只添加了annotation 会自动添加一个大头针视图 pinAnnotationView

    1.点击添加大头针

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        //我们只需要添加大头针模型,剩下的就由系统帮我们做好
        //1.创建大头针模型
        //MKAnnotation *an = [[MKAnnotation alloc] init];  //这地方需要注意
        
        HMAnnotation *annotation = [[HMAnnotation alloc] init];
        //2.获取在屏幕上的点击位置
        UITouch *touch = [touches anyObject];
        //2.1 获取坐标点
        CGPoint point = [touch locationInView:self.mapView];
        //2.2 将UIKit的坐标点,转成经纬度
        CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
        
        //3.设置大头针相关属性(设置坐标)
        annotation.coordinate = coordinate;
        //3.1 设置大头针的标题
        annotation.title = @"夜黑风高我来也";
        annotation.subtitle = @"西门吹雪战队";
        
        //4.添加大头针模型
        [self.mapView addAnnotation:annotation];
    }

    2.从服务器添加大头针

    for (int i = 0; i < _fDataArray.count; i++) {
            ResModel *model = _fDataArray[i];
            CLLocationCoordinate2D center = CLLocationCoordinate2DMake([[model.loc objectForKey:@"lat"] doubleValue],[[model.loc objectForKey:@"lon"] doubleValue]);
            MKPointAnnotation *pinAnnotation = [[MKPointAnnotation alloc] init];
            pinAnnotation.coordinate = center;
            pinAnnotation.title = model.name;
            [_mapView addAnnotation:pinAnnotation];
    }

    3.自定义大头针

    #import <MapKit/MapKit.h>
    
    @interface myAnnotationView : MKAnnotationView
    
    @property (nonatomic,strong) UILabel *label;
    
    @end
    @implementation myAnnotationView
    
    - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier{
        self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
        if (self) {
            
            //        在大头针旁边(上下左右)加一个label
            self.label = [[UILabel alloc]initWithFrame:CGRectMake(-5, -20, 60, 50)];
            self.label.textColor = [UIColor blackColor];
            self.label.textAlignment = NSTextAlignmentCenter;
            self.label.font = [UIFont systemFontOfSize:10];
            self.label.lineBreakMode = 0;
            self.label.numberOfLines = 0;
            [self addSubview:self.label];
            
        }
        return self;
    }
    
    @end

    4.大头针的重用机制

    // 大头针视图的重用,大头针也存在着重用的机制,方便优化内存
    // 每次添加大头针都会调用此方法  可以设置大头针的样式
    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
        // 判断大头针位置是否在原点,如果是则不加大头针或者添加属于自己特殊图标
        if ([annotation isKindOfClass:[MKUserLocation class]]) { return nil; }
        //1.定义一个可重用标识符
        static NSString *reuseIdentifier = @"mapView";
        MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
        if (annotationView == nil) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
        }
        
        //设置可重用标识符的相关属性
        // 显示标题和副标题
        annotationView.canShowCallout = YES;
        // 设置图片(用户头像,或者商品/超市/汽车/单车等等图片)
        annotationView.image = [UIImage imageNamed:@"appStore"];
       //须导入#import "UIImageView+WebCache.h"头文件
       // [annotationView.image sd_setImageWithURL:[NSURL URLWithString:[dict valueForKey:@"icon"]] placeholderImage:[UIImage imageNamed:@"默认图片"]];
    
    
        return annotationView;
    }

    5.动画的效果

    // 已经添加了大头针模型,还没有完全渲染出来之前(mapView的代理)
    - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray<MKAnnotationView *> *)views{
        for (MKAnnotationView *annotationView in views) {
            //目标位置
            CGRect targetRect = annotationView.frame;
            //先让其在最顶上
            annotationView.frame = CGRectMake(targetRect.origin.x, 0, targetRect.size.width, targetRect.size.height);
            //最后通过动画展示到最终的目标地方
            [UIView animateWithDuration:0.3 animations:^{
                annotationView.frame = targetRect;
            }];
        }
    }

    MKMapView常用功能

    1. 地图返回到用户的位置

    方式1,设置用户的跟踪模式
    方式2,设置用户所在的区域(确定中心点,确定区域大小)

    //方式一
    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
    [self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
    //方式二
    MKCoordinateRegion region =  MKCoordinateRegionMake(self.mapView.userLocation.location.coordinate, self.mapView.region.span);
    [self.mapView setRegion:region animated:YES];

    2.放大视图

    /设置其区域
    CLLocationDegrees latitudeDelta = self.mapView.region.span.latitudeDelta * 0.5;
    CLLocationDegrees longitudeDelta = self.mapView.region.span.longitudeDelta * 0.5;
    MKCoordinateSpan changeSpan = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
        
    //设置变大
    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center, changeSpan) animated:YES];

    2.缩小视图

    //设置其区域
    //只改变区域大小,不改变中心位置
    CLLocationDegrees latitudeDelta = self.mapView.region.span.latitudeDelta * 1.5;
    CLLocationDegrees longitudeDelta = self.mapView.region.span.longitudeDelta * 1.5;
    MKCoordinateSpan changeSpan = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
        
    //设置变大
    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center, changeSpan) animated:YES];

    3.计算两点的位置

    CLLocation *location1 = [[CLLocation alloc] initWithLatitude:39.6 longitude:116.2];
    CLLocation *location2 = [[CLLocation alloc] initWithLatitude:28.5 longitude:118.3];
        
    float distance = [location1 distanceFromLocation:location2];
    NSLog(@"%f km",distance / 1000);

    MKMapView导航

     CLLocationCoordinate2D coords1 = {22.56912,113.870033};
     CLLocationCoordinate2D coords2 = {22.570555,113.871039};
     MKMapItem *currentLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coords1 addressDictionary:nil]];
     MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coords2 addressDictionary:nil]];
     NSArray *items = [NSArray arrayWithObjects:currentLocation, toLocation, nil];
        
     NSDictionary *options = @{ MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsMapTypeKey: [NSNumber numberWithInteger:MKMapTypeStandard], MKLaunchOptionsShowsTrafficKey:@YES };
        //打开苹果自身地图应用,并呈现特定的item
     [MKMapItem openMapsWithItems:items launchOptions:options];
  • 相关阅读:
    Hybrid APP基础篇(三)->Hybrid APP之Native和H5页面交互原理
    Hybrid APP基础篇(二)->Native、Hybrid、React Native、Web App方案的分析比较
    Hybrid APP基础篇(一)->什么是Hybrid App
    JavaScript筑基篇(一)->变量、值与对象
    深入Node.js的进程与子进程:从文档到实践
    深入Node模块Buffer-学会操作二进制
    深入Nodejs模块fs
    刷《一年半经验,百度、有赞、阿里面试总结》·手记
    Asp.Net Core 轻松学-被低估的过滤器
    css精灵图&字体图标
  • 原文地址:https://www.cnblogs.com/guchengfengyun/p/8128040.html
Copyright © 2011-2022 走看看