前々から実装しようと思っていたルート検索機能を実装してみました。
目的地と現在地の座標さえ分かれば実装できます。
作ってみたアプリはこんな感じ。
目的地のピンをタップして、経路ボタンを押すとルートが表示されるようにしました。
所要時間がトーストで表示されるようにしました。
コードは以下の通り。
func showRoute(dest: CLLocation) { let sourcePlaceMark = MKPlacemark(coordinate: currentLocation.coordinate) let destinationPlaceMark = MKPlacemark(coordinate: dest.coordinate) let directionRequest = MKDirections.Request() directionRequest.source = MKMapItem(placemark: sourcePlaceMark) directionRequest.destination = MKMapItem(placemark: destinationPlaceMark) directionRequest.transportType = .walking let directions = MKDirections(request: directionRequest) directions.calculate { (response, error) in guard let directionResonse = response else { if let error = error { print("we have error getting directions==\(error.localizedDescription)") } return } let route = directionResonse.routes[0] self.route = route self.dispMap.addOverlay(route.polyline, level: .aboveRoads) let time = route.expectedTravelTime / 60 self.showToast(message: "所要時間は「" + String(time.rounded()) + "」分です。", font: .systemFont(ofSize: 12.0)) } }
ルート検索した時に縮尺を変える処理が参考記事には書いてありましたが、縮尺変更は使いづらかったので消しました。
`MKDirections`を使ってリクエストを投げるとAppleのサーバから目的までのルート情報が手に入ります。
`polyline`が目的地までのルートを表示する線です。
この線を青色で描画するためにmapViewに以下のレンダラーを追加します。
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { let renderer = MKPolylineRenderer(overlay: overlay) renderer.strokeColor = UIColor.blue renderer.lineWidth = 4.0 return renderer }
ちなみにこのレンダラーを追加したら、エミュレータで以下のエラーが出るようになりました。
Compiler error: Invalid library file
Xcodeのバグのようです。。。
実機だと出ないのですけどね。
polylineは一度書くとずっと残り続けるのでどこかのタイミングでremoveする必要があります。
ピン選択が解除された時に、経路線も削除するようにしました。
//ピンが選択解除された時に呼ばれる func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) { if self.route != nil{ self.dispMap.removeOverlay(self.route.polyline) } }