Surface placement

View inQMLC++
View on GitHub
Sample viewer app

Position graphics relative to a surface using different surface placement modes.

screenshot

Use case

Depending on the use case, data might be displayed at an absolute height (e.g. flight data recorded with altitude information), at a relative height to the terrain (e.g. transmission lines positioned relative to the ground), at a relative height to objects in the scene (e.g. extruded polygons, integrated mesh scene layer), or draped directly onto the terrain (e.g. location markers, area boundaries).

How to use the sample

The application loads a scene showing four points that use individual surface placement modes (Absolute, Relative, Relative to Scene, and either Draped Billboarded or Draped Flat). Use the toggle to change the draped mode and the slider to dynamically adjust the Z value of the graphics. Explore the scene by zooming in/out and by panning around to observe the effects of the surface placement rules.

How it works

  1. Create a GraphicsOverlay for each placement mode, setting LayerSceneProperties::surfacePlacement:

    • Absolute, position graphic using only its Z value.
    • Relative, position graphic using its Z value plus the elevation of the surface.
    • DrapedBillboarded, position graphic upright on the surface and always facing the camera, not using its z value.
    • DrapedFlat, position graphic flat on the surface, not using its z value.
    • RelativeToScene, position graphic using its Z value plus the altitude values of the scene.
  2. Add graphics to the graphics overlay, GraphicsOverlay::graphics()::append(Graphic).
  3. Add each graphics overlay to the scene view by calling SceneView::graphicsOverlays()::append(overlay).

Relevant API

  • Graphic
  • GraphicsOverlay
  • LayerSceneProperties::surfacePlacement
  • SceneProperties
  • Surface

About the data

The scene launches with a view of Brest, France. Four points are shown hovering with positions defined by each of the different surface placement modes.

Additional information

This sample uses an elevation service to add elevation/terrain to the scene. Graphics are positioned relative to that surface for the DrapedBillboarded, DrapedFlat, and Relative surface placement modes. It also uses a scene layer containing 3D models of buildings. Graphics are positioned relative to that scene layer for the RelativeToScene surface placement mode.

Tags

3D, absolute, altitude, draped, elevation, floating, relative, scenes, sea level, surface placement

Sample Code

Surface_Placement.qmlSurface_Placement.cppSurface_Placement.h
                                                                                                                                               
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// [WriteFile Name=Surface_Placement, Category=Scenes]
// [Legal]
// Copyright 2016 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 QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.Samples 1.0
import QtQuick.Layouts 1.12

SurfacePlacementSample {
    width: 800
    height: 600

    // Create SceneView here, and create its Scene and GraphicsOverlay in C++ code
    //! [add a sceneView component]
    SceneView {
        objectName: "sceneView"
        anchors.fill: parent
    }

    Rectangle {
        anchors {
            top: parent.top
            left: parent.left
            margins: 5
        }
        width: childrenRect.width
        height: childrenRect.height
        color: "#000000"
        opacity: .8
        radius: 5

        MouseArea {
            anchors.fill: parent
            onClicked: mouse.accepted = true
            onWheel: wheel.accepted = true
        }

        ColumnLayout {
            Text {
                Layout.margins: 2
                Layout.alignment: Qt.AlignHCenter
                text: qsTr("Draped mode")
                color: "white"
            }

            Switch {
                id: surfacePlacementMode
                Layout.alignment: Qt.AlignHCenter
                Layout.margins: 2

                onCheckedChanged: changeDrapedVisibility();
            }
        }
    }

    Rectangle {
        anchors {
            top: parent.top
            right: parent.right
            margins: 5
        }
        width: childrenRect.width
        height: childrenRect.height
        color: "#000000"
        opacity: .8
        radius: 5

        MouseArea {
            anchors.fill: parent
            onClicked: mouse.accepted = true
            onWheel: wheel.accepted = true
        }

        ColumnLayout {
            Text {
                id: zValueSliderLabel
                text: qsTr("Z-Value")
                color: "white"
                Layout.margins: 2
                Layout.alignment: Qt.AlignHCenter
            }

            Slider {
                id: zValueSlider
                from: 0
                to: 140
                value: 70
                Layout.alignment: Qt.AlignHCenter
                Layout.margins: 2
                orientation: Qt.Vertical

                onMoved: changeZValue(value);

                // Custom slider handle that displays the current value
                handle: Item {
                    x: parent.leftPadding + parent.availableWidth / 2 - headingHandleNub.width / 2
                    y: parent.topPadding + parent.visualPosition * (parent.availableHeight - headingHandleNub.height)

                    Rectangle {
                        id: headingHandleNub
                        color: headingHandleRect.color
                        radius: width * 0.5
                        width: 20
                        height: width
                    }
                    Rectangle {
                        id: headingHandleRect
                        height: childrenRect.height
                        width: childrenRect.width
                        radius: 3
                        x: headingHandleNub.x - width
                        y: headingHandleNub.y - height / 2 + headingHandleNub.height / 2
                        color: zValueSlider.background.children[0].color

                        Text {
                            id: headingValue
                            font.pixelSize: 14
                            padding: 3
                            horizontalAlignment: Qt.AlignHCenter
                            verticalAlignment: Qt.AlignVCenter
                            text: (zValueSlider.value).toFixed(0)
                            color: "white"
                        }
                    }
                }
            }
        }
    }
    //! [add a sceneView component]
}

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