QGIS – How to Create Dynamic Filenames Based on Attribute Values in QGIS Model

file pathqgisqgis-3qgis-modelersave

Basic idea

Every user running a model selects a folder where the output of the model, a raster, should be stored as a file. The filename should be created automatically, based on an attribute value (timestamp) to succesively store the output of the same workflow for inputs representing different moments in time.

Context

I created a model with QGIS 3.26 that does the following: 1) download a JSON-file from an URL, 2) load the file in QGIS as point layer, 3) run v.surf.rst to create an interpolated surface (raster). For Model Output of v.surf.rst, I set a name. When I now run the model, I am prompted to define manually a filepath + filename where the output should be saved to. This model runs perfectly.

The problem

The online JSON-file is updated in regular intervals. So the model should run repeatedly and it should grab the timestamp in the attribute named time of the downloaded JSON file. The filename should be created based on the timestamp, avoiding to create manually a filename each time the model runs and to have consistent filenames reflecting the time they represent.

What I tried

I added a File/Folder input named save_to, type set to Folder: it promts me to select a folder when I run the model (this is because the modul should run on different machines for different users).

The idea now is to use this folder path for the output. I thus set the output value to Pre-calculated Value and use the created variable @save_to using this expression: @save_to || 'output.tif'. Like this, the file is saved to the path defined in the prompt when running the model under the static filename output.tif.

Question / where I'm stuck

The last step is now to make this filename dynamic, based on the attribute field name time from the layer I downloaded. How to do this?

enter image description here

Best Answer

Playing around, I finally succeeded with the following syntax. The variable @Load_layer_into_project_OUTPUT is created automatically: it stores the layer that is loaded in step 2 of the model, the Load layer into project algorithm.

This varible can be used to access the field called time of this layer with:

  1. get_feature_by_id () to get one of the features of the layer
  2. attribute() to get the value of the attribute time
  3. string to convert the timestamp to a text/string
  4. format the text string with regex to a proper format for a filename (not represented here to make the expression easier to read)
  5. concatenate using pipes ||: file path (stored in variable @save_to), the filename from above (steps 1-4) plus the file-extension .tif.

All together, the expression to create path to folder selected in input + dynamic filename based on attribute field time looks like:

    @save_to ||  
    to_string (
        attribute ( 
            get_feature_by_id ( 
                @Load_layer_into_project_OUTPUT, 
                1
            ),
            'time'
        )
    ) || 
    '.tif'

enter image description here


Edit: the Download File part, by the way, looks like this:

URL:

https://data.geo.admin.ch/ch.meteoschweiz.messwerte-lufttemperatur-10min/ch.meteoschweiz.messwerte-lufttemperatur-10min_de.json

File Destination:

replace ( @save_to  || '\\', '\\\\', '\\' ) || 
left( regexp_replace(to_string (now()),'(-|T|:)','_'), 16)|| 
'.json'

enter image description here

The Load Layer into project looks like this:

Layer: select Algorithm Output and then "File destination" from algorithm "Download file"

Loaded Layer name:

'measurement_' || left( regexp_replace(to_string (now()),'(-|T|:)','_'), 16)

enter image description here

Related Question