iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS中的mapKit框架对国际化的支持非常出色。在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将介绍两个更加实用的功能的开发:线路导航与兴趣点搜索。前几篇博客的链接如下:
地图基础用法详解:http://my.oschina.net/u/2340880/blog/415360。
添加大头针与自定义标注:http://my.oschina.net/u/2340880/blog/415441。
添加地图覆盖物:http://my.oschina.net/u/2340880/blog/415611。
一、线路导航
1、从几个类的关系说起
(1)MKPlacemark
一个地点信息类,如下:
@interface MKPlacemark : CLPlacemark //初始化方法,通过给定一个经纬度和地点信息字典- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary *)addressDictionary;//国家编码@property (nonatomic, readonly) NSString *countryCode;@end
(2)MKMapItem
地点节点类,包含此节点的许多地点信息,如下:
@interface MKMapItem : NSObject//当前节点的地点信息对象@property (nonatomic, readonly) MKPlacemark *placemark;//是否是当前位置@property (nonatomic, readonly) BOOL isCurrentLocation;//节点名称@property (nonatomic, copy) NSString *name;//电话号码@property (nonatomic, copy) NSString *phoneNumber;//网址@property (nonatomic, strong) NSURL *url;//将当前位置创建为节点+ (MKMapItem *)mapItemForCurrentLocation;//由一个位置信息创建节点- (instancetype)initWithPlacemark:(MKPlacemark *)placemark;@end
(3)MKDirectionsRequest
导航请求类
@interface MKDirectionsRequest : NSObject//起点节点- (MKMapItem *)source NS_AVAILABLE(10_9, 6_0);- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0);//目的地节点- (MKMapItem *)destination NS_AVAILABLE(10_9, 6_0);- (void)setDestination:(MKMapItem *)destination NS_AVAILABLE(10_9, 7_0);@end
这个类还有一些扩展的设置属性:
@property (nonatomic) MKDirectionsTransportType transportType;
设置路线检索类型,枚举如下:
typedef NS_OPTIONS(NSUInteger, MKDirectionsTransportType) { MKDirectionsTransportTypeAutomobile = 1 << 0,//适合驾车时导航 MKDirectionsTransportTypeWalking = 1 << 1,//适合步行时导航 MKDirectionsTransportTypeAny = 0x0FFFFFFF//任何情况};
@property (nonatomic) BOOL requestsAlternateRoutes;
设置是否搜索多条线路
@property (nonatomic, copy) NSDate *departureDate;
设置出发日期
@property (nonatomic, copy) NSDate *arrivalDate;
设置到达日期
(4)MKDirections
从apple服务器获取数据的连接类
@interface MKDirections : NSObject//初始化方法- (instancetype)initWithRequest:(MKDirectionsRequest *)request NS_DESIGNATED_INITIALIZER;//开始计算线路信息- (void)calculateDirectionsWithCompletionHandler:(MKDirectionsHandler)completionHandler;//开始计算时间信息- (void)calculateETAWithCompletionHandler:(MKETAHandler)completionHandler;//取消- (void)cancel;//是否正在计算@property (nonatomic, readonly, getter=isCalculating) BOOL calculating;@end
(5)MKDirectionsResponse
线路信息结果类
@interface MKDirectionsResponse : NSObject@property (nonatomic, readonly) MKMapItem *source;//起点@property (nonatomic, readonly) MKMapItem *destination;//终点@property (nonatomic, readonly) NSArray *routes; //线路规划数组@end
(6)MKETResponse
时间信息结果类
@interface MKETAResponse : NSObject@property (nonatomic, readonly) MKMapItem *source;//起点@property (nonatomic, readonly) MKMapItem *destination;//终点@property (nonatomic, readonly) NSTimeInterval expectedTravelTime;//耗时@end
(7)MKRoute
线路信息类,导航的线路结果是这个类型的对象
@interface MKRoute : NSObject@property (nonatomic, readonly) NSString *name; //线路名称@property (nonatomic, readonly) NSArray *advisoryNotices; //注意事项@property (nonatomic, readonly) CLLocationDistance distance; //距离@property (nonatomic, readonly) NSTimeInterval expectedTravelTime;//耗时@property (nonatomic, readonly) MKDirectionsTransportType transportType; //检索的类型@property (nonatomic, readonly) MKPolyline *polyline; // 线路覆盖物@property (nonatomic, readonly) NSArray *steps; // 线路详情数组@end
(8)MKRouteStep
线路详情信息类,线路中每一步的信息都是这个类的对象
@interface MKRouteStep : NSObject@property (nonatomic, readonly) NSString *instructions; // 节点信息@property (nonatomic, readonly) NSString *notice; // 注意事项@property (nonatomic, readonly) MKPolyline *polyline; //线路覆盖物@property (nonatomic, readonly) CLLocationDistance distance; // 距离@property (nonatomic, readonly) MKDirectionsTransportType transportType; // 导航类型@end
看到上面如此多的类,你可能会觉得一头雾水,那么不用着急,类虽然繁杂,但他们之间的逻辑非常清晰,下面就通过一个例子来进行线路导航。
2、进行线路导航
- (void)viewDidLoad { [super viewDidLoad]; //地图初始化设置 mapView =[[MKMapView alloc]initWithFrame:self.view.frame]; mapView.region=MKCoordinateRegionMake(CLLocationCoordinate2DMake(39.26, 116.3), MKCoordinateSpanMake(5, 5)); mapView.mapType=MKMapTypeStandard; mapView.delegate=self; [self.view addSubview:mapView]; //导航设置 CLLocationCoordinate2D fromcoor=CLLocationCoordinate2DMake(39.26, 116.3); CLLocationCoordinate2D tocoor = CLLocationCoordinate2DMake(33.33, 113.33); //创建出发点和目的点信息 MKPlacemark *fromPlace = [[MKPlacemark alloc] initWithCoordinate:fromcoor addressDictionary:nil]; MKPlacemark *toPlace = [[MKPlacemark alloc]initWithCoordinate:tocoor addressDictionary:nil]; //创建出发节点和目的地节点 MKMapItem * fromItem = [[MKMapItem alloc]initWithPlacemark:fromPlace]; MKMapItem * toItem = [[MKMapItem alloc]initWithPlacemark:toPlace]; //初始化导航搜索请求 MKDirectionsRequest *request = [[MKDirectionsRequest alloc]init]; request.source=fromItem; request.destination=toItem; request.requestsAlternateRoutes=YES; //初始化请求检索 MKDirections *directions = [[MKDirections alloc]initWithRequest:request]; //开始检索,结果会返回在block中 [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { if (error) { NSLog(@"error:%@",error); }else{ //提取导航线路结果中的一条线路 MKRoute *route =response.routes[0]; //将线路中的每一步详情提取出来 NSArray * stepArray = [NSArray arrayWithArray:route.steps]; //进行遍历 for (int i=0; i<steparray.count; i++) { 线路的详情节点 mkroutestep * step =" stepArray[i]; //在此节点处添加一个大头针 MKPointAnnotation * point = [[M<a" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=540947cac5de81c0&k=%C4%BF%B5%C4%B5%D8&k0=%C4%BF%B5%C4%B5%D8&kdi0=0&luki=1&mcpm=0&n=10&p=baidu&q=smileking_cpr&rb=0&rs=1&seller_id=1&sid=c081dec5ca470954&ssp2=1&stid=9&t=tpclicked3_hc&td=1682280&tu=u1682280&u=http%3A%2F%2Fwww%2Eth7%2Ecn%2FProgram%2FIOS%2F201505%2F453699%2Eshtml&urlid=0" target="_blank">KPointAnnotation alloc]init]; point.coordinate=step.polyline.coordinate; point.title=step.instructions; point.subtitle=step.notice; [mapView addAnnotation:point]; //将此段线路添加到地图上 [mapView addOverlay:step.polyline]; } } }]; }//地图覆盖物的代理方法-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay{ MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; renderer.strokeColor = [UIColor redColor]; renderer.lineWidth = 4.0; return renderer;}//标注的代理方法-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation{ MKPinAnnotationView * view= [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"anno"]; view.canShowCallout=YES; return view;}
效果如下:

二、附近兴趣点检索
兴趣点检索的逻辑和导航线路检索的逻辑相似,直接通过代码来演示:
//创建一个位置信息对象,第一个参数为经纬度,第二个为纬度检索范围,单位为米,第三个为经度检索范围,单位为米 MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(tocoor, 5000, 5000); //初始化一个检索请求对象 MKLocalSearchRequest * req = [[MKLocalSearchRequest alloc]init]; //设置检索参数 req.region=region; //兴趣点关键字 req.naturalLanguageQuery=@"hotal"; //初始化检索 MKLocalSearch * ser = [[MKLocalSearch alloc]initWithRequest:req]; //开始检索,结果返回在block中 [ser startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { //兴趣点节点数组 NSArray * array = [NSArray arrayWithArray:response.mapItems]; for (int i=0; i<array.count; i++) { mkmapitem * item=array[i]; mkpointannotation * point = [[mkpointannotation alloc]init]; point.title=item.name; point.subtitle=item.phonenumber; point.coordinate=item.placemark.coordinate; [mapview addannotation:point]; } }];
效果如下:

原文链接:iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS原生地图开发进阶——使用导航和附近兴趣点检索的更多相关文章
- iOS原生地图开发指南续——大头针与自定义标注
iOS原生地图开发指南续——大头针与自定义标注 出自:http://www.sxt.cn/info-6042-u-7372.html 在上一篇博客中http://my.oschina.net/u/23 ...
- iOS原生地图开发详解
在上一篇博客中:http://my.oschina.net/u/2340880/blog/414760.对iOS中的定位服务进行了详细的介绍与参数说明,在开发中,地位服务往往与地图框架结合使用,这篇博 ...
- iOS 原生地图 开发
iOS开发有时候用到地图,不少人第一想到的是用第三方.当然有时候为了和安卓同步,可能会一起使用某一第三方.但有时候,我们是可以用原生地图开发的.上面两个示意图是原生地图的自定义开发.运行demo,将展 ...
- IOS原生地图与高德地图
原生地图 1.什么是LBS LBS: 基于位置的服务 Location Based Service 实际应用:大众点评,陌陌,微信,美团等需要用到地图或定位的App 2.定位方式 1.GPS定位 ...
- iOS原生地图与高德地图的使用
原生地图 1.什么是LBS LBS: 基于位置的服务 Location Based Service 实际应用:大众点评,陌陌,微信,美团等需要用到地图或定位的App 2.定位方式 1.GPS定位 2. ...
- iOS 原生地图地理编码与反地理编码
当我们要在App实现功能:输入地名,编码为经纬度,实现导航功能. 那么,我需要用到原生地图中的地理编码功能,而在Core Location中主要包含了定位.地理编码(包括反编码)功能. 在文件中导入 ...
- iOS 原生地图(MapKit、MKMapView)轨迹渐变
WechatIMG2.png 项目已接入高德地图,并且大部分功能已经实现好,但BOSS觉得iOS自带的地图效果更好...本着面向老板编程的思想,换之.还好,高德地图是在MapKit上封装的,大部分ap ...
- 如何初始化一个iOS原生地图
/** 初始化一个mapView 需导入 #import <MapKit/MapKit.h> - returns: 返回一个mapView对象 */ mapView = [[MKMapV ...
- React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块
尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息. ...
随机推荐
- SQL Server join介绍
介绍Inner Join(可以省略Inner,平常经常inner,就是inner join), Full Out Join,Cross Join,Left Join, Right Join区别. )) ...
- Docker: 解决Docker无法在电信网络中访问外网
在电信网络中,Docker在build和run时会无法访问外网,原因是docker的默认dns地址是8.8.8.8,由于众所周知的原因,我们需要改写这个地址,方法如下: 修改/etc/sysconfi ...
- 在Android开发中使用Ant 三:批量打包
批量打包最常用到的地方是进行产品推广时,为每个渠道打一个包.上一篇随笔中,介绍了怎样进行一次完整的打包,批量打包只要在此基础上做一次循环即可. 在打包之前要做两个准备工作,一个是读取渠道,一个是修改存 ...
- JSP基础--JAVA遇见HTML
1.手工编写第一个WEB应用程序 2.默认访问服务器网页首页欢迎界面是 index.jsp,就是网页链接访问其所在的文件夹目录,不访问这个文件,也会自动访问的.如果这个文件夹目录下没有index.js ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- 推送(PUSH)
一.本地推送 1.建立本地推送 UILocalNotification *notification = [[UILocalNotification alloc] init]; //推送的内容 noti ...
- Linux磁盘、目录、文件操作命令
0x01. Linux磁盘分区与目录结构 ① 主分区.拓展分区.逻辑分区:早期主引导扇区MBR用64B存放主分区信息,每个分区用16B,因而上限为4个主分区,后来,因分区需求,引入拓展分区(类主分区) ...
- MongoDB学习笔记——文档操作之查询
查询文档 使用db.COLLECTION_NAME.findOne()可以查询所有满足条件的第一条数据 预发格式如下: db.COLLECTION_NAME.findOne(<query> ...
- docker-2 深入了解docker
docker镜像.容器.仓库的基本概念 镜像 Docker 镜像就是一个只读的模板.例如:一个镜像可以包含一个完整的 CentOS 操作系统环境,里面仅安装了 httpd或用户需要的其它应用程序. 镜 ...
- hibernate查询方式
hibernate查询方式:1.本地SQL查询 2.HQL查询 3.QBC查询 HQL查询:是面向对象的查询语言,是使用最广的一种查询方法 QBC查询:Query by Criteria是一套接口来实 ...