iOS地图开发-基本使用
2016-04-17 13:15
639 查看
地图的基本使用
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;
2.设置地图的其他属性(操作项)
注意:设置对应属性时,注意该属性是从哪个系统版本开始引入的,做好不同系统版本的适配// 是否可以缩放 self.customMapView.zoomEnabled = NO; // 是否可以滚动 self.customMapView.scrollEnabled = NO; // 是否可以旋转 self.customMapView.rotateEnabled = NO; // 是否显示3D self.customMapView.pitchEnabled = NO;
3.设置地图其他属性
// 是否显示指南针 self.customMapView.showsCompass = YES; // 是否显示比例尺 self.customMapView.showsScale = YES; // 是否显示交通 self.customMapView.showsTraffic = YES; // 是否显示建筑物 self.customMapView.showsBuildings = YES;
4.设置地图的用户追踪模式
1.创建CLLocationManager对象请求授权
-(CLLocationManager *)locationM { if (!_locationM) { _locationM = [[CLLocationManager alloc] init]; if ([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]) { [_locationM requestAlwaysAuthorization]; } } return _locationM; }
2.设置地图的用户追踪模式
/** MKUserTrackingModeNone = 0, // 不跟随 MKUserTrackingModeFollow, // 跟随用户位置 MKUserTrackingModeFollowWithHeading, // 跟随用户位置,并跟随用户方向 */ [self locationM]; self.customMapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
地图中级使用
1.查看当前用户位置信息
设置地图代理,并实现代理方法,在代理方法中获取用户当前位置(注意iOS8.0之后要请求授权)将地图显示中心调整为用户当前所在位置(iOS之前,地图不会自动移动到用户所在位置)
调整当前地图显示的区域(可使用对应代理方法查看当前地图跨度然后调整到合适的跨度即可)
-(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); }
大头针基本使用
在地图上操作大头针,实际上就是操作大头针数据模型添加大头针就是添加大头针数据模型
删除大头针就是删除大头针模型
实现步骤
添加一个/多个大头针
自定义大头针模型(需要遵循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
创建自定义大头针模型,并添加到地图上
-(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];
自定义大头针
添加大头针数据时,其实地图会调用代理方法查找对应的大头针视图,如果没有找到,就会使用系统默认的大头针视图模拟系统大头针实现方案,并对大头针进行部分自定义
(弹出标注, 修改大头针颜色, 设置大头针从天而降, 设置大头针可以被拖拽)
- (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; }
自定义大头针
- (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; }
大头针图标,大头针标注,左侧视图,右侧视图,详情视图,等;
选中和取消选中大头针时的代理方法
// 点击标注 - (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; }
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 百度地图经纬度转换到腾讯地图/Google 对应的经纬度
- Windows下C#的GUI窗口程序中实现调用Google Map的实例
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用中UISearchDisplayController搜索效果的用法
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- 基于JavaScript实现高德地图和百度地图提取行政区边界经纬度坐标
- 在Google 地图上实现做的标记相连接
- .net平台推送ios消息的实现方法