1.可以將需要導航的位置丟給系統自帶的APP進行導航
2.發送網絡請求到公司服務器獲取導航數據, 然後自己手動繪制導航
3.利用三方SDK實現導航(百度)
>當點擊開始導航時獲取用戶輸入的起點和終點
>利用GEO對象進行地理編碼獲取到地標對象(CLPlacemark )
>再利用獲取到的地標對象(CLPlacemark)創建MKPlacemark
>利用MKPlacemark創建起點的item
>終點和起點邏輯一樣
1.發送請求到蘋果的服務器獲取導航路線信息
2.根據服務器返回的路線信息自己繪制導航路線
代碼1
// // ViewController.m // IOS_0403_利用系統App導航 // // Created by ma c on 16/4/3. // Copyright © 2016年 博文科技. All rights reserved. // #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 - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)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.創建起點和終點 // 0.1創建起點 MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark]; MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];; // 0.2創建終點 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]; } #pragma mark - 懶加載 - (CLGeocoder *)geocoder { if (!_geocoder) { self.geocoder = [[CLGeocoder alloc] init]; } return _geocoder; } @end
代碼2
// // ViewController.m // IOS_0404_獲取導航路線信息 // // Created by ma c on 16/4/4. // Copyright © 2016年 博文科技. All rights reserved. // #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 - (void)viewDidLoad { [super viewDidLoad]; } /** * 點擊開始導航按鈕 */ - (IBAction)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 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); } } }]; } #pragma mark - 懶加載 - (CLGeocoder *)geocoder { if (!_geocoder) { self.geocoder = [[CLGeocoder alloc] init]; } return _geocoder; } @end
代碼3
// // ViewController.m // IOS_0404_繪制導航路線 // // Created by ma c on 16/4/4. // Copyright © 2016年 博文科技. All rights reserved. // #import "ViewController.h" #import <MapKit/MapKit.h> #import "HMAnnotation.h" @interface ViewController ()<MKMapViewDelegate> @property (weak, nonatomic) IBOutlet MKMapView *mapVIew; /** * 地理編碼對象 */ @property(nonatomic, strong) CLGeocoder *geocoder; - (IBAction)drawLine; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.mapVIew.delegate = self; } /** * 點擊開始導航按鈕 */ - (IBAction)drawLine { // 1.獲取用戶輸入的起點和終點 NSString *startStr = @"北京"; NSString *endStr = @"雲南"; 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]; // 添加起點的大頭針 HMAnnotation *startAnno = [[HMAnnotation alloc ] init]; startAnno.title = startCLPlacemark.locality; startAnno.subtitle = startCLPlacemark.name; startAnno.coordinate = startCLPlacemark.location.coordinate; [self.mapVIew addAnnotation:startAnno]; // 3. 獲取結束位置的地標 [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) { if (placemarks.count == 0) return; // 結束位置的地標 CLPlacemark *endCLPlacemark = [placemarks firstObject]; // 添加終點的大頭針 HMAnnotation *endAnno = [[HMAnnotation alloc ] init]; endAnno.title = endCLPlacemark.locality; endAnno.subtitle = endCLPlacemark.name; endAnno.coordinate = endCLPlacemark.location.coordinate; [self.mapVIew addAnnotation:endAnno]; // 開始導航 [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); // 3.繪制路線(本質: 往地圖上添加遮蓋) // 傳遞當前路線的幾何遮蓋給地圖, 地圖就會根據遮蓋自動繪制路線 // 當系統開始繪制路線時會調用代理方法詢問當前路線的寬度/顏色等信息 [self.mapVIew addOverlay:route.polyline]; NSArray *steps = route.steps; for (MKRouteStep *step in steps) { NSLog(@"%@ %f", step.instructions, step.distance); } } }]; } #pragma mark - MKMapViewDelegate // 過時 //- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay // 繪制路線時就會調用(添加遮蓋時就會調用) - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay { // MKOverlayRenderer *renderer = [[MKOverlayRenderer alloc] init]; // 創建一條路徑遮蓋 NSLog(@"%s", __func__); //注意, 創建線條時候,一定要制定幾何路線 MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; line.lineWidth = 1; // 路線的寬度 line.strokeColor = [UIColor redColor];// 路線的顏色 // 返回路線 return line; } #pragma mark - 懶加載 - (CLGeocoder *)geocoder { if (!_geocoder) { self.geocoder = [[CLGeocoder alloc] init]; } return _geocoder; } @end