Fork me on GitHub

地图处理之基本使用汇总

1. 创建之前的准备工作

  1.1  在Info.plist文件中添加下面两句话

  NSLocationAlwaysUsageDescription —> 确定定位吗?亲
  //请求的授权,除了可以在APP打开时允许定位服务,也可以在APP进入后台仍然可以使用定位服务(永久) --> 与上边一个可以二选一
  [_locationManager requestAlwaysAuthorization];
  NSLocationWhenInUseUsageDescripyion —>需要定位吗?
  //此方法请求的授权,仅限于用户在打开使用APP时允许使用系统的定位服务(在应用使用期间)
  [_locationManager requestWhenInUseAuthorization];

  1.2  导入库文件 MapKit.framework 和 CoreLocation.framework
2. 工程创建说明 ---> 使用系统自带的MKPointAnnotation、MKPinAnnotationView 及自定义  MKPointAnnotation、MKPinAnnotationView 

  以下是ViewController.m 文件

  2.1 viewDidLoad 中的加载

 1 #import "ViewController.h"
 2 #import "MapKit/MapKit.h"
 3 #import "MyPointAnnotation.h"
 4 #import "MyAnnotationView.h"
 5 
 6 @interface ViewController ()<MKMapViewDelegate> {
 7     
 8     MKMapView *_mapView;    //地图对象
 9     UILabel *_userLocationLable; //查看用户坐标
10 }
11 
12 @end
13 
14 @implementation ViewController
15 
16 - (void)viewDidLoad {
17     [super viewDidLoad];
18     
19     //调用创建地图视图的方法
20     [self createMapView];
21     //调用创建大头针的方法
22     [self createAnnotations];
23     //调用这个方法调用所有的覆盖层的方法
24     [self overLay];
25     //调用创建UI的方法
26     [self createUI];
27 }
28 
29 @end

  2.2 创建地图视图的方法

  1 //创建地图视图的方法
  2 - (void)createMapView {
  3     //创建地图对象
  4     _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
  5     //设置map的类型 或地图模式
  6     _mapView.mapType = MKMapTypeStandard;
  7     /*
  8      MKMapTypeStandard = 0, 纸张地图 标准地图
  9      MKMapTypeSatellite,    纯卫星地图
 10      MKMapTypeHybrid,       混合式地图 描述的卫星图
 11      */
 12     //设置map的初始位置
 13     //创建地理坐标2D 需要经度和纬度 如:经度:120.366486 纬度:36.083743
 14     CLLocationCoordinate2D location = CLLocationCoordinate2DMake(36.083743, 120.366486);
 15     //起始时 锁定一个矩形为1000 X 1000米的方位 ,坐标点location
 16     _mapView.region = MKCoordinateRegionMakeWithDistance(location, 1000, 1000);
 17     //设置地图能否放大缩小
 18     _mapView.zoomEnabled = YES;
 19     //设置地图能否滚动
 20     _mapView.scrollEnabled = YES;
 21     //设置显示用户的位置  先判断是否开始了定位服务
 22     if ([CLLocationManager locationServicesEnabled] == YES) {
 23         //显示用户的位置
 24         _mapView.showsUserLocation = YES;
 25         //设置用户的基本跟踪状态
 26         [_mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];
 27         
 28         /*
 29          MKUserTrackingModeNone = 0,        不尾随 一般不设
 30          MKUserTrackingModeFollow,      尾随用户位置,地图保存正向(北方向)
 31          MKUserTrackingModeFollowWithHeading 随着地图旋转而尾随(地图方向和设备方向同步)
 32          */
 33     }
 34     //设置代理 需遵守MKMapViewDelegate代理协议
 35     _mapView.delegate = self;
 36     //将地图加入到self.view上
 37     [self.view addSubview:_mapView];
 38 }
 39 
 40 #pragma mark - 地图协议中的方法 -
 41 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
 42     
 43     //这里判断必须要加,这个方法在刷新时会将用户的位置也会传到这个方法里,所以需要判断,如果不是大头针就是用户坐标点(蓝点),如果是蓝点(用户坐标点) 直接返回nil
 44     if ([annotation isKindOfClass:[MKPointAnnotation class]] == NO) {
 45         return nil;
 46     }
 47     
 48     //调用系统的方法
 49 //    MKPinAnnotationView *annotationView = [self systemMethodWithMapView:mapView andAnnotation:annotation];
 50     
 51     //调用自定义的方法
 52     MKPinAnnotationView *annotationView = [self customMethodWithMapView:mapView andAnnotation:annotation];
 53     
 54     return annotationView;
 55 }
 56 
 57 //自定义的方法
 58 - (MKPinAnnotationView *)customMethodWithMapView:(MKMapView *)mapView andAnnotation:(MKPointAnnotation *)annotation {
 59     MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotationView"];
 60     
 61     if (annotationView == nil) {
 62         
 63         
 64         annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomAnnotationView"];
 65         
 66     }else {
 67         
 68         annotationView.annotation = annotation;
 69     }
 70     
 71     
 72     
 73     return annotationView;
 74 }
 75 
 76 
 77 //系统方法
 78 - (MKPinAnnotationView *)systemMethodWithMapView:(MKMapView *)mapView andAnnotation:(MKPointAnnotation *)annotation {
 79     
 80     //    类似于tableview的复用机制那个方法
 81     MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"];
 82     if (annotationView == nil) {
 83         //如果从队列取 没有的话,需要创建新的大头针视图
 84         annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"];
 85         //设置大头针的色彩,默认是红色,还有绿色和紫色(了解)
 86         annotationView.pinColor = MKPinAnnotationColorPurple;
 87         //设置允许显示气泡(重要)
 88         annotationView.canShowCallout = YES;
 89         //设置下坠动画 (从上往下掉下来) 默认为NO
 90         annotationView.animatesDrop = YES;
 91         //设置是佛可以拖拽
 92         annotationView.draggable = YES;
 93         
 94     }else {
 95         
 96         //如果有空闲,拿队列里空闲的view 然后显示大头针
 97         annotationView.annotation = annotation;
 98         
 99     }
100     return annotationView;
101 }

  2.3  创建大头针的方法

 1 //创建大头针的方法
 2 - (void)createAnnotations {
 3     //创建大头针1
 4     MKPointAnnotation *annotation1 = [[MKPointAnnotation alloc] init];
 5     //设置title
 6     annotation1.title = @"不知道是哪";
 7     //设置子title
 8     annotation1.subtitle = @"真不知道是哪儿";
 9     //设置大头针的经纬度坐标
10     annotation1.coordinate = CLLocationCoordinate2DMake(-39.89, -79.88);
11     //把大头针1加入到地图上
12     [_mapView addAnnotation:annotation1];
13     //创建大头针2
14     MKPointAnnotation *annotation2 = [[MKPointAnnotation alloc] init];
15     annotation2.title = @"南半球";
16     annotation2.subtitle = @"真是南半球";
17     annotation2.coordinate = CLLocationCoordinate2DMake(-80.89, 156.456);
18     [_mapView addAnnotation:annotation2];
19     //自定义方式创建大头针3
20     MyPointAnnotation *annotation3 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(40.5, -88.7) title:@"第一个位置" subTitle:@"这里风景优美" information:@"这里是国家级旅游景点"];
21     //自定义方式创建大头针4
22     MyPointAnnotation *annotation4 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(37.68, -96.54) title:@"第二个位置" subTitle:@"这里有点冷" information:@"世界冰展所在地"];
23     //将大头针3和4一块加入到地图上  用addAnnotations
24     [_mapView addAnnotations:@[annotation3,annotation4]];
25     
26     //将地图滚动到大头针3的位置
27     _mapView.centerCoordinate = annotation1.coordinate;
28  
29 }

  2.4 这个方法调用所有的覆盖层的方法

  1 //这个方法调用所有的覆盖层的方法
  2 - (void)overLay {
  3     
  4     //调用绘制线的方法
  5     [self pathOverLay];
  6     
  7     //调用多边形图层的方法
  8     [self polyOverlay];
  9     
 10     //调用绘制圆的图层的方法
 11     [self circleOverlay];
 12     
 13 }
 14 
 15 //绘制圆的图层的方法
 16 - (void)circleOverlay {
 17     //圆图层和annotation一样需要添加到地图上,每个图层绘制都需要实现管理图层方法
 18     CLLocationCoordinate2D centerLocation = CLLocationCoordinate2DMake(37.68, -96.54);
 19     //绘制圆
 20     MKCircle *circleOverlay = [MKCircle circleWithCenterCoordinate:centerLocation radius:100000];
 21     //添加到地图上
 22     [_mapView addOverlay:circleOverlay];
 23     
 24 }
 25 
 26 //多边形图层的方法
 27 - (void)polyOverlay {
 28     //设置多边形的角的坐标,记住一定要首尾相连
 29     
 30     CLLocationCoordinate2D ploycoords[5]  = {
 31         CLLocationCoordinate2DMake(35.443, -77.876),
 32         CLLocationCoordinate2DMake(36.553, -77.976),
 33         CLLocationCoordinate2DMake(35.553, -79.567),
 34         CLLocationCoordinate2DMake(34.443, -79.567),
 35         CLLocationCoordinate2DMake(35.443, -77.876)
 36         
 37         
 38     };
 39     
 40     MKPolygon *polygonOverlay = [MKPolygon polygonWithCoordinates:ploycoords count:5];
 41     //添加到地图上
 42     [_mapView addOverlay:polygonOverlay];
 43 }
 44 
 45 //绘制线的方法
 46 - (void)pathOverLay {
 47     CLLocationCoordinate2D pathCoords[6] = {
 48         
 49         CLLocationCoordinate2DMake(33.123, -77.456),
 50         CLLocationCoordinate2DMake(34.123, -78.456),
 51         CLLocationCoordinate2DMake(32.123, -79.456),
 52         CLLocationCoordinate2DMake(36.123, -71.456),
 53         CLLocationCoordinate2DMake(35.123, -70.456),
 54         CLLocationCoordinate2DMake(36.123, 73.456)
 55         
 56     };
 57     
 58     //创建图层
 59     MKPolyline *pathOverlay = [MKPolyline polylineWithCoordinates:pathCoords count:6];
 60     //添加到地图上
 61     [_mapView addOverlay:pathOverlay];
 62     
 63     
 64 }
 65 
 66 //管理图层视图
 67 - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
 68     
 69     if ([overlay isKindOfClass:[MKPolyline class]] == YES) {
 70         MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
 71         //线的宽度
 72         line.lineWidth = 2;
 73         //设置线的颜色
 74         line.strokeColor = [UIColor blueColor];
 75         
 76         return line;
 77         
 78     }else if ([overlay isKindOfClass:[MKPolygon class]] == YES) {
 79         
 80         MKPolygonRenderer *poly = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
 81         //设置线宽
 82         poly.lineWidth = 1;
 83         //设置边缘颜色
 84         poly.strokeColor = [UIColor greenColor];
 85         //设置填充颜色
 86         poly.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
 87         
 88         return poly;
 89         
 90     }else if ([overlay isKindOfClass:[MKCircle class]] == YES) {
 91         
 92         //创建圆视图 所有的视图都是overlay添加到构造方法参数
 93         MKCircleRenderer *circle = [[MKCircleRenderer alloc] initWithOverlay:overlay];
 94         //设置边缘宽度
 95         circle.lineWidth = 1;
 96         //设置边缘颜色
 97         circle.strokeColor = [UIColor redColor];
 98         //设置填充颜色 透明度0.4
 99         circle.fillColor = [[UIColor greenColor] colorWithAlphaComponent:0.4];
100         
101         return circle;
102     }
103     
104     return nil;
105 }

  2.5  创建UI的方法 在创建该方法之前需要在AppDelegate.m 文件中将ViewController包装成导航控制器

  1 //创建UI的方法
  2 - (void)createUI {
  3     
  4     _userLocationLable = [[UILabel alloc] initWithFrame:CGRectMake(0, 64, 320, 80)];
  5     [self.view addSubview:_userLocationLable];
  6     //创建BarButtonItem 这个是用户定位(跟随),参数放入一个MapView类型的地图对象
  7     MKUserTrackingBarButtonItem *item = [[MKUserTrackingBarButtonItem alloc] initWithMapView:_mapView];
  8     //设置导航左边的BarButtonItem
  9     self.navigationItem.leftBarButtonItem = item;
 10     
 11     UIButton *hotSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
 12     hotSearchButton.frame = CGRectMake(0, 64, 100, 40);
 13     [hotSearchButton setTitle:@"热点搜索" forState:UIControlStateNormal];
 14     
 15     [hotSearchButton addTarget:self action:@selector(hotSeatch) forControlEvents:UIControlEventTouchUpInside];
 16     
 17     
 18     [hotSearchButton  setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
 19     
 20     [self.view addSubview:hotSearchButton];
 21     
 22     
 23     UIButton *keywordSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
 24     
 25     keywordSearchButton.frame = CGRectMake(100, 64, 100, 40);
 26     
 27     [keywordSearchButton setTitle:@"关键字搜索" forState:UIControlStateNormal];
 28     
 29     [keywordSearchButton addTarget:self action:@selector(keywordSearch) forControlEvents:UIControlEventTouchUpInside];
 30     [keywordSearchButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
 31     
 32     [self.view addSubview:keywordSearchButton];
 33     
 34     //添加一个长按的手势 用长按的手势添加大头针
 35     UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
 36     longPress.minimumPressDuration = 1;
 37     //长按手势加入到地图
 38     [_mapView addGestureRecognizer:longPress];
 39 }
 40 
 41 //长按手势执行的方法
 42 - (void)longPress:(UILongPressGestureRecognizer *)longPress {
 43     //注:一定别忘了判断
 44     //判断长按手势状态 如果是开始的状态,就执行判断题
 45     if (longPress.state == UIGestureRecognizerStateBegan) {
 46         //在地图上找到CGPoint坐标(屏幕坐标)
 47         CGPoint point = [longPress locationInView:_mapView];
 48         //屏幕坐标转成经纬度坐标
 49         CLLocationCoordinate2D coordinate = [_mapView convertPoint:point toCoordinateFromView:_mapView];
 50         //创建大头针
 51         
 52         MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:coordinate title:@"手势加入" subTitle:@"长按手势" information:@"长按手势信息"];
 53         
 54 
 55         //加入到地图上
 56         [_mapView addAnnotation:annotation];
 57         
 58     }
 59     
 60     
 61 }
 62 
 63 
 64 - (void)hotSeatch {
 65     //创建本地搜索请求
 66     MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
 67     //设置搜索热点词(自然语言)
 68     request.naturalLanguageQuery = @"学校";
 69     //设置搜索范围,以某个原点为中心,向外扩展一段经纬度距离范围
 70     CLLocationCoordinate2D origionpoint = CLLocationCoordinate2DMake(36.08397, 120.37126);
 71     //设置经纬度跨越范围
 72     MKCoordinateSpan span = MKCoordinateSpanMake(0.3, 0.3);
 73     //设置经纬度搜索区域
 74     MKCoordinateRegion region = MKCoordinateRegionMake(origionpoint, span);
 75     //将区域赋值给搜索请求对象中的region属性中
 76     request.region = region;
 77     //将地图移动到该区域
 78     [_mapView setRegion:region];
 79     
 80     //创建本地搜索对象
 81     MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
 82     //开启搜索
 83     [search startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) {
 84         
 85         if (error == nil) {
 86             
 87             //搜索成功
 88             //获取搜索结果
 89             NSArray *arrResult = response.mapItems;
 90             
 91             for (MKMapItem *item in arrResult) {
 92                 
 93                 //先取出地图目的坐标对象(标记)
 94                 MKPlacemark *placeMark = item.placemark;
 95                 /*
 96                  地标里存放的经纬度,以及位置的地理信息说明,如名字、街道等等
 97                  */
 98                 //创建大头针
 99                 MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:placeMark.location.coordinate title:placeMark.name subTitle:placeMark.locality information:placeMark.locality];
100                 
101                 //加入到地图中
102                 [_mapView addAnnotation:annotation];
103             }
104             
105             
106         }else {
107             NSLog(@"搜索失败");
108             
109         }
110         
111     }];
112     
113 }
114 
115 //关键字搜索
116 - (void)keywordSearch {
117     //创建地理编码
118     CLGeocoder *geocoder = [[CLGeocoder alloc] init];
119     //正向地理编码
120     [geocoder geocodeAddressString:@"青岛科技大学" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
121         
122         if (error == nil) {
123             //解析地理位置成功
124             //成功后遍历数组
125             for (CLPlacemark *place in placemarks) {
126                 
127                 //创建大头针
128                 
129                 MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:place.location.coordinate title:place.name subTitle:place.locality information:place.locality];
130                 //将大头针加入到地图
131                 [_mapView addAnnotation:annotation];
132                 
133             }
134             
135         }else {
136             
137             NSLog(@"正向地理编码解析失败");
138         }
139         
140         
141     }];
142     
143 }
144 
145 
146 //完成更新用户定位
147 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
148     
149     
150     _userLocationLable.text = [NSString stringWithFormat:@"用户位置: %.5f, %.5f",userLocation.coordinate.latitude, userLocation.coordinate.longitude];
151     NSLog(@"%@",_userLocationLable.text);
152     
153 }

3. 自定义 MyPointAnnotation 工程如下:

 1 MyPointAnnotation.h文件
 2 
 3 #import <MapKit/MapKit.h>
 4 
 5 @interface MyPointAnnotation : MKPointAnnotation
 6 
 7 /** 大头针信息  */
 8 @property(nonatomic, copy) NSString *information;
 9 
10 //构造方法
11 - (id)initWithCoorDinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subTitle:(NSString *)subTitle information:(NSString *)information;
12 
13 @end
14 
15 MyPointAnnotation.m文件
16 
17 #import "MyPointAnnotation.h"
18 
19 @implementation MyPointAnnotation
20 
21 - (id)initWithCoorDinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subTitle:(NSString *)subTitle information:(NSString *)information {
22     
23     if (self = [super init]) {
24         //标题
25         self.title = title;
26         //子标题
27         self.subtitle = subTitle;
28         //坐标
29         self.coordinate = coordinate;
30         //信息
31         self.information = information;
32     }
33     return self;
34 }
35 
36 @end

4. 自定义 MyAnnotationView工程如下:

 1 MyAnnotationView.h文件
 2 #import <MapKit/MapKit.h>
 3 #import "MyPointAnnotation.h" //导入自定义的大头针
 4 @interface MyAnnotationView : MKPinAnnotationView {
 5     
 6     MyPointAnnotation *myPointAnnotation;
 7     
 8 }
 9 
10 //静态图片需要继承这个
11 //@interface MyAnnotationView : MKAnnotationView {
12 //    MyPointAnnotation *myPointAnnotation;
13 //}
14 
15 @end
16 
17 
18 MyAnnotationView.m文件
19 #import "MyAnnotationView.h"
20 
21 @implementation MyAnnotationView
22 
23 - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
24     if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
25         //保存参数-传过来的大头针
26         myPointAnnotation = annotation;
27         
28         //创建图片
29         UIImage *image = [UIImage imageNamed:@"pink"];
30         
31         //这种方式只适合静态图片 ,不适合动态和拖拽动态功能,它们有冲突 需要更改一下.h文件中的继承
32         //这种方式继承MKAnnotationView 否则没有效果
33         //        NSData *imageData = UIImagePNGRepresentation(image);
34         //        //处理imageData 比例5
35         //        image = [UIImage imageWithData:imageData scale:5];
36         //        //修改当前视图的大小
37         //        self.frame = CGRectMake(0, 0, 40, 40);
38         //        //设置图片
39         //        self.image = image;
40         //        //设置填充模式 按比例填满
41         //        self.contentMode = UIViewContentModeScaleToFill;
42         
43         
44         UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(-15, -5, 45, 45)];
45         imageView.image = image;
46         [self addSubview:imageView];
47         
48         //允许气泡弹出
49         self.canShowCallout = YES;
50         //拖拽
51         self.draggable = YES;
52         //下坠动画
53         self.animatesDrop = YES;
54         
55         
56         UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
57         [leftButton addTarget:self action:@selector(leftButton) forControlEvents:UIControlEventTouchUpInside];
58         //设置左边访问view
59         self.leftCalloutAccessoryView = leftButton;
60         
61         UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
62         [rightButton addTarget:self action:@selector(rightButton) forControlEvents:UIControlEventTouchUpInside];
63         //设置右边访问view
64         self.rightCalloutAccessoryView = rightButton;
65         
66     }
67     return self;
68 }
69 
70 
71 - (void)leftButton {
72     NSLog(@"leftButton:%@",myPointAnnotation.title);
73 }
74 
75 - (void)rightButton {
76     NSLog(@"rightButton:%@",myPointAnnotation.information);
77 }
78 
79 @end
posted @ 2016-05-05 21:10  极度恐慌_JG  阅读(604)  评论(0编辑  收藏  举报