虽然是转载的,还是说几句吧。网上百度地图导航路线规划倒是挺多的,苹果自带的高德导航确实挺少,研究了好久发现就这个讲的稍微全一点,把需要用到的类什么的都讲清楚了。不过高德有个方法可以跳转到它自己的地图上,给个起点终点自动帮你计算路线,还有文字标注,这点倒是很方便。
[MKMapItem openMapsWithItems:items launchOptions:dictM];//这个方法就是跳转到自带地图的,不用手机上安装有高德地图也可以跳转。还是把具体代码贴出来,网上其它地方有,这里就当总结一下。
/**
* 开始导航
*/
- (void)startNavigation{
//1,获取用户输入的起点终点
//2,利用GEO对象进行地理编码获取地标对象
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake([InforCenter shareInfoCenter].lantitude, [InforCenter shareInfoCenter].longitude);
CLLocation * currentLocation = [[CLLocation alloc]initWithLatitude:coords.latitude longitude:coords.longitude];
//2.1 获取开始位置的地标
[self.geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count ==0 ||error != nil) {
return ;
}
//开始位置的地标
CLPlacemark * startPlacemark = [placemarks firstObject];
//3,获得结束位置的地标
float latitude = [[NSString stringWithFormat:@"%@",self.businessDic[@"Y"]] floatValue];
float lOngitude= [[NSString stringWithFormat:@"%@",self.businessDic[@"X"]] floatValue];
CLLocationCoordinate2D coords1 = CLLocationCoordinate2DMake(latitude,longitude);
CLLocation * currentLocation1 = [[CLLocation alloc]initWithLatitude:coords1.latitude longitude:coords1.longitude];
[self.geocoder reverseGeocodeLocation:currentLocation1 completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count ==0 ||error != nil) {
return ;
}
CLPlacemark * endPlacemark = [placemarks firstObject];
//4,获得地标后开始导航
[self startNavigationWithStartPlacemark:startPlacemark endPlacemark:endPlacemark];
}];
}];
}
/**
* 利用地标位置开始设置导航
*
* @param startPlacemark 开始位置的地标
* @param endPlacemark 结束位置的地标
*/
-(void)startNavigationWithStartPlacemark:(CLPlacemark *)startPlacemark endPlacemark:(CLPlacemark*)endPlacemark
{
//0,创建起点
MKPlacemark * startMKPlacemark = [[MKPlacemark alloc]initWithPlacemark:startPlacemark];
//0,创建终点
MKPlacemark * endMKPlacemark = [[MKPlacemark alloc]initWithPlacemark:endPlacemark];
//1,设置起点位置
MKMapItem * startItem = [[MKMapItem alloc]initWithPlacemark:startMKPlacemark];
//2,设置终点位置
MKMapItem * endItem = [[MKMapItem alloc]initWithPlacemark:endMKPlacemark];
//3,起点,终点数组
NSArray * items = @[ startItem ,endItem];
//4,设置地图的附加参数,是个字典
NSMutableDictionary * dictM = [NSMutableDictionary dictionary];
//导航模式(驾车,步行)
dictM[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving;
//地图显示的模式
dictM[MKLaunchOptionsMapTypeKey] = MKMapTypeStandard;
//只要调用MKMapItem的open方法,就可以调用系统自带地图的导航
//Items:告诉系统地图从哪到哪
//launchOptions:启动地图APP参数(导航的模式/是否需要先交通状况/地图的模式/..)
[MKMapItem openMapsWithItems:items launchOptions:dictM];
}
//这里是自己计算路线,相当于把起点和终点用线连接,选择不同的模式就会有不同的路线。
- (IBAction)goSearch {
CLLocationCoordinate2D fromCoordinate = _coordinate;
CLLocationCoordinate2D toCoordinate = CLLocationCoordinate2DMake(32.010241,
118.719635);
MKPlacemark *fromPlacemark = [[MKPlacemark alloc] initWithCoordinate:fromCoordinate
addressDictionary:nil];
MKPlacemark *toPlacemark = [[MKPlacemark alloc] initWithCoordinate:toCoordinate
addressDictionary:nil];
MKMapItem *fromItem = [[MKMapItem alloc] initWithPlacemark:fromPlacemark];
MKMapItem *toItem = [[MKMapItem alloc] initWithPlacemark:toPlacemark];
[self findDirectionsFrom:fromItem
to:toItem];
}
#pragma mark - Private
- (void)findDirectionsFrom:(MKMapItem *)source
to:(MKMapItem *)destination
{
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = source;
request.destination = destination;
request.requestsAlternateRoutes = YES;
MKDirections *directiOns= [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(@"error:%@", error);
}
else {
MKRoute *route = response.routes[0];
[self.mapView addOverlay:route.polyline];
}
}];
}
}
介绍
IOS7在mapping框架中可以看到MapKit的一些改变和新增。其中一个关键的例子,新增一个API可以提供两点之间的路线指南。今天我们将建立一个简单的选择路线的应用来看一下如何使用这个API。我们也会简要的介绍一下叠加渲染的API。
请求方向指南
MapKit中我们需要许多不同的类,但通过依次使用它们会觉得非常简单的。为了查询苹果服务器方向指南集合,我们需要MKDirectionsRequest 对象的封装细节。这个类在IOS6中已经被应用使用了,能够来生成自己的行车方向指南。在IOS7已经进一步被扩展,可以允许开发者从苹果服务器中请求方向指南。
MKDirectionsRequest *directiOnsRequest= [MKDirectionsRequest new];
为了创建一个请求,我们需要设置源和目的地,两个地点都是MKMapItem 对象。这些对象都代表地图上的位置,包括它的地点以及一些元数据,比如名称,手机号码和URL。有几种方法可以用来创建这个对象,其中一种可以使用用户当前的地点;
MKMapItem *source = [MKMapItem mapItemForCurrentLocation];
如果用户第一次运行这个程序,他们将被询问是否允许使用他们当前位置:
你也可以用initWithPlacemark:方法使用自定义位置来创建一个地图item,这也引入了一个新的类。MKPlacemark代表地图上的实际位置,也就是它的经纬度。我们可以使用一个反向地理编码从CoreLocation来生成一个地标,但因为那不是本文的重点,所以我们将用一些固定的坐标创建地标。把所有的放在一起我们就可以完成一个MKDirectionsRequest 对象了。
// Make the destination CLLocationCoordinate2D destinatiOnCoords= CLLocationCoordinate2DMake(38.8977, -77.0365); MKPlacemark *destinatiOnPlacemark= [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil]; MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark]; // Set the source and destination on the request [directionsRequest setSource:source]; [directionsRequest setDestination:destination];
MKDirectionsRequest 有一些其他控制返回路线信息的属性,如下:
1、 departureDate 和arrivalDate。设置这些值,由于旅行时间的限制,将优化返回的路线,例如,会考虑到标准的路况信息。
2、 TransportType。目前苹果通过枚举值MKDirectionsTransportTypeAutomobile 或者MKDirectionsTransportTypeWalking提供步行或者驾车方式。默认值是MKDirectionsTransportTypeAny。
3、 RequestsAlternateRoutes。如果路由服务器可以找出多条合理的路线,设置YES将会返回所有路线。否则,只返回一条路线。
现在我们已经有了一个可用的请求,可以发送去请求路线。需要使用MKDirections 类,它有一个用MKDirectionsRequest对象构造的函数:
MKDirections *directiOns= [[MKDirections alloc] initWithRequest:directionsRequest];
将使用两个方法:calculateETAWithCompletionHandler:计算路线的花费的时间,calculateDirectionsWithCompletionHandler计算真实的路线。两个方法都是异步的,并有一个completion handling块。MKDirections 对象也有一个取消方法,提供给当前任何正在运行的请求。还有calculating属性,如果当前有个请求正在执行,返回为true。单个的MKDirections对象一次只能运行一个请求,额外去请求将会失败。如果你想运行多个并发的请求,你需要创建多个MKDirections对象。但注意,请求太多的话可能会导致苹果服务器因为节流返回错误。
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { // Handle the response here }];
方向指南响应
从苹果服务器回送的对象是MKDirectionsResponse,还有源和目的地,包括MKRoute对象数组。注意,这个数组只有一个对象除非我们设置setrequestsAlternateRoutes为YES。
MKRoute 对象,如它的名字,代表用户选择的两点之间的路线。它包含一些关于路线信息的属性:
1、 name:从服务器找到路线时自动生成的。它是基于路线的重要特征。
2、 advisoryNoties:字符串数组,包含一些适合生成路线的警告等诸如此类的详情。
3、 distance:是沿着路线的距离,不是位移。单位是米。
4、 expectedTravelTime:NSTimeInterval,单位秒。
5、 transportType:
6、 polyline:MKPolyline代表地图上路径。可以画在MKMapView上,下一节将会看到。
7、 steps:MKRouteStep 对象的数组,制作路线的。
其余提供给handler块的参数是NSError对象,仿造下面的块处理方向回调:
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { // Now handle the resultif (error) { NSLog(@"There was an error getting your directions"); return; } // So there wasn't an error - let's plot those routes_currentRoute = [response.routes firstObject]; [self plotRouteOnMap:_currentRoute]; }];
我们已经创建了一个实例方法在地图上绘制一个路线,下一节将会看到。
渲染polyline
我们已经收到路线的polyline,我们想把它体现到地图上。IOS7改变了地图渲染的方法,通过MKOverlayRenderer类。如果我们想做自定义形状或者非标准渲染技术,可以定义一个子类。但是,许多叠加渲染技术都是为标准用例使用的。我们想渲染一个polyline,可以使用对象MKPolylineRenderer。我们会稍后看一下何时何地创建渲染器,先看看上一节提到的plotRouteOnMap: 方法。
MKPolyline 对象代表多个段合成的一条线,遵循MKOverlay协议。也就是说,我们可以把它作为一个叠加层添加到MKMapView上,通过addOverlay:方法:
- (void)plotRouteOnMap:(MKRoute *)route { if(_routeOverlay) { [self.mapView removeOverlay:_routeOverlay]; } // Update the ivar_routeOverlay = route.polyline; // Add it to the map[self.mapView addOverlay:_routeOverlay]; }
这个方法带有MKRoute参数,通过属性mapView添加一个路线的polyline叠加层到MKMapView上。iavr变量_routeOverlay用来关联polyline。也就是说,当方法被调用时,可以移除一个已经存在的,然后用新的来代替它。
虽然我们已经添加了叠加层到地图View上,但是没有被画出来。这是因为地图不知道如何绘制这个叠加层对象,这也就是为什么要引入类MKOverlayRenderer 。当一个叠加层出现在地图view上,地图view会通过代理获取渲染器去绘制它。然后,当用户缩放和拖动地图时,渲染器就会根据不同的地图状态去绘制叠加层。
我们需要遵循MKMapViewDelegate协议,实现下面的方法来为地图view提供一个渲染器绘制polyline;
1 |
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay |
3 |
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; |
4 |
renderer.strokeColor = [UIColor redColor]; |
5 |
renderer.lineWidth = 4.0; |
我们已经获得一个有点简化了的案例,我们知道这里只会有一个叠加层,类型为MKPolyline,所以不需要任何代码去决定回调哪种渲染器。我们创建MKPolylineRenderer对象,它是MKOverlayRenderer的子类,目的是为了绘制polyline叠加层。我们设置了一些简单的属性(strokeColor 和 lineWidth),以便于可以看到叠加层,然后返回新的对象。
剩下的就是设置地图view的delegate属性,以便于当叠加层添加到地图时调用delegate里的方法:
5 |
self.mapView.delegate = self; |
搭建路由器
现在我们已经讨论了请求方向指南和获取响应的处理流程,但是没有给出太多关于本文应用的细节。虽然它没有进一步演示MapKit的细节,但是值得快速看一下它是如何构造出来的。
这个应用不是特别有用,因为它仅仅给出从当前位置到华盛顿特区的路线。应用中使用storyboard,并基于导航栏控制器。下面是app中包含的一些控制器:
1、 SCViewController。主视图。允许用户发送路线请求并当接收到响应时,把整个路线绘制到地图view上。它包含一个按钮(当接收到响应时显示)去查看详细路线,并推进下个视图控制器入栈。
2、 SCStepsViewController。这个是UITableViewController,每个cell展示路线的一段。点击cell将推进最后视图控制器入栈。
3、 SCIndividualStepViewController。展示特别的路段详情,包括地图,距离,路由服务器提供的一些介绍。
由于我们使用storyboards,每个视图控制器重写这个方法prepareForSegue:sender:,给下个视图提供展示需要的数据。例如,SCStepsViewController有一个route属性(MKRoute类型),就是在主视图跳转过来时设置的。
1 |
- ( void )prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender |
推荐阅读
-
SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ...
[详细]
蜡笔小新 2024-12-25 19:26:39
-
本文探讨了如何在 PHP 的 Eloquent ORM 中实现数据表之间的关联查询,并通过具体示例详细解释了如何将关联数据嵌入到查询结果中。这不仅提高了数据查询的效率,还简化了代码逻辑。 ...
[详细]
蜡笔小新 2024-12-25 18:14:14
-
-
本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ...
[详细]
蜡笔小新 2024-12-25 16:03:57
-
微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ...
[详细]
蜡笔小新 2024-12-25 14:08:03
-
探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ...
[详细]
蜡笔小新 2024-12-25 13:38:29
-
本文介绍了基于TCP长连接的设备管理平台的设计理念、技术选型及主要功能模块。最初,项目旨在实现简单的协议测试,但随着需求扩展,逐步演变为一个完整的前后端分离系统。 ...
[详细]
蜡笔小新 2024-12-25 09:07:38
-
本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ...
[详细]
蜡笔小新 2024-12-24 10:38:34
-
本文介绍了ArcXML配置文件的分类及其在不同服务中的应用,详细解释了地图配置文件的结构和功能,包括其在Image Service、Feature Service以及ArcMap Server中的使用方法。 ...
[详细]
蜡笔小新 2024-12-23 20:48:25
-
最近重新审视了新浪云平台(SAE)提供的服务,发现其已支持Python开发。本文将详细介绍如何利用Django框架构建一个简单的新浪微博应用,并分享开发过程中的关键步骤。 ...
[详细]
蜡笔小新 2024-12-26 13:36:52
-
本文探讨了在地理信息系统中,如何通过图层数据获取任意两条道路的交叉点坐标及其名称。文中详细介绍了实现方法和相关技术细节。 ...
[详细]
蜡笔小新 2024-12-25 12:59:41
-
本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ...
[详细]
蜡笔小新 2024-12-25 11:31:48
-
作为一名 Ember.js 新手,了解如何在路由和模型中正确加载 JSON 数据是至关重要的。本文将探讨两者之间的差异,并提供实用的建议。 ...
[详细]
蜡笔小新 2024-12-24 16:26:33
-
在现代Web应用中,当用户滚动到页面底部时,自动加载更多内容的功能变得越来越普遍。这种无刷新加载技术不仅提升了用户体验,还优化了页面性能。本文将探讨如何实现这一功能,并介绍一些实际应用案例。 ...
[详细]
蜡笔小新 2024-12-23 17:01:04
-
本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ...
[详细]
蜡笔小新 2024-12-23 13:54:13
-
历经三十年的开发,Mathematica 已成为技术计算领域的标杆,为全球的技术创新者、教育工作者、学生及其他用户提供了一个领先的计算平台。最新版本 Mathematica 12.3.1 增加了多项核心语言、数学计算、可视化和图形处理的新功能。 ...
[详细]
蜡笔小新 2024-12-22 09:34:59
-
可爱的你公馆_698
这个家伙很懒,什么也没留下!