1.可以将需要导航的位置丢给系统自带的APP进行导航
2.发送网络请求到公司服务器获取导航数据, 然后自己手动绘制导航
3.利用三方SDK实现导航(百度)
>当点击开始导航时获取用户输入的起点和终点
>利用GEO对象进行地理编码获取到地标对象(CLPlacemark )
>再利用获取到的地标对象(CLPlacemark)创建MKPlacemark
>利用MKPlacemark创建起点的item
>终点和起点逻辑一样
1.发送请求到苹果的服务器获取导航路线信息
2.根据服务器返回的路线信息自己绘制导航路线
代码1
1 // 2 // ViewController.m 3 // IOS_0403_利用系统App导航 4 // 5 // Created by ma c on 16/4/3. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import<MapKit/MapKit.h> 11 12 @interface ViewController () 13 14 - (IBAction)startNavigation; 15 /** 16 * 开始位置 17 */ 18 @property (weak, nonatomic) IBOutlet UITextField *startField; 19 /** 20 * 结束位置 21 */ 22 @property (weak, nonatomic) IBOutlet UITextField *endField; 23 /** 24 * 地理编码对象 25 */ 26 @property(nonatomic, strong) CLGeocoder *geocoder; 27 28 @end 29 30 @implementation ViewController 31 32 - (void)viewDidLoad { 33 [super viewDidLoad]; 34 35 } 36 37 - (IBAction)startNavigation 38 { 39 // 1.获取用户输入的起点和终点 40 NSString *startStr = self.startField.text; 41 NSString *endStr = self.endField.text; 42 if (startStr == nil || startStr.length == 0 || 43 endStr == nil || endStr.length == 0) { 44 NSLog(@"请输入起点或者终点"); 45 return; 46 } 47 48 // 2.利用GEO对象进行地理编码获取到地标对象(CLPlacemark ) 49 // 2.1获取开始位置的地标 50 [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) { 51 if (placemarks.count == 0) return; 52 53 // 开始位置的地标 54 CLPlacemark *startCLPlacemark = [placemarks firstObject]; 55 56 57 // 3. 获取结束位置的地标 58 [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) { 59 60 if (placemarks.count == 0) return; 61 62 // 结束位置的地标 63 CLPlacemark *endCLPlacemark = [placemarks firstObject]; 64 65 // 开始导航 66 [self startNavigationWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark]; 67 }]; 68 69 }]; 70 } 71 72 /** 73 * 开始导航 74 * 75 * @param startCLPlacemark 起点的地标 76 * @param endCLPlacemark 终点的地标 77 */ 78 - (void)startNavigationWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark 79 { 80 81 // 0.创建起点和终点 82 // 0.1创建起点 83 MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark]; 84 MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];; 85 86 // 0.2创建终点 87 MKPlacemark *endPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark]; 88 MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endPlacemark]; 89 90 // 1. 设置起点和终点数组 91 NSArray *items = @[startItem, endItem]; 92 93 94 // 2.设置启动附加参数 95 NSMutableDictionary *md = [NSMutableDictionary dictionary]; 96 // 导航模式(驾车/走路) 97 md[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving; 98 // 地图显示模式 99 // md[MKLaunchOptionsMapTypeKey] = @(MKMapTypeHybrid); 100 101 102 // 只要调用MKMapItem的open方法, 就可以打开系统自带的地图APP进行导航 103 // Items: 告诉系统地图APP要从哪到哪 104 // launchOptions: 启动系统自带地图APP的附加参数(导航的模式/是否需要先交通状况/地图的模式/..) 105 [MKMapItem openMapsWithItems:items launchOptions:md]; 106 } 107 108 #pragma mark - 懒加载 109 - (CLGeocoder *)geocoder 110 { 111 if (!_geocoder) { 112 self.geocoder = [[CLGeocoder alloc] init]; 113 } 114 return _geocoder; 115 } 116 117 @end
代码2
1 // 2 // ViewController.m 3 // IOS_0404_获取导航路线信息 4 // 5 // Created by ma c on 16/4/4. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import <MapKit/MapKit.h> 11 12 @interface ViewController () 13 14 - (IBAction)startNavigation; 15 /** 16 * 开始位置 17 */ 18 @property (weak, nonatomic) IBOutlet UITextField *startField; 19 /** 20 * 结束位置 21 */ 22 @property (weak, nonatomic) IBOutlet UITextField *endField; 23 /** 24 * 地理编码对象 25 */ 26 @property(nonatomic, strong) CLGeocoder *geocoder; 27 28 @end 29 30 @implementation ViewController 31 32 - (void)viewDidLoad { 33 [super viewDidLoad]; 34 35 } 36 /** 37 * 点击开始导航按钮 38 */ 39 - (IBAction)startNavigation 40 { 41 // 1.获取用户输入的起点和终点 42 NSString *startStr = self.startField.text; 43 NSString *endStr = self.endField.text; 44 if (startStr == nil || startStr.length == 0 || 45 endStr == nil || endStr.length == 0) { 46 NSLog(@"请输入起点或者终点"); 47 return; 48 } 49 50 // 2.利用GEO对象进行地理编码获取到地标对象(CLPlacemark ) 51 // 2.1获取开始位置的地标 52 [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) { 53 if (placemarks.count == 0) return; 54 55 // 开始位置的地标 56 CLPlacemark *startCLPlacemark = [placemarks firstObject]; 57 58 59 // 3. 获取结束位置的地标 60 [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) { 61 62 if (placemarks.count == 0) return; 63 64 // 结束位置的地标 65 CLPlacemark *endCLPlacemark = [placemarks firstObject]; 66 67 // 开始导航 68 [self startDirectionsWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark]; 69 }]; 70 71 }]; 72 } 73 74 /** 75 * 发送请求获取路线相信信息 76 * 77 * @param startCLPlacemark 起点的地标 78 * @param endCLPlacemark 终点的地标 79 */ 80 - (void)startDirectionsWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark 81 { 82 83 /* 84 MKDirectionsRequest:说清楚:从哪里 --> 到哪里 85 MKDirectionsResponse:从哪里 --> 到哪里 :的具体路线信息 86 */ 87 88 // -1.创建起点和终点对象 89 // -1.1创建起点对象 90 MKPlacemark *startMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark]; 91 MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startMKPlacemark]; 92 93 // -1.2创建终点对象 94 MKPlacemark *endMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark]; 95 MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endMKPlacemark]; 96 97 98 // 0.创建request对象 99 MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init]; 100 // 0.1设置起点 101 request.source = startItem; 102 // 0.2设置终点 103 request.destination = endItem; 104 105 106 107 // 1.发送请求到苹果的服务器获取导航路线信息 108 // 接收一个MKDirectionsRequest请求对象, 我们需要在该对象中说清楚: 109 // 从哪里 --> 到哪里 110 MKDirections *directions = [[MKDirections alloc] initWithRequest:request]; 111 // 2.计算路线信息, 计算完成之后会调用blcok 112 // 在block中会传入一个响应者对象(response), 这个响应者对象中就存放着路线信息 113 [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { 114 115 116 // 打印获取到的路线信息 117 // 2.1获取所有的路线 118 NSArray *routes = response.routes; 119 for (MKRoute *route in routes) { 120 NSLog(@"%f千米 %f小时", route.distance / 1000, route.expectedTravelTime/ 3600); 121 122 NSArray *steps = route.steps; 123 for (MKRouteStep *step in steps) { 124 NSLog(@"%@ %f", step.instructions, step.distance); 125 } 126 127 } 128 }]; 129 } 130 131 #pragma mark - 懒加载 132 - (CLGeocoder *)geocoder 133 { 134 if (!_geocoder) { 135 self.geocoder = [[CLGeocoder alloc] init]; 136 } 137 return _geocoder; 138 } 139 140 141 @end
代码3
1 // 2 // ViewController.m 3 // IOS_0404_绘制导航路线 4 // 5 // Created by ma c on 16/4/4. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import <MapKit/MapKit.h> 11 #import "HMAnnotation.h" 12 13 @interface ViewController ()<MKMapViewDelegate> 14 15 @property (weak, nonatomic) IBOutlet MKMapView *mapVIew; 16 17 /** 18 * 地理编码对象 19 */ 20 @property(nonatomic, strong) CLGeocoder *geocoder; 21 22 - (IBAction)drawLine; 23 @end 24 25 @implementation ViewController 26 27 - (void)viewDidLoad 28 { 29 [super viewDidLoad]; 30 self.mapVIew.delegate = self; 31 } 32 33 /** 34 * 点击开始导航按钮 35 */ 36 - (IBAction)drawLine 37 { 38 // 1.获取用户输入的起点和终点 39 NSString *startStr = @"北京"; 40 NSString *endStr = @"云南"; 41 if (startStr == nil || startStr.length == 0 || 42 endStr == nil || endStr.length == 0) { 43 NSLog(@"请输入起点或者终点"); 44 return; 45 } 46 47 // 2.利用GEO对象进行地理编码获取到地标对象(CLPlacemark ) 48 // 2.1获取开始位置的地标 49 [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) { 50 if (placemarks.count == 0) return; 51 52 // 开始位置的地标 53 CLPlacemark *startCLPlacemark = [placemarks firstObject]; 54 55 // 添加起点的大头针 56 HMAnnotation *startAnno = [[HMAnnotation alloc ] init]; 57 startAnno.title = startCLPlacemark.locality; 58 startAnno.subtitle = startCLPlacemark.name; 59 startAnno.coordinate = startCLPlacemark.location.coordinate; 60 [self.mapVIew addAnnotation:startAnno]; 61 62 // 3. 获取结束位置的地标 63 [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) { 64 65 if (placemarks.count == 0) return; 66 67 // 结束位置的地标 68 CLPlacemark *endCLPlacemark = [placemarks firstObject]; 69 70 // 添加终点的大头针 71 HMAnnotation *endAnno = [[HMAnnotation alloc ] init]; 72 endAnno.title = endCLPlacemark.locality; 73 endAnno.subtitle = endCLPlacemark.name; 74 endAnno.coordinate = endCLPlacemark.location.coordinate; 75 [self.mapVIew addAnnotation:endAnno]; 76 77 // 开始导航 78 [self startDirectionsWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark]; 79 }]; 80 81 }]; 82 } 83 84 /** 85 * 发送请求获取路线相信信息 86 * 87 * @param startCLPlacemark 起点的地标 88 * @param endCLPlacemark 终点的地标 89 */ 90 - (void)startDirectionsWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark 91 { 92 93 /* 94 MKDirectionsRequest:说清楚:从哪里 --> 到哪里 95 MKDirectionsResponse:从哪里 --> 到哪里 :的具体路线信息 96 */ 97 98 // -1.创建起点和终点对象 99 // -1.1创建起点对象 100 MKPlacemark *startMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark]; 101 MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startMKPlacemark]; 102 103 // -1.2创建终点对象 104 MKPlacemark *endMKPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark]; 105 MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endMKPlacemark]; 106 107 108 // 0.创建request对象 109 MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init]; 110 // 0.1设置起点 111 request.source = startItem; 112 // 0.2设置终点 113 request.destination = endItem; 114 115 116 117 // 1.发送请求到苹果的服务器获取导航路线信息 118 // 接收一个MKDirectionsRequest请求对象, 我们需要在该对象中说清楚: 119 // 从哪里 --> 到哪里 120 MKDirections *directions = [[MKDirections alloc] initWithRequest:request]; 121 // 2.计算路线信息, 计算完成之后会调用blcok 122 // 在block中会传入一个响应者对象(response), 这个响应者对象中就存放着路线信息 123 [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { 124 125 126 // 打印获取到的路线信息 127 // 2.1获取所有的路线 128 NSArray *routes = response.routes; 129 for (MKRoute *route in routes) { 130 NSLog(@"%f千米 %f小时", route.distance / 1000, route.expectedTravelTime/ 3600); 131 132 // 3.绘制路线(本质: 往地图上添加遮盖) 133 // 传递当前路线的几何遮盖给地图, 地图就会根据遮盖自动绘制路线 134 // 当系统开始绘制路线时会调用代理方法询问当前路线的宽度/颜色等信息 135 [self.mapVIew addOverlay:route.polyline]; 136 137 NSArray *steps = route.steps; 138 for (MKRouteStep *step in steps) { 139 NSLog(@"%@ %f", step.instructions, step.distance); 140 } 141 142 } 143 }]; 144 } 145 146 #pragma mark - MKMapViewDelegate 147 148 // 过时 149 //- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay 150 151 // 绘制路线时就会调用(添加遮盖时就会调用) 152 - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay 153 { 154 // MKOverlayRenderer *renderer = [[MKOverlayRenderer alloc] init]; 155 // 创建一条路径遮盖 156 NSLog(@"%s", __func__); 157 //注意, 创建线条时候,一定要制定几何路线 158 MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; 159 line.lineWidth = 1; // 路线的宽度 160 line.strokeColor = [UIColor redColor];// 路线的颜色 161 162 // 返回路线 163 return line; 164 } 165 166 #pragma mark - 懒加载 167 - (CLGeocoder *)geocoder 168 { 169 if (!_geocoder) { 170 self.geocoder = [[CLGeocoder alloc] init]; 171 } 172 return _geocoder; 173 } 174 175 176 177 @end