5

CONTEXT

I have several raster layers which overlap. I created a point layer with labels that represent different values for each of these raster layers. I created a function that

  • lists all layer names in the canvas
  • if the layer in the canvas is checked, its name is compared to a list string representing layer names that I would like to label.
  • if they match, then the function returns a string that represents a string representing the field name.

When I use this function for labeling, I still need to use eval() to get the value I want to show as a label.

Is there a way to skip from using eval()?

The function is shown below:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def raster_label(feature, parent):
    field_list = ["LAYER_A", "LAYER_B", "LAYER_C", "LAYER_D"]
    raster_layer_name_list = ["A", "B", "C", "D"]
    field_to_show = ""

    # create a list with all layers in the canvas
    layers_list = []
    root = QgsProject.instance().layerTreeRoot()
    for child in root.children():
        if isinstance(child, QgsLayerTreeGroup):
            get_group_layers(child)
        elif isinstance(child, QgsLayerTreeLayer):
            layers_list.append(child.name())
        
    # iterate over all items in layer list ...
    for item in range(0, len(layers_list)):
        l = QgsProject().instance().mapLayersByName(layers_list[item])
        node = root.findLayer(l[-1])
        # then identify if the layer is checked ...
        if node.isVisible() == True:
            # to compare agains the raster_layer_name_list ...
            for raster in range(0, len(raster_layer_name_list)):
                # returning then the corresponding field
                if l[0].name() == raster_layer_name_list[raster]:
                    field_to_show = field_list[raster]
                    break
            if field_to_show != "":
                break
        if field_to_show != "":
            break
    
    return field_to_show

1 Answer 1

6

You cannot avoid using eval as long as you return a field name (it is a string) to the expression area. It will be considered as a string in Expression Dialog.

But you can use the conditional return instead of return field_to_show as follows:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def raster_label(feature, parent):
    
    #
    # previous lines
    #

    if field_to_show = "":
        return ""
    else:
        return feature[field_to_show]




0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.