7

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?

Kadir Şahbaz
78.6k57 gold badges260 silver badges407 bronze badges
asked Apr 23, 2018 at 14:21
2
  • Try replacing processing.run with processing.runAndLoadResults. Commented Apr 23, 2018 at 14:24
  • nope, already tried. It works in single scripts but not in Processing plugin scripts Commented Apr 23, 2018 at 14:40

2 Answers 2

6

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)
answered Apr 23, 2018 at 15:21
1
  • thanks! I missed that! Did you make some experiments with the method that will be available in 3.2 (QgsProcessingLayerPostProcessorInterface)? Commented Apr 23, 2018 at 16:43
2

You can also do it without having to run your script inside the main thread, which works but may not be ideal.

# And then, try to add layer to map.
view = QgsRasterLayer(viewshed['output'], 'my_output','gdal')
context.temporaryLayerStore().addMapLayer(view)
context.addLayerToLoadOnCompletion(view.id(), QgsProcessingContext.LayerDetails("", QgsProject.instance(), ""))
answered Jun 17, 2021 at 18:34
1
  • Just the line seems to be enough for me, no need for a QgsRasterLayer instance or adding it to the store: context.addLayerToLoadOnCompletion(visibility_viewshed["OUTPUT"], QgsProcessingContext.LayerDetails("", QgsProject.instance())) Commented Apr 6, 2023 at 16:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.