-
Notifications
You must be signed in to change notification settings - Fork 13
New Add Building Scene Layer sample #418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v.next
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "dart.flutterSdkPath": "/usr/local/flutter/flutter/3.38.3" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Add building scene layer | ||
|
|
||
| Add a layer to a local scene to visualize and interact with 3D building models developed using Building Information Modeling (BIM) tools. | ||
|
|
||
|  | ||
|
|
||
| ## Use case | ||
|
|
||
| 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. | ||
|
|
||
| ## How to use the sample | ||
|
|
||
| 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. | ||
|
|
||
| ## How it works | ||
|
|
||
| 1. Create a local scene object with the `ArcGISScene.withBasemapStyle(BasemapStyle, SceneViewingMode)` constructor. | ||
| 2. Create an `ArcGISTiledElevationSource` object and add it to the local scene's base surface. | ||
| 3. Create a `BuildingSceneLayer` and add it to the local scene's operational layers. | ||
| 4. Create a `ArcGISLocalSceneView` object to display the scene. | ||
| 5. Set the local scene to the `ArcGISLocalSceneView`. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Steps 4 & 5 are a little weird -- the scene isn't added to the ArcGISLocalSceneView, it's added to the ArcGISLocalSceneViewController. I'm not sure if that's a little too nuanced to worry about, though. FilterBuildingSceneLayer just has a single step to cover both: 2. Create a LocalSceneView and add the scene. |
||
|
|
||
| ## Relevant API | ||
|
|
||
| * ArcGISLocalSceneView | ||
| * ArcGISScene | ||
| * ArcGISTiledElevationSource | ||
| * BuildingSceneLayer | ||
| * BuildingSublayer | ||
|
|
||
| ## Tags | ||
|
|
||
| 3D, buildings, elevation, layers, scene, surface | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "category": "Layers", | ||
| "description": "Add a layer to a local scene to visualize and interact with 3D building models developed using Building Information Modeling (BIM) tools.", | ||
| "ignore": false, | ||
| "images": [ | ||
| "add_building_scene_layer.png" | ||
| ], | ||
| "keywords": [ | ||
| "3D", | ||
| "buildings", | ||
| "elevation", | ||
| "layers", | ||
| "scene", | ||
| "surface", | ||
| "ArcGISLocalSceneView", | ||
| "ArcGISScene", | ||
| "ArcGISTiledElevationSource", | ||
| "BuildingSceneLayer", | ||
| "BuildingSublayer" | ||
| ], | ||
| "redirect_from": [], | ||
| "relevant_apis": [ | ||
| "ArcGISLocalSceneView", | ||
| "ArcGISScene", | ||
| "ArcGISTiledElevationSource", | ||
| "BuildingSceneLayer", | ||
| "BuildingSublayer" | ||
| ], | ||
| "snippets": [ | ||
| "add_building_scene_layer.dart" | ||
| ], | ||
| "title": "Add building scene layer" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| // Copyright 2025 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 'package:arcgis_maps/arcgis_maps.dart'; | ||
| import 'package:arcgis_maps_sdk_flutter_samples/common/common.dart'; | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| class AddBuildingSceneLayer extends StatefulWidget { | ||
| const AddBuildingSceneLayer({super.key}); | ||
|
|
||
| @override | ||
| State<AddBuildingSceneLayer> createState() => _AddBuildingSceneLayerState(); | ||
| } | ||
|
|
||
| class _AddBuildingSceneLayerState extends State<AddBuildingSceneLayer> | ||
| with SampleStateSupport { | ||
| // Create a controller for the local scene view. | ||
| final _localSceneViewController = ArcGISLocalSceneView.createController(); | ||
| // A flag for when the local scene view is ready and controls can be used. | ||
| var _ready = false; | ||
|
|
||
| late final BuildingSublayer _overviewSublayer; | ||
| late final BuildingSublayer _fullModelSublayer; | ||
| var _showFullModel = false; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these three should have comments |
||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Scaffold( | ||
| body: SafeArea( | ||
| top: false, | ||
| left: false, | ||
| right: false, | ||
| child: Stack( | ||
| children: [ | ||
| Column( | ||
| children: [ | ||
| Expanded( | ||
| // Add a map view to the widget tree and set a controller. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not a map view |
||
| child: ArcGISLocalSceneView( | ||
| controllerProvider: () => _localSceneViewController, | ||
| onLocalSceneViewReady: onLocalSceneViewReady, | ||
| ), | ||
| ), | ||
| Row( | ||
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||
| children: [ | ||
| // A button to perform a task. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update comment |
||
| ElevatedButton( | ||
| onPressed: toggleModelView, | ||
| child: Text(_showFullModel ? 'Overview' : 'Full Model'), | ||
| ), | ||
| ], | ||
| ), | ||
| ], | ||
| ), | ||
| // Display a progress indicator and prevent interaction until state is ready. | ||
| LoadingIndicator(visible: !_ready), | ||
| ], | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Future<void> onLocalSceneViewReady() async { | ||
| // Initialize the Scene. | ||
| final scene = await _initializeScene(); | ||
|
|
||
| // Load the BuildingSceneLayer. | ||
| final buildingSceneLayer = BuildingSceneLayer.withUri( | ||
| Uri.parse( | ||
| 'https://www.arcgis.com/home/item.html?id=669f6279c579486eb4a0acc7eb59d7ca', | ||
| ), | ||
| ); | ||
| await buildingSceneLayer.load(); | ||
|
|
||
| // Add the BuildingSceneLayer to the Scene. | ||
| scene.operationalLayers.add(buildingSceneLayer); | ||
|
|
||
| // Extract the overview and full model sublayers | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. period |
||
| _overviewSublayer = buildingSceneLayer.sublayers.firstWhere( | ||
| (sublayer) => sublayer.name == 'Overview', | ||
| ); | ||
| _fullModelSublayer = buildingSceneLayer.sublayers.firstWhere( | ||
| (sublayer) => sublayer.name == 'Full Model', | ||
| ); | ||
|
|
||
| // Add the Scene to the LocalSceneViewController. | ||
| _localSceneViewController.arcGISScene = scene; | ||
|
|
||
| // Set an initial viewpoint camera. | ||
| final viewpointCamera = Camera.withLocation( | ||
| location: ArcGISPoint( | ||
| x: -13045109, | ||
| y: 4036614, | ||
| z: 511, | ||
| spatialReference: SpatialReference.webMercator, | ||
| ), | ||
| heading: 343, | ||
| pitch: 64, | ||
| roll: 0, | ||
| ); | ||
| _localSceneViewController.setViewpointCamera(viewpointCamera); | ||
|
|
||
| // Set the ready state variable to true to enable the sample UI. | ||
| setState(() => _ready = true); | ||
| } | ||
|
|
||
| Future<ArcGISScene> _initializeScene() async { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no awaiting going on, so this can be ArcGISScene _initializeScene() { |
||
| // Create a Scene with a topographic basemap style. | ||
| final scene = ArcGISScene.withBasemapStyle( | ||
| BasemapStyle.arcGISTopographic, | ||
| viewingMode: SceneViewingMode.local, | ||
| ); | ||
|
|
||
| // Add an ElevationSource to the Scene. | ||
| final elevationSource = ArcGISTiledElevationSource.withUri( | ||
| Uri.parse( | ||
| 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer', | ||
| ), | ||
| ); | ||
| scene.baseSurface.elevationSources.add(elevationSource); | ||
|
|
||
| return scene; | ||
| } | ||
|
|
||
| Future<void> toggleModelView() async { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. likewise void toggleModelView() { |
||
| // Toggle the visibilities for the sublayers. | ||
| _overviewSublayer.isVisible = _showFullModel; | ||
| _fullModelSublayer.isVisible = !_showFullModel; | ||
|
|
||
| // Set the state for the new full model visibility. | ||
| setState(() => _showFullModel = !_showFullModel); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file shouldn't have snuck in here