LoginSignup
0
2

More than 1 year has passed since last update.

一番シンプルな経路探索を実装したい

Last updated at Posted at 2021-06-27

ゴール

なんでもいいから車用のルートを、現在地から目的地までつなげる。

調査

公式を見に行く。
ルート検索のAPIが3つあるぞ。。
Distance Matrix APIはとりあえず除外して、Directions APIか、Roads API。
ならび的には一番左がスタンダードだろうが、Roads APIの”正確なルート”っていう文言が気になる。
スクリーンショット 2021-06-12 9.54.49.png

Roads API

Directions API

実装

上記参考ページ実装をコピペ。拡張として追加する。
車用の経路なので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)
        }
    })
}

アプリを実行
スクリーンショット 2021-06-27 19.23.35.png

チェルシーのホームスタジアム「stanford bridge」を検索して選択。ルートらしい線が出現。
スクリーンショット 2021-06-27 19.24.17.png
スクリーンショット 2021-06-27 19.24.33.png

拡大してみると、それっぽい経路が引かれている。
スクリーンショット 2021-06-27 19.25.10.png

しかし、さらに拡大してみると。。
右左折する点を直線で結んでいるだけなので、カーブの道は正しく線を引けていない。
スクリーンショット 2021-06-27 19.26.16.png

これは、課題として解決・更新する。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2