Horizontal window/map on visionOS

Hi, would anyone be so kind and try to guide me, which technologies, Kits, APIs, approaches etc. are useful for creating a horizontal window with map (preferrably MapKit) on visionOS using SwiftUI?

I was hoping to achieve scenario: User can walk around and interact with horizontal map window and also interact with (3D) pins on the map. Similar thing was done by SAP in their "SAP Analytics Cloud" app (second image from top).

Since I am complete beginner in this area, I was looking for a clean, simple solution. I need to know, if AR/RealityKit is necessary or is this achievable only using native SwiftUI? I tried using just Map() with .rotation3DEffect() which actually makes the map horizontal, but gestures on the map are out of sync and I really dont know, if this approach is valid or complete rubbish.

Any feedback appreciated.

Answered by elukasino in 817409022

Hi, for anyone looking for similar thing, this solution worked nice for me:

import SwiftUI
import RealityKit
import MapKit

struct SwiftUIView: View {
    @PhysicalMetric(from: .meters) private var oneMeter = 1
    @State var mainEntity = Entity()

    var body: some View {
        RealityView { content, attachments in
            // Create and configure the 3D shape entity
            let shapeEntity = ModelEntity(mesh: .generateCylinder(height: 0.03, radius: 0.45))
            mainEntity.addChild(shapeEntity)
            content.add(shapeEntity)
            mainEntity.addChild(shapeEntity)

            if let mapAttachment = attachments.entity(for: "mapAttachment") {
                // Adjust the map attachment's transformation to the same size and orientation as the 3D shape entity
                mapAttachment.transform = Transform(pitch: -.pi / 2, yaw: 0, roll: 0)

                // Position the map slightly above the 3D shape entity
                let shapeDimensions = shapeEntity.visualBounds(relativeTo: nil).extents
                mapAttachment.setPosition(SIMD3<Float>(0, shapeDimensions.y / 2 + 0.0001, 0), relativeTo: shapeEntity)

                mainEntity.addChild(mapAttachment)
            }
            content.add(mainEntity)
        }
        attachments: {
            // Create and add a map attachment to the RealityKit scene
            Attachment(id: "mapAttachment") {
                Map()
                    .frame(width: oneMeter * 0.45 * 2, height: oneMeter * 0.45 * 2)
                    .mask(Circle())
            }
        }
    }
}

Start with the basic volumetric app in Xcode.

Look here for an example;

https://stackoverflow.com/questions/78265212/how-to-display-3d-map-in-realitykit

In that example the placed the view over a cylinder, but you can use a box like the example you linked to. You can add whatever you want to the sides of the box.

This should get you started.

Accepted Answer

Hi, for anyone looking for similar thing, this solution worked nice for me:

import SwiftUI
import RealityKit
import MapKit

struct SwiftUIView: View {
    @PhysicalMetric(from: .meters) private var oneMeter = 1
    @State var mainEntity = Entity()

    var body: some View {
        RealityView { content, attachments in
            // Create and configure the 3D shape entity
            let shapeEntity = ModelEntity(mesh: .generateCylinder(height: 0.03, radius: 0.45))
            mainEntity.addChild(shapeEntity)
            content.add(shapeEntity)
            mainEntity.addChild(shapeEntity)

            if let mapAttachment = attachments.entity(for: "mapAttachment") {
                // Adjust the map attachment's transformation to the same size and orientation as the 3D shape entity
                mapAttachment.transform = Transform(pitch: -.pi / 2, yaw: 0, roll: 0)

                // Position the map slightly above the 3D shape entity
                let shapeDimensions = shapeEntity.visualBounds(relativeTo: nil).extents
                mapAttachment.setPosition(SIMD3<Float>(0, shapeDimensions.y / 2 + 0.0001, 0), relativeTo: shapeEntity)

                mainEntity.addChild(mapAttachment)
            }
            content.add(mainEntity)
        }
        attachments: {
            // Create and add a map attachment to the RealityKit scene
            Attachment(id: "mapAttachment") {
                Map()
                    .frame(width: oneMeter * 0.45 * 2, height: oneMeter * 0.45 * 2)
                    .mask(Circle())
            }
        }
    }
}
Horizontal window/map on visionOS
 
 
Q