How to display attribute values when clicking a point from a feature server?

927
4
Jump to solution
07-13-2018 06:37 AM
KyleSchultz
New Contributor

I want to click on a point to display attributes from a feature server.  The only tutorial/sample I could find was from App Studio v1.4  sample on github and too much has changed to get it working.

Currently my code looks like this

        onMouseClicked: {
            var tolerance = 22;
            var returnPopupsOnly = false;
            var maximumResults = 1;
            mapView.identifyLayerWithMaxResults(featureLayer, mouse.x, mouse.y, tolerance, returnPopupsOnly, maximumResults);
        }
        onIdentifyLayerStatusChanged: {
            if (identifyLayerStatus === Enums.TaskStatusCompleted) {
        
                featureLayer.clearSelection();
                var identifiedObjects = [];
                for (var i = 0; i < identifyLayerResult.geoElements.length; i++){
                    var elem = identifyLayerResult.geoElements[i];
                    identifiedObjects.push(elem);
                }
                var count = identifyLayerResult.geoElements.length;
                featureLayer.selectFeatures(identifiedObjects);
            }
        }

Which is just code I took from the selecting feature app sample.

I have this code

                        onSelectFeaturesStatusChanged: {
                
                            if (selectFeaturesStatus === Enums.TaskStatusCompleted) {
                                if (!selectFeaturesResult.iterator.hasNext)
                                    return;
                                selectedFeature = selectFeaturesResult.iterator.next();
                                value= selectedFeature.attributes.attributeValue("attributeValue");
                                console.log(value)
                            }


but it does not get invoked because selectFeatures apparently doesn't call
onSelectFeaturesStatusChanged? 





I find this all very frustrating, this should be extremely simple to do but there is no documentation that has been properly maintained
That even suggests how to properly accomplish this.

0 Kudos
1 Solution

Accepted Solutions
nakulmanocha
Esri Regular Contributor

Hi Kyle,

Sorry to hear that. Yes it is quite simple to get attributes from the GeoElement. GeoElement has a sub class called Feature and Feature provides a property called attributes which is a ListModel (the model name is AttributeListModel in Runtime) that has the attribute names and value listed.

However, showing it in a dialog or a popup is a UI aspect and it can vary on the users requirement. This can be done in many ways.

AttributeListModel QML Type | ArcGIS for Developers 

But just to give you a proof of concept I have provided a code snippet below for you to show how we can tweak the Feature Layer Selection Sample to show the feature attributes when you click on the feature. In this sample I have added a Dialog known as Pane which show all the attribute values along with the name using the AttributeListModel to show the attributes. 

property real scaleFactor: AppFramework.displayScaleFactor
    property string displayText: "Click or tap to select features."

    ListModel{
        id:displayAttributesModel
    }

    // Map view UI presentation at top
    MapView {
        id: mapView
        anchors {
            left: parent.left
            right: parent.right
            top: parent.top
            bottom: messageBar.top
        }
        wrapAroundMode: Enums.WrapAroundModeDisabled

        Map {
            id: map
            BasemapStreets {}

            FeatureLayer {
                id: featureLayer

                selectionColor: "cyan"
                selectionWidth: 3

                // feature table
                ServiceFeatureTable {
                    id: featureTable
                    url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0"


                }               
            }

            onLoadStatusChanged: {
                if (loadStatus === Enums.LoadStatusLoaded) {
                    mapView.setViewpoint(viewPoint);
                }
            }
        }

        // initial viewpoint
        ViewpointCenter {
            id: viewPoint
            Point {
                x: -10800000
                y: 4500000
                spatialReference: SpatialReference {
                    wkid: 102100
                }
            }
            targetScale: 3e7
        }

        //! [identify feature layer qml api snippet]
        onMouseClicked: {
            var tolerance = 22;
            var returnPopupsOnly = false;
            var maximumResults = 1000;
            mapView.identifyLayerWithMaxResults(featureLayer, mouse.x, mouse.y, tolerance, returnPopupsOnly, maximumResults);
        }

        onIdentifyLayerStatusChanged: {
            if (identifyLayerStatus === Enums.TaskStatusCompleted) {
                // clear any previous selections
                featureLayer.clearSelection();
                displayAttributesModel.clear();

                // create an array to store the features
                var identifiedObjects = [];
                for (var i = 0; i < identifyLayerResult.geoElements.length; i++){
                    var elem = identifyLayerResult.geoElements;
                    identifiedObjects.push(elem);
                    displayAttributesModel.append(elem);

                }
                // cache the number of identifyLayerResult
                var count = identifyLayerResult.geoElements.length;

                // select the features in the feature layer
                featureLayer.selectFeatures(identifiedObjects);
                displayText = "%1 %2 selected.".arg(count).arg(count > 1 ? "features" : "feature");
            }
        }
        //! [identify feature layer qml api snippet]

        // Busy Indicator
        BusyIndicator {
            anchors.centerIn: parent
            height: 48 * scaleFactor
            width: height
            running: true
            Material.accent:"#8f499c"
            visible: (mapView.drawStatus === Enums.DrawStatusInProgress)
        }
    }

    Pane {
        id: attributeViewDialog
        Material.primary: "white"
        Material.elevation:2
        padding: 5 * scaleFactor
        visible: displayAttributesModel.count > 0

        x: 10 * scaleFactor
        y: 10 * scaleFactor
        SwipeView{
            id:swipeView
            implicitHeight: 150 * scaleFactor
            implicitWidth: 175 * scaleFactor
            clip: true
            Repeater {
                model:displayAttributesModel
                Rectangle{
                    color: "white"
                    clip: true
                    Flickable {
                        anchors.fill:parent
                        contentWidth:parent.width
                        contentHeight: popupColumn.height
                        clip: true
                        flickableDirection: Flickable.VerticalFlick
                        ColumnLayout {
                            id: popupColumn
                            width: parent.width *  0.95
                            anchors.horizontalCenter: parent.horizontalCenter
                            spacing: 3 * scaleFactor
                            clip: true
                            Text {
                                Layout.preferredWidth:  parent.width
                                id:itemDesc
                                text: attributes.attributeValue("objectid")
                                elide: Text.ElideRight
                                color: "red"
                                font {
                                    family: "serif"
                                    pixelSize: 14 * scaleFactor
                                    bold: true
                                }
                                renderType: Text.NativeRendering
                            }
                            Rectangle {
                                Layout.preferredWidth: parent.width
                                Layout.preferredHeight: 2 * scaleFactor
                                color: "black"
                            }
                            Repeater {
                                model: attributes
                                RowLayout {
                                    Layout.fillWidth: true
                                    clip: true
                                    spacing: 5 * scaleFactor

                                    Text {
                                        Layout.preferredWidth: popupColumn.width * 0.55
                                        Layout.fillHeight: true
                                        text:  attributeName
                                        wrapMode: Text.WrapAnywhere
                                        font.pixelSize: 12 * scaleFactor
                                        color: "gray"
                                    }

                                    Text {
                                        Layout.fillWidth: true
                                        Layout.fillHeight: true
                                        text:attributeValue
                                        wrapMode: Text.WrapAnywhere
                                        font.pixelSize: 12 * scaleFactor
                                        color: "#4f4f4f"

                                    }
                                }
                            }
                        }
                    }
                }
            }


        }

    }

    Rectangle {
        id: messageBar
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        height: 30 * scaleFactor
        color: "lightgrey"
        border {
            width: 0.5 * scaleFactor
            color: "black"
        }

        Text {
            id: msgText
            anchors {
                verticalCenter: parent.verticalCenter
                left: parent.left
                leftMargin: 10 * scaleFactor
            }
            text: displayText
            font.pixelSize: 14 * scaleFactor
        }
    }

If you notice in the code I added a SwipeView within the Pane to accommodate multiple selected features. Hence you can swipe horizontally to get to the next feature attributes if you would like.

I hope you find this useful. Thank you.

Nakul

View solution in original post

4 Replies
nakulmanocha
Esri Regular Contributor

Hi Kyle,

Sorry to hear that. Yes it is quite simple to get attributes from the GeoElement. GeoElement has a sub class called Feature and Feature provides a property called attributes which is a ListModel (the model name is AttributeListModel in Runtime) that has the attribute names and value listed.

However, showing it in a dialog or a popup is a UI aspect and it can vary on the users requirement. This can be done in many ways.

AttributeListModel QML Type | ArcGIS for Developers 

But just to give you a proof of concept I have provided a code snippet below for you to show how we can tweak the Feature Layer Selection Sample to show the feature attributes when you click on the feature. In this sample I have added a Dialog known as Pane which show all the attribute values along with the name using the AttributeListModel to show the attributes. 

property real scaleFactor: AppFramework.displayScaleFactor
    property string displayText: "Click or tap to select features."

    ListModel{
        id:displayAttributesModel
    }

    // Map view UI presentation at top
    MapView {
        id: mapView
        anchors {
            left: parent.left
            right: parent.right
            top: parent.top
            bottom: messageBar.top
        }
        wrapAroundMode: Enums.WrapAroundModeDisabled

        Map {
            id: map
            BasemapStreets {}

            FeatureLayer {
                id: featureLayer

                selectionColor: "cyan"
                selectionWidth: 3

                // feature table
                ServiceFeatureTable {
                    id: featureTable
                    url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0"


                }               
            }

            onLoadStatusChanged: {
                if (loadStatus === Enums.LoadStatusLoaded) {
                    mapView.setViewpoint(viewPoint);
                }
            }
        }

        // initial viewpoint
        ViewpointCenter {
            id: viewPoint
            Point {
                x: -10800000
                y: 4500000
                spatialReference: SpatialReference {
                    wkid: 102100
                }
            }
            targetScale: 3e7
        }

        //! [identify feature layer qml api snippet]
        onMouseClicked: {
            var tolerance = 22;
            var returnPopupsOnly = false;
            var maximumResults = 1000;
            mapView.identifyLayerWithMaxResults(featureLayer, mouse.x, mouse.y, tolerance, returnPopupsOnly, maximumResults);
        }

        onIdentifyLayerStatusChanged: {
            if (identifyLayerStatus === Enums.TaskStatusCompleted) {
                // clear any previous selections
                featureLayer.clearSelection();
                displayAttributesModel.clear();

                // create an array to store the features
                var identifiedObjects = [];
                for (var i = 0; i < identifyLayerResult.geoElements.length; i++){
                    var elem = identifyLayerResult.geoElements;
                    identifiedObjects.push(elem);
                    displayAttributesModel.append(elem);

                }
                // cache the number of identifyLayerResult
                var count = identifyLayerResult.geoElements.length;

                // select the features in the feature layer
                featureLayer.selectFeatures(identifiedObjects);
                displayText = "%1 %2 selected.".arg(count).arg(count > 1 ? "features" : "feature");
            }
        }
        //! [identify feature layer qml api snippet]

        // Busy Indicator
        BusyIndicator {
            anchors.centerIn: parent
            height: 48 * scaleFactor
            width: height
            running: true
            Material.accent:"#8f499c"
            visible: (mapView.drawStatus === Enums.DrawStatusInProgress)
        }
    }

    Pane {
        id: attributeViewDialog
        Material.primary: "white"
        Material.elevation:2
        padding: 5 * scaleFactor
        visible: displayAttributesModel.count > 0

        x: 10 * scaleFactor
        y: 10 * scaleFactor
        SwipeView{
            id:swipeView
            implicitHeight: 150 * scaleFactor
            implicitWidth: 175 * scaleFactor
            clip: true
            Repeater {
                model:displayAttributesModel
                Rectangle{
                    color: "white"
                    clip: true
                    Flickable {
                        anchors.fill:parent
                        contentWidth:parent.width
                        contentHeight: popupColumn.height
                        clip: true
                        flickableDirection: Flickable.VerticalFlick
                        ColumnLayout {
                            id: popupColumn
                            width: parent.width *  0.95
                            anchors.horizontalCenter: parent.horizontalCenter
                            spacing: 3 * scaleFactor
                            clip: true
                            Text {
                                Layout.preferredWidth:  parent.width
                                id:itemDesc
                                text: attributes.attributeValue("objectid")
                                elide: Text.ElideRight
                                color: "red"
                                font {
                                    family: "serif"
                                    pixelSize: 14 * scaleFactor
                                    bold: true
                                }
                                renderType: Text.NativeRendering
                            }
                            Rectangle {
                                Layout.preferredWidth: parent.width
                                Layout.preferredHeight: 2 * scaleFactor
                                color: "black"
                            }
                            Repeater {
                                model: attributes
                                RowLayout {
                                    Layout.fillWidth: true
                                    clip: true
                                    spacing: 5 * scaleFactor

                                    Text {
                                        Layout.preferredWidth: popupColumn.width * 0.55
                                        Layout.fillHeight: true
                                        text:  attributeName
                                        wrapMode: Text.WrapAnywhere
                                        font.pixelSize: 12 * scaleFactor
                                        color: "gray"
                                    }

                                    Text {
                                        Layout.fillWidth: true
                                        Layout.fillHeight: true
                                        text:attributeValue
                                        wrapMode: Text.WrapAnywhere
                                        font.pixelSize: 12 * scaleFactor
                                        color: "#4f4f4f"

                                    }
                                }
                            }
                        }
                    }
                }
            }


        }

    }

    Rectangle {
        id: messageBar
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        height: 30 * scaleFactor
        color: "lightgrey"
        border {
            width: 0.5 * scaleFactor
            color: "black"
        }

        Text {
            id: msgText
            anchors {
                verticalCenter: parent.verticalCenter
                left: parent.left
                leftMargin: 10 * scaleFactor
            }
            text: displayText
            font.pixelSize: 14 * scaleFactor
        }
    }

If you notice in the code I added a SwipeView within the Pane to accommodate multiple selected features. Hence you can swipe horizontally to get to the next feature attributes if you would like.

I hope you find this useful. Thank you.

Nakul

KyleSchultz
New Contributor

What libraries are you importing to get this to work?

0 Kudos
nakulmanocha
Esri Regular Contributor

If you are using Appstudio 3.0. Then the sample should have the libraries listed below

import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Material 2.1

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import Esri.ArcGISRuntime 100.2
KyleSchultz
New Contributor

Thank you for your response

.

Is it possible to control which values are displayed? I don't want some of the fields being displayed visible

0 Kudos