iOS--导航

1.系统自带App导航

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

@interface ViewController ()

- (IBAction)startNavigation;
/***  开始位置 */
@property (weak, nonatomic) IBOutlet UITextField *startField;
/***  结束位置 */
@property (weak, nonatomic) IBOutlet UITextField *endField;
/***  地理编码对象 */
@property(nonatomic, strong) CLGeocoder *geocoder;
@end

@implementation ViewController

#pragma mark - 懒加载
- (CLGeocoder *)geocoder
{
    if (!_geocoder) {
        self.geocoder = [[CLGeocoder alloc] init];
    }
    return _geocoder;
}

- (void)startNavigation
{
    // 1.获取用户输入的起点和终点
    NSString *startStr = self.startField.text;
    NSString *endStr = self.endField.text;
    if (startStr == nil || startStr.length == 0 ||
        endStr == nil || endStr.length == 0) {
        NSLog(@"请输入起点或者终点");
        return;
    }
    
    // 2.利用GEO对象进行地理编码获取到地标对象(CLPlacemark )
    // 2.1获取开始位置的地标
    [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placemarks.count == 0) return;
        
        // 开始位置的地标
        CLPlacemark *startCLPlacemark = [placemarks firstObject];
        
        
        // 3. 获取结束位置的地标
        [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) {
            
            if (placemarks.count == 0) return;
            
            // 结束位置的地标
            CLPlacemark *endCLPlacemark = [placemarks firstObject];
            
            // 开始导航
            [self startNavigationWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark];
        }];
        
    }];
}

/**
 *  开始导航
 *
 *  @param startCLPlacemark 起点的地标
 *  @param endCLPlacemark   终点的地标
 */
- (void)startNavigationWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark
{

    // 0.创建起点和终点
    MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark];
    MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];;

    MKPlacemark *endPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark];
    MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endPlacemark];
    
    // 1. 设置起点和终点数组
    NSArray *items = @[startItem, endItem];
    
    
    // 2.设置启动附加参数
    NSMutableDictionary *md = [NSMutableDictionary dictionary];
    // 导航模式(驾车/走路)
    md[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving;
    // 地图显示模式
//    md[MKLaunchOptionsMapTypeKey] = @(MKMapTypeHybrid);
    
    
    // 只要调用MKMapItem的open方法, 就可以打开系统自带的地图APP进行导航
    // Items: 告诉系统地图APP要从哪到哪
    // launchOptions: 启动系统自带地图APP的附加参数(导航的模式/是否需要先交通状况/地图的模式/..)
    [MKMapItem openMapsWithItems:items launchOptions:md];
}
@end


2.获取路线信息

需要导入MapKit框架。使用到MKDirections对象

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

@interface ViewController ()

- (IBAction)startNavigation;
/***  开始位置*/
@property (weak, nonatomic) IBOutlet UITextField *startField;
/***  结束位置*/
@property (weak, nonatomic) IBOutlet UITextField *endField;
/** * 地理编码对象*/
@property(nonatomic, strong) CLGeocoder *geocoder;

@end

@implementation ViewController
#pragma mark - 懒加载
- (CLGeocoder *)geocoder
{
    if (!_geocoder) {
        self.geocoder = [[CLGeocoder alloc] init];
    }
    return _geocoder;
}


/** 点击开始导航按钮*/
- (void)startNavigation
{
    // 1.获取用户输入的起点和终点
    NSString *startStr = self.startField.text;
    NSString *endStr = self.endField.text;
    if (startStr == nil || startStr.length == 0 ||
        endStr == nil || endStr.length == 0) {
        NSLog(@"请输入起点或者终点");
        return;
    }
    
    // 2.利用GEO对象进行地理编码获取到地标对象(CLPlacemark )
    // 2.1获取开始位置的地标
    [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placemarks.count == 0) return;
        
        // 开始位置的地标
        CLPlacemark *startCLPlacemark = [placemarks firstObject];
        
        
        // 2.2 获取结束位置的地标
        [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) {
            
            if (placemarks.count == 0) return;
            
            // 结束位置的地标
            CLPlacemark *endCLPlacemark = [placemarks firstObject];
            
            // 开始导航
            [self startDirectionsWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark];
        }];
        
    }];
}

/**
 *  发送请求获取路线相信信息
 *
 *  @param startCLPlacemark 起点的地标
 *  @param endCLPlacemark   终点的地标
 */
- (void)startDirectionsWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark
{

    /*
     MKDirectionsRequest:说清楚:从哪里 --> 到哪里
     MKDirectionsResponse:从哪里 --> 到哪里 :的具体路线信息
     */
    
    // -1.创建起点和终点对象
    // -1.1创建起点对象
    MKPlacemark *startMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark];
    MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startMKPlacemark];
    
    // -1.2创建终点对象
    MKPlacemark *endMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark];
    MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endMKPlacemark];
    
    
    // 0.创建request对象
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
    // 0.1设置起点
    request.source = startItem;
    // 0.2设置终点
    request.destination = endItem;
    
    
    
    // 1.发送请求到苹果的服务器获取导航路线信息
    // 接收一个MKDirectionsRequest请求对象, 我们需要在该对象中说清楚:
    // 从哪里 --> 到哪里
    MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
    // 2.计算路线信息, 计算完成之后会调用blcok
    // 在block中会传入一个响应者对象(response), 这个响应者对象中就存放着路线信息
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
        
        
        // 打印获取到的路线信息
        // 2.1获取所有的路线
        NSArray *routes = response.routes;
        for (MKRoute *route in routes) {
            NSLog(@"%f千米 %f小时", route.distance / 1000, route.expectedTravelTime/ 3600);
            
            NSArray *steps = route.steps;
            for (MKRouteStep *step in steps) {
                NSLog(@"%@ %f", step.instructions, step.distance);
            }
            
        }
    }];
}
@end


3.绘制路线

需要使用2.获取路线信息的方法,再添加MKMapView绘制和显示路线。需要使用MKMapViewDelegate代理

@interface ViewController ()<MKMapViewDelegate>
**还要添加大头针,导航中有大头针的详解

但在绘制路线,还有需要做以下:
            // 传递当前路线的几何遮盖给地图, 地图就会根据遮盖自动绘制路线
            // 当系统开始绘制路线时会调用代理方法询问当前路线的宽度/颜色等信息

        NSArray *routes = response.routes;
        for (MKRoute *route in routes) {
            NSLog(@"%f千米 %f小时", route.distance / 1000, route.expectedTravelTime/ 3600);
          =================
            [self.mapVIew addOverlay:route.polyline];
          =================  
绘制路线,其实就是添加遮盖
// 过时
//- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    // 创建一条路径遮盖
#warning 注意, 创建线条时候,一定要制定几何路线
    MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
    line.lineWidth = 5; // 路线的宽度
    line.strokeColor = [UIColor redColor];// 路线的颜色
    
    // 返回路线
    return line;
}
}




你可能感兴趣的:(iOS--导航)