MKMapViewでの3Dマップの利用
3Dマップは、OSに既定でインストールされている地図アプリのみで利用できました。iOS16以降では、MKMapViewが3Dマップに対応し、開発者が作成するアプリで3Dマップが利用できるようになりました。
マップの種類を指定する
preferredConfigurationプロパティで行います。マップの種類を指定する構造体は、MKStandardMapConfiguration(標準)、MKHybridMapConfiguration(ハイブリッド)、MKImageryMapConfiguration(衛星画像)の3種類です。
MKMapConfiguration.ElevationStyle(標高のレベル)、MKStandardMapConfiguration.EmphasisStyle(地図上のオブジェクトを強調するか)の2つのオブジェクトで設定します。
| 構造体 | 概要 | 値 |
|---|---|---|
| MKMapConfiguration.ElevationStyle | 標高を地図に反映するか(標準の地図のみ) | 0:しない(既定)、1:する |
| MKStandardMapConfiguration.EmphasisStyl | 地図上のオブジェクトを強調するか | 0:しない(既定)、1:する |
これら3つの要素で地図の種類を決められますので、その3つに応じたプロパティを持つクラスをMapSettingの名前で作成します。
class MapSetting: ObservableObject {
@Published var mapType = 0
@Published var elevation = 0
@Published var emphasis = 0
}
作成したMapSettingクラスをMapView構造体にEnvironmentObject型のプロパティとして設けます。Viewを更新する際に、プロパティの値に応じて地図の種類を切り替える処理を作成します。
struct MapView: UIViewRepresentable {
@EnvironmentObject var mapSetting: MapSetting
# 略
// View更新処理
func updateUIView(_ uiView: MKMapView, context: Context) {
switch self.mapSetting.mapType {
case 0: // 標準の地図
uiView.preferredConfiguration = MKStandardMapConfiguration(
elevationStyle: MKMapConfiguration.ElevationStyle(rawValue: mapSetting.elevation)!,
emphasisStyle: MKStandardMapConfiguration.EmphasisStyle(rawValue: mapSetting.emphasis)! )
# 以下、同様にハイブリッド/衛星画像を指定
# 略
}
}
}
ContentView側では、MapSettingクラスをObservedObject型のプロパティとして設けます。PickerでMapSettingクラスの各プロパティの値を変更できるようにします。
struct ContentView: View {
@ObservedObject var mapSetting = MapSetting()
var body: some View {
ZStack {
MapView().environmentObject(mapSetting).edgesIgnoringSafeArea(.all) // -------- ①
}.overlay(alignment: .bottom) {
VStack {
// 地図の種別設定
Picker("Map Type", selection: $mapSetting.mapType) { // -------- ②
Text("Standard").tag(0)
Text("Hybrid").tag(1)
Text("Image").tag(2)
}.pickerStyle(SegmentedPickerStyle())
.onChange(of: mapSetting.mapType) {
mapSetting.mapType = $0
}.padding([.top, .leading, .trailing], 16)
// 標高スタイル、地図上のオブジェクトに関しても同様の処理を作成
// 略
}.background(.gray)
}
}
}
ObservedObject型のプロパティとMapView内に設けたプロパティを接続します(①)。(②)以降では、Pickerでプロパティの各値を指定できるようにします。このことによって、バインディング変数を通してPickerで選択した値が地図の種類に反映されるようにできます。
iOS16以前の地図と比べると、ハイブリッドと衛星画像の場合は標高差が分かる画像に変わりました。
3Dマップを確認する
3Dマップは地図を2本指で上にドラッグする動作で表示できます。シミュレーターの場合は、オプションとシフトのキーを同時に押したままマウスを上に動かすことで、3Dマップを表示できます。
当然ですが、3Dマップが表示されるのは3Dデータが存在する地図の部分です。都市部以外では3Dマップが表示されないこともあります。
