3

How can I get an array of all visible layer names automatically using QGIS expressions? In principle it should work with the variable @map_layers. Using the following expression works fine for what I want to do, but only in a semi-manual way:

array (
    layer_property( 
        array_get (
            @map_layers , 
            0
        ), 
       'name'), 
    layer_property( 
        array_get (
            @map_layers , 
            1
        ), 
        'name'
    )
)

I have to add manually an array_get (@map_layers, [index]) statement for each layer. I would rather like to iterate and get all visible layers automatically, indifferent of how many layers are visible. In a first step, I calculate the no. of visible layers: array_length (array_first (array ( @map_layers ))) (abbreviated no_visible in the next expression).

Where I'm stuck is iterating to create the layer name for for each visible layer. I tried the following expression, but it returns no results: No feature was found on this layer to evaluate the expression.

array_foreach (
    generate_series(0,[no_visible]),
    layer_property ( 
        array_get (
            @map_layers , 
            @element
        ),
        'name'
    )
)

What am I doing wrong?

Update: The expression in itself seems to be correct, even though the one offered by @lejedi76 is more elegant to achieve the same goal. However, the behavior of QGIS is quite buggy when using either of these expressions to select several (raster) layers at once as input for a tool in batch mode - see https://gis.stackexchange.com/a/385917/88814 for details.

1 Answer 1

4

I don't think you're doing wrong. It's a little bug (in the model) but it works. I just tested on QGIS 3.16.3 by setting a variable and it works.

By the way, you could just do :

array_to_string(
  array_foreach ( 
    @map_layers,
    layer_property(@element,'name')
  )
)

Demo

enter image description here

Model (.model3)

<!DOCTYPE model>
<Option type="Map">
  <Option name="children" type="Map">
    <Option name="native:setprojectvariable_1" type="Map">
      <Option name="active" type="bool" value="true"/>
      <Option name="alg_config"/>
      <Option name="alg_id" type="QString" value="native:setprojectvariable"/>
      <Option name="color" type="QString" value=""/>
      <Option name="comment" type="Map">
        <Option name="color" type="QString" value=""/>
        <Option name="component_description" type="QString" value=""/>
        <Option name="component_height" type="double" value="60"/>
        <Option name="component_pos_x" type="double" value="464"/>
        <Option name="component_pos_y" type="double" value="392"/>
        <Option name="component_width" type="double" value="100"/>
        <Option name="outputs_collapsed" type="bool" value="true"/>
        <Option name="parameters_collapsed" type="bool" value="true"/>
      </Option>
      <Option name="component_description" type="QString" value="Setting variable with visible layers"/>
      <Option name="component_height" type="double" value="30"/>
      <Option name="component_pos_x" type="double" value="511"/>
      <Option name="component_pos_y" type="double" value="318"/>
      <Option name="component_width" type="double" value="200"/>
      <Option name="dependencies"/>
      <Option name="id" type="QString" value="native:setprojectvariable_1"/>
      <Option name="outputs"/>
      <Option name="outputs_collapsed" type="bool" value="true"/>
      <Option name="parameters_collapsed" type="bool" value="true"/>
      <Option name="params" type="Map">
        <Option name="NAME" type="List">
          <Option type="Map">
            <Option name="source" type="int" value="2"/>
            <Option name="static_value" type="QString" value="Visible_layers"/>
          </Option>
        </Option>
        <Option name="VALUE" type="List">
          <Option type="Map">
            <Option name="expression" type="QString" value="array_to_string(array_foreach ( @map_layer_ids,&#xa;layer_property(@element,'name')))"/>
            <Option name="source" type="int" value="3"/>
          </Option>
        </Option>
      </Option>
    </Option>
  </Option>
  <Option name="designerParameterValues" type="Map">
    <Option name="VERBOSE_LOG" type="bool" value="true"/>
    <Option name="test" type="datetime" value="2021-01-30T18:21:02"/>
  </Option>
  <Option name="groupBoxes"/>
  <Option name="help"/>
  <Option name="modelVariables"/>
  <Option name="model_group" type="QString" value="test"/>
  <Option name="model_name" type="QString" value="visible_layers"/>
  <Option name="parameterDefinitions" type="Map">
    <Option name="test" type="Map">
      <Option name="data_type" type="int" value="0"/>
      <Option name="default" type="invalid"/>
      <Option name="defaultGui" type="invalid"/>
      <Option name="description" type="QString" value="test"/>
      <Option name="flags" type="int" value="0"/>
      <Option name="help" type="QString" value=""/>
      <Option name="max" type="datetime" value=""/>
      <Option name="metadata"/>
      <Option name="min" type="datetime" value=""/>
      <Option name="name" type="QString" value="test"/>
      <Option name="parameter_type" type="QString" value="datetime"/>
    </Option>
  </Option>
  <Option name="parameterOrder"/>
  <Option name="parameters" type="Map">
    <Option name="test" type="Map">
      <Option name="color" type="QString" value=""/>
      <Option name="comment" type="Map">
        <Option name="color" type="QString" value=""/>
        <Option name="component_description" type="QString" value=""/>
        <Option name="component_height" type="double" value="60"/>
        <Option name="component_pos_x" type="double" value="528"/>
        <Option name="component_pos_y" type="double" value="168"/>
        <Option name="component_width" type="double" value="100"/>
        <Option name="outputs_collapsed" type="bool" value="true"/>
        <Option name="parameters_collapsed" type="bool" value="true"/>
      </Option>
      <Option name="component_description" type="QString" value="test"/>
      <Option name="component_height" type="double" value="30"/>
      <Option name="component_pos_x" type="double" value="328"/>
      <Option name="component_pos_y" type="double" value="213"/>
      <Option name="component_width" type="double" value="200"/>
      <Option name="name" type="QString" value="test"/>
      <Option name="outputs_collapsed" type="bool" value="true"/>
      <Option name="parameters_collapsed" type="bool" value="true"/>
    </Option>
  </Option>
</Option>
9
  • It's strange, in my setting (QGIS 3.16.2 on Win 10), neither of these two expressions works. I want to use the expression to select several layers as input for a tool in batch mode and I always get this same error No feature was found on this layer to evaluate the expression. But also when I try to repeat your steps, creating a model, I get an empty output: i.stack.imgur.com/gPhwD.png - does it have to do with the fact that I'm using raster layers?
    – Babel
    Jan 30, 2021 at 20:14
  • You didn't do exactly the same. Switch to precalculated value (sigma icon ) instead of value (123 icon).
    – lejedi76
    Jan 30, 2021 at 20:19
  • I should have had the .model3 before. Sorry for that.
    – lejedi76
    Jan 30, 2021 at 20:26
  • I tested it with your model - same (empty) output - very strange!
    – Babel
    Jan 30, 2021 at 20:40
  • 1
    If you have a repository or a ressource sharing, I'm very interested by your work. Happy to help. By the way, I test a merge algorithm with the formula without the string_to_array part and it works like a charm. It merges all the visible layer. I wouldn't have thought of that.
    – lejedi76
    Jan 30, 2021 at 20:57

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.