Use augmented reality (AR) to quickly explore a scene more naturally than you could with a touch or mouse interface.
Use case
You can use AR to drop into an area and visualize information, like a proposed development or a historical model of a city. You could use flyover AR to explore a city by walking through it virtually.
How to use the sample
When you open the sample, you'll be viewing the scene from above. You can walk around, using your device as a window into the scene. Try moving vertically to get closer to the ground.
How it works
- Create the
FlyoverSceneView
and add it to the view. - Create the scene, add content, then display it.
- When the content you want to view loads, get its center point and use that to create the origin camera for the AR view. Note that the altitude should be set so that all scene content is visible. For a city, a good value might be a bit higher than the tallest building.
- Set the translation factor so that you can move through the scene easily. With a translation factor of 1000, you will move 1000 feet in the scene for every foot you move the physical device.
- Set the space effect to
stars
and atmosphere effect torealistic
to create an immersive experience.
Relevant API
- FlyoverSceneView
- SceneView
About the data
This sample uses an integrated mesh that depicts the city of Girona, Spain and is attributed to the Institut Cartogràfic i Geològic de Catalunya (ICGC). The data was produced from photogrammetrically correct imagery. Areas of white space within the integrated mesh are areas that had poor overlapping coverage from photos.
The world elevation service is used to show terrain while the integrated mesh layer loads.
Additional information
Flyover AR is one of three main patterns for working with geographic information in augmented reality. Augmented reality is made possible with the ArcGIS Maps SDK Toolkit.
Tags
augmented reality, bird's eye, birds-eye-view, fly over, flyover, mixed reality, translation factor
Sample Code
// Copyright 2023 Esri
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import ArcGIS
import ArcGISToolkit
import SwiftUI
struct AugmentRealityToFlyOverSceneView: View {
/// A scene with an imagery basemap, a world elevation source, and a mesh layer of Girona, Spain.
@State private var scene: ArcGIS.Scene = {
let scene = Scene(basemapStyle: .arcGISImagery)
// Create a mesh layer from a URL and add it to the scene.
let meshLayer = IntegratedMeshLayer(url: .gironaSpain)
scene.addOperationalLayer(meshLayer)
// Create an elevation source from a URL and add to the scene's base surface.
let elevationSource = ArcGISTiledElevationSource(url: .worldElevationService)
scene.baseSurface.addElevationSource(elevationSource)
return scene
}()
var body: some View {
// Create a flyover scene view with an initial location, translation factor,
// initial heading, and scene view.
FlyoverSceneView(
initialLocation: Point(x: 2.82407, y: 41.99101, z: 230, spatialReference: .wgs84),
translationFactor: 1_000,
initialHeading: 160
) { _ in
SceneView(scene: scene)
.spaceEffect(.stars)
.atmosphereEffect(.realistic)
}
}
}
private extension URL {
/// A URL to an integrated mesh layer of Girona, Spain.
static var gironaSpain: Self {
.init(string: "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Girona_Spain/SceneServer")!
}
/// A URL to world elevation service from Terrain3D ArcGIS REST service.
static var worldElevationService: Self {
.init(string: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")!
}
}
#Preview {
AugmentRealityToFlyOverSceneView()
}