(八十二)利用苹果服务器获取导航信息和绘制路径
要通过苹果的服务器获得导航数据,利用系统自带的类即可实现,先创建MKDirectionsRequest,然后利用request创建MKDirections,最后调用MKDirection对象的calculateDirectionsWithCompletionHandler:方法,该方法通过一个结构体回调,来获取导航信息。
结构体传入的参数是MKDirectionsResponse对象,其中routes包含的是路径,一般只有一条,就是从起点通往终点的路线,在route里还包含step,每个step是路径中的一小部分,利用for-in进行遍历即可。
需要注意的是,request在请求之前需要传入起点和终点,属性名为source和destination,接收MKMapItem对象,要得到MKMapItem,应该先得到MKPlacemark,要得到MKPlacemark,首先应当利用地理编码得到CLPlacemark,然后利用CLPlacemark初始化MKPlacemark。这个在上一节有讲,这里不再赘述。
- (void)startNavigation{
MKPlacemark *startMrk = [[MKPlacemark alloc] initWithPlacemark:_startMrk];
MKPlacemark *endMrk = [[MKPlacemark alloc] initWithPlacemark:_endMrk];
MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startMrk];
MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endMrk];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = startItem;
request.destination = endItem;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if(error){
return;
}
for (MKRoute *route in response.routes) {
NSLog(@"%@ %fkm %fh",route.name,route.distance / 1000,route.expectedTravelTime / 3600);
// 绘制路线,通过向地图上添加遮盖(蒙板)
// 系统开始绘制路径时,会询问路径的属性,宽度、颜色等。
[_mapView addOverlay:route.polyline];
for (MKRouteStep *step in route.steps) {
NSLog(@"%@ %f",step.instructions,step.distance);
}
}
}];
}
观察上面的代码,对于路径,可以通过mapView的addOverlay:方法传入一个MKPolyline对象即可实现向地图上添加路径。
需要注意的是,绘制路径之前系统会调用mapView的代理方法,询问路径绘制的细节,如果不实现这个方法,无法绘制路径,首先让控制器成为mapView的代理,然后实现下面的方法,设置路径样式。
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
MKPolylineRenderer *pathRender = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
pathRender.lineWidth = 6;
pathRender.lineJoin = kCGLineJoinRound;
pathRender.strokeColor = [UIColor redColor];
return pathRender;
}一般要在起点和终点放置大头针,只需要定义模型遵循MKAnnotation协议,然后创建模型,调用mapView的addAnnotation:方法即可放置大头针,样式为默认。这个方法应该在地理编码获取到终点回调时添加,下面是完整的代码。
//
// ViewController.m
// 通过苹果服务器获取导航信息
//
// Created by 11 on 7/22/15.
// Copyright (c) 2015 soulghost. All rights reserved.
//
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnotation.h"
@interface ViewController () <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet UITextField *startView;
@property (weak, nonatomic) IBOutlet UITextField *endView;
@property (strong, nonatomic) CLGeocoder *gcoder;
@property (strong, nonatomic) CLPlacemark *startMrk,*endMrk;
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_gcoder = [[CLGeocoder alloc] init];
_mapView.delegate = self;
}
- (IBAction)startBtnClick:(id)sender {
NSString *start = _startView.text;
NSString *end = _endView.text;
[_gcoder geocodeAddressString:start completionHandler:^(NSArray *placemarks, NSError *error) {
if(placemarks.count) _startMrk = [placemarks firstObject];
else return;
[_gcoder geocodeAddressString:end completionHandler:^(NSArray *placemarks, NSError *error) {
if(placemarks.count) _endMrk = [placemarks firstObject];
else return;
[self startNavigation];
// 添加起点和终点的大头针
MyAnnotation *startAnnotation = [[MyAnnotation alloc] init];
startAnnotation.title = _startMrk.locality;
startAnnotation.subtitle = _startMrk.name;
startAnnotation.coordinate = _startMrk.location.coordinate;
[_mapView addAnnotation:startAnnotation];
MyAnnotation *endAnnotation = [[MyAnnotation alloc] init];
endAnnotation.title = _endMrk.locality;
endAnnotation.subtitle = _endMrk.name;
endAnnotation.coordinate = _endMrk.location.coordinate;
[_mapView addAnnotation:endAnnotation];
}];
}];
}
- (void)startNavigation{
MKPlacemark *startMrk = [[MKPlacemark alloc] initWithPlacemark:_startMrk];
MKPlacemark *endMrk = [[MKPlacemark alloc] initWithPlacemark:_endMrk];
MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startMrk];
MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endMrk];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = startItem;
request.destination = endItem;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if(error){
return;
}
for (MKRoute *route in response.routes) {
NSLog(@"%@ %fkm %fh",route.name,route.distance / 1000,route.expectedTravelTime / 3600);
// 绘制路线,通过向地图上添加遮盖(蒙板)
// 系统开始绘制路径时,会询问路径的属性,宽度、颜色等。
[_mapView addOverlay:route.polyline];
for (MKRouteStep *step in route.steps) {
NSLog(@"%@ %f",step.instructions,step.distance);
}
}
}];
}
// 绘制路径的样式
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
MKPolylineRenderer *pathRender = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
pathRender.lineWidth = 6;
pathRender.lineJoin = kCGLineJoinRound;
pathRender.strokeColor = [UIColor redColor];
return pathRender;
}
@end
浙公网安备 33010602011771号