Skip to content

Commit 21b02e0

Browse files
authored
New Add Building Scene Layer sample (#418)
* New Add building scene layer sample * Updated metadata * Revert "Updated metadata" This reverts commit 32ee0cc. * Removed settings.json file * PR updates - Readme How it Works changes - Comment fixes - Removed unnecessary async/await code - refactored building scene layer init logic to separate function
1 parent 16819d5 commit 21b02e0

File tree

4 files changed

+226
-0
lines changed

4 files changed

+226
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Add building scene layer
2+
3+
Add a layer to a local scene to visualize and interact with 3D building models developed using Building Information Modeling (BIM) tools.
4+
5+
![Image of add building scene layer](add_building_scene_layer.png)
6+
7+
## Use case
8+
9+
Building Scene Layers allow you to display and analyze detailed building models created from 3D BIM data. Unlike 3D object scene layers, which represent all features within a single layer, Building Scene Layers are organized into a hierarchy of sublayers representing individual building components such as walls, light fixtures, and mechanical systems. These sublayers are often grouped by disciplines like Architectural, Mechanical, or Structural. This structure enables deeper interaction and analysis of both interior and exterior features, providing insight into how a building is designed, used, and situated in its spatial context.
10+
11+
## How to use the sample
12+
13+
When loaded, the sample displays a scene with a Building Scene Layer. By default, the Overview sublayer is visible, showing the building's exterior shell. Use the "Full Model" toggle to switch to the Full Model sublayer, which reveals the building's components. Pan around and zoom in to observe the detailed features such as walls, light fixtures, mechanical systems, and more, both outside and inside the building.
14+
15+
## How it works
16+
17+
1. Create a local scene object with the `ArcGISScene.withBasemapStyle(BasemapStyle, SceneViewingMode)` constructor.
18+
2. Create an `ArcGISTiledElevationSource` object and add it to the local scene's base surface.
19+
3. Create a `BuildingSceneLayer` and add it to the local scene's operational layers.
20+
4. Create an `ArcGISLocalSceneView` object and add the scene.
21+
22+
## Relevant API
23+
24+
* ArcGISLocalSceneView
25+
* ArcGISScene
26+
* ArcGISTiledElevationSource
27+
* BuildingSceneLayer
28+
* BuildingSublayer
29+
30+
## Tags
31+
32+
3D, buildings, elevation, layers, scene, surface
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"category": "Layers",
3+
"description": "Add a layer to a local scene to visualize and interact with 3D building models developed using Building Information Modeling (BIM) tools.",
4+
"ignore": false,
5+
"images": [
6+
"add_building_scene_layer.png"
7+
],
8+
"keywords": [
9+
"3D",
10+
"buildings",
11+
"elevation",
12+
"layers",
13+
"scene",
14+
"surface",
15+
"ArcGISLocalSceneView",
16+
"ArcGISScene",
17+
"ArcGISTiledElevationSource",
18+
"BuildingSceneLayer",
19+
"BuildingSublayer"
20+
],
21+
"redirect_from": [],
22+
"relevant_apis": [
23+
"ArcGISLocalSceneView",
24+
"ArcGISScene",
25+
"ArcGISTiledElevationSource",
26+
"BuildingSceneLayer",
27+
"BuildingSublayer"
28+
],
29+
"snippets": [
30+
"add_building_scene_layer.dart"
31+
],
32+
"title": "Add building scene layer"
33+
}
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2025 Esri
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
import 'package:arcgis_maps/arcgis_maps.dart';
17+
import 'package:arcgis_maps_sdk_flutter_samples/common/common.dart';
18+
import 'package:flutter/material.dart';
19+
20+
class AddBuildingSceneLayer extends StatefulWidget {
21+
const AddBuildingSceneLayer({super.key});
22+
23+
@override
24+
State<AddBuildingSceneLayer> createState() => _AddBuildingSceneLayerState();
25+
}
26+
27+
class _AddBuildingSceneLayerState extends State<AddBuildingSceneLayer>
28+
with SampleStateSupport {
29+
// Create a controller for the local scene view.
30+
final _localSceneViewController = ArcGISLocalSceneView.createController();
31+
32+
// A flag for when the local scene view is ready and controls can be used.
33+
var _ready = false;
34+
35+
// The overview sublayer. This contains a simplified, exterior-only model of
36+
// the building.
37+
late final BuildingSublayer _overviewSublayer;
38+
39+
// The full model sublayer. This contains the fully detailed model of the
40+
// building including all exterior and interior features.
41+
late final BuildingSublayer _fullModelSublayer;
42+
43+
// Flag indicating if the app is displaying the full model or overview sublayer.
44+
var _showFullModel = false;
45+
46+
@override
47+
Widget build(BuildContext context) {
48+
return Scaffold(
49+
body: SafeArea(
50+
top: false,
51+
left: false,
52+
right: false,
53+
child: Stack(
54+
children: [
55+
Column(
56+
children: [
57+
Expanded(
58+
// Add a local scene view to the widget tree and set the controller.
59+
child: ArcGISLocalSceneView(
60+
controllerProvider: () => _localSceneViewController,
61+
onLocalSceneViewReady: onLocalSceneViewReady,
62+
),
63+
),
64+
Row(
65+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
66+
children: [
67+
// Button to toggle overview or full model sublayers.
68+
ElevatedButton(
69+
onPressed: toggleModelView,
70+
child: Text(_showFullModel ? 'Overview' : 'Full Model'),
71+
),
72+
],
73+
),
74+
],
75+
),
76+
// Display a progress indicator and prevent interaction until state is ready.
77+
LoadingIndicator(visible: !_ready),
78+
],
79+
),
80+
),
81+
);
82+
}
83+
84+
Future<void> onLocalSceneViewReady() async {
85+
// Initialize the Scene.
86+
final scene = _initializeScene();
87+
88+
// Initialize the BuildingSceneLayer.
89+
final buildingSceneLayer = await _initializeBuildingSceneLayer();
90+
91+
// Add the BuildingSceneLayer to the Scene.
92+
scene.operationalLayers.add(buildingSceneLayer);
93+
94+
// Add the Scene to the LocalSceneViewController.
95+
_localSceneViewController.arcGISScene = scene;
96+
97+
// Set an initial viewpoint camera.
98+
final viewpointCamera = Camera.withLocation(
99+
location: ArcGISPoint(
100+
x: -13045109,
101+
y: 4036614,
102+
z: 511,
103+
spatialReference: SpatialReference.webMercator,
104+
),
105+
heading: 343,
106+
pitch: 64,
107+
roll: 0,
108+
);
109+
_localSceneViewController.setViewpointCamera(viewpointCamera);
110+
111+
// Set the ready state variable to true to enable the sample UI.
112+
setState(() => _ready = true);
113+
}
114+
115+
ArcGISScene _initializeScene() {
116+
// Create a Scene with a topographic basemap style.
117+
final scene = ArcGISScene.withBasemapStyle(
118+
BasemapStyle.arcGISTopographic,
119+
viewingMode: SceneViewingMode.local,
120+
);
121+
122+
// Add an ElevationSource to the Scene.
123+
final elevationSource = ArcGISTiledElevationSource.withUri(
124+
Uri.parse(
125+
'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
126+
),
127+
);
128+
scene.baseSurface.elevationSources.add(elevationSource);
129+
130+
return scene;
131+
}
132+
133+
Future<BuildingSceneLayer> _initializeBuildingSceneLayer() async {
134+
// Load the BuildingSceneLayer.
135+
final buildingSceneLayer = BuildingSceneLayer.withUri(
136+
Uri.parse(
137+
'https://www.arcgis.com/home/item.html?id=669f6279c579486eb4a0acc7eb59d7ca',
138+
),
139+
);
140+
await buildingSceneLayer.load();
141+
142+
// Extract the overview and full model sublayers.
143+
_overviewSublayer = buildingSceneLayer.sublayers.firstWhere(
144+
(sublayer) => sublayer.name == 'Overview',
145+
);
146+
_fullModelSublayer = buildingSceneLayer.sublayers.firstWhere(
147+
(sublayer) => sublayer.name == 'Full Model',
148+
);
149+
150+
return buildingSceneLayer;
151+
}
152+
153+
void toggleModelView() {
154+
// Toggle the visibilities for the sublayers.
155+
_overviewSublayer.isVisible = _showFullModel;
156+
_fullModelSublayer.isVisible = !_showFullModel;
157+
158+
// Set the state for the new full model visibility.
159+
setState(() => _showFullModel = !_showFullModel);
160+
}
161+
}
169 KB
Loading

0 commit comments

Comments
 (0)