mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[processing] Add explicit output type for multiple layers
This was a missing capability in the processing API - while algorithms could declare multiple layer input parameters, there was no corresponding multi-layer output. This meant that algorithms (such as Package Layers, Vector Split) which create a set of layers which cannot be determined in advance had no way to pass these generated layers on for further model processing steps. It's also useful for algorithms which operate on a specified folder, processing all layers found there, and allowing these generated outputs to be utilised in other model steps (e.g. packaging all of them, merging them, etc)
This commit is contained in:
parent
779fe1a91d
commit
4bcc9df5b4
@ -33,6 +33,8 @@ as generated layers or calculated values.
|
||||
sipType = sipType_QgsProcessingOutputRasterLayer;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputMapLayer::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputMapLayer;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputMultipleLayers::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputMultipleLayers;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputHtml::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputHtml;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputNumber::typeName() )
|
||||
@ -196,6 +198,42 @@ Returns the type name for the output class.
|
||||
virtual QString type() const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class QgsProcessingOutputMultipleLayers : QgsProcessingOutputDefinition
|
||||
{
|
||||
%Docstring
|
||||
A multi-layer output for processing algorithms which create map layers, when
|
||||
the number and nature of the output layers is not predefined.
|
||||
|
||||
.. note::
|
||||
|
||||
Always prefer to explicitly define QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputRasterLayer or QgsProcessingOutputMapLayer where possible. :py:class:`QgsProcessingOutputMultipleLayers`
|
||||
should only ever be used when the number of output layers is not
|
||||
fixed - e.g. as a result of processing all layers in a specified
|
||||
folder.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingoutputs.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingOutputMultipleLayers( const QString &name, const QString &description = QString() );
|
||||
%Docstring
|
||||
Constructor for QgsProcessingOutputMultipleLayers.
|
||||
%End
|
||||
|
||||
static QString typeName();
|
||||
%Docstring
|
||||
Returns the type name for the output class.
|
||||
%End
|
||||
virtual QString type() const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class QgsProcessingOutputHtml : QgsProcessingOutputDefinition
|
||||
|
@ -42,7 +42,8 @@ from qgis.core import (QgsMessageLog,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputRasterLayer,
|
||||
QgsProcessingOutputMapLayer)
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers)
|
||||
|
||||
import processing
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
@ -163,6 +164,22 @@ class Processing(object):
|
||||
layer = context.takeResultLayer(result) # transfer layer ownership out of context
|
||||
if layer:
|
||||
results[out.name()] = layer # replace layer string ref with actual layer (+ownership)
|
||||
elif isinstance(out, QgsProcessingOutputMultipleLayers):
|
||||
result = results[out.name()]
|
||||
if result:
|
||||
layers_result = []
|
||||
for l in result:
|
||||
if not isinstance(result, QgsMapLayer):
|
||||
layer = context.takeResultLayer(l) # transfer layer ownership out of context
|
||||
if layer:
|
||||
layers_result.append(layer)
|
||||
else:
|
||||
layers_result.append(l)
|
||||
else:
|
||||
layers_result.append(l)
|
||||
|
||||
results[out.name()] = layers_result # replace layers strings ref with actual layers (+ownership)
|
||||
|
||||
else:
|
||||
msg = Processing.tr("There were errors executing the algorithm.")
|
||||
feedback.reportError(msg)
|
||||
|
@ -42,7 +42,8 @@ from qgis.core import (QgsExpressionContext,
|
||||
QgsProcessingOutputHtml,
|
||||
QgsProcessingOutputNumber,
|
||||
QgsProcessingOutputString,
|
||||
QgsProcessingOutputFolder)
|
||||
QgsProcessingOutputFolder,
|
||||
QgsProcessingOutputMultipleLayers)
|
||||
|
||||
|
||||
def getOutputFromString(s):
|
||||
@ -69,6 +70,8 @@ def getOutputFromString(s):
|
||||
out = QgsProcessingOutputVectorLayer(name, description)
|
||||
elif token.lower().strip() == 'outputlayer':
|
||||
out = QgsProcessingOutputMapLayer(name, description)
|
||||
elif token.lower().strip() == 'outputmultilayers':
|
||||
out = QgsProcessingOutputMultipleLayers(name, description)
|
||||
# elif token.lower().strip() == 'vector point':
|
||||
# out = OutputVector(datatype=[dataobjects.TYPE_VECTOR_POINT])
|
||||
# elif token.lower().strip() == 'vector line':
|
||||
|
@ -66,6 +66,7 @@ from qgis.core import (
|
||||
QgsProcessingOutputRasterLayer,
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers,
|
||||
QgsProcessingOutputFile,
|
||||
QgsProcessingOutputString,
|
||||
QgsProcessingOutputNumber,
|
||||
@ -544,20 +545,23 @@ class MultipleLayerWidgetWrapper(WidgetWrapper):
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer])
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVector:
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer],
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers],
|
||||
[QgsProcessing.TypeVector])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorPoint:
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer],
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers],
|
||||
[QgsProcessing.TypeVectorPoint,
|
||||
QgsProcessing.TypeVectorAnyGeometry])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorLine:
|
||||
@ -565,7 +569,8 @@ class MultipleLayerWidgetWrapper(WidgetWrapper):
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer],
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers],
|
||||
[QgsProcessing.TypeVectorLine,
|
||||
QgsProcessing.TypeVectorAnyGeometry])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorPolygon:
|
||||
@ -573,18 +578,22 @@ class MultipleLayerWidgetWrapper(WidgetWrapper):
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMapLayer],
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers],
|
||||
[QgsProcessing.TypeVectorPolygon,
|
||||
QgsProcessing.TypeVectorAnyGeometry])
|
||||
elif self.param.layerType() == QgsProcessing.TypeRaster:
|
||||
options = self.dialog.getAvailableValuesOfType(
|
||||
(QgsProcessingParameterRasterLayer, QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputRasterLayer,
|
||||
QgsProcessingOutputMapLayer])
|
||||
QgsProcessingOutputMapLayer,
|
||||
QgsProcessingOutputMultipleLayers])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVector:
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers), QgsProcessingOutputVectorLayer)
|
||||
QgsProcessingParameterMultipleLayers),
|
||||
[QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputMultipleLayers])
|
||||
else:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFile, QgsProcessingOutputFile)
|
||||
options = sorted(options, key=lambda opt: self.dialog.resolveValueDescription(opt))
|
||||
|
@ -65,13 +65,18 @@ QgsProcessingOutputFile::QgsProcessingOutputFile( const QString &name, const QSt
|
||||
|
||||
QgsProcessingOutputMapLayer::QgsProcessingOutputMapLayer( const QString &name, const QString &description )
|
||||
: QgsProcessingOutputDefinition( name, description )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
{}
|
||||
|
||||
QString QgsProcessingOutputMapLayer::type() const
|
||||
{
|
||||
return typeName();
|
||||
}
|
||||
|
||||
QgsProcessingOutputMultipleLayers::QgsProcessingOutputMultipleLayers( const QString &name, const QString &description )
|
||||
: QgsProcessingOutputDefinition( name, description )
|
||||
{}
|
||||
|
||||
QString QgsProcessingOutputMultipleLayers::type() const
|
||||
{
|
||||
return typeName();
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ class CORE_EXPORT QgsProcessingOutputDefinition
|
||||
sipType = sipType_QgsProcessingOutputRasterLayer;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputMapLayer::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputMapLayer;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputMultipleLayers::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputMultipleLayers;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputHtml::typeName() )
|
||||
sipType = sipType_QgsProcessingOutputHtml;
|
||||
else if ( sipCpp->type() == QgsProcessingOutputNumber::typeName() )
|
||||
@ -209,6 +211,36 @@ class CORE_EXPORT QgsProcessingOutputRasterLayer : public QgsProcessingOutputDef
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \class QgsProcessingOutputMultipleLayers
|
||||
* \ingroup core
|
||||
* A multi-layer output for processing algorithms which create map layers, when
|
||||
* the number and nature of the output layers is not predefined.
|
||||
*
|
||||
* \note Always prefer to explicitly define QgsProcessingOutputVectorLayer,
|
||||
* QgsProcessingOutputRasterLayer or QgsProcessingOutputMapLayer where possible. QgsProcessingOutputMultipleLayers
|
||||
* should only ever be used when the number of output layers is not
|
||||
* fixed - e.g. as a result of processing all layers in a specified
|
||||
* folder.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsProcessingOutputMultipleLayers : public QgsProcessingOutputDefinition
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsProcessingOutputMultipleLayers.
|
||||
*/
|
||||
QgsProcessingOutputMultipleLayers( const QString &name, const QString &description = QString() );
|
||||
|
||||
/**
|
||||
* Returns the type name for the output class.
|
||||
*/
|
||||
static QString typeName() { return QStringLiteral( "outputMultilayer" ); }
|
||||
QString type() const override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \class QgsProcessingOutputHtml
|
||||
* \ingroup core
|
||||
|
Loading…
x
Reference in New Issue
Block a user