Scene layer selection

View inC++QMLView on GitHubSample viewer app

Identify features in a scene to select.

screenshot

Use case

You can select features to visually distinguish them with a selection color or highlighting. This can be useful to demonstrate the physical extent or associated attributes of a feature, or to initiate another action such as centering that feature in the scene view.

How to use the sample

Click on a building in the scene layer to select it. Deselect buildings by clicking away from the buildings.

How it works

  1. Create an ArcGISSceneLayer passing in the URL to a scene layer service.
  2. Use SceneView::mouseClicked signal to get the screen tap location screenPoint.
  3. Call SceneView::identifyLayerAsync to identify features in the scene that intersect the tapped screen point.
  4. From the resulting IdentifyLayerResult, a list of identified GeoElements are obtained.
  5. Get the first element in the list, checking that it is a feature, and call ArcGISSceneLayer::selectFeature(feature) to select it.

Relevant API

  • ArcGISSceneLayer
  • Scene
  • SceneView

About the data

This sample shows a Berlin, Germany Scene hosted on ArcGIS Online.

Tags

3D, Berlin, buildings, identify, model, query, search, select

Sample Code

SceneLayerSelection.cppSceneLayerSelection.cppSceneLayerSelection.hSceneLayerSelection.qml
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// [WriteFile Name=SceneLayerSelection, Category=Scenes]
// [Legal]
// Copyright 2018 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
// http://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.
// [Legal]

#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD

#include "SceneLayerSelection.h"

#include "ArcGISTiledElevationSource.h"
#include "Scene.h"
#include "SceneQuickView.h"
#include "Surface.h"
#include "Basemap.h"
#include "ArcGISSceneLayer.h"
#include "Point.h"
#include "Camera.h"
#include "SpatialReference.h"
#include "Viewpoint.h"
#include "Camera.h"
#include "MapTypes.h"
#include "Surface.h"
#include "ElevationSourceListModel.h"
#include "LayerListModel.h"
#include "IdentifyLayerResult.h"
#include "Feature.h"

#include <QFuture>
#include <QUuid>

using namespace Esri::ArcGISRuntime;

SceneLayerSelection::SceneLayerSelection(QQuickItem* parent /* = nullptr */):
  QQuickItem(parent)
{
}

void SceneLayerSelection::init()
{
  // Register classes for QML
  qmlRegisterType<SceneQuickView>("Esri.Samples", 1, 0, "SceneView");
  qmlRegisterType<SceneLayerSelection>("Esri.Samples", 1, 0, "SceneLayerSelectionSample");
}

void SceneLayerSelection::componentComplete()
{
  QQuickItem::componentComplete();

  m_sceneView = findChild<SceneQuickView*>("sceneView");

  // Create a scene with the topographic basemap
  Scene* scene = new Scene(BasemapStyle::ArcGISTopographic, this);

  // add a surface
  Surface* surface = new Surface(this);
  surface->elevationSources()->append(
        new ArcGISTiledElevationSource(
          QUrl("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"),
          this));
  scene->setBaseSurface(surface);

  // add a scene layer
  m_sceneLayer = new ArcGISSceneLayer(QUrl("https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Buildings_Brest/SceneServer/layers/0"), this);
  scene->operationalLayers()->append(m_sceneLayer);

  // Set an initial viewpoint
  Point pt(-4.49779155626782, 48.38282454039932, 62.013264927081764, SpatialReference(4326));
  Camera camera(pt, 41.64729875588979, 71.2017391571523, 2.194677223e-314);
  Viewpoint initViewpoint(pt, camera);
  scene->setInitialViewpoint(initViewpoint);

  // connect signals
  connectSignals();

  // set the scene on the scene view
  m_sceneView->setArcGISScene(scene);
}

void SceneLayerSelection::connectSignals()
{
  // when the scene is clicked, identify the clicked feature and select it
  connect(m_sceneView, &SceneQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
  {
    // clear any previous selection
    m_sceneLayer->clearSelection();

    // identify from the click
    m_sceneView->identifyLayerAsync(m_sceneLayer, mouseEvent.position(), 10, false).then(this,
    [this](IdentifyLayerResult* result)
    {
      // get the results
      QList<GeoElement*> geoElements = result->geoElements();

      // make sure we have at least 1 GeoElement
      if (geoElements.isEmpty())
        return;

      // get the first GeoElement
      GeoElement* geoElement = geoElements.first();

      // cast the GeoElement to a Feature
      Feature* feature = static_cast<Feature*>(geoElement);

      // select the Feature in the SceneLayer
      if (feature)
      {
        feature->setParent(this);
        m_sceneLayer->selectFeature(feature);
      }
    });
  });
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.