Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for Qt

Scene properties expressions

Sample Viewer View Sample on GitHub

Update the orientation of a graphic using expressions based on its attributes.

Use case

Instead of reading the attribute and changing the rotation on the symbol for a single graphic (a manual CPU operation), you can bind the rotation to an expression that applies to the whole overlay (an automatic GPU operation). This usually results in a noticeable performance boost (smooth rotations).

How to use the sample

Adjust the heading and pitch sliders to rotate the cone.

How it works

  1. Create a new graphics overlay.
  2. Create a simple renderer and set its scene properties.
  3. Set the heading expression to [HEADING].
  4. Apply the renderer to the graphics overlay.
  5. Create a graphic and add it to the overlay.
  6. To update the graphic's rotation, update the HEADING or PITCH property in the graphic's attributes.

Relevant API

  • Graphic.attributes
  • GraphicsOverlay
  • SceneProperties
  • SceneProperties.headingExpression
  • SceneProperties.pitchExpression
  • SimpleRenderer
  • SimpleRenderer.rendererSceneProperties

Tags

3D, expression, graphics, heading, pitch, rotation, scene, symbology

Sample Code

import QtQuick 2.6
import Esri.ArcGISRuntime 100.9
import QtQuick.Controls 2.2

Rectangle {
    id: rootRectangle
    clip: true
    width: 800
    height: 600

    readonly property real longitude: -118.71
    readonly property real latitude: 32.09
    readonly property real altitude: 100000.0
    readonly property int coneDimension: 10000
    readonly property real initialPitch: 90.0
    readonly property real initialHeading: 180.0
    readonly property string headingStr: "heading"
    readonly property string pitchStr: "pitch"

    SceneView {
        id: sceneView
        anchors.fill: parent

        Scene {
            id: scene
            BasemapImagery {}

            Surface {
                ArcGISTiledElevationSource {
                    url: "http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
                }
            }
        }

        // add a graphics overlay
        GraphicsOverlay {
            id: graphicsOverlay
            LayerSceneProperties {
                surfacePlacement: Enums.SurfacePlacementAbsolute
            }

            SimpleRenderer {
                id: sceneRenderer
                RendererSceneProperties {
                    id: renderProps
                    headingExpression: "["+headingStr+"]"
                    pitchExpression:  "["+pitchStr+"]"
                }
            }

            Graphic {
                id: coneGraphic

                geometry: Point {
                    x: longitude
                    y: latitude
                    z: altitude
                    spatialReference: sceneView.spatialReference
                }

                SimpleMarkerSceneSymbol{
                    style: Enums.SimpleMarkerSceneSymbolStyleCone
                    color: "red"
                    width: coneDimension
                    depth: coneDimension
                    height: coneDimension * 2
                    anchorPosition: Enums.SceneSymbolAnchorPositionCenter
                }

                Component.onCompleted: {
                    coneGraphic.attributes.insertAttribute(headingStr, initialHeading);
                    coneGraphic.attributes.insertAttribute(pitchStr, initialPitch);
                }
            }
        }

        Component.onCompleted: {
            // set viewpoint to the specified camera
            setViewpointCameraAndWait(camera);
        }
    }

    Rectangle {
        anchors.fill: sliderColumn
        color: "lightblue"
    }

    Column{
        id: sliderColumn

        spacing: 4

        anchors {
            left: parent.left
            top: parent.top
        }

        height: childrenRect.height

        Text {
            anchors {
                margins: 5
            }
            text: pitchStr + ": " + pitchSlider.value.toFixed(0)
            font.pixelSize: 20
            verticalAlignment: Text.AlignTop
        }

        Slider{
            id: pitchSlider
            opacity: 0.7
            height: 64

            // slider controls degrees of rotation:
            from: -90
            to: 90
            value: initialPitch
            anchors {
                margins: 5
            }

            onValueChanged: {
                coneGraphic.attributes.replaceAttribute(pitchStr, value);
            }
        }

        Text {
            anchors {
                margins: 5
            }
            text: headingStr + ": " + headingSlider.value.toFixed(0)
            verticalAlignment: Text.AlignTop
            font.pixelSize: 20
        }

        Slider{
            id: headingSlider
            opacity: 0.7
            height: 64

            // slider controls degrees of rotation:
            from: 0
            to: 360
            value: initialHeading
            anchors {
                margins: 5
            }

            onValueChanged: {
                coneGraphic.attributes.replaceAttribute(headingStr, value);
            }
        }
    }

    Camera {
        id: camera
        heading: 0.0
        pitch: 45.0
        roll: 0.0

        Point {
            x: longitude
            y: latitude - 1.0 // place the camera somewhat south of the cone
            z: altitude * 2.0 // place the camera somewhat higher than the cone
            spatialReference: SpatialReference { wkid: 4326 }
        }
    }
}