View in QML C++ View on GitHub Sample viewer app
This sample demonstrates how to display custom labels in a 3D scene.
Use case
Labeling features is useful to visually display information or attributes on a scene. For example, city officials or maintenance crews may want to show installation dates of features of a gas network.
How to use the sample
Pan and zoom to explore the scene. Notice the labels showing installation dates of features in the 3D gas network.
How it works
Create a Scene
from a PortalItem
.
Add the scene to a SceneView
and load it.
After loading is complete, obtain the FeatureLayer
from one of the GroupLayer
s in the scene's operationalLayers
.
Create a TextSymbol
to define how labels are stylized.
After the Scene
has loaded, obtain the FeatureLayer
from the scene's operationalLayers
.
Create an LabelDefinition
using an ArcadeLabelExpression
.
Set the "labelExpressionInfo.expression" key to define what text the label should display. You can use fields of the feature by using $feature.NAME
in the expression.
Add the definition to the feature layer's labelDefinitions
array.
Relevant API
ArcadeLabelExpression
FeatureLayer
LabelDefinition
Scene
SceneView
TextSymbol
About the data
This sample shows a New York City infrastructure scene hosted on ArcGIS Online.
3D, arcade, attribute, buildings, label, model, scene, symbol, text, URL, visualization
Sample CodeDisplay3DLabelsInScene.cpp Display3DLabelsInScene.cpp Display3DLabelsInScene.h Display3DLabelsInScene.qml
Use dark colors for code blocks Copy
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
// [WriteFile Name=Display3DLabelsInScene, Category=Scenes]
// [Legal]
// Copyright 2021 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 "Display3DLabelsInScene.h"
# include "ArcadeLabelExpression.h"
# include "FeatureLayer.h"
# include "LabelDefinition.h"
# include "Scene.h"
# include "SceneQuickView.h"
# include "TextSymbol.h"
# include "Error.h"
# include "LayerListModel.h"
# include "GroupLayer.h"
# include "ServiceTypes.h"
# include "LabelDefinitionListModel.h"
using namespace Esri::ArcGISRuntime;
Display3DLabelsInScene:: Display3DLabelsInScene (QObject* parent /* = nullptr */ ):
QObject (parent),
m_scene ( new Scene ( QUrl ( "https://www.arcgis.com/home/item.html?id=850dfee7d30f4d9da0ebca34a533c169" ), this ))
{
connect (m_scene, &Scene::doneLoading, this , [ this ]()
{
for (Layer* layer : *m_scene-> operationalLayers ())
{
if (layer-> name () == "Gas" )
{
// The gas layer is a GroupLayer type consisting of Layer types.
// Labels can only be displayed on FeatureLayer types, so we must first convert it to a FeatureLayer class.
GroupLayer* gasGroupLayer = dynamic_cast <GroupLayer*>(layer);
if (!gasGroupLayer)
continue ;
FeatureLayer* gasFeatureLayer = dynamic_cast <FeatureLayer*>(gasGroupLayer-> layers ()-> first ());
if (gasFeatureLayer)
display3DLabelsOnFeatureLayer (gasFeatureLayer);
break ;
}
}
});
}
void Display3DLabelsInScene::display3DLabelsOnFeatureLayer (FeatureLayer* featureLayer)
{
TextSymbol* textSymbol = new TextSymbol ( this );
textSymbol-> setColor ( QColor ( "#ffa500" ));
textSymbol-> setHaloColor ( QColor (Qt::white));
textSymbol-> setHaloWidth ( 2.0 );
textSymbol-> setSize ( 14.0 );
ArcadeLabelExpression* labelExpression = new ArcadeLabelExpression ( "Text($feature.INSTALLATIONDATE, 'D MMM Y')" , this );
LabelDefinition* labelDefinition = new LabelDefinition (labelExpression, textSymbol, this );
labelDefinition-> setPlacement (LabelingPlacement::LineAboveAlong);
labelDefinition-> setUseCodedValues ( true );
featureLayer-> labelDefinitions ()-> clear ();
featureLayer-> labelDefinitions ()-> append (labelDefinition);
featureLayer-> setLabelsEnabled ( true );
}
Display3DLabelsInScene::~ Display3DLabelsInScene () = default ;
void Display3DLabelsInScene::init ()
{
// Register classes for QML
qmlRegisterType<SceneQuickView>( "Esri.Samples" , 1 , 0 , "SceneView" );
qmlRegisterType<Display3DLabelsInScene>( "Esri.Samples" , 1 , 0 , "Display3DLabelsInSceneSample" );
}
SceneQuickView* Display3DLabelsInScene::sceneView () const
{
return m_sceneView;
}
// Set the view (created in QML)
void Display3DLabelsInScene::setSceneView (SceneQuickView* sceneView)
{
if (!sceneView || sceneView == m_sceneView)
return ;
m_sceneView = sceneView;
m_sceneView-> setArcGISScene (m_scene);
emit sceneViewChanged () ;
}