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