質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.23%

Mapsでルートのシミュレーションがしたい

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,442

interpiamobile

score 52

現在MapKit.frameworkを使って地図機能を実装しているのですが、目的地にピンを留めた後に現在地からその目的地までのルートをシミュレーションしたいです。しかしどうすればいいか分かりません。
詳しくは以下のページにある動画のようにしたいです。(3Dでなくて2Dで構いません)

【裏技】Googleマップのルート検索で「3D」をオンにするとアニメーションが見られます

この動画のようにルートに沿ってピンを走らせるにはどうすればいいのでしょうか?
現在以下のようにコードを実装しており、現在地から目的地までの線引き等はできています。

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var mapView: MKMapView!
    var lm: CLLocationManager! = nil
    var fromCoordinate: CLLocationCoordinate2D?
    var toCoordinate: CLLocationCoordinate2D?

    override func viewDidLoad() {
        super.viewDidLoad()

        setCoreLocation()
        addLongPressGesture()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    //MARK: ViewDidLoadPreference

    func setCoreLocation() {
        lm = CLLocationManager()
        lm.delegate = self

        lm.requestAlwaysAuthorization()
        lm.desiredAccuracy = kCLLocationAccuracyBest
        lm.distanceFilter = 300
        lm.startUpdatingLocation()
    }

    func addLongPressGesture() {
        let myLongPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPressGesture(_:)))
        myLongPressGesture.minimumPressDuration = 1.0
        myLongPressGesture.allowableMovement = 150

        mapView.addGestureRecognizer(myLongPressGesture)
    }

    //MARK: GestureRecognizer

    func longPressGesture(sender: UILongPressGestureRecognizer) {
        if sender.state != UIGestureRecognizerState.Ended {
            let touchLocation = sender.locationInView(mapView)
            let locationCoordinate = mapView.convertPoint(touchLocation,toCoordinateFromView: mapView)
            toCoordinate = CLLocationCoordinate2D(latitude: locationCoordinate.latitude, longitude: locationCoordinate.longitude)

            setPointAnnotation(toCoordinate!)

            routeSearch()
        }
    }

    //MARK: CoreLocationDelegate

    func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation){
        fromCoordinate = CLLocationCoordinate2D(latitude: newLocation.coordinate.latitude, longitude: newLocation.coordinate.longitude)

        guard let coodinate = fromCoordinate else {
            return
        }

        let region = MKCoordinateRegionMake(coodinate, MKCoordinateSpanMake(0.01, 0.01))
        mapView.setRegion(region, animated:true)
        mapView.userTrackingMode = MKUserTrackingMode.FollowWithHeading
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        NSLog("Error")
    }

    //MARK: MapKit

    func routeSearch() {
        let fromPlacemark = MKPlacemark(coordinate:fromCoordinate!, addressDictionary:nil)
        let toPlacemark = MKPlacemark(coordinate:toCoordinate!, addressDictionary:nil)

        let fromItem = MKMapItem(placemark:fromPlacemark);
        let toItem = MKMapItem(placemark:toPlacemark);

        let request = MKDirectionsRequest()
        request.source = fromItem
        request.destination = toItem
        request.requestsAlternateRoutes = true;
        request.transportType = MKDirectionsTransportType.Walking

        let directions = MKDirections(request: request)
        directions.calculateDirectionsWithCompletionHandler { [unowned self] response, error in
            guard let unwrappedResponse = response else { return }

            for route in unwrappedResponse.routes {
                self.mapView.addOverlay(route.polyline)
                self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)

                self.title = String(Int(round(route.distance / 100))) + "km   " + String(Int(round(route.expectedTravelTime / 60))) + "分"
            }
        }
    }

    func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        let route: MKPolyline = overlay as! MKPolyline
        let routeRenderer = MKPolylineRenderer(polyline:route)
        routeRenderer.lineWidth = 5.0
        routeRenderer.strokeColor = UIColor.redColor()
        return routeRenderer
    }

    func setPointAnnotation(coordinate: CLLocationCoordinate2D) {
        let annotation = MKPointAnnotation()
        annotation.coordinate = coordinate
        self.mapView.addAnnotation(annotation)
    }

}

どうすればルートのシミュレーションをすることができるでしょうか?
どなたかわかる方がいれば教えていただきたいです。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

MapKit や Google Maps SDK for iOS には、「ルートのシミュレーション」を行う機能はないと思われますので、それを行うには地道に実装するしかないと思います。

具体的には、

  1. タイマーで1秒置きなどで、以下の処理を行う
  2. MKDirection で得られたルート探索結果 route.polyline の座標を順に取る
  3. その座標に車などのマーカーを表示させる&地図をその位置に移動させる

となると思います。

「いい感じ」にシミュレーションしているように見せるには、

  • 車のマーカーの向き(角度)または地図の向き
  • 車の走行速度(km/h)の考慮
  • 地図の表示領域

などを考慮しないといけないので、より複雑なプログラムになると思います。

他の案としては、

で、GoogleマップアプリやiOSのマップアプリを呼び出す方法がありますが、これが「シミュレーション」の要件を満たすかは、確認されるとよろしいかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る