Skip to content

Commit

Permalink
Merge pull request #4831 from nyalldawson/processing_alg_config2
Browse files Browse the repository at this point in the history
Minor refactoring to processing algorithms, future proofing some API
  • Loading branch information
nyalldawson authored Jul 11, 2017
2 parents 1693873 + 2b8e067 commit 726936e
Show file tree
Hide file tree
Showing 170 changed files with 705 additions and 94 deletions.
1 change: 1 addition & 0 deletions cmake_templates/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,7 @@ EXPAND_AS_DEFINED = "SIP_ABSTRACT" \
"SIP_TRANSFER" \
"SIP_TRANSFERBACK" \
"SIP_TRANSFERTHIS" \
"SIP_VIRTUAL_CATCHER_CODE" \
"SIP_VIRTUALERRORHANDLER" \
"SIP_WHEN_FEATURE"

Expand Down
8 changes: 6 additions & 2 deletions python/core/processing/models/qgsprocessingmodelalgorithm.sip
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
Constructor for QgsProcessingModelAlgorithm.
%End

virtual void initAlgorithm( const QVariantMap &configuration = QVariantMap() ); //#spellok


virtual QString name() const;

virtual QString displayName() const;
Expand All @@ -46,8 +49,6 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm

virtual QString asPythonCommand( const QVariantMap &parameters, QgsProcessingContext &context ) const;

virtual QgsProcessingModelAlgorithm *create() const /Factory/;


void setName( const QString &name );
%Docstring
Expand Down Expand Up @@ -364,6 +365,9 @@ Translated description of variable

protected:

virtual QgsProcessingAlgorithm *createInstance() const /Factory/;


virtual QVariantMap processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback );


Expand Down
27 changes: 27 additions & 0 deletions python/core/processing/models/qgsprocessingmodelchildalgorithm.sip
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class QgsProcessingModelChildAlgorithm : QgsProcessingModelComponent
should be set to a QgsProcessingAlgorithm algorithm ID.
%End

QgsProcessingModelChildAlgorithm( const QgsProcessingModelChildAlgorithm &other );

QString childId() const;
%Docstring
Returns the child algorithm's unique ID string, used the identify
Expand Down Expand Up @@ -68,6 +70,31 @@ class QgsProcessingModelChildAlgorithm : QgsProcessingModelComponent
should be set to an existing QgsProcessingAlgorithm algorithm ID.
.. seealso:: algorithm()
.. seealso:: algorithmId()
%End

QVariantMap configuration() const;
%Docstring
Returns the child algorithm's configuration map.

This map specifies configuration settings which are passed
to the algorithm, allowing it to dynamically adjust its initialized parameters
and outputs according to this configuration. This allows child algorithms in the model
to adjust their behavior at run time according to some user configuration.

.. seealso:: setConfiguration()
:rtype: QVariantMap
%End

void setConfiguration( const QVariantMap &configuration );
%Docstring
Sets the child algorithm's ``configuration`` map.

This map specifies configuration settings which are passed
to the algorithm, allowing it to dynamically adjust its initialized parameters
and outputs according to this configuration. This allows child algorithms in the model
to adjust their behavior at run time according to some user configuration.

.. seealso:: configuration()
%End

const QgsProcessingAlgorithm *algorithm() const;
Expand Down
72 changes: 70 additions & 2 deletions python/core/processing/qgsprocessingalgorithm.sip
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@



%ModuleHeaderCode
#include <qgsprocessingmodelalgorithm.h>
%End


class QgsProcessingAlgorithm
{
%Docstring
Expand All @@ -20,6 +25,13 @@ class QgsProcessingAlgorithm

%TypeHeaderCode
#include "qgsprocessingalgorithm.h"
%End

%ConvertToSubClassCode
if ( dynamic_cast< QgsProcessingModelAlgorithm * >( sipCpp ) != NULL )
sipType = sipType_QgsProcessingModelAlgorithm;
else
sipType = sipType_QgsProcessingAlgorithm;
%End
public:

Expand All @@ -38,15 +50,29 @@ class QgsProcessingAlgorithm
QgsProcessingAlgorithm();
%Docstring
Constructor for QgsProcessingAlgorithm.

initAlgorithm() should be called after creating an algorithm to ensure it can correctly configure
its parameterDefinitions() and outputDefinitions(). Alternatively, calling create() will return
a pre-initialized copy of the algorithm.
%End

virtual ~QgsProcessingAlgorithm();



virtual QgsProcessingAlgorithm *create() const = 0 /Factory/;
QgsProcessingAlgorithm *create( const QVariantMap &configuration = QVariantMap() ) const /Factory/;
%Docstring
Creates a copy of the algorithm, ready for execution.

This method returns a new, preinitialized copy of the algorithm, ready for
executing.

The ``configuration`` argument allows passing of a map of configuration settings
to the algorithm, allowing it to dynamically adjust its initialized parameters
and outputs according to this configuration. This is generally used only for
algorithms in a model, allowing them to adjust their behavior at run time
according to some user configuration.

.. seealso:: initAlgorithm()
:rtype: QgsProcessingAlgorithm
%End

Expand Down Expand Up @@ -332,11 +358,49 @@ class QgsProcessingAlgorithm

protected:

virtual QgsProcessingAlgorithm *createInstance() const = 0;
%Docstring
Creates a new instance of the algorithm class.

This method should return a 'pristine' instance of the algorithm class.
:rtype: QgsProcessingAlgorithm
%End
%VirtualCatcherCode
PyObject *resObj = sipCallMethod( 0, sipMethod, "" );
sipIsErr = !resObj || sipParseResult( 0, sipMethod, resObj, "H2", sipType_QgsProcessingAlgorithm, &sipRes ) < 0;
if ( !sipIsErr )
sipTransferTo( resObj, Py_None );
%End

virtual void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) = 0;
%Docstring
Initializes the algorithm using the specified ``configuration``.

This should be called directly after creating algorithms and before retrieving
any parameterDefinitions() or outputDefinitions().

Subclasses should use their implementations to add all required input parameter and output
definitions (which can be dynamically adjusted according to ``configuration``).

Dynamic configuration can be used by algorithms which alter their behavior
when used inside processing models. For instance, a "feature router" type
algorithm which sends input features to one of any number of outputs sinks
based on some preconfigured filter parameters can use the init method to
create these outputs based on the specified ``configuration``.

.. seealso:: addParameter()
.. seealso:: addOutput()
%End

bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/ );
%Docstring
Adds a parameter ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
Returns true if parameter could be successfully added, or false if the parameter could not be added (e.g.
as a result of a duplicate name).

This should usually be called from a subclass' initAlgorithm() implementation.

.. seealso:: initAlgorithm()
.. seealso:: addOutput()
:rtype: bool
%End
Expand All @@ -352,7 +416,11 @@ class QgsProcessingAlgorithm
Adds an output ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
Returns true if the output could be successfully added, or false if the output could not be added (e.g.
as a result of a duplicate name).

This should usually be called from a subclass' initAlgorithm() implementation.

.. seealso:: addParameter()
.. seealso:: initAlgorithm()
:rtype: bool
%End

Expand Down
17 changes: 17 additions & 0 deletions python/core/processing/qgsprocessingregistry.sip
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ class QgsProcessingRegistry : QObject
Finds an algorithm by its ID. If no matching algorithm is found, a None
is returned.
.. seealso:: algorithms()
.. seealso:: createAlgorithmById()
:rtype: QgsProcessingAlgorithm
%End

QgsProcessingAlgorithm *createAlgorithmById( const QString &id, const QVariantMap &configuration = QVariantMap() ) const /Factory/;
%Docstring
Creates a new instance of an algorithm by its ID. If no matching algorithm is found, a None
is returned. Callers take responsibility for deleting the returned object.

The ``configuration`` argument allows passing of a map of configuration settings
to the algorithm, allowing it to dynamically adjust its initialized parameters
and outputs according to this configuration. This is generally used only for
algorithms in a model, allowing them to adjust their behavior at run time
according to some user configuration.

.. seealso:: algorithms()
.. seealso:: algorithmById()
:rtype: QgsProcessingAlgorithm
%End

Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/AddTableField.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(self):
self.tr('Float'),
self.tr('String')]

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterString(self.FIELD_NAME,
Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/Aspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def group(self):
def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT,
self.tr('Elevation layer')))
self.addParameter(QgsProcessingParameterNumber(self.Z_FACTOR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class AutoincrementalField(QgisAlgorithm):
def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))

Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/BarPlot.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def group(self):
def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterField(self.NAME_FIELD,
Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/BasicStatistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def group(self):
def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER,
self.tr('Input layer')))

Expand Down
2 changes: 2 additions & 0 deletions python/plugins/processing/algs/qgis/Boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class Boundary(QgisAlgorithm):

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER, self.tr('Input layer'), [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon]))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Boundary')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Boundaries")))
Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/BoundingBox.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def group(self):
def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER, self.tr('Input layer')))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Bounds'), QgsProcessing.TypeVectorPolygon))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Bounds")))
Expand Down
2 changes: 2 additions & 0 deletions python/plugins/processing/algs/qgis/BoxPlot.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ def group(self):

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterTable(self.INPUT, self.tr('Input table')))
self.addParameter(ParameterTableField(self.NAME_FIELD,
self.tr('Category name field'),
Expand Down
2 changes: 2 additions & 0 deletions python/plugins/processing/algs/qgis/CheckValidity.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def group(self):

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.methods = [self.tr('The one selected in digitizing settings'),
'QGIS',
'GEOS']