Skip to content

Commit fb81176

Browse files
committed
Add framework for algorithm outputs
This somewhat changes the meaning of outputs from processing 2.x. In 2.x processing outputs were used both as a method of specifying inputs to algorithms (file paths to destination layers created by the algorithm) AND pure outputs (such as statistics calculated by the algorithm). This is now split. The old input-type-outputs (destination layers) are now input parameters (since the parameter value IS an input to the algorithm). To differentiate them from parameters indicating pure input layers a new "isDestination()" method was added to QgsProcessingParameterDefinition. Output definitions are now purely indications of values CREATED by the algorithms. Suitable candidates are the existing calculated stats and actual file path/URI of any layers created by the algorithm. Moving forward we should ensure all algorithms output as much useful information as possible - e.g. number of features processed, number of skipped features, count null geometries encountered, etc...
1 parent fac8ca4 commit fb81176

20 files changed

+600
-44
lines changed

python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@
287287
%Include processing/qgsprocessingalgorithm.sip
288288
%Include processing/qgsprocessingcontext.sip
289289
%Include processing/qgsprocessingfeedback.sip
290+
%Include processing/qgsprocessingoutputs.sip
290291
%Include processing/qgsprocessingparameters.sip
291292
%Include processing/qgsprocessingprovider.sip
292293
%Include processing/qgsprocessingregistry.sip

python/core/processing/qgsprocessingalgorithm.sip

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class QgsProcessingAlgorithm
124124
Returns an ordered list of parameter definitions utilized by the algorithm.
125125
.. seealso:: addParameter()
126126
.. seealso:: parameterDefinition()
127+
.. seealso:: destinationParameterDefinitions()
127128
:rtype: QgsProcessingParameterDefinitions
128129
%End
129130

@@ -142,6 +143,30 @@ class QgsProcessingAlgorithm
142143
:rtype: int
143144
%End
144145

146+
QgsProcessingParameterDefinitions destinationParameterDefinitions() const;
147+
%Docstring
148+
Returns a list of destination parameters definitions utilized by the algorithm.
149+
.. seealso:: QgsProcessingParameterDefinition.isDestination()
150+
.. seealso:: parameterDefinitions()
151+
:rtype: QgsProcessingParameterDefinitions
152+
%End
153+
154+
QgsProcessingOutputDefinitions outputDefinitions() const;
155+
%Docstring
156+
Returns an ordered list of output definitions utilized by the algorithm.
157+
.. seealso:: addOutput()
158+
.. seealso:: outputDefinition()
159+
:rtype: QgsProcessingOutputDefinitions
160+
%End
161+
162+
const QgsProcessingOutputDefinition *outputDefinition( const QString &name ) const;
163+
%Docstring
164+
Returns a matching output by ``name``. Matching is done in a case-insensitive
165+
manner.
166+
.. seealso:: outputDefinitions()
167+
:rtype: QgsProcessingOutputDefinition
168+
%End
169+
145170
virtual QVariantMap run( const QVariantMap &parameters,
146171
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
147172
%Docstring
@@ -166,6 +191,16 @@ class QgsProcessingAlgorithm
166191
Adds a parameter ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
167192
Returns true if parameter could be successfully added, or false if the parameter could not be added (e.g.
168193
as a result of a duplicate name).
194+
.. seealso:: addOutput()
195+
:rtype: bool
196+
%End
197+
198+
bool addOutput( QgsProcessingOutputDefinition *outputDefinition /Transfer/ );
199+
%Docstring
200+
Adds an output ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
201+
Returns true if the output could be successfully added, or false if the output could not be added (e.g.
202+
as a result of a duplicate name).
203+
.. seealso:: addParameter()
169204
:rtype: bool
170205
%End
171206

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/processing/qgsprocessingoutputs.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
14+
class QgsProcessingOutputDefinition
15+
{
16+
%Docstring
17+
18+
Base class for the definition of processing outputs.
19+
20+
Output definitions encapsulate the properties regarding the outputs from algorithms, such
21+
as generated layers or calculated values.
22+
23+
.. versionadded:: 3.0
24+
%End
25+
26+
%TypeHeaderCode
27+
#include "qgsprocessingoutputs.h"
28+
%End
29+
public:
30+
31+
QgsProcessingOutputDefinition( const QString &name, const QString &description = QString() );
32+
%Docstring
33+
Constructor for QgsProcessingOutputDefinition.
34+
%End
35+
36+
virtual ~QgsProcessingOutputDefinition();
37+
38+
virtual QString type() const = 0;
39+
%Docstring
40+
Unique output type name.
41+
:rtype: str
42+
%End
43+
44+
QString name() const;
45+
%Docstring
46+
Returns the name of the output. This is the internal identifier by which
47+
algorithms access this output.
48+
@see setName()
49+
:rtype: str
50+
%End
51+
52+
void setName( const QString &name );
53+
%Docstring
54+
Sets the ``name`` of the output. This is the internal identifier by which
55+
algorithms access this output.
56+
@see name()
57+
%End
58+
59+
QString description() const;
60+
%Docstring
61+
Returns the description for the output. This is the user-visible string
62+
used to identify this output.
63+
@see setDescription()
64+
:rtype: str
65+
%End
66+
67+
void setDescription( const QString &description );
68+
%Docstring
69+
Sets the ``description`` for the output. This is the user-visible string
70+
used to identify this output.
71+
@see description()
72+
%End
73+
74+
protected:
75+
76+
77+
78+
};
79+
80+
typedef QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefinitions;
81+
82+
class QgsProcessingOutputVectorLayer : QgsProcessingOutputDefinition
83+
{
84+
%Docstring
85+
A vector layer output for processing algorithms.
86+
.. versionadded:: 3.0
87+
%End
88+
89+
%TypeHeaderCode
90+
#include "qgsprocessingoutputs.h"
91+
%End
92+
public:
93+
94+
QgsProcessingOutputVectorLayer( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny );
95+
%Docstring
96+
Constructor for QgsProcessingOutputVectorLayer.
97+
%End
98+
99+
virtual QString type() const;
100+
101+
QgsProcessingParameterDefinition::LayerType dataType() const;
102+
%Docstring
103+
Returns the layer type for the output layer.
104+
.. seealso:: setDataType()
105+
:rtype: QgsProcessingParameterDefinition.LayerType
106+
%End
107+
108+
void setDataType( QgsProcessingParameterDefinition::LayerType type );
109+
%Docstring
110+
Sets the layer ``type`` for the output layer.
111+
.. seealso:: dataType()
112+
%End
113+
114+
};
115+
116+
117+
118+
119+
/************************************************************************
120+
* This file has been generated automatically from *
121+
* *
122+
* src/core/processing/qgsprocessingoutputs.h *
123+
* *
124+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
125+
************************************************************************/

python/core/processing/qgsprocessingparameters.sip

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ class QgsProcessingParameterDefinition
6464
:rtype: str
6565
%End
6666

67+
virtual bool isDestination() const;
68+
%Docstring
69+
Returns true if this parameter represents a file or layer destination, e.g. parameters
70+
which are used for the destination for layers output by an algorithm will return
71+
true.
72+
:rtype: bool
73+
%End
74+
6775
QString name() const;
6876
%Docstring
6977
Returns the name of the parameter. This is the internal identifier by which
@@ -906,7 +914,7 @@ class QgsProcessingParameterTableField : QgsProcessingParameterDefinition
906914

907915
};
908916

909-
class QgsProcessingParameterVector : QgsProcessingParameterDefinition
917+
class QgsProcessingParameterVectorLayer : QgsProcessingParameterDefinition
910918
{
911919
%Docstring
912920
A vector layer parameter for processing algorithms.
@@ -918,10 +926,10 @@ class QgsProcessingParameterVector : QgsProcessingParameterDefinition
918926
%End
919927
public:
920928

921-
QgsProcessingParameterVector( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny, const QVariant &defaultValue = QVariant(),
922-
bool optional = false );
929+
QgsProcessingParameterVectorLayer( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny, const QVariant &defaultValue = QVariant(),
930+
bool optional = false );
923931
%Docstring
924-
Constructor for QgsProcessingParameterVector.
932+
Constructor for QgsProcessingParameterVectorLayer.
925933
%End
926934

927935
virtual QString type() const;
@@ -943,6 +951,45 @@ class QgsProcessingParameterVector : QgsProcessingParameterDefinition
943951
};
944952

945953

954+
class QgsProcessingParameterOutputVectorLayer : QgsProcessingParameterDefinition
955+
{
956+
%Docstring
957+
A vector layer output for processing algorithms.
958+
959+
A parameter which represents the destination for a vector layer created by an algorithm.
960+
.. versionadded:: 3.0
961+
%End
962+
963+
%TypeHeaderCode
964+
#include "qgsprocessingparameters.h"
965+
%End
966+
public:
967+
968+
QgsProcessingParameterOutputVectorLayer( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny, const QVariant &defaultValue = QVariant(),
969+
bool optional = false );
970+
%Docstring
971+
Constructor for QgsProcessingParameterOutputVectorLayer.
972+
%End
973+
974+
virtual QString type() const;
975+
virtual bool isDestination() const;
976+
977+
QgsProcessingParameterDefinition::LayerType dataType() const;
978+
%Docstring
979+
Returns the layer type for the output layer associated with the parameter.
980+
.. seealso:: setDataType()
981+
:rtype: QgsProcessingParameterDefinition.LayerType
982+
%End
983+
984+
void setDataType( QgsProcessingParameterDefinition::LayerType type );
985+
%Docstring
986+
Sets the layer ``type`` for the output layer associated with the parameter.
987+
.. seealso:: dataType()
988+
%End
989+
990+
};
991+
992+
946993

947994
/************************************************************************
948995
* This file has been generated automatically from *

python/plugins/processing/core/GeoAlgorithm.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,6 @@ def setOutputValue(self, outputName, value):
398398
if out.name == outputName:
399399
out.setValue(value)
400400

401-
def getVisibleOutputsCount(self):
402-
"""Returns the number of non-hidden outputs.
403-
"""
404-
i = 0
405-
for out in self.outputs:
406-
if not out.hidden:
407-
i += 1
408-
return i
409-
410401
def getHTMLOutputsCount(self):
411402
"""Returns the number of HTML outputs.
412403
"""

python/plugins/processing/core/Processing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def runAlgorithm(algOrName, onFinish, *args, **kwargs):
165165
Processing.tr("Processing"))
166166
return
167167
else:
168-
if len(args) != alg.countVisibleParameters() + alg.getVisibleOutputsCount():
168+
if len(args) != alg.countVisibleParameters():
169169
# fix_print_with_import
170170
print('Error: Wrong number of parameters')
171171
QgsMessageLog.logMessage(Processing.tr('Error: Wrong number of parameters'),

python/plugins/processing/gui/BatchAlgorithmDialog.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def accept(self):
7474
for row in range(self.mainWidget.tblParameters.rowCount()):
7575
alg = self.alg
7676
col = 0
77-
for param in alg.parameters:
78-
if param.hidden:
77+
for param in alg.parameterDefinitions():
78+
if param.hidden or param.isDestination():
7979
continue
8080
wrapper = self.mainWidget.wrappers[row][col]
8181
if not self.mainWidget.setParamValue(param, wrapper, alg):
@@ -85,7 +85,7 @@ def accept(self):
8585
self.algs = None
8686
return
8787
col += 1
88-
for out in alg.outputs:
88+
for out in alg.destinationParameterDefinitions():
8989
if out.hidden:
9090
continue
9191

@@ -102,7 +102,7 @@ def accept(self):
102102
return
103103

104104
self.algs.append(alg)
105-
if self.alg.getVisibleOutputsCount():
105+
if len(self.alg.destinationParameterDefinitions()) > 0:
106106
widget = self.mainWidget.tblParameters.cellWidget(row, col)
107107
self.load.append(widget.currentIndex() == 0)
108108
else:

python/plugins/processing/gui/BatchPanel.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,30 +97,32 @@ def initWidgets(self):
9797
break
9898

9999
# Determine column count
100-
nOutputs = self.alg.getVisibleOutputsCount() + 1
100+
nOutputs = len(self.alg.destinationParameterDefinitions()) + 1
101101
if nOutputs == 1:
102102
nOutputs = 0
103103

104104
self.tblParameters.setColumnCount(
105-
self.alg.countVisibleParameters() + nOutputs)
105+
self.alg.countVisibleParameters())
106106

107107
# Table headers
108108
column = 0
109-
for param in self.alg.parameters:
109+
for param in self.alg.parameterDefinitions():
110+
if param.isDestination():
111+
continue
110112
self.tblParameters.setHorizontalHeaderItem(
111113
column, QTableWidgetItem(param.description))
112114
if param.isAdvanced:
113115
self.tblParameters.setColumnHidden(column, True)
114116
column += 1
115117

116-
for out in self.alg.outputs:
118+
for out in self.alg.destinationParameterDefinitions():
117119
if not out.hidden:
118120
self.tblParameters.setHorizontalHeaderItem(
119121
column, QTableWidgetItem(out.description))
120122
column += 1
121123

122124
# Last column for indicating if output will be added to canvas
123-
if self.alg.getVisibleOutputsCount():
125+
if len(self.alg.destinationParameterDefinitions()) > 0:
124126
self.tblParameters.setHorizontalHeaderItem(
125127
column, QTableWidgetItem(self.tr('Load in QGIS')))
126128

@@ -233,16 +235,16 @@ def addRow(self):
233235
wrappers = {}
234236
row = self.tblParameters.rowCount() - 1
235237
column = 0
236-
for param in self.alg.parameters:
237-
if param.hidden:
238+
for param in self.alg.parameterDefinitions():
239+
if param.hidden or param.isDestination():
238240
continue
239241

240242
wrapper = param.wrapper(self.parent, row, column)
241243
wrappers[param.name] = wrapper
242244
self.setCellWrapper(row, column, wrapper)
243245
column += 1
244246

245-
for out in self.alg.outputs:
247+
for out in self.alg.destinationParameterDefinitions():
246248
if out.hidden:
247249
continue
248250

@@ -251,7 +253,7 @@ def addRow(self):
251253
out, self.alg, row, column, self))
252254
column += 1
253255

254-
if self.alg.getVisibleOutputsCount():
256+
if len(self.alg.destinationParameterDefinitions()) > 0:
255257
item = QComboBox()
256258
item.addItem(self.tr('Yes'))
257259
item.addItem(self.tr('No'))

0 commit comments

Comments
 (0)