@interface ViewController () <MKMapViewDelegate> {
//地图对象
MKMapView *_mapView;
UILabel *_userLocationLabel; //用户坐标
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createMapView];
[self createAnnotations];
//调用覆盖层
[self overLay];
[self createUI];
}
//创建UI
- (void)createUI {
_userLocationLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 64, 320, 80)];
[self.view addSubview:_userLocationLabel];
//创建BarButtonItem 这个是用户定位(跟随),参数放入一个MapView类型的地图对象
MKUserTrackingBarButtonItem *item = [[MKUserTrackingBarButtonItem alloc] initWithMapView:_mapView];
//设置导航左边BarButtonItem
self.navigationItem.leftBarButtonItem = item;
UIButton *hotSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
hotSearchButton.frame = CGRectMake(0, 64, 100, 40);
[hotSearchButton setTitle:@"热点搜索" forState:UIControlStateNormal];
[hotSearchButton addTarget:self action:@selector(hotSearch) forControlEvents:UIControlEventTouchUpInside];
[hotSearchButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[self.view addSubview:hotSearchButton];
UIButton *keywordSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
keywordSearchButton.frame = CGRectMake(100, 64, 100, 40);
[keywordSearchButton setTitle:@"关键字搜索" forState:UIControlStateNormal];
[keywordSearchButton addTarget:self action:@selector(keywordSearch) forControlEvents:UIControlEventTouchUpInside];
[keywordSearchButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[self.view addSubview:keywordSearchButton];
//添加一个长按的手势 用这个长按手势添加大头针
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
longPress.minimumPressDuration = 1;
//长按手势加入到地图
[_mapView addGestureRecognizer:longPress];
}
//长按手势的方法
- (void)longPress:(UILongPressGestureRecognizer *)longPress {
//注:一定别忘了判断
//判断长按手势状态 如果是开始的状态,就执行判断体
if (longPress.state == UIGestureRecognizerStateBegan) {
//在地图上找到CGPoint坐标(屏幕坐标)
CGPoint point = [longPress locationInView:_mapView];
//屏幕坐标转换成经纬度坐标
CLLocationCoordinate2D coordinate = [_mapView convertPoint:point toCoordinateFromView:_mapView];
//创建大头针
MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:coordinate title:@"手势加入" subTitle:@"长按手势" information:@"长按手势信息"];
//加入到地图上
[_mapView addAnnotation:annotation];
}
}
- (void)hotSearch {
//创建本地搜索请求
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
//设置搜索热点词 (自然语言)
request.naturalLanguageQuery = @"学校";
//设置搜索范围,以某个原点为中心,向外扩展一段经纬度距离范围
CLLocationCoordinate2D origionPoint = CLLocationCoordinate2DMake(36.08397, 120.37126);
//设置经纬度跨越范围
MKCoordinateSpan span = MKCoordinateSpanMake(0.3, 0.3);
//设置经纬度搜索区域
MKCoordinateRegion region = MKCoordinateRegionMake(origionPoint, span);
//将区域赋值给搜索请求对象中的region属性中
request.region = region;
//将地图移动到该区域
[_mapView setRegion:region];
//创建本地搜索对象
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
//开启搜索
[search startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
//搜索成功
//获取搜索结果
NSArray *arrResult = response.mapItems;
for (MKMapItem *item in arrResult) {
//先取出地图目的坐标对象(标记)
MKPlacemark *placeMark = item.placemark;
/*
地标里存放了位置的经纬度,以及位置的地理信息说明,如名字 街道等等
*/
//创建大头针
MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:placeMark.location.coordinate title:placeMark.name subTitle:placeMark.locality information:placeMark.locality];
//加入到地图中
[_mapView addAnnotation:annotation];
}
}else {
NSLog(@"搜索失败");
}
}];
}
//关键字搜索
- (void)keywordSearch {
//创建地理编码对象
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//正向地理编码
[geocoder geocodeAddressString:@"青岛科技大学" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error == nil) {
//解析地理位置成功
//成功后遍历数组
for (CLPlacemark *place in placemarks) {
//创建大头针
MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:place.location.coordinate title:place.name subTitle:place.locality information:place.locality];
//将大头针加入到地图
[_mapView addAnnotation:annotation];
}
}else {
NSLog(@"正向地理编码解析失败");
}
}];
}
#pragma mark - 图层覆盖 -
//这个方法调用所有的覆盖层
- (void)overLay {
//线
[self pathOverLay];
//多边形
[self polyOverLay];
//圆
[self circleOverlay];
}
//绘制圆的图层
- (void)circleOverlay {
//圆图层和annotation一样需要添加到地图上,每个图层绘制都需要实现管理图层的方法
CLLocationCoordinate2D centerLocation = CLLocationCoordinate2DMake(37.68, -96.54);
//绘制圆
MKCircle *circleOverlay = [MKCircle circleWithCenterCoordinate:centerLocation radius:10000];
//添加到地图上
[_mapView addOverlay:circleOverlay];
}
//多边形图层
- (void)polyOverLay {
//设置多边形的角的点坐标,记住一定要首尾相连
CLLocationCoordinate2D ployCoords[5] = {
CLLocationCoordinate2DMake(35.443, -77.876),
CLLocationCoordinate2DMake(36.553, -77.976),
CLLocationCoordinate2DMake(35.553, -78.876),
CLLocationCoordinate2DMake(34.443, -79.567),
CLLocationCoordinate2DMake(35.443, -77.876)
};
//创建多边形图层 传入c数组需要一个元素个数 这里是5
MKPolygon *polygonOverlay = [MKPolygon polygonWithCoordinates:ployCoords count:5];
//添加到地图上
[_mapView addOverlay:polygonOverlay];
}
//绘制线
- (void)pathOverLay {
CLLocationCoordinate2D pathCoords[6] = {
CLLocationCoordinate2DMake(33.123, -77.456),
CLLocationCoordinate2DMake(34.123, -78.456),
CLLocationCoordinate2DMake(32.123, -79.456),
CLLocationCoordinate2DMake(36.123, -71.456),
CLLocationCoordinate2DMake(35.123, -70.456),
CLLocationCoordinate2DMake(36.123, 73.456)
};
//创建图层
MKPolyline *pathOverlay = [MKPolyline polylineWithCoordinates:pathCoords count:6];
//添加到地图上
[_mapView addOverlay:pathOverlay];
}
//创建大头针的方法
- (void)createAnnotations {
//创建大头针1
MKPointAnnotation *annotation1 = [[MKPointAnnotation alloc] init];
//设置title
annotation1.title = @"不知道是哪";
//设置子title
annotation1.subtitle = @"真不知道是哪儿";
//设置大头针的经纬度坐标
annotation1.coordinate = CLLocationCoordinate2DMake(-39.89, -79.88);
//把大头针1加入到地图上
[_mapView addAnnotation:annotation1];
//创建大头针2
MKPointAnnotation *annotation2 = [[MKPointAnnotation alloc] init];
annotation2.title = @"南半球";
annotation2.subtitle = @"真是南半球";
annotation2.coordinate = CLLocationCoordinate2DMake(-80.89, 156.456);
[_mapView addAnnotation:annotation2];
//自定义方式创建大头针3
MyPointAnnotation *annotation3 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(40.5, -88.7) title:@"第一个位置" subTitle:@"这里风景优美" information:@"这里是国家级旅游景点"];
//大头针4
MyPointAnnotation *annotation4 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(37.68, -96.54) title:@"第二个位置" subTitle:@"这里有点冷" information:@"世界冰展所在地"];
//将大头针3和4一块加入到地图上 用addAnnotations
[_mapView addAnnotations:@[annotation3,annotation4]];
//将地图滚动到大头针3的位置
_mapView.centerCoordinate = annotation1.coordinate;
}
//创建地图视图的方法
- (void)createMapView {
//创建地图对象
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
//设置map的类型 或地图模式
_mapView.mapType = MKMapTypeStandard;
/*
MKMapTypeStandard = 0, 纸张地图 标准地图
MKMapTypeSatellite, 纯卫星地图
MKMapTypeHybrid, 混合式地图 描述的卫星图
*/
//设置map的初始位置
//创建地理坐标2D 需要经度和纬度
// 经度:120.366486 纬度:36.083743
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(36.083743, 120.366486);
//起始时 锁定一个矩形为1000 X 1000米的方位 ,坐标点location
_mapView.region = MKCoordinateRegionMakeWithDistance(location, 1000, 1000);
//设置地图能否放大缩小
_mapView.zoomEnabled = YES;
//设置地图能否滚动
_mapView.scrollEnabled = YES;
//设置显示用户的位置
//判断是否开始了定位服务
if ([CLLocationManager locationServicesEnabled] == YES) {
//显示用户的位置
_mapView.showsUserLocation = YES;
//设置用户的基本跟踪状态
[_mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];
/*
MKUserTrackingModeNone = 0, 不尾随 一般不设
MKUserTrackingModeFollow, 尾随用户位置,地图保存正向(北方向)
MKUserTrackingModeFollowWithHeading 随着地图旋转而尾随(地图方法和设备方法同步)
*/
}
//设置代理
_mapView.delegate = self;
//将地图加入到self.view上
[self.view addSubview:_mapView];
}
#pragma mark - 地图协议中的方法 -
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
//这里判断必须要加,这个方法在刷新时会将用户的位置也会传到这个方法里,所以需要判断,如果不是大头针就是用户坐标点(蓝点),如果是蓝点(用户坐标点) 直接返回nil
if ([annotation isKindOfClass:[MKPointAnnotation class]] == NO) {
return nil;
}
//系统方法
//类似于tableview的复用机制那个方法
// MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"];
// if (annotationView == nil) {
// //如果从队列取 没有的话,需要创建新的大头针视图
// annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"];
// //设置大头针的色彩,默认是红色,还有绿色和紫色(了解)
// annotationView.pinColor = MKPinAnnotationColorPurple;
// //设置允许显示气泡(重要)
// annotationView.canShowCallout = YES;
// //设置下坠动画 (从上往下掉下来) 默认为NO
// annotationView.animatesDrop = YES;
// //设置是佛可以拖拽
// annotationView.draggable = YES;
//
// }else {
//
// //如果有空闲,拿队列里空闲的view 然后显示大头针
// annotationView.annotation = annotation;
//
// }
//自定义
MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotationView"];
if (annotationView == nil) {
annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomAnnotationView"];
}else {
annotationView.annotation = annotation;
}
return annotationView;
}
//管理图层视图
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolyline class]] == YES) {
MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
//线的宽度
line.lineWidth = 2;
//设置线的颜色
line.strokeColor = [UIColor blueColor];
return line;
}else if([overlay isKindOfClass:[MKPolygon class]] == YES) {
MKPolygonRenderer *poly = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
//设置线的宽度
poly.lineWidth = 1;
//设置边缘颜色
poly.strokeColor = [UIColor greenColor];
//设置填充颜色
poly.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
return poly;
}else if([overlay isKindOfClass:[MKCircle class]] == YES) {
//创建圆视图 所有的视图都是overlay添加到构造方法参数
MKCircleRenderer *circle = [[MKCircleRenderer alloc] initWithOverlay:overlay];
//设置边缘宽度
circle.lineWidth = 1;
//设置边缘颜色
circle.strokeColor = [UIColor redColor];
//设置填充颜色 透明度0.4
circle.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
return circle;
}
return nil;
}
//完成更新用户定位
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
_userLocationLabel.text = [NSString stringWithFormat:@"用户位置:%.5f,%.5f",userLocation.coordinate.latitude,userLocation.coordinate.longitude];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
#import <MapKit/MapKit.h>
#import "MyPointAnnotation.h" //导入自定义的大头针
@interface MyAnnotationView : MKPinAnnotationView {
MyPointAnnotation *myPointAnnotation;
}
@end