Select to view content in your preferred language

Accessing LegendInfoListModel QML Roles outside of ListView

1320
3
02-11-2021 10:12 AM
DrewMorris
New Contributor II

Hello,

I'm trying to create a dynamic Legend component object using a LegendInfoListModel from a separate component. I am able to access the roles found here when I use a ListView, but I also need to access these roles in other functions within the Legend component, but they just return undefined. I've tried using the forEach and get method(s) but can only access name and symbol from the LegendInfo type. Are these roles able to be used via other means? I've read this post but it only specifies for the case of symbol, and so I was looking for a broader explanation of use.

Thanks!

Tags (3)
0 Kudos
3 Replies
LucasDanzinger
Esri Frequent Contributor

The roles are primarily there for use within delegates/views.  We tried to create it so it had smart defaults and would plug into a view easily, so sometimes that involved doing some plumbing to retrieve the information that ultimately gets exposed as a role.

 

If you want to access the values of the roles outside of the view/delegate, instead of getting the LegendInfoListModel off of the Map, you could instead, loop through the Map's operational layers - this will give you a Layer object, which contains much of the information you need. 

 

Here are a list of roles accessible on the LegendInfoListModel and how you can access the info programmatically:

 

- name - get the name string directly from the LegendInfo object

- symbolUrl - get the Symbol from LegendInfo, then access the Symbol.swatchImage property

- symbolHeight - get the Symbol from LegendInfo, then get/set SwatchOptions via Symbol.swatchOptions

- symbolWidth - get the Symbol from LegendInfo, then get/set SwatchOptions via Symbol.swatchOptions

- layerMinScale - get from the Layer (Loop through the map's operational layers, and for each layer, get the min/max scale and legend infos)

- layerMaxScale -get from the Layer (Loop through the map's operational layers, and for each layer, get the min/max scale and legend infos)

 

Hope that helps get you on the right track

0 Kudos
rob_hewy
Occasional Contributor

In the future could the symbolUrl role be added to UniqueValueListModel

https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-uniquevaluelistmodel.html

Currently the roles are:

  • description
  • label
  • values

The reason is that the values[0] typically lines up with an editing template and the symbols in the legend can be in a different order than the templates.

rob_hewy_0-1614051734586.png

 

 

rob_hewy
Occasional Contributor

Hi Drew,

Hopefully you have solved your problem. If not, maybe the code below might give you some ideas. I was going to the layer's render (unique value in my case) and I was getting a lot of undefined issues too. The magic line for me was type casting (I use that term loosely here) the generic symbol to a specific implementation (my symbols were type 11)  then things started to work (line 71):

 

// ==============================================================================
// File         : MyApp.QML
//
// Current Author: Robert Hewlett
//
// Previous Author: None
//
// Contact Info: rob.hewy@gmail.com
//
// Purpose : Demo a unique value render to listview
//           using role data and data off the role
//
// Dependencies: ArcGIS QT runtime
//
// Modification Log :
//    --> Created 2021-02-22 (rh)
//    --> Updated YYYY-MM-DD (fl)
//
// =============================================================================
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.12
import ArcGIS.AppFramework 1.0
import Esri.ArcGISRuntime 100.8
App {
    id: app
    width: 400
    height: 640
    // ====================================
    // SOP for display factor
    // =====================================
    property double scaleFactor: AppFramework.displayScaleFactor
    property UniqueValueListModel uniqueValues: null
    // ===============================================
    // Feature layer to get a unique value renderer
    // ===============================================
    FeatureLayer{
        id:featLyr
        ServiceFeatureTable {
            url: 'https://services1.arcgis.com/KsnB2VOAvO5LjdB4/arcgis/rest/services/bcit_poi_short_no_space/FeatureServer/0'
        }
        onLoadStatusChanged: {
            if (loadStatus == Enums.LoadStatusLoaded)
            {
                uniqueValues = featLyr.renderer.uniqueValues
                lstViewValues.model = uniqueValues
                lstViewValues.visible = true
            }
        } // end of once loaded
    } // end of the FeatureLayer
    // ===============================================
    // need to see if this actually works
    // ===============================================
    ListView{
        id: lstViewValues
        anchors.fill: parent
        visible: false
        spacing: 20
        header: Text { text: "Unique Value Renderer"}
        delegate: Item {
            id: showUniqueValue
            height: 62*scaleFactor
            width: parent.width
            // ====================================================
            // This was the magic for me as my symbols were type 11
            // If I do not 'type cast' from a generic symbol to
            // MultilayerPointSymbol then type is -1, size is -1,-1
            // and swatchImage is null for aUniqueValue.symbol
            // =====================================================
            property UniqueValue aUniqueValue: uniqueValues.get(index)
            property MultilayerPointSymbol mlpSym: aUniqueValue.symbol
            Rectangle{
                anchors.fill: parent
                color: lstViewValues.currentIndex == index? "#d3d3d3":"#ffffff"
                ColumnLayout{
                    Image {
                        // ================================================
                        // As a 'true' MultilayerPointSymbol the bind works
                        // ================================================
                        source: mlpSym.swatchImage
                    }
                    Text {
                        text: `Name in legend: ${label}` // data on a role
                    }
                    Text {
                        text: `Domain template: ${aUniqueValue.values[0]}` // off the role
                    }
                } // end of the row
                MouseArea{
                    anchors.fill: parent
                    onClicked: { lstViewValues.currentIndex = index}
                }
            } // end of the rectangle
        } // end of the delegate
    } // end of the list view
    Component.onCompleted: {
        // ===========================================================
        // This sample is not inside a map so I had to force the load
        // ===========================================================
        featLyr.load();
    }
} // end of the app