方案一:使用的是系統(tǒng)APP的導(dǎo)航(高德地圖)
- 根據(jù)用戶輸入的兩個地點進行導(dǎo)航(或者是一個目的地,再獲取用戶的位置)
- 所用到的技術(shù)點
- 地理編碼/反地理編碼
- 系統(tǒng)的MKMapItem類
- 反向逆推發(fā)進行設(shè)計實現(xiàn)(缺什么補什么)
// MARK:- 懶加載
private lazy var geoc : CLGeocoder = {
return CLGeocoder()
}()
// 在touchesBegan中進行測試
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// 根據(jù)用戶的輸入的地點進行地理編碼
geoc.geocodeAddressString("廣州") { (clpls : [CLPlacemark]?, error : NSError?) -> Void in
if error == nil {
// 判斷地標對象數(shù)組是否有值
guard let clpls = clpls else {return}
// 取出相關(guān)度最好的地標對象
guard let gzCLPL = clpls.first else {return}
self.geoc.geocodeAddressString("上海") { (clpls : [CLPlacemark]?, error : NSError?) -> Void in
if error == nil {
guard let clpls = clpls else {return}
guard let shCLPL = clpls.first else {return}
self.beginNavigation(gzCLPL, endCLPL: shCLPL)
}
}
}
}
}
// 參數(shù)兩個地標對象
func beginNavigation(startCLPL : CLPlacemark, endCLPL : CLPlacemark) {
// 設(shè)置起點
// 轉(zhuǎn)換為MKPlacemark的類型的地表對象
let startMKPL = MKPlacemark(placemark: startCLPL)
// 轉(zhuǎn)化MKMapItem
let startItem = MKMapItem(placemark: startMKPL)
// 設(shè)置終點
let endMKPL = MKPlacemark(placemark: endCLPL)
let endItem = MKMapItem(placemark: endMKPL)
// 設(shè)置起點和終點(mapItems: [MKMapItem])
let mapItems : [MKMapItem] = [startItem, endItem]
// 設(shè)置啟動項(launchOptions: )
let dict : [String : AnyObject] = [
// (鍵 : 值)的形式
// 方向模式 : 開車
MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,
// 地圖類型 :普通(Standard)
MKLaunchOptionsMapTypeKey : MKMapType.Standard.rawValue,
// 交通 :true表示顯示
MKLaunchOptionsShowsTrafficKey : true
]
// 通過設(shè)置的內(nèi)容,打開系統(tǒng)的導(dǎo)航app進行導(dǎo)航
MKMapItem.openMapsWithItems(mapItems, launchOptions: dict)
MKMapItem.openMapsWithItems(<#T##mapItems: [MKMapItem]##[MKMapItem]#>, launchOptions: <#T##[String : AnyObject]?#>)
}
方案二:發(fā)送網(wǎng)絡(luò)請求給蘋果服務(wù)器獲取導(dǎo)航路線(MKDirections)
其中也是要根據(jù)出發(fā)地和目的地來發(fā)送xing請求路線的,并根據(jù)出發(fā)地和目的地進行地理編碼/反地理編碼來得到最好的相關(guān)度的地標對象(CLPlacemark),然后將對應(yīng)的地標對象轉(zhuǎn)化為MKPlacemark類型的地標對象
// CLPlacemark類型的出發(fā)地和目的地的地標對象
func getRouteMessage(sourceCLPL : CLPlacemark, destinationCLPL : CLPlacemark ) {
// 創(chuàng)建路線請求對象
let request = MKDirectionsRequest()
// 設(shè)置起點
let sourceMKPL = MKPlacemark(placemark: sourceCLPL)
request.source = MKMapItem(placemark: sourceMKPL)
// 設(shè)置終點
let destinationMKPL = MKPlacemark(placemark: destinationCLPL)
request.destination = MKMapItem(placemark: destinationMKPL)
// 創(chuàng)建路線對象
let directions = MKDirections(request: request)
// 請求路線信息
directions.calculateDirectionsWithCompletionHandler { (response : MKDirectionsResponse?, error : NSError?) -> Void in
if error == nil {
// MKDirectionsResponse 響應(yīng)對象
// routes: [MKRoute] 所有的路線
// MKRoute
// name 路線名稱
// advisoryNotices 警告信息
// distance 整條路線的總距離
// expectedTravelTime 預(yù)期到達時間
// transportType 交通方式
// polyline : 折線數(shù)據(jù)模型,展示在地圖上幾何圖形(覆蓋層)
// steps: [MKRouteStep] :每個步驟應(yīng)該怎么走
// [MKRouteStep]
// instructions : 每一步的描述 "前方500 左轉(zhuǎn)"
// notice : 每個路線的警告
// polyline : 單個折線的數(shù)據(jù)模型
// distance : 每一步驟的距離
// transportType : 每一步驟的交通方式
guard let response = response else {return}
let routes : [MKRoute] = response.routes
for route in routes {
print(route.name,route.distance)
let steps = route.steps
for step in steps {
print(step.instructions)
}
}
}
}
- 渲染層描繪行走路線
/**
當向地圖上添加覆蓋層的時候就會調(diào)用這個代理方法,找到對應(yīng)的渲染圖層并返回
// 每一個覆蓋層的渲染圖層都是不一樣的
- parameter mapView: 地圖
- parameter overlay: 覆蓋層
- returns: 渲染圖層
*/
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
// 1.創(chuàng)建折線的渲染圖層
let polylineRender = MKPolylineRenderer(overlay: overlay)
// 2.設(shè)置線寬以及顏色
polylineRender.lineWidth = 6
polylineRender.strokeColor = UIColor.redColor()
// 3.返回對應(yīng)的渲染圖層
return polylineRender
}