iOS系统导航/自绘制导航路线

系统自带导航

/**
 系统自带导航
 当前位置导航到目的地
 1.根据目的地进行地理编码
 2.把当前位置和目的地封装成MKMapItem对象
 3.使用 MKMapItem openMapsWithItems: launchOptions: 方法进行导航
 */
@interface ViewController ()

// 目的地的输入框
@property (weak, nonatomic) IBOutlet UITextField *destinationField;

/**
 *  点击按钮之后开始导航
 */
- (IBAction)navigate;

@end

@implementation ViewController

- (IBAction)navigate {
    // 1.拿到用户输入的目的地
    NSString *destination = self.destinationField.text;
    if (destination.length == 0) {
        return;
    }
    
    // 2.地理编码
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:destination completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placemarks.count == 0 || error) return ;
        
        // 2.1.取出地理编码出的地标
        CLPlacemark *clpm = [placemarks firstObject];
        
        // 2.2.利用CLPlacemark来创建MKPlacemark
        MKPlacemark *mkpm = [[MKPlacemark alloc] initWithPlacemark:clpm];
        
        // 2.3.利用MKPlacemark来创建目的地的MKMapItem
        MKMapItem *destinationItem = [[MKMapItem alloc] initWithPlacemark:mkpm];
        
        // 2.4.拿到起点的MKMapItem
        MKMapItem *sourceItem = [MKMapItem mapItemForCurrentLocation];
        
        // 2.5.开始导航
        [self startNavigateWithSourceItem:sourceItem destinationItem:destinationItem];
    }];
}

/**
 *  开始导航
 *
 *  @param sourceItem      起点的Item
 *  @param destinationItem 终点的Item
 */
- (void)startNavigateWithSourceItem:(MKMapItem *)sourceItem destinationItem:(MKMapItem *)destinationItem
{
    // 1.将起点和终点item放入数组中
    NSArray *items = @[sourceItem, destinationItem];
    
    // 2.设置Options参数(字典)
//    MKLaunchOptionsDirectionsModeKey :导航模式
//    MKLaunchOptionsMapTypeKey:地图类型
//    MKLaunchOptionsShowsTrafficKey:是否显示交通状况
    NSDictionary *options = @{
            MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,
            MKLaunchOptionsMapTypeKey : @(MKMapTypeHybrid),
            MKLaunchOptionsShowsTrafficKey : @YES
                    };
    
    // 3.开始导航
    [MKMapItem openMapsWithItems:items launchOptions:options];
}

@end

导航自定义绘制路线

#import "ViewController.h"
#import <MapKit/MapKit.h>

/**
 根据目的地自实现绘制路线
 1.封装当前位置和目的地为MKMapItem对象
 2.MKDirectionsRequest对象包装源地址和目的地址
 3.MKDirections的对象calculateDirectionsWithCompletionHandler:方法进行绘制
 4.使用Mapview addOverlay:polyLine]添加遍历出来的线路
 6.设置mapview代理,遵守协议,并实现- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(MKPolyline *)overlay方法(当往Mapview中添加一个遮盖到地图上时会执行该方法,此时画线才能正常显示)

 */
@interface ViewController () <MKMapViewDelegate>

// 地图的View
@property (weak, nonatomic) IBOutlet MKMapView *mapView;

// 目的地的输入框
@property (weak, nonatomic) IBOutlet UITextField *destinationField;

/**
 *  点击之后开始画线
 */
- (IBAction)drawLine;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.mapView.delegate = self;
}

- (IBAction)drawLine {
    // 0.退出键盘
    [self.view endEditing:YES];
    
    // 1.获取用户输入的目的地
    NSString *destination = self.destinationField.text;
    if (destination.length == 0) {
        return;
    }
    
    // 2.地理编码
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:destination completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placemarks.count == 0 || error) return;
        
        // 2.1.获取CLPlaceMark对象
        CLPlacemark *clpm = [placemarks firstObject];
        
        // 2.2.利用CLPlacemark来创建MKPlacemark
        MKPlacemark *mkpm = [[MKPlacemark alloc] initWithPlacemark:clpm];
        
        // 2.3.创建目的地的MKMapItem对象
        MKMapItem *destinationItem = [[MKMapItem alloc] initWithPlacemark:mkpm];
        
        // 2.4.起点的MKMapItem
        MKMapItem *sourceItem = [MKMapItem mapItemForCurrentLocation];
        
        // 2.5.开始画线
        [self drawLineWithSourceItem:sourceItem destinationItem:destinationItem];
    }];
}

/**
 *  开始画线
 *
 *  @param sourceItem      起点的Item
 *  @param destinationItem 终点的Item
 */
- (void)drawLineWithSourceItem:(MKMapItem *)sourceItem destinationItem:(MKMapItem *)destinationItem
{
    // 1.创建MKDirectionsRequest对象
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
    
    // 1.1.设置起点的Item
    request.source = sourceItem;
    
    // 1.2.设置终点的Item
    request.destination = destinationItem;
    
    // 2.创建MKDirections对象
    MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
    
    // 3.请求/计算(当请求到路线信息的时候会来到该方法)
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
        // 3.1.当有错误,或者路线数量为0直接返回
        if (error || response.routes.count == 0) return;
        
        NSLog(@"%ld", response.routes.count);
        
        // 3.2.遍历所有的路线
        for (MKRoute *route in response.routes) {
            
            // 3.3.取出路线(遵守MKOverlay)
            MKPolyline *polyLine = route.polyline;
            
            // 3.4.将路线添加到地图上
            [self.mapView addOverlay:polyLine];
        }
    }];
}

/**
 *  当一个遮盖添加到地图上时会执行该方法
 *
 *  @param overlay 遵守MKOverlay的对象
 *
 *  @return 画线的渲染
 */
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(MKPolyline *)overlay
{
    MKPolylineRenderer *poly = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
    
    poly.strokeColor = [UIColor yellowColor];
    poly.lineWidth = 5.0;
    
    return poly;
}

@end
原文地址:https://www.cnblogs.com/HJiang/p/4344792.html