Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
When calling procesing.run(), map layer results are automatically
converted to QgsMapLayer objects with the ownership transferred
to the Python caller

This should make it super-easy for PyQGIS scripts to run processing
algorithms and immediately utilise the results, even if they
are memory layers. They call processing.run(), and get a dict of
results back which includes those layers ready for adding to the
current project or doing some other processing or operations
with, and if they don't transfer to ownership off then these
layers will be correctly garbaged collected by Python.
  • Loading branch information
nyalldawson committed Jul 6, 2017
1 parent a2af3a9 commit 55ce31b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
6 changes: 2 additions & 4 deletions python/plugins/processing/algs/qgis/ConcaveHull.py
Expand Up @@ -87,8 +87,7 @@ def processAlgorithm(self, parameters, context, feedback):

# Delaunay triangulation from input point layer
feedback.setProgressText(self.tr('Creating Delaunay triangles...'))
delone_triangles = processing.run("qgis:delaunaytriangulation", {'INPUT': parameters[ConcaveHull.INPUT], 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']
delaunay_layer = context.takeResultLayer(delone_triangles)
delaunay_layer = processing.run("qgis:delaunaytriangulation", {'INPUT': parameters[ConcaveHull.INPUT], 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']

# Get max edge length from Delaunay triangles
feedback.setProgressText(self.tr('Computing edges max length...'))
Expand Down Expand Up @@ -131,8 +130,7 @@ def processAlgorithm(self, parameters, context, feedback):

# Dissolve all Delaunay triangles
feedback.setProgressText(self.tr('Dissolving Delaunay triangles...'))
dissolved = processing.run("native:dissolve", {'INPUT': delaunay_layer, 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']
dissolved_layer = context.takeResultLayer(dissolved)
dissolved_layer = processing.run("native:dissolve", {'INPUT': delaunay_layer, 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']

# Save result
feedback.setProgressText(self.tr('Saving data...'))
Expand Down
14 changes: 13 additions & 1 deletion python/plugins/processing/core/Processing.py
Expand Up @@ -38,9 +38,12 @@
from qgis.utils import iface
from qgis.core import (QgsMessageLog,
QgsApplication,
QgsMapLayer,
QgsProcessingProvider,
QgsProcessingAlgorithm,
QgsProcessingParameterDefinition)
QgsProcessingParameterDefinition,
QgsProcessingOutputVectorLayer,
QgsProcessingOutputRasterLayer)

import processing
from processing.script.ScriptUtils import ScriptUtils
Expand Down Expand Up @@ -173,6 +176,15 @@ def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=No

if onFinish is not None:
onFinish(alg, context, feedback)
else:
# auto convert layer references in results to map layers
for out in alg.outputDefinitions():
if isinstance(out, (QgsProcessingOutputVectorLayer, QgsProcessingOutputRasterLayer)):
result = results[out.name()]
if not isinstance(result, QgsMapLayer):
layer = context.takeResultLayer(result) # transfer layer ownership out of context
if layer:
results[out.name()] = layer # replace layer string ref with actual layer (+ownership)
else:
msg = Processing.tr("There were errors executing the algorithm.")
feedback.reportError(msg)
Expand Down

0 comments on commit 55ce31b

Please sign in to comment.