Retrieve layer simple line symbol color

576
6
Jump to solution
01-28-2022 06:19 PM
DavidPuckett
Occasional Contributor

How do I retrieve the color of a simple line symbol from specific layers in a web map?

I'm using an existing web map and want to create my own symbols for 3 of the layers in the map. I am able to create the full legend via the sample but I'm struggling to simply grab colors. In the image below, the full legend created from the LegendInfoListModel is at the bottom in the tab but I need to color the rectangles at the top according to the legend info (hard coded now). I am a web developer so perhaps am missing a pattern here. Any help?

DavidPuckett_0-1643422460249.png

 

0 Kudos
1 Solution

Accepted Solutions
JamesBallard1
Esri Regular Contributor

@DavidPuckett interesting, yes could be something with the data. I am getting the name printed out, but it does depend on which legendInfo it is, and it will also depend on the source data online and whether that contains any name info.

Row {
    Component.onCompleted: {
        if (index !== -1) {
            let legendInfo = map.legendInfos.get(index);
            console.log(legendInfo.name);
        }
    }

Using that with the sample prints as follows as I scroll through the legend:

qml: 0 - 61
qml: 62 - 264
qml: 265 - 759
qml: 760 - 1900
qml: 1901 - 9409
qml: 
qml: 
qml: 
qml: Camping
qml: Dining
qml: Drinking Water
qml: Medical Facility

 

You can see that some of the legend entries here don't contain any "label"

https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/legend?f=pjson 

View solution in original post

0 Kudos
6 Replies
Nicholas-Furness
Esri Regular Contributor

Hi David.

If you have the legend info, you should have access to the symbol.

How you get the color out of that symbol will depend on the type of symbol and how the web map was authored, but explore the various symbol types (SimpleLineSymbol, CompositeSymbol, MultilayerPolylineSymbol) which should eventually lead you to a color.

Hope that helps.

DavidPuckett
Occasional Contributor

Thanks for this Nick, I should have provided more detail however. I am having 2 issues that are keeping me from applying colors dynamically:

  1. The legendInfo.name property returns an empty string for every legendInfo item so I am not able to find specific legend items to grab the color from
  2. I cannot capture the map.legendInfos because the onFetchLegendInfosStatusChanged signal returns an error (when placed within the Map item).

For now I am using the operationalLayers to get the color for specific layers via the renderer like so:

operationalLayers.forEach(layer =>
    {
        // only way i can see to identify layers is by name, brittle but...
        if(layer.name === "Serviced 3+ Hours Ago") {
          servicedRoute3PlusHoursLayerLegendColor = layer.renderer.symbol.color;
        }
        else if(layer.name === "Serviced 1-3 Hours Ago") {
          servicedRoute1To3HoursLayerLegendColor = layer.renderer.symbol.color;
        }
        else if(layer.name === "Serviced Less Than 1 Hour Ago") {
          servicedRoute1HourLayerLegendColor = layer.renderer.symbol.color;
        }
        else if(layer.name === "Closed Road") {
          closedRoadLayerLegendColor = layer.renderer.symbol.color;
        }
    })

I am certainly open to using legendInfos if these issues can be resolved and share with the community here.

0 Kudos
JamesBallard1
Esri Regular Contributor

Hi @DavidPuckett,

Looks like you're on the right track. Take a look at our QML BuildLegend sample for some guidance.

https://github.com/Esri/arcgis-runtime-samples-qt/tree/main/ArcGISRuntimeSDKQt_QMLSamples/DisplayInf... 

A few things you want to check for are to be sure that the autoFetchLegendInfos property on the map is set to true. That will make sure all the legend infos came down automatically without extra work on your part.

https://github.com/Esri/arcgis-runtime-samples-qt/blob/main/ArcGISRuntimeSDKQt_QMLSamples/DisplayInf...

After that, if your symbol types in the model are SimpleLineSymbol types, you should be able to pull out the color.

Here's a minor tweak I added to the sample I mentioned. It shows the basic idea of accessing each LegendInfo from the model's delegate and printing the color if it's a SimpleLineSymbol.

// Create a list view to display the legend
ListView {
    id: legendListView
    anchors.margins: 10
    width: 165
    height: 150
    clip: true
    model: map.legendInfos

    // Create delegate to display the name with an image
    delegate: Item {
        width: parent ? parent.width : 0
        height: 35
        clip: true

        Row {
            Component.onCompleted: {
                if (index !== -1) {
                    let symbol = map.legendInfos.get(index).symbol;
                    if (symbol && symbol.symbolType === Enums.SymbolTypeSimpleLineSymbol) {
                        // this symbol is a simple line symbol, print the color
                        console.log(symbol.color);
                    }
                }
            }

 

Let us know if this helps.

DavidPuckett
Occasional Contributor

Thank you, yes, this is helpful to get a hook into when I can grab those colors. I didn't know you could add a completed signal to the Row, good to know. I'm still not getting the name property of the legendInfo item back however. It is an empty string which makes me wonder if it has to do with the source web map and\or how it is handled. Any insights there would be much appreciated.

0 Kudos
JamesBallard1
Esri Regular Contributor

@DavidPuckett interesting, yes could be something with the data. I am getting the name printed out, but it does depend on which legendInfo it is, and it will also depend on the source data online and whether that contains any name info.

Row {
    Component.onCompleted: {
        if (index !== -1) {
            let legendInfo = map.legendInfos.get(index);
            console.log(legendInfo.name);
        }
    }

Using that with the sample prints as follows as I scroll through the legend:

qml: 0 - 61
qml: 62 - 264
qml: 265 - 759
qml: 760 - 1900
qml: 1901 - 9409
qml: 
qml: 
qml: 
qml: Camping
qml: Dining
qml: Drinking Water
qml: Medical Facility

 

You can see that some of the legend entries here don't contain any "label"

https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/legend?f=pjson 

0 Kudos
DavidPuckett
Occasional Contributor

Right, this is interesting. First, it appears that the 'name' property in legendInfo is the 'label' in the legend item. And, if there is only a single symbol for the layer, the name is not included in the legendInfo item. This is a good explanation of what's going on albeit a little confusing to navigate. So really what I was after was the layerName and that isn't found within legendInfos. Now if I were using unique symbols for example it would be useful.

So ultimately, for my situation, getting the symbol colors directly from the layer renderers was the solution.

This latest example provided the clarity to get there and hopefully others with issues around legendInfos will find it useful.

0 Kudos