【Swift】iOSのマップの2Dと3Dをプログラムで切り替える方法

先日、iOSのマップの2Dと3Dをジェスチャーで切り替える方法という投稿をしましたが、今回はプログラムで切り替える方法です

標準のマップアプリには2Dマップと3Dマップを切り替えるボタンが用意されています

iOSの地図(MKMapView)2Dと3Dをプログラムで切り替える方法

このボタンで切り替えると、このような感じになります。静止画ではちょっとわかりにくいですが、地図の中心を軸にして奥に傾ける感じ。この動きを再現したい

iOSの地図(MKMapView)2Dと3Dをプログラムで切り替える方法

2Dと3Dを切り替える簡単な関数でもあるのかと思いきや、もっと細やかな操作ができるような仕組みが用意されていました。マップを見下ろしているカメラ(MKMapCamera)の操作です

カメラの角度が設定できるので、それを変更すれば斜めからみた角度になるはず。
pitchというがそれです。

というわけで、切り替えボタンを押すとpitchを変更するようにプログラムを書いてみました。

@IBAction func changeCamera(sender: AnyObject) {
    
    let newCamera = mapView.camera.copy() as! MKMapCamera
    
    if mapView.camera.pitch != 0 {
        newCamera.pitch = 0
    } else {
        newCamera.pitch = 45
    }    
    mapView.setCamera(newCamera, animated: true)   
}

これで動かしてみると、、、

iOSの地図(MKMapView)2Dと3Dをプログラムで切り替える方法

3D表示にはなったけど、地図の表示範囲が広くなってしまいました
なぜだろう??

表示が広範囲になってしまうというのは、カメラの位置が高すぎるわけです。なので、MKMapCameraのaltitude(地面からの高さ)を変更してみました。

iOSの地図(MKMapView)2Dと3Dをプログラムで切り替える方法

最終的にはこういうプログラムになりました

@IBAction func changeCamera(sender: AnyObject) {
    
    let newCamera = mapView.camera.copy() as! MKMapCamera
    let angle: CGFloat = 45
    
    if mapView.camera.pitch != 0 {
        newCamera.pitch = 0
        
        let newAltitude = mapView.camera.altitude / sin(Double(90-mapView.camera.pitch) * M_PI / 180)
        newCamera.altitude = newAltitude
        
    } else {
        
        // 広域地図の場合は3Dにならないのでなにもしない
        if mapView.camera.altitude > 100000 {
            return
        }
        
        newCamera.pitch = angle
        
        let newAltitude = mapView.camera.altitude * sin(Double(90-angle) * M_PI / 180)
        newCamera.altitude = newAltitude
        
    }
    mapView.setCamera(newCamera, animated: true)
}

とりあえず標準マップと同じような感じで2Dと3Dの切り替えができるボタンができました!

地図のスクロール中にこのボタンを押すと、スクロールする前の位置に戻って2D・3Dの切り替わりが行われてしまうので、実際にアプリに組み込む場合は、スクロール中はボタンを押せなくするなどの対応が必要です。

タイトルとURLをコピーしました