Identify features in a scene to select.

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
- Create an
ArcGISSceneLayerpassing in the URL to a scene layer service. - Use
SceneView::mouseClickedsignal to get the screen tap locationscreenPoint. - Call
SceneView::identifyLayerAsyncto identify features in the scene that intersect the tapped screen point. - From the resulting
IdentifyLayerResult, a list of identifiedGeoElementsare obtained. - 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 Brest France Buildings Scene hosted on ArcGIS Online.
Tags
3D, buildings, identify, model, query, search, select
Sample Code
// [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
// sample headers#include "SceneLayerSelection.h"
// ArcGIS Maps SDK headers#include "ArcGISSceneLayer.h"#include "ArcGISTiledElevationSource.h"#include "Basemap.h"#include "Camera.h"#include "ElevationSourceListModel.h"#include "Feature.h"#include "IdentifyLayerResult.h"#include "LayerListModel.h"#include "MapTypes.h"#include "Point.h"#include "Scene.h"#include "SceneQuickView.h"#include "SpatialReference.h"#include "Surface.h"#include "Viewpoint.h"
// Qt headers#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); } }); });}// [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]
#ifndef SCENELAYERSELECTION_H#define SCENELAYERSELECTION_H
// Qt headers#include <QQuickItem>
namespace Esri::ArcGISRuntime{class SceneQuickView;class ArcGISSceneLayer;}
class SceneLayerSelection : public QQuickItem{ Q_OBJECT
public: explicit SceneLayerSelection(QQuickItem* parent = nullptr); ~SceneLayerSelection() override = default;
void componentComplete() override; static void init();
private: Esri::ArcGISRuntime::SceneQuickView* m_sceneView = nullptr; Esri::ArcGISRuntime::ArcGISSceneLayer* m_sceneLayer = nullptr; void connectSignals();};
#endif // SCENELAYERSELECTION_H// [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]
import QtQuickimport QtQuick.Controlsimport Esri.Samples
SceneLayerSelectionSample { id: rootRectangle clip: true width: 800 height: 600
SceneView { objectName: "sceneView" anchors.fill: parent
Component.onCompleted: { // Set the focus on SceneView to initially enable keyboard navigation forceActiveFocus(); } }}// [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]
// sample headers#include "SceneLayerSelection.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"
// Qt headers#include <QCommandLineParser>#include <QDir>#include <QGuiApplication>#include <QQmlEngine>#include <QQuickView>#include <QSurfaceFormat>
// Platform specific headers#ifdef Q_OS_WIN#include <Windows.h>#endif
#define STRINGIZE(x) #x#define QUOTE(x) STRINGIZE(x)
int main(int argc, char *argv[]){ Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setUseLegacyAuthentication(false);#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // Linux requires 3.2 OpenGL Context // in order to instance 3D symbols QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); fmt.setVersion(3, 2); QSurfaceFormat::setDefaultFormat(fmt);#endif
QGuiApplication app(argc, argv); app.setApplicationName(QString("SceneLayerSelection"));
// Use of ArcGIS location services, such as basemap styles, geocoding, and routing services, // requires an access token. For more information see // https://links.esri.com/arcgis-runtime-security-auth.
// The following methods grant an access token:
// 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account. // To generate a token, a user logs in to the app with an ArcGIS account that is part of an // organization in ArcGIS Online or ArcGIS Enterprise.
// 2. API key authentication: Get a long-lived access token that gives your application access to // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key. // Copy the API Key access token.
const QString accessToken = QString("");
if (accessToken.isEmpty()) { qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" << "you to authenticate with an ArcGIS account or set the API Key property."; } else { Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setApiKey(accessToken); }
// Initialize the sample SceneLayerSelection::init();
// Initialize application view QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView);
QString arcGISRuntimeImportPath = QUOTE(ARCGIS_RUNTIME_IMPORT_PATH);
#if defined(LINUX_PLATFORM_REPLACEMENT) // on some linux platforms the string 'linux' is replaced with 1 // fix the replacement paths which were created QString replaceString = QUOTE(LINUX_PLATFORM_REPLACEMENT); arcGISRuntimeImportPath = arcGISRuntimeImportPath.replace(replaceString, "linux", Qt::CaseSensitive);#endif
// Add the import Path view.engine()->addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml")); // Add the Runtime and Extras path view.engine()->addImportPath(arcGISRuntimeImportPath);
// Set the source view.setSource(QUrl("qrc:/Samples/Scenes/SceneLayerSelection/SceneLayerSelection.qml"));
view.show();
return app.exec();}