15

After running Processing algorithm ending up with a layer by run or runAndLoadResults in QGIS 3, these methods return a result which is mostly a dictionary like {'OUTPUT': 'file_path'} etc. So, after result = processing.run*(...), I can get the output by result['OUTPUT']. But its value is mostly just a string.

Is there a way method that returns layer instance/reference directly, e.g. QgsVectorLayer, so that we can get the layer reference by writing just layer = processing.run*(...)["OUTPUT"]?

0

2 Answers 2

33

Please note that all solutions explained here are related to vector layer used as the input and QGIS native algorithms. The answer doesn't explain the results of other providers' tools. (GRASS, GDAL, SAGA, ...). They may be different from native ones.

QGIS 3:

  • OPTION 1: run() method with memory output:

      result = processing.run("native:buffer",
                              {'INPUT':'D:/foo/bar.shp', 
                               ... 
                               'OUTPUT':'TEMPORARY_OUTPUT'
                              })
    
      # OUTPUT
      #`result = {'OUTPUT': <qgis._core.QgsVectorLayer object at 0x00...>}`
    

Result is a dictionary. result['OUTPUT'] gives an instance of a layer (QgsVectorLayer). No layer is added. Option 1 is one and only solution that returns a reference for QgsVectorLayer in QGIS 3.

It can be used in the following way:

result_layer = processing.run("alg_name", {...,  "OUTPUT":'TEMPORARY_OUTPUT'})["OUTPUT"]

result_layer is now qgis._core.QgsVectorLayer. Since it's a memory layer, it should be added to the project using addMapLayer() method.

Other Processing Options

  • OPTION 2: run() method with file output:

      result = processing.run("native:buffer",
                              {'INPUT':'D:/foo/bar.shp', 
                               ... 
                               'OUTPUT':'c:/foo/baz.shp'})
    
      # OUTPUT
      # `result = {'OUTPUT': 'c:/foo/baz.shp'}`
    

Result is a dictionary, value is a string. No layer is added.

  • OPTION 3: runAndLoadResults() method with file output

      result = processing.runAndLoadResults("native:buffer",
                                            {'INPUT':'D:/foo/bar.shp', 
                                             ... 
                                             'OUTPUT':'c:/foo/baz.shp'})
    
      # OUTPUT
      # `result = {'OUTPUT': 'c:/foo/baz.shp'}`
    

Result is a dictionary, value is a string. A layer is added.

  • OPTION 4: runAndLoadResults() method with memory output

      result = processing.runAndLoadResults("native:buffer",
                                            {'INPUT':'D:/foo/bar.shp', 
                                             ... 
                                             'OUTPUT':'TEMPORARY_OUTPUT'
                                            })
    
      # OUTPUT
      # `result = {'OUTPUT': 'buffer_0ae....'}`
    

Result is a dictionary, value is a string. A layer is added.


QGIS 2: (Old version)

  • OPTION 1: runandload() method with file output

      result = processing.runandload("qgis:fixeddistancebuffer",
                                     "c:/foo/bar.shp", 10, 5, False,
                                     "c:/foo/baz.shp")
      # OUTPUT
      # `result = <*****.FixedDistanceBuffer instance at 0x00...>`
    

Result is an instance of related algorithm class. A layer is added.

  • OPTION 2: runandload() method with memory output

      result = processing.runandload("qgis:fixeddistancebuffer",
                                     "c:/foo/bar.shp", 10, 5, False,
                                     "memory:mem_layer")
      # OUTPUT
      # `result = <*****.FixedDistanceBuffer instance at 0x00...>`
    

Result is an instance of related algorithm class. A layer is added.

  • OPTION 3: runalg() method with file output

      result = processing.runalg("qgis:fixeddistancebuffer",
                                 "c:/foo/bar.shp", 10, 5, False,
                                 "c:/foo/baz.shp")
      # OUTPUT
      # `result = {'OUTPUT': "c:/foo/baz.shp"}`
    

Result is a dictionary, value is a string. No layer is added.

  • OPTION 4: runalg() method with memory output

      result = processing.runalg("qgis:fixeddistancebuffer",
                                 "c:/foo/bar.shp", 10, 5, False,
                                 "memory:mem_layer") 
    
      # OUTPUT
      # `result = {'OUTPUT': "memory:mem_layer"}`
    

Result is a dictionary, value is a string. No layer is added.

Neither runalg nor runandload returns a layer reference/instance for output in QGIS 2.

3
  • 1
    I'm not sure to understand.. does it mean the only way to "reuse" the layer outputed is to export it as temporary file? I should missunderstand?! If so, can it be dued to the format of the path: maybe the side of the "/" should be more exploitabled in the other side "\" ? And that could explain why it's read as string? I've noticed when I select an existing folder, the path is write in this side "\" using QFileDialog.getExistingDirectory. At contrary when I write a path for a file that doesn't exist it can be saved with "/".
    – zlikotp
    Commented Dec 20, 2019 at 11:22
  • 5
    It doesn't mean the only way to reuse. After using a processing tool, you can get output layer in different ways. What I've asked/explained here is which method (run, runandload, etc.) gives directly the reference of output layer returned by a processing tool. All options return mostly file path (as string) except option 1. Only option 1 returns (programmatically) reference/instance/pointer of output layer in memory. Commented Dec 20, 2019 at 11:57
  • Depending on the input layer, run may return another reference of the output. Commented Dec 19, 2021 at 7:34
5

If you want to save the output file on the processing output folder, please see this example:

1 - where is the processing output folder (QGis3)? Settings -> User Profiles -> Open Active Profile Folder -> "processing" folder -> "outputs" folder

2 - save the output of this processing algorithm on the above "output" folder and put it on the TOC (or legend):

    #.......................
self.addParameter(QgsProcessingParameterVectorLayer('Areadeestudo', 'Area de estudo', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
self.addParameter(QgsProcessingParameterVectorLayer('COS', 'COS', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
self.addParameter(QgsProcessingParameterVectorDestination('CosAreaEstudo', 'COS Area Estudo', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue='COS Area Estudo.shp'))
    
    #......................... other algorithms, etc
    
    # Polygon clipping2
            alg_params = {
                'CLIP': parameters['Areadeestudo'],
                'S_INPUT': parameters['COS'],
                'S_OUTPUT': parameters['CosAreaEstudo']
            }
            outputs['PolygonClipping2'] = processing.run('saga:polygonclipping', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
            results['CosAreaEstudo'] = outputs['PolygonClipping2']['S_OUTPUT']
    
    #..............................

The important factor here is the [defaultValue='COS Area Estudo.shp']

If the output is a raster, and if the processing algorithm is a SAGA one, the output file must be written [name of the raster file].sdat ; if the processing algorithm is GDAL or QGis native, you may use *.tif

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