3

When I run a GDAL processing algorithm from the Python Console in QGIS that loads a result raster:

resultClip = processing.runAndLoadResults("gdal:cliprasterbymasklayer", { 
                                          'ALPHA_BAND' : False, 
                                          'CROP_TO_CUTLINE' : True, 
                                          'DATA_TYPE' : 0, 
                                          'EXTRA' : '', 
                                          'INPUT' : 'E:/geodata/nsw100k.vrt', 
                                          'KEEP_RESOLUTION' : False, 
                                          'MASK' : 'C:/Users/brennant/Downloads/data.geojson', 
                                          'MULTITHREADING' : False, 
                                          'NODATA' : None, 'OPTIONS' : '', 
                                          'OUTPUT' : 'TEMPORARY_OUTPUT', 
                                          'SET_RESOLUTION' : False, 
                                          'SOURCE_CRS' : None, 
                                          'TARGET_CRS' : None, 
                                          'X_RESOLUTION' : None, 
                                          'Y_RESOLUTION' : None })

I can access the temporary raster output file via resultClip['OUTPUT']

However, when I do the same thing with one of the Whitebox Tools algorithms (eg BreachDepressions):

resultBreach = processing.runAndLoadResults("wbt:BreachDepressions", { 'dem' : resultClip['OUTPUT'], 'max_depth' : '20.0', 'flat_increment' : 0.00001, 'fill_pits' : 1, 'output' : 'TEMPORARY_OUTPUT' })

resultBreach['output'] returns a QgsProcessingOutputLayerDefinition variable:

<QgsProcessingOutputLayerDefinition {'sink':TEMPORARY_OUTPUT, 'createOptions': {}}>}

The temporary layer is created and loaded in the layers window, but from a PyQGIS processing point of view, I can't see how to access it for use in future steps.

And if I look at both algorithms using processing.algorithmHelp eg

processing.algorithmHelp("gdal:cliprasterbymasklayer")

the output type for both is the same (QgsProcessingOutputRasterLayer)

Suggestions welcomed.

2 Answers 2

1

Temporary files are stored in special folders in your PC. When you turn it off, all temporary files are automatically deleted. For some reason, developers of Whitebox implemented an automatic deletion of files when they are created as 'TEMPORARY_OUTPUT' in a processing tool algorithm with 'run' and 'runAndLoadResults' methods. However, this is not a problem. In my Linux operating system, temporary files are stored in /tmp folder. If you use a Windows system you can read this article for information of where is TEMP Folder Location in that system.

For testing "wbt:BreachDepressions" tool, my output file (OutputFile.tif) was put in /tmp folder as parameter definitions. I used 'run' method for not retrieving it from that folder with that tool. So, in same code, for accessing created file, I can define a new layer as:

new_layer = QgsRasterLayer('/tmp/OutputFile.tif', 
            'OutputFile')

Only for visualization purpose, for proving this layer was created, I loaded it with 'addMapLayer' method of QgsProject. On the other hand, I also can probe it with:

>>>resultBreach['output']
'/tmp/OutputFile.tif'

in Python Console. This is a better option for use in future steps.

Complete code looks as follows:

import processing

layer = iface.activeLayer()

resultBreach = processing.run("wbt:BreachDepressions", 
                                          { 'dem' : layer, 
                                            'max_depth' : '20.0', 
                                            'flat_increment' : 0.00001, 
                                            'fill_pits' : 1, 
                                            'output' : '/tmp/OutputFile.tif' })

new_layer = QgsRasterLayer('/tmp/test.tif', 
            'OutputFile')

QgsProject.instance().addMapLayer(new_layer)

print("done");

After running above code in Python Console of QGIS, it works as expected.

enter image description here

3
  • Thanks, however the key point is that I am trying to avoid specifying a fixed file path in the processing.run step, because it will be system-dependent. For example, I'm on Windows, so I can't use your code without editing. If I can use PyQGIS to access the path of the file, then the code will be system-independent. I can do this for GDAL and SAGA tools, but not (currently) for WhiteBox tools. Commented Feb 19, 2021 at 20:46
  • That is not completely true. Based in this article askvg.com/… you will have TEMP and TMP variables in your Windows system (you only need to explore them). So, you can also do resultBreach['output'] and result will be equivalent to other processing tools. Code would be completely portable.
    – xunilk
    Commented Feb 19, 2021 at 21:29
  • As per the original question, resultBreach['output'] for Whitebox tools is not equivalent to other tools when TEMPORARY_OUTPUT is set. It's a QgsProcessingOutputLayerDefinition instead of a file path. I'm trying to access the file path. Commented Feb 19, 2021 at 22:19
0

This issue seems to be identical for the one raised in:

https://github.com/qgis/QGIS/issues/41719

and this is still an open issue.

The best workaround I have found is to use QgsProcessingUtils.generateTempFilename() to generate a temporary file. The main catch is that you need to pass a filename (and type), but QGIS handles the temporary folder requirements.

eg

resultBreach = processing.runAndLoadResults("wbt:BreachDepressions", { 
    'dem' : resultClip['OUTPUT'], 
    'max_depth' : '20.0', 
    'flat_increment' : 0.00001, 
    'fill_pits' : 1, 
    'output' : QgsProcessingUtils.generateTempFilename('output.tif') 
})

(From QGIS Processing algorithm output)

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.