ゴール
なんでもいいから車用のルートを、現在地から目的地までつなげる。
調査
公式を見に行く。
ルート検索のAPIが3つあるぞ。。
Distance Matrix APIはとりあえず除外して、Directions APIか、Roads API。
ならび的には一番左がスタンダードだろうが、Roads APIの”正確なルート”っていう文言が気になる。
Roads API
-
自分が歩いてきた経路を辿ろう!Roads APIの使い方
自分が通った経路を記憶したり、適当に引いた線を経路として補完してくれる。補完した経路情報として、制限速度も返してくれる。 -
日光いろは坂で「Roads API」を使ってみたら・・・
なるほど。自分の通った経路上の点を補完して、経路として表示できるらしい。1度に保持できる点は最大100。
Directions API
-
Google Maps SDK for iOS で経路案内を実装する
こちらを参考にとりあえず経路検索、経路の描画を実装してみる。
実装
上記参考ページ実装をコピペ。拡張として追加する。
車用の経路なのでURLQueryItem(name: "mode", value: "drive")
を追記している。
extension ViewController{
func getDirection(destination: String, start startLocation: String, completion: @escaping (Direction) -> Void) {
guard var components = URLComponents(string: BASEURL) else { return }
components.queryItems = [
URLQueryItem(name: "key", value: GOOGLE_API_KEY),
URLQueryItem(name: "mode", value: "drive"),
URLQueryItem(name: "origin", value: startLocation),
URLQueryItem(name: "destination", value: destination)
]
guard let url = components.url else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
let decorder = JSONDecoder()
do {
let direction = try decorder.decode(Direction.self, from: data)
completion(direction)
} catch {
print(error.localizedDescription)
}
} else {
print(error ?? "Error")
}
}
task.resume()
}
func showRoute(_ direction: Direction) {
guard let route = direction.routes.first, let leg = route.legs.first else { return }
let path = GMSMutablePath()
for step in leg.steps {
// steps の中には曲がるところの座標が入っているので、
// 曲がるところの座標を線で結んでいく
path.add(CLLocationCoordinate2D(latitude: step.startLocation.lat,
longitude: step.startLocation.lng))
path.add(CLLocationCoordinate2D(latitude: step.endLocation.lat,
longitude: step.endLocation.lng))
}
// 曲がるところを結んだ線を Map 上に表示する
let polyline = GMSPolyline(path: path)
polyline.strokeWidth = 4.0
polyline.map = mapView
}
}
前回の目的地にピンを刺すタイミングと同じタイミングで経路が表示できるよう実装。動くかな。。
func PointPlace(pos: CLLocationCoordinate2D, title: String?) {
camera = GMSCameraPosition.camera(withTarget: pos, zoom: ZOOM)
self.mapView.animate(to: camera)
marker.position = pos
marker.title = title
marker.map = mapView
goButton.isHidden = false
// ルート検索と表示
let goalLocation = "\(targetPos.latitude),\(targetPos.longitude)"
let startLocation = "\(myPos.latitude),\(myPos.longitude)"
getDirection(destination: goalLocation,
start: startLocation,
completion: { [weak self] direction in
DispatchQueue.main.async {
self?.showRoute(direction)
}
})
}
チェルシーのホームスタジアム「stanford bridge」を検索して選択。ルートらしい線が出現。
しかし、さらに拡大してみると。。
右左折する点を直線で結んでいるだけなので、カーブの道は正しく線を引けていない。
これは、課題として解決・更新する。