(八十二)利用苹果服务器获取导航信息和绘制路径

要通过苹果的服务器获得导航数据,利用系统自带的类即可实现,先创建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


posted on 2015-07-23 19:36  张大大123  阅读(212)  评论(0编辑  收藏  举报

导航