qgis – How to Load a Layer in QGIS Legend from a Processing Script [QGIS 3]

pyqgisqgisqgis-3qgis-processing

I have a weird problem. I'm writing a Processing standalone plugin in QGIS 3 (current master, 3.1).

In the main algorithm I have to create some intermediate layers (mostly raster) with GRASS and SAGA provider, no problem so far. For example here the snippet of r.watershed:

viewshed = processing.run('grass7:r.viewshed', {
    'input': raster,
    'coordinates': coordStr,
    'observer_elevation': 0,
    'target_elevation': 0,
    'max_distance': Visibility_Distance,
    'refraction_coeff': 0.14286,
    'memory': 500,
    '-c':False,
    '-r':False,
    '-b':False,
    '-e':False,
    'output':os.path.join(Results, 'my_output.tif'),
    'GRASS_REGION_PARAMETER': tr_extent,
    'GRASS_REGION_CELLSIZE_PARAMETER':0,
    'GRASS_RASTER_FORMAT_OPT':'',
    'GRASS_RASTER_FORMAT_META':''

})

but then I cannot load the resulting layer in the legend, even if it is correctly created and I can load it by hand.

Here what I'm trying to do:

view = QgsRasterLayer(viewshed['output'], 'my_output','gdal')
QgsProject.instance().addMapLayer(view)

I don't get any error from the console.

The exact same syntax works in a single script written in the Python editor of QGIS.

Any clue?

Best Answer

I used that way to change layer order while processing. As I know, normally you can't add layer to legend while processing in QGIS 3 unlike QGIS 2.

Try that. But it's risky according to this post.

# add this method to your algorithm class.
def flags(self):
    return super().flags() | QgsProcessingAlgorithm.FlagNoThreading

and

# add last two lines (feedback and context parameters) to your 'run' method
viewshed = processing.run('grass7:r.viewshed', {
    'input': raster,
    'coordinates': coordStr,
    'observer_elevation': 0,
    'target_elevation': 0,
    'max_distance': Visibility_Distance,
    'refraction_coeff': 0.14286,
    'memory': 500,
    '-c':False,
    '-r':False,
    '-b':False,
    '-e':False,
    'output':os.path.join(Results, 'my_output.tif'),
    'GRASS_REGION_PARAMETER': tr_extent,
    'GRASS_REGION_CELLSIZE_PARAMETER':0,
    'GRASS_RASTER_FORMAT_OPT':'',
    'GRASS_RASTER_FORMAT_META':''
},
feedback=feedback, # without these two lines 
context=context)   # QGIS may crash

# And then, try to add layer to map.
view = QgsRasterLayer(viewshed['output'], 'my_output','gdal')
QgsProject.instance().addMapLayer(view)
Related Question