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.
This commit is contained in:
Nyall Dawson 2017-07-01 20:04:36 +10:00
parent a2af3a9345
commit 55ce31b371
2 changed files with 15 additions and 5 deletions

View File

@ -87,8 +87,7 @@ class ConcaveHull(QgisAlgorithm):
# 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...'))
@ -131,8 +130,7 @@ class ConcaveHull(QgisAlgorithm):
# 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...'))

View File

@ -38,9 +38,12 @@ from qgis.PyQt.QtGui import QCursor
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
@ -173,6 +176,15 @@ class Processing(object):
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)