先日、iOSのマップの2Dと3Dをジェスチャーで切り替える方法という投稿をしましたが、今回はプログラムで切り替える方法です
標準のマップアプリには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)
}
これで動かしてみると、、、

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

最終的にはこういうプログラムになりました
@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の切り替わりが行われてしまうので、実際にアプリに組み込む場合は、スクロール中はボタンを押せなくするなどの対応が必要です。


