MKDirectionsで公共交通機関(transit)の所要時間を取得する
はじめに
先日、MapKitのMKDirections
を使用した実装でハマった点があったので、備忘録として記事にします。MKDirections
を使用すると、出発地から目的地へのルートや距離・所要時間を計算できます。
公共交通機関(transit)を指定するとエラーになる
実現したいことは、現在地から目的地への公共交通機関利用時の所要時間を取得することです。MKDirections
のcalculate
メソッドを使用することでそれを実現できそうだと分かったので、試してみました。
以下の様に書いてみました。
// 現在地の座標はあらかじめ取得しておく
let currentPlacemark = MKPlacemark(coordinate: currentLocation.coordinate)
// 今回は'東京駅'を目的地に指定
let destinationCoordinate = CLLocationCoordinate2D(latitude: 35.681236, longitude: 139.767125)
let destinationPlacemark = MKPlacemark(coordinate: destinationCoordinate)
// リクエストの作成
let request = MKDirections.Request()
request.source = MKMapItem(placemark: currentPlacemark) // 出発地
request.destination = MKMapItem(placemark: destinationPlacemark) // 目的地
/*
移動手段を指定
- automobile: 車・バイク
- walking: 徒歩
- transit: 公共交通機関
- any: あらゆる交通手段
*/
request.transportType = .transit // '公共交通機関'を指定
let directions = MKDirections(request: request)
directions.calculate { response, error in
// ルート情報が返却される
guard let route = response?.routes.first, error == nil else {
return
}
// 所要時間を出力
let minutes = Int(route.expectedTravelTime / 60)
print("所要時間は\(minutes)分")
}
このように書いて実行してみましたが、Error Domain=MKErrorDomain Code=5 "(null)"
というエラーが返却されてしまいました。.transit
の代わりに.automobile
や.walking
を指定するとルート情報や距離、所要時間を取得できる為、すぐに原因が分かりませんでした。
公共交通機関(transit)は所要時間(ETA)のみをサポートしている
出発時間を未来日付にしてみたり、transportTypeに.any
を指定することで.transit
を含むルート情報が返却されないか試しましたが、いずれも上手くいきませんでした。
そこでMKDirectionsTransportType
のtransit
のドキュメントを改めて見返してみたところ、こんな記載がありました。
This type is only supported for estimating time of arrival.
つまり、transportTypeが.transit
の場合は、ルート情報(MKRoute
の配列)を返すことができない様です。また同時に、所要時間(ETA, Estimating Time of Arrival)であれば.transit
もサポートされているということが分かりました。これを取得すれば所要時間が分かりそうです。
公共交通機関(transit)の所要時間を取得する方法
MKDirections
はculculate
メソッドの他にも、calculateETA
というメソッドも持っています。こちらを使用すれば所要時間を計算することが出来ます。
以下の様に実装すると、.transit
の場合でも所要時間を計算することが出来ました。レスポンスには目的地までの所要時間を示すexpectedTravelTime
が含まれています。
// リクエストの作成
let request = MKDirections.Request()
request.source = MKMapItem(placemark: currentPlacemark) // 出発地
request.destination = MKMapItem(placemark: destinationPlacemark) // 目的地
request.transportType = .transit // '公共交通機関'を指定
let directions = MKDirections(request: request)
directions.calculateETA { response, error in
guard let response, error == nil else { return }
// 所要時間を出力
print("所要時間は\(Int(round(response.expectedTravelTime / 60)))分")
}
また上記のドキュメントによると、calculateETA
の計算時間はcalculate
よりもかなり早い為、.transit
に限らずルート情報が不要で所要時間のみを知りたい場合は、こちらを使った方が良さそうです。
Travel-time estimates take much less time to generate than directions, so use this method in situations where you want a time estimate only.
さいごに
今回はMKDirections
で公共交通機関の所要時間を取得する際にハマった点について書きました。
この記事が同じように困っている方の役に立つものであればうれしいです!
Discussion