mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-18 00:06:00 -04:00
Begin port of modeler algorithm to c++
This commit is contained in:
parent
efe8bba006
commit
f6358b2118
@ -288,6 +288,7 @@
|
|||||||
%Include processing/qgsprocessingalgrunnertask.sip
|
%Include processing/qgsprocessingalgrunnertask.sip
|
||||||
%Include processing/qgsprocessingcontext.sip
|
%Include processing/qgsprocessingcontext.sip
|
||||||
%Include processing/qgsprocessingfeedback.sip
|
%Include processing/qgsprocessingfeedback.sip
|
||||||
|
%Include processing/qgsprocessingmodelalgorithm.sip
|
||||||
%Include processing/qgsprocessingoutputs.sip
|
%Include processing/qgsprocessingoutputs.sip
|
||||||
%Include processing/qgsprocessingparameters.sip
|
%Include processing/qgsprocessingparameters.sip
|
||||||
%Include processing/qgsprocessingprovider.sip
|
%Include processing/qgsprocessingprovider.sip
|
||||||
|
@ -276,6 +276,12 @@ class QgsProcessingAlgorithm
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
void removeParameter( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Removes the parameter with matching ``name`` from the algorithm, and deletes any existing
|
||||||
|
definition.
|
||||||
|
%End
|
||||||
|
|
||||||
bool addOutput( QgsProcessingOutputDefinition *outputDefinition /Transfer/ );
|
bool addOutput( QgsProcessingOutputDefinition *outputDefinition /Transfer/ );
|
||||||
%Docstring
|
%Docstring
|
||||||
Adds an output ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
|
Adds an output ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
|
||||||
|
617
python/core/processing/qgsprocessingmodelalgorithm.sip
Normal file
617
python/core/processing/qgsprocessingmodelalgorithm.sip
Normal file
@ -0,0 +1,617 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* This file has been generated automatically from *
|
||||||
|
* *
|
||||||
|
* src/core/processing/qgsprocessingmodelalgorithm.h *
|
||||||
|
* *
|
||||||
|
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Model based algorithm with processing.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
class ChildParameterSource
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Source for the value of a parameter for a child algorithm within a model.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Source
|
||||||
|
{
|
||||||
|
ModelParameter,
|
||||||
|
ChildOutput,
|
||||||
|
StaticValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
ChildParameterSource();
|
||||||
|
%Docstring
|
||||||
|
Constructor for ChildParameterSource. It is recommended that the static methods
|
||||||
|
fromStaticValue(), fromModelParameter() and fromChildOutput() are used instead.
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||||
|
bool operator!=( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||||
|
%Docstring
|
||||||
|
:rtype: bool
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromStaticValue( const QVariant &value );
|
||||||
|
%Docstring
|
||||||
|
Returns a new ChildParameterSource which takes its value from a static ``value``.
|
||||||
|
.. seealso:: fromModelParameter()
|
||||||
|
.. seealso:: fromChildOutput()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromModelParameter( const QString ¶meterName );
|
||||||
|
%Docstring
|
||||||
|
Returns a new ChildParameterSource which takes its value from a parent model parameter.
|
||||||
|
.. seealso:: fromStaticValue()
|
||||||
|
.. seealso:: fromChildOutput()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
|
||||||
|
%Docstring
|
||||||
|
Returns a new ChildParameterSource which takes its value from an output generated by a child algorithm.
|
||||||
|
.. seealso:: fromStaticValue()
|
||||||
|
.. seealso:: fromModelParameter()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||||
|
%End
|
||||||
|
|
||||||
|
Source source() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the parameter value's source.
|
||||||
|
:rtype: Source
|
||||||
|
%End
|
||||||
|
|
||||||
|
QVariant staticValue() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the source's static value. This is only used when the source() is StaticValue.
|
||||||
|
.. seealso:: setStaticValue()
|
||||||
|
:rtype: QVariant
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setStaticValue( const QVariant &value );
|
||||||
|
%Docstring
|
||||||
|
Sets the source's static value. Calling this will also change the source() to StaticValue.
|
||||||
|
.. seealso:: staticValue()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString parameterName() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the source's model parameter name. This is only used when the source() is ModelParameter.
|
||||||
|
.. seealso:: setParameterName()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParameterName( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Sets the source's model parameter ``name``. Calling this will also change the source() to ModelParameter.
|
||||||
|
.. seealso:: parameterName()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString outputChildId() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the source's child algorithm ID from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||||
|
.. seealso:: setOutputChildId()
|
||||||
|
.. seealso:: outputName()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setOutputChildId( const QString &id );
|
||||||
|
%Docstring
|
||||||
|
Sets the source's child algorithm ``id`` from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||||
|
.. seealso:: parameterName()
|
||||||
|
.. seealso:: setOutputName()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString outputName() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the source's child algorithm output name from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||||
|
.. seealso:: setOutputName()
|
||||||
|
.. seealso:: outputChildId()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setOutputName( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Sets the source's child algorithm output ``name`` from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||||
|
.. seealso:: outputName()
|
||||||
|
.. seealso:: setOutputChildId()
|
||||||
|
%End
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Component
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Represents a component of a model algorithm.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
QString description() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the friendly description text for the component.
|
||||||
|
.. seealso:: setDescription()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setDescription( const QString &description );
|
||||||
|
%Docstring
|
||||||
|
Sets the friendly ``description`` text for the component.
|
||||||
|
.. seealso:: description()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QPointF position() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the position of the model component within the graphical modeler.
|
||||||
|
.. seealso:: setPosition()
|
||||||
|
:rtype: QPointF
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setPosition( const QPointF &position );
|
||||||
|
%Docstring
|
||||||
|
Sets the ``position`` of the model component within the graphical modeler.
|
||||||
|
.. seealso:: position()
|
||||||
|
%End
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Component( const QString &description = QString() );
|
||||||
|
%Docstring
|
||||||
|
Only subclasses can be created
|
||||||
|
%End
|
||||||
|
|
||||||
|
Component( const QgsProcessingModelAlgorithm::Component &other );
|
||||||
|
%Docstring
|
||||||
|
Copies are protected to avoid slicing
|
||||||
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModelParameter : QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Represents an input parameter used by the model.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
ModelParameter( const QString ¶meterName = QString() );
|
||||||
|
%Docstring
|
||||||
|
Constructor for ModelParameter. The parameter name should match one of the
|
||||||
|
parameters from the parent model.
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString parameterName() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the associated parameter name. The parameter name should match one of the
|
||||||
|
parameters from the parent model.
|
||||||
|
.. seealso:: parameterName()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParameterName( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Sets the associated parameter name. The parameter name should match one of the
|
||||||
|
parameters from the parent model.
|
||||||
|
.. seealso:: parameterName()
|
||||||
|
%End
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ModelOutput : QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Represents a final output created by the model.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
ModelOutput( const QString &description = QString() );
|
||||||
|
%Docstring
|
||||||
|
Constructor for ModelOutput with the specified ``description``.
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString childId() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the child algorithm ID from which this output is generated.
|
||||||
|
.. seealso:: setChildId()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setChildId( const QString &id );
|
||||||
|
%Docstring
|
||||||
|
Sets the child algorithm ``id`` from which this output is generated.
|
||||||
|
.. seealso:: childId()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString outputName() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the child algorithm output name from which this output is generated.
|
||||||
|
.. seealso:: setOutputName()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setOutputName( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Sets the child algorithm output ``name`` from which this output is generated.
|
||||||
|
.. seealso:: outputName()
|
||||||
|
%End
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChildAlgorithm : QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
Child algorithm representing a single component of a QgsProcessingModelAlgorithm.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChildAlgorithm( const QString &algorithmId = QString() );
|
||||||
|
%Docstring
|
||||||
|
Constructor for ChildAlgorithm. The ``algorithmId`` parameter
|
||||||
|
should be set to a QgsProcessingAlgorithm algorithm ID.
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString childId() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the child algorithm's unique ID string, used the identify
|
||||||
|
this child algorithm within its parent model.
|
||||||
|
.. seealso:: setChildId()
|
||||||
|
.. seealso:: generateChildId()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setChildId( const QString &id );
|
||||||
|
%Docstring
|
||||||
|
Sets the child algorithm's unique ``id`` string, used the identify
|
||||||
|
this child algorithm within its parent model.
|
||||||
|
.. seealso:: childId()
|
||||||
|
.. seealso:: generateChildId()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void generateChildId( const QgsProcessingModelAlgorithm &model );
|
||||||
|
%Docstring
|
||||||
|
Automatically generates a unique childId() for the algorithm,
|
||||||
|
avoiding child IDs which are already present in ``model``.
|
||||||
|
.. seealso:: childId()
|
||||||
|
.. seealso:: setChildId()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString algorithmId() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the underlying child algorithm's ID.
|
||||||
|
.. seealso:: algorithm()
|
||||||
|
.. seealso:: setAlgorithmId()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setAlgorithmId( const QString &algorithmId );
|
||||||
|
%Docstring
|
||||||
|
Sets the underlying child algorithm's ID. This
|
||||||
|
should be set to an existing QgsProcessingAlgorithm algorithm ID.
|
||||||
|
.. seealso:: algorithm()
|
||||||
|
.. seealso:: algorithmId()
|
||||||
|
%End
|
||||||
|
|
||||||
|
const QgsProcessingAlgorithm *algorithm() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the underlying child algorithm, or a None
|
||||||
|
if a matching algorithm is not available.
|
||||||
|
.. seealso:: algorithmId()
|
||||||
|
:rtype: QgsProcessingAlgorithm
|
||||||
|
%End
|
||||||
|
|
||||||
|
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > parameterSources() const;
|
||||||
|
%Docstring
|
||||||
|
Returns a map of parameter sources. The keys are the child algorithm
|
||||||
|
parameter names, the values are the source for that parameter.
|
||||||
|
.. seealso:: setParameterSources()
|
||||||
|
.. seealso:: addParameterSource()
|
||||||
|
:rtype: QMap< str, QgsProcessingModelAlgorithm.ChildParameterSource >
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > &sources );
|
||||||
|
%Docstring
|
||||||
|
Sets the map of parameter ``sources``. The keys are the child algorithm
|
||||||
|
parameter names, the values are the source for that parameter.
|
||||||
|
.. seealso:: parameterSources()
|
||||||
|
.. seealso:: addParameterSource()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void addParameterSource( const QString &name, const QgsProcessingModelAlgorithm::ChildParameterSource &source );
|
||||||
|
%Docstring
|
||||||
|
Adds a parameter source. The ``name`` argument should match
|
||||||
|
one of the child algorithm's parameter names, and the ``source``
|
||||||
|
argument is used to set the source for that parameter.
|
||||||
|
|
||||||
|
Any existing parameter source with matching name will be replaced.
|
||||||
|
.. seealso:: parameterSources()
|
||||||
|
.. seealso:: setParameterSources()
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool isActive() const;
|
||||||
|
%Docstring
|
||||||
|
Returns true if the child algorithm is active.
|
||||||
|
.. seealso:: setActive()
|
||||||
|
:rtype: bool
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setActive( bool active );
|
||||||
|
%Docstring
|
||||||
|
Sets whether the child algorithm is active.
|
||||||
|
.. seealso:: isActive()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QStringList dependencies() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the list of child algorithms from the parent model on which this
|
||||||
|
algorithm is dependent. The returned list contains the id() of the
|
||||||
|
dependent algorithms.
|
||||||
|
.. seealso:: setDependencies()
|
||||||
|
:rtype: list of str
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setDependencies( const QStringList &dependencies );
|
||||||
|
%Docstring
|
||||||
|
Sets the list of child algorithms from the parent model on which this
|
||||||
|
algorithm is dependent. The list should contain the id() of the
|
||||||
|
dependent algorithms.
|
||||||
|
.. seealso:: dependencies()
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool parametersCollapsed() const;
|
||||||
|
%Docstring
|
||||||
|
Returns true if the list of parameters for this algorithm should be collapsed
|
||||||
|
in the graphical modeller.
|
||||||
|
.. seealso:: setParametersCollapsed()
|
||||||
|
.. seealso:: outputsCollapsed()
|
||||||
|
:rtype: bool
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParametersCollapsed( bool collapsed );
|
||||||
|
%Docstring
|
||||||
|
Sets whether the list of parameters for this algorithm should be collapsed
|
||||||
|
in the graphical modeller.
|
||||||
|
.. seealso:: parametersCollapsed()
|
||||||
|
.. seealso:: setOutputsCollapsed()
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool outputsCollapsed() const;
|
||||||
|
%Docstring
|
||||||
|
Returns true if the list of outputs for this algorithm should be collapsed
|
||||||
|
in the graphical modeller.
|
||||||
|
.. seealso:: setParametersCollapsed()
|
||||||
|
.. seealso:: parametersCollapsed()
|
||||||
|
:rtype: bool
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setOutputsCollapsed( bool collapsed );
|
||||||
|
%Docstring
|
||||||
|
Sets whether the list of outputs for this algorithm should be collapsed
|
||||||
|
in the graphical modeller.
|
||||||
|
.. seealso:: outputsCollapsed()
|
||||||
|
.. seealso:: setParametersCollapsed()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> modelOutputs() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the map of final model outputs which are generated by this child algorithm.
|
||||||
|
The keys are the output names from this child algorithm. Only outputs which are
|
||||||
|
part of the final outputs from the model are included in this map.
|
||||||
|
.. seealso:: setModelOutputs()
|
||||||
|
.. seealso:: modelOutput()
|
||||||
|
:rtype: QMap<str, QgsProcessingModelAlgorithm.ModelOutput>
|
||||||
|
%End
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput &modelOutput( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Returns the final model output with matching ``name``. If no output
|
||||||
|
exists with the name, a new one will be created and returned.
|
||||||
|
.. seealso:: modelOutputs()
|
||||||
|
.. seealso:: setModelOutputs()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ModelOutput
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
|
||||||
|
%Docstring
|
||||||
|
Sets the map of final model ``outputs`` which are generated by this child algorithm.
|
||||||
|
The keys are the output names from this child algorithm. Only outputs which are
|
||||||
|
part of the final outputs from the model should be included in this map.
|
||||||
|
.. seealso:: modelOutputs()
|
||||||
|
%End
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm( const QString &name = QString(), const QString &group = QString() );
|
||||||
|
%Docstring
|
||||||
|
Constructor for QgsProcessingModelAlgorithm.
|
||||||
|
%End
|
||||||
|
|
||||||
|
virtual QString name() const;
|
||||||
|
|
||||||
|
virtual QString displayName() const;
|
||||||
|
|
||||||
|
virtual QString group() const;
|
||||||
|
|
||||||
|
virtual QIcon icon() const;
|
||||||
|
|
||||||
|
virtual QString svgIconPath() const;
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool canExecute( QString *errorMessage /Out/ = 0 ) const;
|
||||||
|
|
||||||
|
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||||
|
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> childAlgorithms() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the map of child algorithms contained in the model. The keys
|
||||||
|
are the child algorithm ids (see QgsProcessingModelAlgorithm.ChildAlgorithm.childId()).
|
||||||
|
.. seealso:: childAlgorithm()
|
||||||
|
.. seealso:: setChildAlgorithms()
|
||||||
|
.. seealso:: addChildAlgorithm()
|
||||||
|
:rtype: QMap<str, QgsProcessingModelAlgorithm.ChildAlgorithm>
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setChildAlgorithms( const QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> &childAlgorithms );
|
||||||
|
%Docstring
|
||||||
|
Sets the map of child algorithms contained in the model. The keys
|
||||||
|
are the child algorithm ids (see QgsProcessingModelAlgorithm.ChildAlgorithm.childId()).
|
||||||
|
All existing child algorithms will be replaced.
|
||||||
|
.. seealso:: childAlgorithms()
|
||||||
|
.. seealso:: childAlgorithm()
|
||||||
|
.. seealso:: setChildAlgorithm()
|
||||||
|
.. seealso:: addChildAlgorithm()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||||
|
%Docstring
|
||||||
|
Sets the child ``algorithm`` within the model. If a child algorithm already
|
||||||
|
exists in the model with the same child ID then that algorithm will be replaced.
|
||||||
|
.. seealso:: addChildAlgorithm()
|
||||||
|
.. seealso:: setChildAlgorithms()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString addChildAlgorithm( QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||||
|
%Docstring
|
||||||
|
Adds a new child ``algorithm`` to the model. If a child algorithm already exists
|
||||||
|
in the model with the same child ID then ``algorithm`` will be assigned a new
|
||||||
|
autogenerated unique ID.
|
||||||
|
The assigned child ID will be returned.
|
||||||
|
.. seealso:: childAlgorithms()
|
||||||
|
.. seealso:: childAlgorithm()
|
||||||
|
.. seealso:: setChildAlgorithm()
|
||||||
|
.. seealso:: setChildAlgorithms()
|
||||||
|
:rtype: str
|
||||||
|
%End
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm &childAlgorithm( const QString &id );
|
||||||
|
%Docstring
|
||||||
|
Returns the child algorithm with matching ``id``. If no child algorithm exists with
|
||||||
|
this ID a new algorithm will be added to the model and returned.
|
||||||
|
.. seealso:: addChildAlgorithm()
|
||||||
|
.. seealso:: childAlgorithms()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ChildAlgorithm
|
||||||
|
%End
|
||||||
|
|
||||||
|
void addModelParameter( QgsProcessingParameterDefinition *definition /Transfer/, const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||||
|
%Docstring
|
||||||
|
Adds a new parameter to the model, with the specified ``definition`` and graphical ``component``.
|
||||||
|
Ownership of ``definition`` is transferred to the model.
|
||||||
|
.. seealso:: updateModelParameter()
|
||||||
|
.. seealso:: removeModelParameter()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void updateModelParameter( QgsProcessingParameterDefinition *definition /Transfer/ );
|
||||||
|
%Docstring
|
||||||
|
Replaces the definition of an existing parameter (by parameter name) with a new ``definition``. Ownership of
|
||||||
|
``definition`` is transferred to the model, and any existing parameter is deleted.
|
||||||
|
.. seealso:: addModelParameter()
|
||||||
|
.. seealso:: removeModelParameter()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void removeModelParameter( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Removes an existing model parameter by ``name``. The definition of the matching parameter
|
||||||
|
is deleted.
|
||||||
|
.. seealso:: addModelParameter()
|
||||||
|
.. seealso:: updateModelParameter()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> parameterComponents() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the map of parameter components used by the model. The keys
|
||||||
|
should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||||
|
.. seealso:: setParameterComponent()
|
||||||
|
.. seealso:: parameterComponent()
|
||||||
|
:rtype: QMap<str, QgsProcessingModelAlgorithm.ModelParameter>
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents );
|
||||||
|
%Docstring
|
||||||
|
Sets the map of parameter components used by the model. The keys
|
||||||
|
should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||||
|
All existing parameter components will be replaced.
|
||||||
|
.. seealso:: parameterComponents()
|
||||||
|
.. seealso:: setParameterComponent()
|
||||||
|
.. seealso:: parameterComponent()
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||||
|
%Docstring
|
||||||
|
Sets a parameter ``component`` for the model. If a parameter component already
|
||||||
|
exists in the model with the same parameter name then that component will be replaced.
|
||||||
|
.. seealso:: parameterComponents()
|
||||||
|
.. seealso:: setParameterComponents()
|
||||||
|
.. seealso:: parameterComponent()
|
||||||
|
%End
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter ¶meterComponent( const QString &name );
|
||||||
|
%Docstring
|
||||||
|
Returns the parameter component with matching ``name``. If no parameter component exists with
|
||||||
|
this name a new component will be added to the model and returned.
|
||||||
|
.. seealso:: parameterComponents()
|
||||||
|
.. seealso:: setParameterComponents()
|
||||||
|
.. seealso:: setParameterComponent()
|
||||||
|
:rtype: QgsProcessingModelAlgorithm.ModelParameter
|
||||||
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QStringList dependentChildAlgorithms( const QString &childId ) const;
|
||||||
|
%Docstring
|
||||||
|
:rtype: list of str
|
||||||
|
%End
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* This file has been generated automatically from *
|
||||||
|
* *
|
||||||
|
* src/core/processing/qgsprocessingmodelalgorithm.h *
|
||||||
|
* *
|
||||||
|
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||||
|
************************************************************************/
|
@ -65,7 +65,8 @@ from qgis.core import (
|
|||||||
QgsProcessingOutputRasterLayer,
|
QgsProcessingOutputRasterLayer,
|
||||||
QgsProcessingOutputVectorLayer,
|
QgsProcessingOutputVectorLayer,
|
||||||
QgsProcessingOutputString,
|
QgsProcessingOutputString,
|
||||||
QgsProcessingOutputNumber)
|
QgsProcessingOutputNumber,
|
||||||
|
QgsProcessingModelAlgorithm)
|
||||||
|
|
||||||
from qgis.PyQt.QtWidgets import (
|
from qgis.PyQt.QtWidgets import (
|
||||||
QCheckBox,
|
QCheckBox,
|
||||||
|
@ -36,6 +36,7 @@ from qgis.PyQt.QtCore import QPointF
|
|||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from qgis.core import (QgsApplication,
|
from qgis.core import (QgsApplication,
|
||||||
|
QgsProcessingAlgorithm,
|
||||||
QgsProcessingParameterDefinition,
|
QgsProcessingParameterDefinition,
|
||||||
QgsProcessingParameterBoolean,
|
QgsProcessingParameterBoolean,
|
||||||
QgsProcessingParameterCrs,
|
QgsProcessingParameterCrs,
|
||||||
@ -53,10 +54,10 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsProcessingParameterExpression,
|
QgsProcessingParameterExpression,
|
||||||
QgsProcessingParameterTable,
|
QgsProcessingParameterTable,
|
||||||
QgsProcessingParameterTableField,
|
QgsProcessingParameterTableField,
|
||||||
QgsProcessingParameterFeatureSource)
|
QgsProcessingParameterFeatureSource,
|
||||||
|
QgsProcessingModelAlgorithm)
|
||||||
from qgis.gui import QgsMessageBar
|
from qgis.gui import QgsMessageBar
|
||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
|
||||||
from processing.modeler.WrongModelException import WrongModelException
|
from processing.modeler.WrongModelException import WrongModelException
|
||||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||||
|
|
||||||
@ -65,85 +66,26 @@ from processing.gui.Help2Html import getHtmlFromDescriptionsDict
|
|||||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||||
|
|
||||||
|
|
||||||
class ModelerParameter(object):
|
class Algorithm(QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
|
|
||||||
def __init__(self, param=None, pos=None):
|
def __init__(self, consoleName=None):
|
||||||
self.param = param
|
super().__init__(consoleName)
|
||||||
self.pos = pos
|
|
||||||
|
|
||||||
def todict(self):
|
|
||||||
return self.__dict__
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fromdict(d):
|
|
||||||
return ModelerParameter(d["param"], d["pos"])
|
|
||||||
|
|
||||||
|
|
||||||
class ModelerOutput(object):
|
|
||||||
|
|
||||||
def __init__(self, description=""):
|
|
||||||
self.description = description
|
|
||||||
self.pos = None
|
|
||||||
|
|
||||||
def todict(self):
|
|
||||||
return self.__dict__
|
|
||||||
|
|
||||||
|
|
||||||
class Algorithm(object):
|
|
||||||
|
|
||||||
def __init__(self, consoleName=""):
|
|
||||||
|
|
||||||
self.name = None
|
|
||||||
self.description = ""
|
|
||||||
|
|
||||||
# The type of the algorithm, indicated as a string, which corresponds
|
|
||||||
# to the string used to refer to it in the python console
|
|
||||||
self.consoleName = consoleName
|
|
||||||
|
|
||||||
self._algInstance = None
|
|
||||||
|
|
||||||
# A dict of Input object. keys are param names
|
|
||||||
self.params = {}
|
|
||||||
|
|
||||||
# A dict of ModelerOutput with final output descriptions. Keys are output names.
|
|
||||||
# Outputs not final are not stored in this dict
|
|
||||||
self.outputs = {}
|
|
||||||
|
|
||||||
self.pos = None
|
|
||||||
|
|
||||||
self.dependencies = []
|
|
||||||
|
|
||||||
self.paramsFolded = True
|
|
||||||
self.outputsFolded = True
|
|
||||||
self.active = True
|
|
||||||
|
|
||||||
def todict(self):
|
def todict(self):
|
||||||
return {k: v for k, v in list(self.__dict__.items()) if not k.startswith("_")}
|
return {k: v for k, v in list(self.__dict__.items()) if not k.startswith("_")}
|
||||||
|
|
||||||
@property
|
|
||||||
def algorithm(self):
|
|
||||||
if self._algInstance is None:
|
|
||||||
self._algInstance = QgsApplication.processingRegistry().algorithmById(self.consoleName)
|
|
||||||
return self._algInstance
|
|
||||||
|
|
||||||
def setName(self, model):
|
|
||||||
if self.name is None:
|
|
||||||
i = 1
|
|
||||||
name = self.consoleName + "_" + str(i)
|
|
||||||
while name in model.algs:
|
|
||||||
i += 1
|
|
||||||
name = self.consoleName + "_" + str(i)
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
def getOutputType(self, outputName):
|
def getOutputType(self, outputName):
|
||||||
output = self.algorithm.getOutputFromName(outputName)
|
output = self.algorithm().outputDefinition(outputName)
|
||||||
return "output " + output.__class__.__name__.split(".")[-1][6:].lower()
|
return "output " + output.__class__.__name__.split(".")[-1][6:].lower()
|
||||||
|
|
||||||
def toPython(self):
|
def toPython(self):
|
||||||
s = []
|
s = []
|
||||||
params = []
|
params = []
|
||||||
for param in self.algorithm.parameters:
|
if not self.algorithm():
|
||||||
value = self.params[param.name]
|
return None
|
||||||
|
|
||||||
|
for param in self.algorithm().parameterDefinitions():
|
||||||
|
value = self.parameterSources()[param.name()]
|
||||||
|
|
||||||
def _toString(v):
|
def _toString(v):
|
||||||
if isinstance(v, (ValueFromInput, ValueFromOutput)):
|
if isinstance(v, (ValueFromInput, ValueFromOutput)):
|
||||||
@ -155,13 +97,13 @@ class Algorithm(object):
|
|||||||
else:
|
else:
|
||||||
return str(value)
|
return str(value)
|
||||||
params.append(_toString(value))
|
params.append(_toString(value))
|
||||||
for out in self.algorithm.outputs:
|
for out in self.algorithm().outputs:
|
||||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
if out.name() in self.outputs:
|
if out.name() in self.outputs:
|
||||||
params.append(safeName(self.outputs[out.name()].description()).lower())
|
params.append(safeName(self.outputs[out.name()].description()).lower())
|
||||||
else:
|
else:
|
||||||
params.append(str(None))
|
params.append(str(None))
|
||||||
s.append("outputs_%s=processing.run('%s', %s)" % (self.name, self.consoleName, ",".join(params)))
|
s.append("outputs_%s=processing.run('%s', %s)" % (self.childId(), self.algorithmId(), ",".join(params)))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
@ -230,88 +172,31 @@ class CompoundValue(object):
|
|||||||
return "" # TODO
|
return "" # TODO
|
||||||
|
|
||||||
|
|
||||||
class ModelerAlgorithm(GeoAlgorithm):
|
class ModelerAlgorithm(QgsProcessingModelAlgorithm):
|
||||||
|
|
||||||
CANVAS_SIZE = 4000
|
CANVAS_SIZE = 4000
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._name = self.tr('Model', 'ModelerAlgorithm')
|
super().__init__()
|
||||||
|
|
||||||
# The dialog where this model is being edited
|
# The dialog where this model is being edited
|
||||||
self.modelerdialog = None
|
self.modelerdialog = None
|
||||||
self.descriptionFile = None
|
self.descriptionFile = None
|
||||||
self.helpContent = {}
|
self.helpContent = {}
|
||||||
self._group = ''
|
|
||||||
|
|
||||||
# Geoalgorithms in this model. A dict of Algorithm objects, with names as keys
|
# Geoalgorithms in this model. A dict of Algorithm objects, with names as keys
|
||||||
self.algs = {}
|
self.algs = {}
|
||||||
|
|
||||||
# Input parameters. A dict of Input objects, with names as keys
|
|
||||||
self.inputs = {}
|
|
||||||
GeoAlgorithm.__init__(self)
|
|
||||||
|
|
||||||
classes = [c for c in QgsProcessingParameterDefinition.__subclasses__()]
|
|
||||||
self.parameters = []
|
|
||||||
for c in classes:
|
|
||||||
for inp in list(self.inputs.values()):
|
|
||||||
if isinstance(inp.param, c):
|
|
||||||
self.parameters.append(inp.param)
|
|
||||||
for inp in list(self.inputs.values()):
|
|
||||||
if inp.param not in self.parameters:
|
|
||||||
self.parameters.append(inp.param)
|
|
||||||
self.parameters.sort(key=attrgetter("description"))
|
|
||||||
|
|
||||||
self.outputs = []
|
|
||||||
for alg in list(self.algs.values()):
|
|
||||||
if alg.active:
|
|
||||||
for out in alg.outputs:
|
|
||||||
modelOutput = copy.deepcopy(alg.algorithm.getOutputFromName(out))
|
|
||||||
modelOutput.name = self.getSafeNameForOutput(alg.modeler_name, out)
|
|
||||||
modelOutput.description = alg.outputs[out].description()
|
|
||||||
self.outputs.append(modelOutput)
|
|
||||||
self.outputs.sort(key=attrgetter("description"))
|
|
||||||
|
|
||||||
def name(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
def displayName(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
def group(self):
|
|
||||||
return self._group
|
|
||||||
|
|
||||||
def icon(self):
|
|
||||||
return QgsApplication.getThemeIcon("/processingModel.svg")
|
|
||||||
|
|
||||||
def svgIconPath(self):
|
|
||||||
return QgsApplication.iconPath("processingModel.svg")
|
|
||||||
|
|
||||||
def addParameter(self, param):
|
|
||||||
self.inputs[param.param.name()] = param
|
|
||||||
|
|
||||||
def updateParameter(self, param):
|
|
||||||
self.inputs[param.name()].param = param
|
|
||||||
|
|
||||||
def addAlgorithm(self, alg):
|
|
||||||
name = self.getNameForAlgorithm(alg)
|
|
||||||
alg.modeler_name = name
|
|
||||||
self.algs[name] = alg
|
|
||||||
|
|
||||||
def getNameForAlgorithm(self, alg):
|
|
||||||
i = 1
|
|
||||||
while alg.consoleName.upper().replace(":", "") + "_" + str(i) in list(self.algs.keys()):
|
|
||||||
i += 1
|
|
||||||
return alg.consoleName.upper().replace(":", "") + "_" + str(i)
|
|
||||||
|
|
||||||
def updateAlgorithm(self, alg):
|
def updateAlgorithm(self, alg):
|
||||||
alg.pos = self.algs[alg.modeler_name].pos
|
alg.setPosition(self.childAlgorithm(alg.childId()).position())
|
||||||
alg.paramsFolded = self.algs[alg.modeler_name].paramsFolded
|
alg.setParametersCollapsed(self.childAlgorithm(alg.childId()).parametersCollapsed())
|
||||||
alg.outputsFolded = self.algs[alg.modeler_name].outputsFolded
|
alg.setOutputsCollapsed(self.childAlgorithm(alg.childId()).outputsCollapsed())
|
||||||
self.algs[alg.modeler_name] = alg
|
self.setChildAlgorithm(alg)
|
||||||
|
|
||||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||||
for i, out in enumerate(alg.outputs):
|
for i, out in enumerate(alg.modelOutputs().keys()):
|
||||||
alg.outputs[out].pos = (alg.outputs[out].pos or
|
alg.modelOutput(out).setPosition(alg.modelOutput(out).position() or
|
||||||
alg.pos + QPointF(
|
alg.position() + QPointF(
|
||||||
ModelerGraphicItem.BOX_WIDTH,
|
ModelerGraphicItem.BOX_WIDTH,
|
||||||
(i + 1.5) * ModelerGraphicItem.BOX_HEIGHT))
|
(i + 1.5) * ModelerGraphicItem.BOX_HEIGHT))
|
||||||
|
|
||||||
@ -331,7 +216,7 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
"""
|
"""
|
||||||
if self.hasDependencies(name):
|
if self.hasDependencies(name):
|
||||||
return False
|
return False
|
||||||
del self.inputs[name]
|
self.removeModelParameter(name)
|
||||||
self.modelerdialog.hasChanged = True
|
self.modelerdialog.hasChanged = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -357,8 +242,8 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
elif isinstance(value, ValueFromOutput):
|
elif isinstance(value, ValueFromOutput):
|
||||||
if value.alg == name:
|
if value.alg == name:
|
||||||
return True
|
return True
|
||||||
if alg.modeler_name != name:
|
if alg.childId() != name:
|
||||||
for dep in alg.dependencies:
|
for dep in alg.dependencies():
|
||||||
if (dep == name):
|
if (dep == name):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -369,7 +254,7 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
"""
|
"""
|
||||||
alg = self.algs[name]
|
alg = self.algs[name]
|
||||||
algs = set()
|
algs = set()
|
||||||
algs.update(set(alg.dependencies))
|
algs.update(set(alg.dependencies()))
|
||||||
for value in list(alg.params.values()):
|
for value in list(alg.params.values()):
|
||||||
if value is None:
|
if value is None:
|
||||||
continue
|
continue
|
||||||
@ -402,23 +287,14 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
for v in value:
|
for v in value:
|
||||||
if isinstance(v, ValueFromOutput) and v.alg == name:
|
if isinstance(v, ValueFromOutput) and v.alg == name:
|
||||||
algs.update(self.getDependentAlgorithms(alg.modeler_name))
|
algs.update(self.getDependentAlgorithms(alg.childId()))
|
||||||
elif isinstance(value, ValueFromOutput) and value.alg == name:
|
elif isinstance(value, ValueFromOutput) and value.alg == name:
|
||||||
algs.update(self.getDependentAlgorithms(alg.modeler_name))
|
algs.update(self.getDependentAlgorithms(alg.childId()))
|
||||||
|
|
||||||
return algs
|
return algs
|
||||||
|
|
||||||
def setPositions(self, paramPos, algPos, outputsPos):
|
|
||||||
for param, pos in list(paramPos.items()):
|
|
||||||
self.inputs[param].pos = pos
|
|
||||||
for alg, pos in list(algPos.items()):
|
|
||||||
self.algs[alg].pos = pos
|
|
||||||
for alg, positions in list(outputsPos.items()):
|
|
||||||
for output, pos in list(positions.items()):
|
|
||||||
self.algs[alg].outputs[output].pos = pos
|
|
||||||
|
|
||||||
def prepareAlgorithm(self, alg):
|
def prepareAlgorithm(self, alg):
|
||||||
algInstance = alg.algorithm
|
algInstance = alg.algorithm()
|
||||||
for param in algInstance.parameterDefinitions():
|
for param in algInstance.parameterDefinitions():
|
||||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
if param.name() in alg.params:
|
if param.name() in alg.params:
|
||||||
@ -441,10 +317,11 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
for out in algInstance.outputs:
|
# note to self - these are parameters, not outputs
|
||||||
|
for out in algInstance.outputDefinitions():
|
||||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
if out.name() in alg.outputs:
|
if out.name() in alg.outputs:
|
||||||
name = self.getSafeNameForOutput(alg.modeler_name, out.name())
|
name = self.getSafeNameForOutput(alg.childId(), out.name())
|
||||||
modelOut = self.getOutputFromName(name)
|
modelOut = self.getOutputFromName(name)
|
||||||
if modelOut:
|
if modelOut:
|
||||||
out.value = modelOut.value
|
out.value = modelOut.value
|
||||||
@ -456,14 +333,14 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
def deactivateAlgorithm(self, algName):
|
def deactivateAlgorithm(self, algName):
|
||||||
dependent = self.getDependentAlgorithms(algName)
|
dependent = self.getDependentAlgorithms(algName)
|
||||||
for alg in dependent:
|
for alg in dependent:
|
||||||
self.algs[alg].active = False
|
self.algs[alg].setActive(False)
|
||||||
|
|
||||||
def activateAlgorithm(self, algName):
|
def activateAlgorithm(self, algName):
|
||||||
parents = self.getDependsOnAlgorithms(algName)
|
parents = self.getDependsOnAlgorithms(algName)
|
||||||
for alg in parents:
|
for alg in parents:
|
||||||
if not self.algs[alg].active:
|
if not self.childAlgorithm(alg).isActive():
|
||||||
return False
|
return False
|
||||||
self.algs[algName].active = True
|
self.childAlgorithm(algName).setActive(True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getSafeNameForOutput(self, algName, outName):
|
def getSafeNameForOutput(self, algName, outName):
|
||||||
@ -479,47 +356,47 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
elif isinstance(value, ValueFromInput):
|
elif isinstance(value, ValueFromInput):
|
||||||
v = self.getParameterFromName(value.name).value
|
v = self.getParameterFromName(value.name).value
|
||||||
elif isinstance(value, ValueFromOutput):
|
elif isinstance(value, ValueFromOutput):
|
||||||
v = self.algs[value.alg].algorithm.getOutputFromName(value.output).value
|
v = self.algs[value.alg].algorithm().outputDefinition(value.output).value
|
||||||
else:
|
else:
|
||||||
v = value
|
v = value
|
||||||
return param.evaluateForModeler(v, self)
|
return param.evaluateForModeler(v, self)
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def processAlgorithm(self, parameters, context, feedback):
|
||||||
executed = []
|
executed = []
|
||||||
toExecute = [alg for alg in list(self.algs.values()) if alg.active]
|
toExecute = [alg for alg in list(self.algs.values()) if alg.isActive()]
|
||||||
while len(executed) < len(toExecute):
|
while len(executed) < len(toExecute):
|
||||||
for alg in toExecute:
|
for alg in toExecute:
|
||||||
if alg.modeler_name not in executed:
|
if alg.childId() not in executed:
|
||||||
canExecute = True
|
canExecute = True
|
||||||
required = self.getDependsOnAlgorithms(alg.modeler_name)
|
required = self.getDependsOnAlgorithms(alg.childId())
|
||||||
for requiredAlg in required:
|
for requiredAlg in required:
|
||||||
if requiredAlg != alg.modeler_name and requiredAlg not in executed:
|
if requiredAlg != alg.childId() and requiredAlg not in executed:
|
||||||
canExecute = False
|
canExecute = False
|
||||||
break
|
break
|
||||||
if canExecute:
|
if canExecute:
|
||||||
try:
|
try:
|
||||||
feedback.pushDebugInfo(
|
feedback.pushDebugInfo(
|
||||||
self.tr('Prepare algorithm: {0}', 'ModelerAlgorithm').format(alg.modeler_name))
|
self.tr('Prepare algorithm: {0}', 'ModelerAlgorithm').format(alg.childId()))
|
||||||
self.prepareAlgorithm(alg)
|
self.prepareAlgorithm(alg)
|
||||||
feedback.setProgressText(
|
feedback.setProgressText(
|
||||||
self.tr('Running {0} [{1}/{2}]', 'ModelerAlgorithm').format(alg.description, len(executed) + 1, len(toExecute)))
|
self.tr('Running {0} [{1}/{2}]', 'ModelerAlgorithm').format(alg.description, len(executed) + 1, len(toExecute)))
|
||||||
feedback.pushDebugInfo('Parameters: ' + ', '.join([str(p).strip() +
|
feedback.pushDebugInfo('Parameters: ' + ', '.join([str(p).strip() +
|
||||||
'=' + str(p.value) for p in alg.algorithm.parameters]))
|
'=' + str(p.value) for p in alg.algorithm.parameters]))
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
alg.algorithm.execute(parameters, context, feedback)
|
alg.algorithm().execute(parameters, context, feedback)
|
||||||
dt = time.time() - t0
|
dt = time.time() - t0
|
||||||
|
|
||||||
# copy algorithm output value(s) back to model in case the algorithm modified those
|
# copy algorithm output value(s) back to model in case the algorithm modified those
|
||||||
for out in alg.algorithm.outputs:
|
for out in alg.algorithm().outputs:
|
||||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
if out.name() in alg.outputs:
|
if out.name() in alg.modelOutputs():
|
||||||
modelOut = self.getOutputFromName(self.getSafeNameForOutput(alg.modeler_name, out.name()))
|
modelOut = self.getOutputFromName(self.getSafeNameForOutput(alg.childId(), out.name()))
|
||||||
if modelOut:
|
if modelOut:
|
||||||
modelOut.value = out.value
|
modelOut.value = out.value
|
||||||
|
|
||||||
executed.append(alg.modeler_name)
|
executed.append(alg.childId())
|
||||||
feedback.pushDebugInfo(
|
feedback.pushDebugInfo(
|
||||||
self.tr('OK. Execution took %{0:.3f} ms ({1} outputs).', 'ModelerAlgorithm').format(dt, len(alg.algorithm.outputs)))
|
self.tr('OK. Execution took %{0:.3f} ms ({1} outputs).', 'ModelerAlgorithm').format(dt, len(alg.algorithm.modelOutputs())))
|
||||||
except GeoAlgorithmExecutionException as e:
|
except GeoAlgorithmExecutionException as e:
|
||||||
feedback.pushDebugInfo(self.tr('Failed', 'ModelerAlgorithm'))
|
feedback.pushDebugInfo(self.tr('Failed', 'ModelerAlgorithm'))
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
@ -534,13 +411,6 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def canExecute(self):
|
|
||||||
for alg in list(self.algs.values()):
|
|
||||||
algInstance = QgsApplication.processingRegistry().algorithmById(alg.consoleName)
|
|
||||||
if algInstance is None:
|
|
||||||
return False, self.tr("The model you are trying to run contains an algorithm that is not available: <i>{0}</i>").format(alg.consoleName)
|
|
||||||
return True, None
|
|
||||||
|
|
||||||
def setModelerView(self, dialog):
|
def setModelerView(self, dialog):
|
||||||
self.modelerdialog = dialog
|
self.modelerdialog = dialog
|
||||||
|
|
||||||
@ -642,26 +512,26 @@ class ModelerAlgorithm(GeoAlgorithm):
|
|||||||
|
|
||||||
def toPython(self):
|
def toPython(self):
|
||||||
s = ['##%s=name' % self.name()]
|
s = ['##%s=name' % self.name()]
|
||||||
for param in list(self.inputs.values()):
|
for param in list(self.parameterComponents().values()):
|
||||||
s.append(param.param.getAsScriptCode())
|
s.append(param.param.getAsScriptCode())
|
||||||
for alg in list(self.algs.values()):
|
for alg in list(self.algs.values()):
|
||||||
for name, out in list(alg.outputs.items()):
|
for name, out in list(alg.modelOutputs().items()):
|
||||||
s.append('##%s=%s' % (safeName(out.description()).lower(), alg.getOutputType(name)))
|
s.append('##%s=%s' % (safeName(out.description()).lower(), alg.getOutputType(name)))
|
||||||
|
|
||||||
executed = []
|
executed = []
|
||||||
toExecute = [alg for alg in list(self.algs.values()) if alg.active]
|
toExecute = [alg for alg in list(self.algs.values()) if alg.isActive()]
|
||||||
while len(executed) < len(toExecute):
|
while len(executed) < len(toExecute):
|
||||||
for alg in toExecute:
|
for alg in toExecute:
|
||||||
if alg.modeler_name not in executed:
|
if alg.childId() not in executed:
|
||||||
canExecute = True
|
canExecute = True
|
||||||
required = self.getDependsOnAlgorithms(alg.modeler_name)
|
required = self.getDependsOnAlgorithms(alg.childId())
|
||||||
for requiredAlg in required:
|
for requiredAlg in required:
|
||||||
if requiredAlg != alg.modeler_name and requiredAlg not in executed:
|
if requiredAlg != alg.childId() and requiredAlg not in executed:
|
||||||
canExecute = False
|
canExecute = False
|
||||||
break
|
break
|
||||||
if canExecute:
|
if canExecute:
|
||||||
s.extend(alg.toPython())
|
s.extend(alg.toPython())
|
||||||
executed.append(alg.modeler_name)
|
executed.append(alg.childId())
|
||||||
|
|
||||||
return '\n'.join(s)
|
return '\n'.join(s)
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@
|
|||||||
***************************************************************************
|
***************************************************************************
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from qgis.core import QgsProcessingModelAlgorithm
|
||||||
from qgis.PyQt.QtCore import Qt, QPointF
|
from qgis.PyQt.QtCore import Qt, QPointF
|
||||||
from qgis.PyQt.QtWidgets import QGraphicsPathItem, QGraphicsItem
|
from qgis.PyQt.QtWidgets import QGraphicsPathItem, QGraphicsItem
|
||||||
from qgis.PyQt.QtGui import QPen, QPainterPath, QPolygonF, QPainter
|
from qgis.PyQt.QtGui import QPen, QPainterPath, QPolygonF, QPainter
|
||||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||||
from processing.modeler.ModelerAlgorithm import Algorithm
|
|
||||||
|
|
||||||
|
|
||||||
class ModelerArrowItem(QGraphicsPathItem):
|
class ModelerArrowItem(QGraphicsPathItem):
|
||||||
@ -75,7 +75,7 @@ class ModelerArrowItem(QGraphicsPathItem):
|
|||||||
controlPoints = []
|
controlPoints = []
|
||||||
endPt = self.endItem.getLinkPointForParameter(self.endIndex)
|
endPt = self.endItem.getLinkPointForParameter(self.endIndex)
|
||||||
startPt = self.startItem.getLinkPointForOutput(self.startIndex)
|
startPt = self.startItem.getLinkPointForOutput(self.startIndex)
|
||||||
if isinstance(self.startItem.element, Algorithm):
|
if isinstance(self.startItem.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
if self.startIndex != -1:
|
if self.startIndex != -1:
|
||||||
controlPoints.append(self.startItem.pos() + startPt)
|
controlPoints.append(self.startItem.pos() + startPt)
|
||||||
controlPoints.append(self.startItem.pos() + startPt +
|
controlPoints.append(self.startItem.pos() + startPt +
|
||||||
|
@ -29,6 +29,7 @@ __revision__ = '$Format:%H$'
|
|||||||
import codecs
|
import codecs
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import math
|
||||||
|
|
||||||
from qgis.PyQt import uic
|
from qgis.PyQt import uic
|
||||||
from qgis.PyQt.QtCore import Qt, QRectF, QMimeData, QPoint, QPointF, QByteArray, QSize, QSizeF, pyqtSignal
|
from qgis.PyQt.QtCore import Qt, QRectF, QMimeData, QPoint, QPointF, QByteArray, QSize, QSizeF, pyqtSignal
|
||||||
@ -40,12 +41,13 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsProcessingAlgorithm,
|
QgsProcessingAlgorithm,
|
||||||
QgsSettings,
|
QgsSettings,
|
||||||
QgsMessageLog,
|
QgsMessageLog,
|
||||||
QgsProcessingUtils)
|
QgsProcessingUtils,
|
||||||
|
QgsProcessingModelAlgorithm)
|
||||||
from qgis.gui import QgsMessageBar
|
from qgis.gui import QgsMessageBar
|
||||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
||||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||||
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm, ModelerParameter
|
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm
|
||||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||||
from processing.modeler.ModelerUtils import ModelerUtils
|
from processing.modeler.ModelerUtils import ModelerUtils
|
||||||
from processing.modeler.ModelerScene import ModelerScene
|
from processing.modeler.ModelerScene import ModelerScene
|
||||||
@ -62,7 +64,7 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
|
|
||||||
update_model = pyqtSignal()
|
update_model = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, alg=None):
|
def __init__(self, model=None):
|
||||||
super(ModelerDialog, self).__init__(None)
|
super(ModelerDialog, self).__init__(None)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
@ -128,6 +130,11 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
|
|
||||||
settings = QgsSettings()
|
settings = QgsSettings()
|
||||||
factor = settings.value('/qgis/zoom_favor', 2.0)
|
factor = settings.value('/qgis/zoom_favor', 2.0)
|
||||||
|
|
||||||
|
# "Normal" mouse has an angle delta of 120, precision mouses provide data
|
||||||
|
# faster, in smaller steps
|
||||||
|
factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())
|
||||||
|
|
||||||
if (event.modifiers() == Qt.ControlModifier):
|
if (event.modifiers() == Qt.ControlModifier):
|
||||||
factor = 1.0 + (factor - 1.0) / 20.0
|
factor = 1.0 + (factor - 1.0) / 20.0
|
||||||
|
|
||||||
@ -135,7 +142,6 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
factor = 1 / factor
|
factor = 1 / factor
|
||||||
|
|
||||||
self.view.scale(factor, factor)
|
self.view.scale(factor, factor)
|
||||||
self.repaintModel()
|
|
||||||
|
|
||||||
def _enterEvent(e):
|
def _enterEvent(e):
|
||||||
QGraphicsView.enterEvent(self.view, e)
|
QGraphicsView.enterEvent(self.view, e)
|
||||||
@ -228,21 +234,21 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
self.mActionEditHelp.triggered.connect(self.editHelp)
|
self.mActionEditHelp.triggered.connect(self.editHelp)
|
||||||
self.mActionRun.triggered.connect(self.runModel)
|
self.mActionRun.triggered.connect(self.runModel)
|
||||||
|
|
||||||
if alg is not None:
|
if model is not None:
|
||||||
self.alg = alg
|
self.model = model
|
||||||
self.textGroup.setText(alg._group)
|
self.textGroup.setText(model.group())
|
||||||
self.textName.setText(alg.displayName())
|
self.textName.setText(model.displayName())
|
||||||
self.repaintModel()
|
self.repaintModel()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.alg = ModelerAlgorithm()
|
self.model = ModelerAlgorithm()
|
||||||
self.alg.modelerdialog = self
|
self.model.modelerdialog = self
|
||||||
|
|
||||||
self.fillInputsTree()
|
self.fillInputsTree()
|
||||||
self.fillAlgorithmTree()
|
self.fillAlgorithmTree()
|
||||||
|
|
||||||
self.view.centerOn(0, 0)
|
self.view.centerOn(0, 0)
|
||||||
self.alg.setModelerView(self)
|
self.model.setModelerView(self)
|
||||||
self.help = None
|
self.help = None
|
||||||
|
|
||||||
self.hasChanged = False
|
self.hasChanged = False
|
||||||
@ -269,19 +275,19 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
evt.accept()
|
evt.accept()
|
||||||
|
|
||||||
def editHelp(self):
|
def editHelp(self):
|
||||||
alg = self.alg
|
alg = self.model
|
||||||
dlg = HelpEditionDialog(alg)
|
dlg = HelpEditionDialog(alg)
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
if dlg.descriptions:
|
if dlg.descriptions:
|
||||||
self.alg.helpContent = dlg.descriptions
|
self.model.helpContent = dlg.descriptions
|
||||||
self.hasChanged = True
|
self.hasChanged = True
|
||||||
|
|
||||||
def runModel(self):
|
def runModel(self):
|
||||||
if len(self.alg.algs) == 0:
|
if len(self.model.childAlgorithms()) == 0:
|
||||||
self.bar.pushMessage("", "Model doesn't contain any algorithm and/or parameter and can't be executed", level=QgsMessageBar.WARNING, duration=5)
|
self.bar.pushMessage("", "Model doesn't contain any algorithm and/or parameter and can't be executed", level=QgsMessageBar.WARNING, duration=5)
|
||||||
return
|
return
|
||||||
|
|
||||||
dlg = AlgorithmDialog(self.alg)
|
dlg = AlgorithmDialog(self.model)
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -399,7 +405,7 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
svg.setFileName(filename)
|
svg.setFileName(filename)
|
||||||
svg.setSize(QSize(totalRect.width(), totalRect.height()))
|
svg.setSize(QSize(totalRect.width(), totalRect.height()))
|
||||||
svg.setViewBox(svgRect)
|
svg.setViewBox(svgRect)
|
||||||
svg.setTitle(self.alg.displayName())
|
svg.setTitle(self.model.displayName())
|
||||||
|
|
||||||
painter = QPainter(svg)
|
painter = QPainter(svg)
|
||||||
self.scene.render(painter, svgRect, totalRect)
|
self.scene.render(painter, svgRect, totalRect)
|
||||||
@ -418,7 +424,7 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
if not filename.lower().endswith('.py'):
|
if not filename.lower().endswith('.py'):
|
||||||
filename += '.py'
|
filename += '.py'
|
||||||
|
|
||||||
text = self.alg.toPython()
|
text = self.model.toPython()
|
||||||
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
||||||
fout.write(text)
|
fout.write(text)
|
||||||
|
|
||||||
@ -431,10 +437,10 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
self, self.tr('Warning'), self.tr('Please enter group and model names before saving')
|
self, self.tr('Warning'), self.tr('Please enter group and model names before saving')
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
self.alg._name = str(self.textName.text())
|
self.model._name = str(self.textName.text())
|
||||||
self.alg._group = str(self.textGroup.text())
|
self.model._group = str(self.textGroup.text())
|
||||||
if self.alg.descriptionFile is not None and not saveAs:
|
if self.model.descriptionFile is not None and not saveAs:
|
||||||
filename = self.alg.descriptionFile
|
filename = self.model.descriptionFile
|
||||||
else:
|
else:
|
||||||
filename, filter = QFileDialog.getSaveFileName(self,
|
filename, filter = QFileDialog.getSaveFileName(self,
|
||||||
self.tr('Save Model'),
|
self.tr('Save Model'),
|
||||||
@ -443,9 +449,9 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
if filename:
|
if filename:
|
||||||
if not filename.endswith('.model'):
|
if not filename.endswith('.model'):
|
||||||
filename += '.model'
|
filename += '.model'
|
||||||
self.alg.descriptionFile = filename
|
self.model.descriptionFile = filename
|
||||||
if filename:
|
if filename:
|
||||||
text = self.alg.toJson()
|
text = self.model.toJson()
|
||||||
try:
|
try:
|
||||||
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
||||||
fout.write(text)
|
fout.write(text)
|
||||||
@ -473,8 +479,8 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
if filename:
|
if filename:
|
||||||
try:
|
try:
|
||||||
alg = ModelerAlgorithm.fromFile(filename)
|
alg = ModelerAlgorithm.fromFile(filename)
|
||||||
self.alg = alg
|
self.model = alg
|
||||||
self.alg.setModelerView(self)
|
self.model.setModelerView(self)
|
||||||
self.textGroup.setText(alg._group)
|
self.textGroup.setText(alg._group)
|
||||||
self.textName.setText(alg._name)
|
self.textName.setText(alg._name)
|
||||||
self.repaintModel()
|
self.repaintModel()
|
||||||
@ -499,7 +505,7 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
self.scene = ModelerScene()
|
self.scene = ModelerScene()
|
||||||
self.scene.setSceneRect(QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE,
|
self.scene.setSceneRect(QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE,
|
||||||
ModelerAlgorithm.CANVAS_SIZE))
|
ModelerAlgorithm.CANVAS_SIZE))
|
||||||
self.scene.paintModel(self.alg, controls)
|
self.scene.paintModel(self.model, controls)
|
||||||
self.view.setScene(self.scene)
|
self.view.setScene(self.scene)
|
||||||
|
|
||||||
def addInput(self):
|
def addInput(self):
|
||||||
@ -509,14 +515,16 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
|
|
||||||
def addInputOfType(self, paramType, pos=None):
|
def addInputOfType(self, paramType, pos=None):
|
||||||
if paramType in ModelerParameterDefinitionDialog.paramTypes:
|
if paramType in ModelerParameterDefinitionDialog.paramTypes:
|
||||||
dlg = ModelerParameterDefinitionDialog(self.alg, paramType)
|
dlg = ModelerParameterDefinitionDialog(self.model, paramType)
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
if dlg.param is not None:
|
if dlg.param is not None:
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos = self.getPositionForParameterItem()
|
pos = self.getPositionForParameterItem()
|
||||||
if isinstance(pos, QPoint):
|
if isinstance(pos, QPoint):
|
||||||
pos = QPointF(pos)
|
pos = QPointF(pos)
|
||||||
self.alg.addParameter(ModelerParameter(dlg.param, pos))
|
component = QgsProcessingModelAlgorithm.ModelParameter(dlg.param.name())
|
||||||
|
component.setPosition(pos)
|
||||||
|
self.model.addModelParameter(dlg.param, component)
|
||||||
self.repaintModel()
|
self.repaintModel()
|
||||||
# self.view.ensureVisible(self.scene.getLastParameterItem())
|
# self.view.ensureVisible(self.scene.getLastParameterItem())
|
||||||
self.hasChanged = True
|
self.hasChanged = True
|
||||||
@ -525,8 +533,8 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
MARGIN = 20
|
MARGIN = 20
|
||||||
BOX_WIDTH = 200
|
BOX_WIDTH = 200
|
||||||
BOX_HEIGHT = 80
|
BOX_HEIGHT = 80
|
||||||
if self.alg.inputs:
|
if len(self.model.parameterComponents() > 0):
|
||||||
maxX = max([i.pos.x() for i in list(self.alg.inputs.values())])
|
maxX = max([i.position().x() for i in list(self.model.parameterComponents().values())])
|
||||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||||
else:
|
else:
|
||||||
newX = MARGIN + BOX_WIDTH / 2
|
newX = MARGIN + BOX_WIDTH / 2
|
||||||
@ -554,24 +562,22 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
def _addAlgorithm(self, alg, pos=None):
|
def _addAlgorithm(self, alg, pos=None):
|
||||||
dlg = None
|
dlg = None
|
||||||
try:
|
try:
|
||||||
dlg = alg.getCustomModelerParametersDialog(self.alg)
|
dlg = alg.getCustomModelerParametersDialog(self.model)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not dlg:
|
if not dlg:
|
||||||
dlg = ModelerParametersDialog(alg, self.alg)
|
dlg = ModelerParametersDialog(alg, self.model)
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
if dlg.alg is not None:
|
if dlg.alg is not None:
|
||||||
if pos is None:
|
if pos is None:
|
||||||
dlg.alg.pos = self.getPositionForAlgorithmItem()
|
dlg.alg.setPosition(self.getPositionForAlgorithmItem())
|
||||||
else:
|
else:
|
||||||
dlg.alg.pos = pos
|
dlg.alg.setPosition(pos)
|
||||||
if isinstance(dlg.alg.pos, QPoint):
|
|
||||||
dlg.alg.pos = QPointF(pos)
|
|
||||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||||
for i, out in enumerate(dlg.alg.outputs):
|
for i, out in enumerate(dlg.alg.modelOutputs()):
|
||||||
dlg.alg.outputs[out].pos = dlg.alg.pos + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
|
dlg.alg.modelOutput(out).setPosition(dlg.alg.position() + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
|
||||||
ModelerGraphicItem.BOX_HEIGHT)
|
ModelerGraphicItem.BOX_HEIGHT))
|
||||||
self.alg.addAlgorithm(dlg.alg)
|
self.model.addChildAlgorithm(dlg.alg)
|
||||||
self.repaintModel()
|
self.repaintModel()
|
||||||
self.hasChanged = True
|
self.hasChanged = True
|
||||||
|
|
||||||
@ -579,9 +585,9 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
MARGIN = 20
|
MARGIN = 20
|
||||||
BOX_WIDTH = 200
|
BOX_WIDTH = 200
|
||||||
BOX_HEIGHT = 80
|
BOX_HEIGHT = 80
|
||||||
if self.alg.algs:
|
if self.model.childAlgorithms():
|
||||||
maxX = max([alg.pos.x() for alg in list(self.alg.algs.values())])
|
maxX = max([alg.position().x() for alg in list(self.model.childAlgorithms().values())])
|
||||||
maxY = max([alg.pos.y() for alg in list(self.alg.algs.values())])
|
maxY = max([alg.position().y() for alg in list(self.model.childAlgorithms().values())])
|
||||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||||
newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE -
|
newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE -
|
||||||
BOX_HEIGHT)
|
BOX_HEIGHT)
|
||||||
@ -611,7 +617,7 @@ class ModelerDialog(BASE, WIDGET):
|
|||||||
for alg in provider.algorithms():
|
for alg in provider.algorithms():
|
||||||
if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler:
|
if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler:
|
||||||
continue
|
continue
|
||||||
if alg.id() == self.alg.id():
|
if alg.id() == self.model.id():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
item_text = [alg.displayName().lower()]
|
item_text = [alg.displayName().lower()]
|
||||||
|
@ -33,8 +33,8 @@ from qgis.PyQt.QtCore import Qt, QPointF, QRectF
|
|||||||
from qgis.PyQt.QtGui import QFont, QFontMetricsF, QPen, QBrush, QColor, QPolygonF, QPicture, QPainter
|
from qgis.PyQt.QtGui import QFont, QFontMetricsF, QPen, QBrush, QColor, QPolygonF, QPicture, QPainter
|
||||||
from qgis.PyQt.QtWidgets import QGraphicsItem, QMessageBox, QMenu
|
from qgis.PyQt.QtWidgets import QGraphicsItem, QMessageBox, QMenu
|
||||||
from qgis.PyQt.QtSvg import QSvgRenderer
|
from qgis.PyQt.QtSvg import QSvgRenderer
|
||||||
from qgis.core import QgsProcessingParameterDefinition
|
from qgis.core import (QgsProcessingParameterDefinition,
|
||||||
from processing.modeler.ModelerAlgorithm import ModelerParameter, Algorithm, ModelerOutput
|
QgsProcessingModelAlgorithm)
|
||||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||||
|
|
||||||
@ -51,31 +51,31 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
self.controls = controls
|
self.controls = controls
|
||||||
self.model = model
|
self.model = model
|
||||||
self.element = element
|
self.element = element
|
||||||
if isinstance(element, ModelerParameter):
|
if isinstance(element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg'))
|
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg'))
|
||||||
self.picture = QPicture()
|
self.picture = QPicture()
|
||||||
painter = QPainter(self.picture)
|
painter = QPainter(self.picture)
|
||||||
svg.render(painter)
|
svg.render(painter)
|
||||||
self.pixmap = None
|
self.pixmap = None
|
||||||
self.text = element.param.description()
|
self.text = self.model.parameterDefinition(element.parameterName()).description()
|
||||||
elif isinstance(element, ModelerOutput):
|
elif isinstance(element, QgsProcessingModelAlgorithm.ModelOutput):
|
||||||
# Output name
|
# Output name
|
||||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg'))
|
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg'))
|
||||||
self.picture = QPicture()
|
self.picture = QPicture()
|
||||||
painter = QPainter(self.picture)
|
painter = QPainter(self.picture)
|
||||||
svg.render(painter)
|
svg.render(painter)
|
||||||
self.pixmap = None
|
self.pixmap = None
|
||||||
self.text = element.description
|
self.text = element.description()
|
||||||
else:
|
else:
|
||||||
self.text = element.description
|
self.text = element.description()
|
||||||
self.pixmap = element.algorithm.icon().pixmap(15, 15)
|
self.pixmap = element.algorithm().icon().pixmap(15, 15)
|
||||||
self.arrows = []
|
self.arrows = []
|
||||||
self.setFlag(QGraphicsItem.ItemIsMovable, True)
|
self.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||||
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||||
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
|
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
|
||||||
self.setZValue(1000)
|
self.setZValue(1000)
|
||||||
|
|
||||||
if not isinstance(element, ModelerOutput) and controls:
|
if not isinstance(element, QgsProcessingModelAlgorithm.ModelOutput) and controls:
|
||||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg'))
|
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg'))
|
||||||
picture = QPicture()
|
picture = QPicture()
|
||||||
painter = QPainter(picture)
|
painter = QPainter(picture)
|
||||||
@ -98,25 +98,27 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
self.removeElement)
|
self.removeElement)
|
||||||
self.deleteButton.setParentItem(self)
|
self.deleteButton.setParentItem(self)
|
||||||
|
|
||||||
if isinstance(element, Algorithm):
|
if isinstance(element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
alg = element.algorithm
|
alg = element.algorithm()
|
||||||
if [a for a in alg.parameterDefinitions() if not a.isDestination()]:
|
if [a for a in alg.parameterDefinitions() if not a.isDestination()]:
|
||||||
pt = self.getLinkPointForParameter(-1)
|
pt = self.getLinkPointForParameter(-1)
|
||||||
pt = QPointF(0, pt.y())
|
pt = QPointF(0, pt.y())
|
||||||
if controls:
|
if controls:
|
||||||
self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.paramsFolded)
|
self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.parametersCollapsed())
|
||||||
self.inButton.setParentItem(self)
|
self.inButton.setParentItem(self)
|
||||||
if alg.outputDefinitions():
|
if alg.outputDefinitions():
|
||||||
pt = self.getLinkPointForOutput(-1)
|
pt = self.getLinkPointForOutput(-1)
|
||||||
pt = QPointF(0, pt.y())
|
pt = QPointF(0, pt.y())
|
||||||
if controls:
|
if controls:
|
||||||
self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsFolded)
|
self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsCollapsed())
|
||||||
self.outButton.setParentItem(self)
|
self.outButton.setParentItem(self)
|
||||||
|
|
||||||
def foldInput(self, folded):
|
def foldInput(self, folded):
|
||||||
self.element.paramsFolded = folded
|
self.element.setParametersCollapsed(folded)
|
||||||
|
#also need to update the model's stored component
|
||||||
|
self.model.childAlgorithm(self.element.childId()).setParametersCollapsed(folded)
|
||||||
self.prepareGeometryChange()
|
self.prepareGeometryChange()
|
||||||
if self.element.algorithm.outputDefinitions():
|
if self.element.algorithm().outputDefinitions():
|
||||||
pt = self.getLinkPointForOutput(-1)
|
pt = self.getLinkPointForOutput(-1)
|
||||||
pt = QPointF(0, pt.y())
|
pt = QPointF(0, pt.y())
|
||||||
self.outButton.position = pt
|
self.outButton.position = pt
|
||||||
@ -125,7 +127,9 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def foldOutput(self, folded):
|
def foldOutput(self, folded):
|
||||||
self.element.outputsFolded = folded
|
self.element.setOutputsCollapsed(folded)
|
||||||
|
# also need to update the model's stored component
|
||||||
|
self.model.childAlgorithm(self.element.childId()).setOutputsCollapsed(folded)
|
||||||
self.prepareGeometryChange()
|
self.prepareGeometryChange()
|
||||||
for arrow in self.arrows:
|
for arrow in self.arrows:
|
||||||
arrow.updatePath()
|
arrow.updatePath()
|
||||||
@ -138,10 +142,10 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
font = QFont('Verdana', 8)
|
font = QFont('Verdana', 8)
|
||||||
font.setPixelSize(12)
|
font.setPixelSize(12)
|
||||||
fm = QFontMetricsF(font)
|
fm = QFontMetricsF(font)
|
||||||
unfolded = isinstance(self.element, Algorithm) and not self.element.paramsFolded
|
unfolded = isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.parametersCollapsed()
|
||||||
numParams = len([a for a in self.element.algorithm.parameterDefinitions() if not a.isDestination()]) if unfolded else 0
|
numParams = len([a for a in self.element.algorithm().parameterDefinitions() if not a.isDestination()]) if unfolded else 0
|
||||||
unfolded = isinstance(self.element, Algorithm) and not self.element.outputsFolded
|
unfolded = isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.outputsCollapsed()
|
||||||
numOutputs = len(self.element.algorithm.outputDefinitions()) if unfolded else 0
|
numOutputs = len(self.element.algorithm().outputDefinitions()) if unfolded else 0
|
||||||
|
|
||||||
hUp = fm.height() * 1.2 * (numParams + 2)
|
hUp = fm.height() * 1.2 * (numParams + 2)
|
||||||
hDown = fm.height() * 1.2 * (numOutputs + 2)
|
hDown = fm.height() * 1.2 * (numOutputs + 2)
|
||||||
@ -155,15 +159,15 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
self.editElement()
|
self.editElement()
|
||||||
|
|
||||||
def contextMenuEvent(self, event):
|
def contextMenuEvent(self, event):
|
||||||
if isinstance(self.element, ModelerOutput):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelOutput):
|
||||||
return
|
return
|
||||||
popupmenu = QMenu()
|
popupmenu = QMenu()
|
||||||
removeAction = popupmenu.addAction('Remove')
|
removeAction = popupmenu.addAction('Remove')
|
||||||
removeAction.triggered.connect(self.removeElement)
|
removeAction.triggered.connect(self.removeElement)
|
||||||
editAction = popupmenu.addAction('Edit')
|
editAction = popupmenu.addAction('Edit')
|
||||||
editAction.triggered.connect(self.editElement)
|
editAction.triggered.connect(self.editElement)
|
||||||
if isinstance(self.element, Algorithm):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
if not self.element.active:
|
if not self.element.isActive():
|
||||||
removeAction = popupmenu.addAction('Activate')
|
removeAction = popupmenu.addAction('Activate')
|
||||||
removeAction.triggered.connect(self.activateAlgorithm)
|
removeAction.triggered.connect(self.activateAlgorithm)
|
||||||
else:
|
else:
|
||||||
@ -172,11 +176,11 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
popupmenu.exec_(event.screenPos())
|
popupmenu.exec_(event.screenPos())
|
||||||
|
|
||||||
def deactivateAlgorithm(self):
|
def deactivateAlgorithm(self):
|
||||||
self.model.deactivateAlgorithm(self.element.modeler_name)
|
self.model.deactivateAlgorithm(self.element.childId())
|
||||||
self.model.updateModelerView()
|
self.model.updateModelerView()
|
||||||
|
|
||||||
def activateAlgorithm(self):
|
def activateAlgorithm(self):
|
||||||
if self.model.activateAlgorithm(self.element.modeler_name):
|
if self.model.activateAlgorithm(self.element.childId()):
|
||||||
self.model.updateModelerView()
|
self.model.updateModelerView()
|
||||||
else:
|
else:
|
||||||
QMessageBox.warning(None, 'Could not activate Algorithm',
|
QMessageBox.warning(None, 'Could not activate Algorithm',
|
||||||
@ -184,39 +188,41 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
'Activate them them before trying to activate it.')
|
'Activate them them before trying to activate it.')
|
||||||
|
|
||||||
def editElement(self):
|
def editElement(self):
|
||||||
if isinstance(self.element, ModelerParameter):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||||
dlg = ModelerParameterDefinitionDialog(self.model,
|
dlg = ModelerParameterDefinitionDialog(self.model,
|
||||||
param=self.element.param)
|
param=self.model.parameterDefinition(self.element.parameterName()))
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
if dlg.param is not None:
|
if dlg.param is not None:
|
||||||
self.model.updateParameter(dlg.param)
|
self.model.updateModelParameter(dlg.param)
|
||||||
self.element.param = dlg.param
|
self.element.setParameterName(dlg.param.name())
|
||||||
|
# also need to update the model's stored component
|
||||||
|
self.model.childAlgorithm(self.element.childId()).setParameterName(dlg.param.name())
|
||||||
self.text = dlg.param.description()
|
self.text = dlg.param.description()
|
||||||
self.update()
|
self.update()
|
||||||
elif isinstance(self.element, Algorithm):
|
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
dlg = None
|
dlg = None
|
||||||
try:
|
try:
|
||||||
dlg = self.element.algorithm.getCustomModelerParametersDialog(self.model, self.element.modeler_name)
|
dlg = self.element.algorithm().getCustomModelerParametersDialog(self.model, self.element.childId())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not dlg:
|
if not dlg:
|
||||||
dlg = ModelerParametersDialog(self.element.algorithm, self.model, self.element.modeler_name)
|
dlg = ModelerParametersDialog(self.element.algorithm(), self.model, self.element.childId())
|
||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
if dlg.alg is not None:
|
if dlg.alg is not None:
|
||||||
dlg.alg.modeler_name = self.element.modeler_name
|
dlg.alg.setChildId(self.element.childId())
|
||||||
self.model.updateAlgorithm(dlg.alg)
|
self.model.updateAlgorithm(dlg.alg)
|
||||||
self.model.updateModelerView()
|
self.model.updateModelerView()
|
||||||
|
|
||||||
def removeElement(self):
|
def removeElement(self):
|
||||||
if isinstance(self.element, ModelerParameter):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||||
if not self.model.removeParameter(self.element.param.name):
|
if not self.model.removeParameter(self.element.parameterName()):
|
||||||
QMessageBox.warning(None, 'Could not remove element',
|
QMessageBox.warning(None, 'Could not remove element',
|
||||||
'Other elements depend on the selected one.\n'
|
'Other elements depend on the selected one.\n'
|
||||||
'Remove them before trying to remove it.')
|
'Remove them before trying to remove it.')
|
||||||
else:
|
else:
|
||||||
self.model.updateModelerView()
|
self.model.updateModelerView()
|
||||||
elif isinstance(self.element, Algorithm):
|
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
if not self.model.removeAlgorithm(self.element.modeler_name):
|
if not self.model.removeAlgorithm(self.element.childId()):
|
||||||
QMessageBox.warning(None, 'Could not remove element',
|
QMessageBox.warning(None, 'Could not remove element',
|
||||||
'Other elements depend on the selected one.\n'
|
'Other elements depend on the selected one.\n'
|
||||||
'Remove them before trying to remove it.')
|
'Remove them before trying to remove it.')
|
||||||
@ -244,11 +250,11 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
ModelerGraphicItem.BOX_WIDTH + 2,
|
ModelerGraphicItem.BOX_WIDTH + 2,
|
||||||
ModelerGraphicItem.BOX_HEIGHT + 2)
|
ModelerGraphicItem.BOX_HEIGHT + 2)
|
||||||
|
|
||||||
if isinstance(self.element, ModelerParameter):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||||
color = QColor(238, 242, 131)
|
color = QColor(238, 242, 131)
|
||||||
stroke = QColor(234, 226, 118)
|
stroke = QColor(234, 226, 118)
|
||||||
selected = QColor(116, 113, 68)
|
selected = QColor(116, 113, 68)
|
||||||
elif isinstance(self.element, Algorithm):
|
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
color = QColor(255, 255, 255)
|
color = QColor(255, 255, 255)
|
||||||
stroke = Qt.gray
|
stroke = Qt.gray
|
||||||
selected = QColor(50, 50, 50)
|
selected = QColor(50, 50, 50)
|
||||||
@ -267,7 +273,7 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
painter.setFont(font)
|
painter.setFont(font)
|
||||||
painter.setPen(QPen(Qt.black))
|
painter.setPen(QPen(Qt.black))
|
||||||
text = self.getAdjustedText(self.text)
|
text = self.getAdjustedText(self.text)
|
||||||
if isinstance(self.element, Algorithm) and not self.element.active:
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.isActive():
|
||||||
painter.setPen(QPen(Qt.gray))
|
painter.setPen(QPen(Qt.gray))
|
||||||
text = text + "\n(deactivated)"
|
text = text + "\n(deactivated)"
|
||||||
fm = QFontMetricsF(font)
|
fm = QFontMetricsF(font)
|
||||||
@ -276,14 +282,14 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, ModelerGraphicItem.BOX_HEIGHT / 2.0 - h + 1)
|
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, ModelerGraphicItem.BOX_HEIGHT / 2.0 - h + 1)
|
||||||
painter.drawText(pt, text)
|
painter.drawText(pt, text)
|
||||||
painter.setPen(QPen(Qt.black))
|
painter.setPen(QPen(Qt.black))
|
||||||
if isinstance(self.element, Algorithm):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
h = -(fm.height() * 1.2)
|
h = -(fm.height() * 1.2)
|
||||||
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
||||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
||||||
painter.drawText(pt, 'In')
|
painter.drawText(pt, 'In')
|
||||||
i = 1
|
i = 1
|
||||||
if not self.element.paramsFolded:
|
if not self.element.parametersCollapsed():
|
||||||
for param in [p for p in self.element.algorithm.parameterDefinitions() if not p.isDestination()]:
|
for param in [p for p in self.element.algorithm().parameterDefinitions() if not p.isDestination()]:
|
||||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
text = self.getAdjustedText(param.description())
|
text = self.getAdjustedText(param.description())
|
||||||
h = -(fm.height() * 1.2) * (i + 1)
|
h = -(fm.height() * 1.2) * (i + 1)
|
||||||
@ -295,8 +301,8 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
||||||
painter.drawText(pt, 'Out')
|
painter.drawText(pt, 'Out')
|
||||||
if not self.element.outputsFolded:
|
if not self.element.outputsCollapsed():
|
||||||
for i, out in enumerate(self.element.algorithm.outputDefinitions()):
|
for i, out in enumerate(self.element.algorithm().outputDefinitions()):
|
||||||
text = self.getAdjustedText(out.description())
|
text = self.getAdjustedText(out.description())
|
||||||
h = fm.height() * 1.2 * (i + 2)
|
h = fm.height() * 1.2 * (i + 2)
|
||||||
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||||
@ -311,13 +317,13 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
|
|
||||||
def getLinkPointForParameter(self, paramIndex):
|
def getLinkPointForParameter(self, paramIndex):
|
||||||
offsetX = 25
|
offsetX = 25
|
||||||
if isinstance(self.element, Algorithm) and self.element.paramsFolded:
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and self.element.parametersCollapsed():
|
||||||
paramIndex = -1
|
paramIndex = -1
|
||||||
offsetX = 17
|
offsetX = 17
|
||||||
font = QFont('Verdana', 8)
|
font = QFont('Verdana', 8)
|
||||||
font.setPixelSize(12)
|
font.setPixelSize(12)
|
||||||
fm = QFontMetricsF(font)
|
fm = QFontMetricsF(font)
|
||||||
if isinstance(self.element, Algorithm):
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8
|
h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8
|
||||||
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0
|
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||||
else:
|
else:
|
||||||
@ -325,9 +331,9 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
return QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + offsetX, h)
|
return QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + offsetX, h)
|
||||||
|
|
||||||
def getLinkPointForOutput(self, outputIndex):
|
def getLinkPointForOutput(self, outputIndex):
|
||||||
if isinstance(self.element, Algorithm) and self.element.algorithm.outputDefinitions():
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and self.element.algorithm().outputDefinitions():
|
||||||
outputIndex = (outputIndex if not self.element.outputsFolded else -1)
|
outputIndex = (outputIndex if not self.element.outputsCollapsed() else -1)
|
||||||
text = self.getAdjustedText(self.element.algorithm.outputDefinitions()[outputIndex].description())
|
text = self.getAdjustedText(self.element.algorithm().outputDefinitions()[outputIndex].description())
|
||||||
font = QFont('Verdana', 8)
|
font = QFont('Verdana', 8)
|
||||||
font.setPixelSize(12)
|
font.setPixelSize(12)
|
||||||
fm = QFontMetricsF(font)
|
fm = QFontMetricsF(font)
|
||||||
@ -335,7 +341,7 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0
|
h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0
|
||||||
y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
||||||
x = (-ModelerGraphicItem.BOX_WIDTH / 2 + 33 + w + 5
|
x = (-ModelerGraphicItem.BOX_WIDTH / 2 + 33 + w + 5
|
||||||
if not self.element.outputsFolded
|
if not self.element.outputsCollapsed()
|
||||||
else 10)
|
else 10)
|
||||||
return QPointF(x, y)
|
return QPointF(x, y)
|
||||||
else:
|
else:
|
||||||
@ -345,7 +351,15 @@ class ModelerGraphicItem(QGraphicsItem):
|
|||||||
if change == QGraphicsItem.ItemPositionHasChanged:
|
if change == QGraphicsItem.ItemPositionHasChanged:
|
||||||
for arrow in self.arrows:
|
for arrow in self.arrows:
|
||||||
arrow.updatePath()
|
arrow.updatePath()
|
||||||
self.element.pos = self.pos()
|
self.element.setPosition(self.pos())
|
||||||
|
|
||||||
|
# also need to update the model's stored component's position
|
||||||
|
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||||
|
self.model.childAlgorithm(self.element.childId()).setPosition(self.pos())
|
||||||
|
elif isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||||
|
self.model.parameterComponent(self.element.parameterName()).setPosition(self.pos())
|
||||||
|
elif isinstance(self.element, QgsProcessingModelAlgorithm.ModelOutput):
|
||||||
|
self.model.childAlgorithm(self.element.childId()).modelOutput(self.element.name()).setPosition(self.pos())
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -127,11 +127,12 @@ class ModelerParameterDefinitionDialog(QDialog):
|
|||||||
self.verticalLayout.addWidget(QLabel(self.tr('Parent layer')))
|
self.verticalLayout.addWidget(QLabel(self.tr('Parent layer')))
|
||||||
self.parentCombo = QComboBox()
|
self.parentCombo = QComboBox()
|
||||||
idx = 0
|
idx = 0
|
||||||
for param in list(self.alg.inputs.values()):
|
for param in list(self.alg.parameterComponents().values()):
|
||||||
if isinstance(param.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
definition = self.alg.parameterDefinition(param.parameterName())
|
||||||
self.parentCombo.addItem(param.param.description(), param.param.name())
|
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||||
|
self.parentCombo.addItem(definition.description(), definition.name())
|
||||||
if self.param is not None:
|
if self.param is not None:
|
||||||
if self.param.parentLayerParameter() == param.param.name():
|
if self.param.parentLayerParameter() == definition.name():
|
||||||
self.parentCombo.setCurrentIndex(idx)
|
self.parentCombo.setCurrentIndex(idx)
|
||||||
idx += 1
|
idx += 1
|
||||||
self.verticalLayout.addWidget(self.parentCombo)
|
self.verticalLayout.addWidget(self.parentCombo)
|
||||||
@ -215,11 +216,12 @@ class ModelerParameterDefinitionDialog(QDialog):
|
|||||||
self.parentCombo = QComboBox()
|
self.parentCombo = QComboBox()
|
||||||
self.parentCombo.addItem(self.tr("None"), None)
|
self.parentCombo.addItem(self.tr("None"), None)
|
||||||
idx = 1
|
idx = 1
|
||||||
for param in list(self.alg.inputs.values()):
|
for param in list(self.alg.parameterComponents().values()):
|
||||||
if isinstance(param.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
definition = self.alg.parameterDefinition(param.parameterName())
|
||||||
self.parentCombo.addItem(param.param.description(), param.param.name())
|
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||||
|
self.parentCombo.addItem(definition.description(), definition.name())
|
||||||
if self.param is not None:
|
if self.param is not None:
|
||||||
if self.param.parentLayerParameter() == param.param.name():
|
if self.param.parentLayerParameter() == definition.name():
|
||||||
self.parentCombo.setCurrentIndex(idx)
|
self.parentCombo.setCurrentIndex(idx)
|
||||||
idx += 1
|
idx += 1
|
||||||
self.verticalLayout.addWidget(self.parentCombo)
|
self.verticalLayout.addWidget(self.parentCombo)
|
||||||
@ -290,8 +292,9 @@ class ModelerParameterDefinitionDialog(QDialog):
|
|||||||
safeName = ''.join(c for c in description if c in validChars)
|
safeName = ''.join(c for c in description if c in validChars)
|
||||||
name = safeName.lower()
|
name = safeName.lower()
|
||||||
i = 2
|
i = 2
|
||||||
while name in self.alg.inputs:
|
while self.alg.parameterDefinition(name):
|
||||||
name = safeName.lower() + str(i)
|
name = safeName.lower() + str(i)
|
||||||
|
i += 1
|
||||||
else:
|
else:
|
||||||
name = self.param.name()
|
name = self.param.name()
|
||||||
if (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or
|
if (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or
|
||||||
|
@ -36,7 +36,8 @@ from qgis.PyQt.QtWidgets import (QDialog, QDialogButtonBox, QLabel, QLineEdit,
|
|||||||
|
|
||||||
from qgis.core import (QgsProcessingParameterDefinition,
|
from qgis.core import (QgsProcessingParameterDefinition,
|
||||||
QgsProcessingParameterPoint,
|
QgsProcessingParameterPoint,
|
||||||
QgsProcessingParameterExtent)
|
QgsProcessingParameterExtent,
|
||||||
|
QgsProcessingModelAlgorithm)
|
||||||
|
|
||||||
from qgis.gui import (QgsMessageBar,
|
from qgis.gui import (QgsMessageBar,
|
||||||
QgsScrollArea)
|
QgsScrollArea)
|
||||||
@ -52,11 +53,6 @@ from processing.core.outputs import (OutputRaster,
|
|||||||
OutputDirectory)
|
OutputDirectory)
|
||||||
from processing.core.parameters import ParameterPoint, ParameterExtent
|
from processing.core.parameters import ParameterPoint, ParameterExtent
|
||||||
|
|
||||||
from processing.modeler.ModelerAlgorithm import (ValueFromInput,
|
|
||||||
ValueFromOutput,
|
|
||||||
Algorithm,
|
|
||||||
ModelerOutput)
|
|
||||||
|
|
||||||
|
|
||||||
class ModelerParametersDialog(QDialog):
|
class ModelerParametersDialog(QDialog):
|
||||||
|
|
||||||
@ -206,8 +202,8 @@ class ModelerParametersDialog(QDialog):
|
|||||||
else:
|
else:
|
||||||
dependent = self.model.getDependentAlgorithms(self._algName)
|
dependent = self.model.getDependentAlgorithms(self._algName)
|
||||||
opts = []
|
opts = []
|
||||||
for alg in list(self.model.algs.values()):
|
for alg in list(self.model.childAlgorithms().values()):
|
||||||
if alg.modeler_name not in dependent:
|
if alg.childId() not in dependent:
|
||||||
opts.append(alg)
|
opts.append(alg)
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
@ -237,16 +233,16 @@ class ModelerParametersDialog(QDialog):
|
|||||||
outTypes = [outTypes]
|
outTypes = [outTypes]
|
||||||
|
|
||||||
values = []
|
values = []
|
||||||
inputs = self.model.inputs
|
inputs = self.model.parameterComponents()
|
||||||
for i in list(inputs.values()):
|
for i in list(inputs.values()):
|
||||||
param = i.param
|
param = self.model.parameterDefinition(i.parameterName())
|
||||||
for t in paramType:
|
for t in paramType:
|
||||||
if isinstance(param, t):
|
if isinstance(param, t):
|
||||||
if dataType is not None:
|
if dataType is not None:
|
||||||
if param.datatype in dataType:
|
if param.datatype in dataType:
|
||||||
values.append(ValueFromInput(param.name()))
|
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromModelParameter(param.name()))
|
||||||
else:
|
else:
|
||||||
values.append(ValueFromInput(param.name()))
|
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromModelParameter(param.name()))
|
||||||
break
|
break
|
||||||
if not outTypes:
|
if not outTypes:
|
||||||
return values
|
return values
|
||||||
@ -254,73 +250,81 @@ class ModelerParametersDialog(QDialog):
|
|||||||
dependent = []
|
dependent = []
|
||||||
else:
|
else:
|
||||||
dependent = self.model.getDependentAlgorithms(self._algName)
|
dependent = self.model.getDependentAlgorithms(self._algName)
|
||||||
for alg in list(self.model.algs.values()):
|
for alg in list(self.model.childAlgorithms().values()):
|
||||||
if alg.modeler_name not in dependent:
|
if alg.childId() not in dependent:
|
||||||
for out in alg.algorithm.outputDefinitions():
|
for out in alg.algorithm().outputDefinitions():
|
||||||
for t in outTypes:
|
for t in outTypes:
|
||||||
if isinstance(out, t):
|
if isinstance(out, t):
|
||||||
if dataType is not None and out.datatype in dataType:
|
if dataType is not None and out.datatype in dataType:
|
||||||
values.append(ValueFromOutput(alg.modeler_name, out.name()))
|
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromChildOutput(alg.childId(), out.name()))
|
||||||
else:
|
else:
|
||||||
values.append(ValueFromOutput(alg.modeler_name, out.name()))
|
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromChildOutput(alg.childId(), out.name()))
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def resolveValueDescription(self, value):
|
def resolveValueDescription(self, value):
|
||||||
if isinstance(value, ValueFromInput):
|
if isinstance(value, QgsProcessingModelAlgorithm.ChildParameterSource):
|
||||||
return self.model.inputs[value.name].param.description()
|
if value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.StaticValue:
|
||||||
else:
|
return value.staticValue()
|
||||||
alg = self.model.algs[value.alg]
|
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ModelParameter:
|
||||||
return self.tr("'{0}' from algorithm '{1}'").format(alg.algorithm.outputDefinition(value.output).description(), alg.description)
|
return self.model.parameterDefinition(value.parameterName()).description()
|
||||||
|
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ChildOutput:
|
||||||
|
alg = self.model.childAlgorithm(value.outputChildId())
|
||||||
|
return self.tr("'{0}' from algorithm '{1}'").format(alg.algorithm().outputDefinition(value.outputName()).description(), alg.description())
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
def setPreviousValues(self):
|
def setPreviousValues(self):
|
||||||
if self._algName is not None:
|
if self._algName is not None:
|
||||||
alg = self.model.algs[self._algName]
|
alg = self.model.childAlgorithm(self._algName)
|
||||||
self.descriptionBox.setText(alg.description)
|
self.descriptionBox.setText(alg.description())
|
||||||
for param in alg.algorithm.parameterDefinitions():
|
for param in alg.algorithm().parameterDefinitions():
|
||||||
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
continue
|
continue
|
||||||
if param.name() in alg.params:
|
if param.name() in alg.parameterSources():
|
||||||
value = alg.params[param.name()]
|
value = alg.parameterSources()[param.name()]
|
||||||
else:
|
else:
|
||||||
value = param.defaultValue()
|
value = param.defaultValue()
|
||||||
self.wrappers[param.name()].setValue(value)
|
self.wrappers[param.name()].setValue(value)
|
||||||
for name, out in list(alg.outputs.items()):
|
for name, out in list(alg.modelOutputs().items()):
|
||||||
self.valueItems[name].setText(out.description())
|
self.valueItems[name].setText(out.description())
|
||||||
|
|
||||||
selected = []
|
selected = []
|
||||||
dependencies = self.getAvailableDependencies() # spellok
|
dependencies = self.getAvailableDependencies() # spellok
|
||||||
for idx, dependency in enumerate(dependencies):
|
for idx, dependency in enumerate(dependencies):
|
||||||
if dependency.modeler_name in alg.dependencies:
|
if dependency.childId() in alg.dependencies():
|
||||||
selected.append(idx)
|
selected.append(idx)
|
||||||
|
|
||||||
self.dependenciesPanel.setSelectedItems(selected)
|
self.dependenciesPanel.setSelectedItems(selected)
|
||||||
|
|
||||||
def createAlgorithm(self):
|
def createAlgorithm(self):
|
||||||
alg = Algorithm(self._alg.id())
|
alg = QgsProcessingModelAlgorithm.ChildAlgorithm(self._alg.id())
|
||||||
alg.setName(self.model)
|
alg.generateChildId(self.model)
|
||||||
alg.description = self.descriptionBox.text()
|
alg.setDescription(self.descriptionBox.text())
|
||||||
for param in self._alg.parameterDefinitions():
|
for param in self._alg.parameterDefinitions():
|
||||||
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
continue
|
continue
|
||||||
val = self.wrappers[param.name()].value()
|
val = self.wrappers[param.name()].value()
|
||||||
if not isinstance(val, ValueFromInput) and not isinstance(val, ValueFromOutput) and not param.checkValueIsAcceptable(val):
|
if ( isinstance(val, QgsProcessingModelAlgorithm.ChildParameterSource) and val.source() == QgsProcessingModelAlgorithm.ChildParameterSource.StaticValue and not param.checkValueIsAcceptable(val.staticValue())) \
|
||||||
|
or (not isinstance(val, QgsProcessingModelAlgorithm.ChildParameterSource) and not param.checkValueIsAcceptable(val)):
|
||||||
self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description(),
|
self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description(),
|
||||||
level=QgsMessageBar.WARNING)
|
level=QgsMessageBar.WARNING)
|
||||||
return None
|
return None
|
||||||
alg.params[param.name()] = val
|
alg.addParameterSource(param.name(), val)
|
||||||
|
|
||||||
# outputs = self._alg.outputDefinitions()
|
# outputs = self._alg.outputDefinitions()
|
||||||
#for output in outputs:
|
#for output in outputs:
|
||||||
# if not output.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
# if not output.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
# name = str(self.valueItems[output.name()].text())
|
# name = str(self.valueItems[output.name()].text())
|
||||||
# if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
|
# if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
|
||||||
# alg.outputs[output.name()] = ModelerOutput(name)
|
# alg.outputs[output.name()] = QgsProcessingModelAlgorithm.ModelOutput(name)
|
||||||
|
|
||||||
selectedOptions = self.dependenciesPanel.selectedoptions
|
selectedOptions = self.dependenciesPanel.selectedoptions
|
||||||
availableDependencies = self.getAvailableDependencies() # spellok
|
availableDependencies = self.getAvailableDependencies() # spellok
|
||||||
|
dep_ids = []
|
||||||
for selected in selectedOptions:
|
for selected in selectedOptions:
|
||||||
alg.dependencies.append(availableDependencies[selected].modeler_name) # spellok
|
dep_ids.append(availableDependencies[selected].childId()) # spellok
|
||||||
|
alg.setDependencies(dep_ids)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._alg.processBeforeAddingToModeler(alg, self.model)
|
self._alg.processBeforeAddingToModeler(alg, self.model)
|
||||||
|
@ -28,10 +28,11 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
from qgis.PyQt.QtCore import QPointF, Qt
|
from qgis.PyQt.QtCore import QPointF, Qt
|
||||||
from qgis.PyQt.QtWidgets import QGraphicsItem, QGraphicsScene
|
from qgis.PyQt.QtWidgets import QGraphicsItem, QGraphicsScene
|
||||||
from qgis.core import QgsProcessingParameterDefinition
|
from qgis.core import (QgsProcessingParameterDefinition,
|
||||||
|
QgsProcessingModelAlgorithm)
|
||||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||||
from processing.modeler.ModelerArrowItem import ModelerArrowItem
|
from processing.modeler.ModelerArrowItem import ModelerArrowItem
|
||||||
from processing.modeler.ModelerAlgorithm import ValueFromInput, ValueFromOutput, CompoundValue
|
from processing.modeler.ModelerAlgorithm import CompoundValue
|
||||||
|
|
||||||
|
|
||||||
class ModelerScene(QGraphicsScene):
|
class ModelerScene(QGraphicsScene):
|
||||||
@ -66,93 +67,93 @@ class ModelerScene(QGraphicsScene):
|
|||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
for v in value:
|
for v in value:
|
||||||
items.extend(self.getItemsFromParamValue(v))
|
items.extend(self.getItemsFromParamValue(v))
|
||||||
|
elif isinstance(value, QgsProcessingModelAlgorithm.ChildParameterSource):
|
||||||
|
if value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ModelParameter:
|
||||||
|
items.append((self.paramItems[value.parameterName()], 0))
|
||||||
|
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ChildOutput:
|
||||||
|
outputs = self.model.childAlgorithm(value.outputChildId()).algorithm().outputDefinitions()
|
||||||
|
for i, out in enumerate(outputs):
|
||||||
|
if out.name() == value.outputName():
|
||||||
|
break
|
||||||
|
if value.outputChildId() in self.algItems:
|
||||||
|
items.append((self.algItems[value.outputChildId()], i))
|
||||||
elif isinstance(value, CompoundValue):
|
elif isinstance(value, CompoundValue):
|
||||||
for v in value.values:
|
for v in value.values:
|
||||||
items.extend(self.getItemsFromParamValue(v))
|
items.extend(self.getItemsFromParamValue(v))
|
||||||
elif isinstance(value, ValueFromInput):
|
|
||||||
items.append((self.paramItems[value.name], 0))
|
|
||||||
elif isinstance(value, ValueFromOutput):
|
|
||||||
outputs = self.model.algs[value.alg].algorithm.outputDefinitions()
|
|
||||||
for i, out in enumerate(outputs):
|
|
||||||
if out.name() == value.output:
|
|
||||||
break
|
|
||||||
if value.alg in self.algItems:
|
|
||||||
items.append((self.algItems[value.alg], i))
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def paintModel(self, model, controls=True):
|
def paintModel(self, model, controls=True):
|
||||||
self.model = model
|
self.model = model
|
||||||
# Inputs
|
# Inputs
|
||||||
for inp in list(model.inputs.values()):
|
for inp in list(model.parameterComponents().values()):
|
||||||
item = ModelerGraphicItem(inp, model, controls)
|
item = ModelerGraphicItem(inp, model, controls)
|
||||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||||
self.addItem(item)
|
self.addItem(item)
|
||||||
item.setPos(inp.pos.x(), inp.pos.y())
|
item.setPos(inp.position().x(), inp.position().y())
|
||||||
self.paramItems[inp.param.name()] = item
|
self.paramItems[inp.parameterName()] = item
|
||||||
|
|
||||||
# We add the algs
|
# We add the algs
|
||||||
for alg in list(model.algs.values()):
|
for alg in list(model.childAlgorithms().values()):
|
||||||
item = ModelerGraphicItem(alg, model, controls)
|
item = ModelerGraphicItem(alg, model, controls)
|
||||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||||
self.addItem(item)
|
self.addItem(item)
|
||||||
item.setPos(alg.pos.x(), alg.pos.y())
|
item.setPos(alg.position().x(), alg.position().y())
|
||||||
self.algItems[alg.modeler_name] = item
|
self.algItems[alg.childId()] = item
|
||||||
|
|
||||||
# And then the arrows
|
# And then the arrows
|
||||||
for alg in list(model.algs.values()):
|
for alg in list(model.childAlgorithms().values()):
|
||||||
idx = 0
|
idx = 0
|
||||||
for parameter in alg.algorithm.parameterDefinitions():
|
for parameter in alg.algorithm().parameterDefinitions():
|
||||||
if not parameter.isDestination() and not parameter.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if not parameter.isDestination() and not parameter.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
if parameter.name() in alg.params:
|
if parameter.name() in alg.parameterSources():
|
||||||
value = alg.params[parameter.name()]
|
value = alg.parameterSources()[parameter.name()]
|
||||||
else:
|
else:
|
||||||
value = None
|
value = None
|
||||||
sourceItems = self.getItemsFromParamValue(value)
|
sourceItems = self.getItemsFromParamValue(value)
|
||||||
for sourceItem, sourceIdx in sourceItems:
|
for sourceItem, sourceIdx in sourceItems:
|
||||||
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.modeler_name], idx)
|
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.childId()], idx)
|
||||||
sourceItem.addArrow(arrow)
|
sourceItem.addArrow(arrow)
|
||||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
self.algItems[alg.childId()].addArrow(arrow)
|
||||||
arrow.updatePath()
|
arrow.updatePath()
|
||||||
self.addItem(arrow)
|
self.addItem(arrow)
|
||||||
idx += 1
|
idx += 1
|
||||||
for depend in alg.dependencies:
|
for depend in alg.dependencies():
|
||||||
arrow = ModelerArrowItem(self.algItems[depend], -1,
|
arrow = ModelerArrowItem(self.algItems[depend], -1,
|
||||||
self.algItems[alg.modeler_name], -1)
|
self.algItems[alg.childId()], -1)
|
||||||
self.algItems[depend].addArrow(arrow)
|
self.algItems[depend].addArrow(arrow)
|
||||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
self.algItems[alg.childId()].addArrow(arrow)
|
||||||
arrow.updatePath()
|
arrow.updatePath()
|
||||||
self.addItem(arrow)
|
self.addItem(arrow)
|
||||||
|
|
||||||
# And finally the outputs
|
# And finally the outputs
|
||||||
for alg in list(model.algs.values()):
|
for alg in list(model.childAlgorithms().values()):
|
||||||
outputs = alg.outputs
|
outputs = alg.modelOutputs()
|
||||||
outputItems = {}
|
outputItems = {}
|
||||||
idx = 0
|
idx = 0
|
||||||
for key in outputs:
|
for key, out in outputs.items():
|
||||||
out = outputs[key]
|
|
||||||
if out is not None:
|
if out is not None:
|
||||||
item = ModelerGraphicItem(out, model, controls)
|
item = ModelerGraphicItem(out, model, controls)
|
||||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||||
self.addItem(item)
|
self.addItem(item)
|
||||||
pos = alg.outputs[key].pos
|
pos = out.position()
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos = (alg.pos + QPointF(ModelerGraphicItem.BOX_WIDTH, 0) +
|
pos = (alg.position() + QPointF(ModelerGraphicItem.BOX_WIDTH, 0) +
|
||||||
self.algItems[alg.modeler_name].getLinkPointForOutput(idx))
|
self.algItems[alg.childId()].getLinkPointForOutput(idx))
|
||||||
item.setPos(pos)
|
item.setPosition(pos)
|
||||||
outputItems[key] = item
|
outputItems[key] = item
|
||||||
arrow = ModelerArrowItem(self.algItems[alg.modeler_name], idx, item,
|
arrow = ModelerArrowItem(self.algItems[alg.childId()], idx, item,
|
||||||
-1)
|
-1)
|
||||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
self.algItems[alg.childId()].addArrow(arrow)
|
||||||
item.addArrow(arrow)
|
item.addArrow(arrow)
|
||||||
arrow.updatePath()
|
arrow.updatePath()
|
||||||
self.addItem(arrow)
|
self.addItem(arrow)
|
||||||
idx += 1
|
idx += 1
|
||||||
else:
|
else:
|
||||||
outputItems[key] = None
|
outputItems[key] = None
|
||||||
self.outputItems[alg.modeler_name] = outputItems
|
self.outputItems[alg.childId()] = outputItems
|
||||||
|
|
||||||
def mousePressEvent(self, mouseEvent):
|
def mousePressEvent(self, mouseEvent):
|
||||||
if mouseEvent.button() != Qt.LeftButton:
|
if mouseEvent.button() != Qt.LeftButton:
|
||||||
|
@ -96,6 +96,7 @@ SET(QGIS_CORE_SRCS
|
|||||||
processing/qgsnativealgorithms.cpp
|
processing/qgsnativealgorithms.cpp
|
||||||
processing/qgsprocessingalgorithm.cpp
|
processing/qgsprocessingalgorithm.cpp
|
||||||
processing/qgsprocessingalgrunnertask.cpp
|
processing/qgsprocessingalgrunnertask.cpp
|
||||||
|
processing/qgsprocessingmodelalgorithm.cpp
|
||||||
processing/qgsprocessingoutputs.cpp
|
processing/qgsprocessingoutputs.cpp
|
||||||
processing/qgsprocessingparameters.cpp
|
processing/qgsprocessingparameters.cpp
|
||||||
processing/qgsprocessingprovider.cpp
|
processing/qgsprocessingprovider.cpp
|
||||||
@ -896,6 +897,7 @@ SET(QGIS_CORE_HDRS
|
|||||||
processing/qgsnativealgorithms.h
|
processing/qgsnativealgorithms.h
|
||||||
processing/qgsprocessingalgorithm.h
|
processing/qgsprocessingalgorithm.h
|
||||||
processing/qgsprocessingcontext.h
|
processing/qgsprocessingcontext.h
|
||||||
|
processing/qgsprocessingmodelalgorithm.h
|
||||||
processing/qgsprocessingoutputs.h
|
processing/qgsprocessingoutputs.h
|
||||||
processing/qgsprocessingparameters.h
|
processing/qgsprocessingparameters.h
|
||||||
processing/qgsprocessingutils.h
|
processing/qgsprocessingutils.h
|
||||||
|
@ -218,6 +218,16 @@ bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *def
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsProcessingAlgorithm::removeParameter( const QString &name )
|
||||||
|
{
|
||||||
|
const QgsProcessingParameterDefinition *def = parameterDefinition( name );
|
||||||
|
if ( def )
|
||||||
|
{
|
||||||
|
delete def;
|
||||||
|
mParameters.removeAll( def );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool QgsProcessingAlgorithm::addOutput( QgsProcessingOutputDefinition *definition )
|
bool QgsProcessingAlgorithm::addOutput( QgsProcessingOutputDefinition *definition )
|
||||||
{
|
{
|
||||||
if ( !definition )
|
if ( !definition )
|
||||||
|
@ -272,6 +272,12 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
|||||||
*/
|
*/
|
||||||
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition SIP_TRANSFER );
|
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition SIP_TRANSFER );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the parameter with matching \a name from the algorithm, and deletes any existing
|
||||||
|
* definition.
|
||||||
|
*/
|
||||||
|
void removeParameter( const QString &name );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an output \a definition to the algorithm. Ownership of the definition is transferred to the algorithm.
|
* Adds an output \a 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.
|
* Returns true if the output could be successfully added, or false if the output could not be added (e.g.
|
||||||
|
370
src/core/processing/qgsprocessingmodelalgorithm.cpp
Normal file
370
src/core/processing/qgsprocessingmodelalgorithm.cpp
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsprocessingmodelalgorithm.cpp
|
||||||
|
------------------------------
|
||||||
|
begin : June 2017
|
||||||
|
copyright : (C) 2017 by Nyall Dawson
|
||||||
|
email : nyall dot dawson at gmail dot com
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
#include "qgsprocessingregistry.h"
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm::ChildAlgorithm( const QString &algorithmId )
|
||||||
|
: mAlgorithmId( algorithmId )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const QgsProcessingAlgorithm *QgsProcessingModelAlgorithm::ChildAlgorithm::algorithm() const
|
||||||
|
{
|
||||||
|
return QgsApplication::processingRegistry()->algorithmById( mAlgorithmId );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::Component::description() const
|
||||||
|
{
|
||||||
|
return mDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::Component::setDescription( const QString &description )
|
||||||
|
{
|
||||||
|
mDescription = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ChildParameterSource> QgsProcessingModelAlgorithm::ChildAlgorithm::parameterSources() const
|
||||||
|
{
|
||||||
|
return mParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > ¶ms )
|
||||||
|
{
|
||||||
|
mParams = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::addParameterSource( const QString &name, const ChildParameterSource &source )
|
||||||
|
{
|
||||||
|
mParams.insert( name, source );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsProcessingModelAlgorithm::ChildAlgorithm::isActive() const
|
||||||
|
{
|
||||||
|
return mActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setActive( bool active )
|
||||||
|
{
|
||||||
|
mActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF QgsProcessingModelAlgorithm::Component::position() const
|
||||||
|
{
|
||||||
|
return mPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::Component::setPosition( const QPointF &position )
|
||||||
|
{
|
||||||
|
mPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::Component::Component( const QString &description )
|
||||||
|
: mDescription( description )
|
||||||
|
{}
|
||||||
|
|
||||||
|
QStringList QgsProcessingModelAlgorithm::ChildAlgorithm::dependencies() const
|
||||||
|
{
|
||||||
|
return mDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setDependencies( const QStringList &dependencies )
|
||||||
|
{
|
||||||
|
mDependencies = dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsProcessingModelAlgorithm::ChildAlgorithm::outputsCollapsed() const
|
||||||
|
{
|
||||||
|
return mOutputsCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setOutputsCollapsed( bool outputsCollapsed )
|
||||||
|
{
|
||||||
|
mOutputsCollapsed = outputsCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> QgsProcessingModelAlgorithm::ChildAlgorithm::modelOutputs() const
|
||||||
|
{
|
||||||
|
return mModelOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput &QgsProcessingModelAlgorithm::ChildAlgorithm::modelOutput( const QString &name )
|
||||||
|
{
|
||||||
|
return mModelOutputs[ name ];
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &modelOutputs )
|
||||||
|
{
|
||||||
|
mModelOutputs = modelOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsProcessingModelAlgorithm::ChildAlgorithm::parametersCollapsed() const
|
||||||
|
{
|
||||||
|
return mParametersCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setParametersCollapsed( bool parametersCollapsed )
|
||||||
|
{
|
||||||
|
mParametersCollapsed = parametersCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::ChildAlgorithm::childId() const
|
||||||
|
{
|
||||||
|
return mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setChildId( const QString &id )
|
||||||
|
{
|
||||||
|
mId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::generateChildId( const QgsProcessingModelAlgorithm &model )
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
QString id;
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
id = QStringLiteral( "%1_%2" ).arg( mAlgorithmId ).arg( i );
|
||||||
|
if ( !model.childAlgorithms().contains( id ) )
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
mId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::ChildAlgorithm::algorithmId() const
|
||||||
|
{
|
||||||
|
return mAlgorithmId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::ChildAlgorithm::setAlgorithmId( const QString &algorithmId )
|
||||||
|
{
|
||||||
|
mAlgorithmId = algorithmId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// QgsProcessingModelAlgorithm
|
||||||
|
//
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm( const QString &name, const QString &group )
|
||||||
|
: QgsProcessingAlgorithm()
|
||||||
|
, mModelName( name.isEmpty() ? QObject::tr( "model" ) : name )
|
||||||
|
, mModelGroup( group )
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::name() const
|
||||||
|
{
|
||||||
|
return mModelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::displayName() const
|
||||||
|
{
|
||||||
|
return mModelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::group() const
|
||||||
|
{
|
||||||
|
return mModelGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon QgsProcessingModelAlgorithm::icon() const
|
||||||
|
{
|
||||||
|
return QgsApplication::getThemeIcon( QStringLiteral( "/processingModel.svg" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::svgIconPath() const
|
||||||
|
{
|
||||||
|
return QgsApplication::iconPath( QStringLiteral( "processingModel.svg" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
|
||||||
|
{
|
||||||
|
Q_UNUSED( parameters );
|
||||||
|
Q_UNUSED( context );
|
||||||
|
Q_UNUSED( feedback );
|
||||||
|
return QVariantMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms() const
|
||||||
|
{
|
||||||
|
return mChildAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents )
|
||||||
|
{
|
||||||
|
mParameterComponents = parameterComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component )
|
||||||
|
{
|
||||||
|
mParameterComponents.insert( component.parameterName(), component );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter &QgsProcessingModelAlgorithm::parameterComponent( const QString &name )
|
||||||
|
{
|
||||||
|
if ( !mParameterComponents.contains( name ) )
|
||||||
|
{
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter &component = mParameterComponents[ name ];
|
||||||
|
component.setParameterName( name );
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
return mParameterComponents[ name ];
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::setChildAlgorithms( const QMap<QString, ChildAlgorithm> &childAlgorithms )
|
||||||
|
{
|
||||||
|
mChildAlgorithms = childAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm )
|
||||||
|
{
|
||||||
|
mChildAlgorithms.insert( algorithm.childId(), algorithm );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorithm )
|
||||||
|
{
|
||||||
|
if ( algorithm.childId().isEmpty() || mChildAlgorithms.contains( algorithm.childId() ) )
|
||||||
|
algorithm.generateChildId( *this );
|
||||||
|
|
||||||
|
mChildAlgorithms.insert( algorithm.childId(), algorithm );
|
||||||
|
return algorithm.childId();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm( const QString &childId )
|
||||||
|
{
|
||||||
|
return mChildAlgorithms[ childId ];
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::addModelParameter( QgsProcessingParameterDefinition *definition, const QgsProcessingModelAlgorithm::ModelParameter &component )
|
||||||
|
{
|
||||||
|
addParameter( definition );
|
||||||
|
mParameterComponents.insert( definition->name(), component );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::updateModelParameter( QgsProcessingParameterDefinition *definition )
|
||||||
|
{
|
||||||
|
removeParameter( definition->name() );
|
||||||
|
addParameter( definition );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingModelAlgorithm::removeModelParameter( const QString &name )
|
||||||
|
{
|
||||||
|
removeParameter( name );
|
||||||
|
mParameterComponents.remove( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> QgsProcessingModelAlgorithm::parameterComponents() const
|
||||||
|
{
|
||||||
|
return mParameterComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QgsProcessingModelAlgorithm::dependentChildAlgorithms( const QString &childId ) const
|
||||||
|
{
|
||||||
|
QSet< QString > algs;
|
||||||
|
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
|
||||||
|
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
|
||||||
|
{
|
||||||
|
if ( childIt->childId() == childId )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// does alg have a direct dependency on this child?
|
||||||
|
if ( childIt->dependencies().contains( childId ) )
|
||||||
|
algs << childIt->childId();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return algs.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage ) const
|
||||||
|
{
|
||||||
|
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
|
||||||
|
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
|
||||||
|
{
|
||||||
|
if ( !childIt->algorithm() )
|
||||||
|
{
|
||||||
|
if ( errorMessage )
|
||||||
|
{
|
||||||
|
*errorMessage = QObject::tr( "The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QgsProcessingModelAlgorithm::ChildParameterSource::operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const
|
||||||
|
{
|
||||||
|
if ( mSource != other.mSource )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch ( mSource )
|
||||||
|
{
|
||||||
|
case StaticValue:
|
||||||
|
return mStaticValue == other.mStaticValue;
|
||||||
|
case ChildOutput:
|
||||||
|
return mChildId == other.mChildId && mOutputName == other.mOutputName;
|
||||||
|
case ModelParameter:
|
||||||
|
return mParameterName == other.mParameterName;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( const QVariant &value )
|
||||||
|
{
|
||||||
|
ChildParameterSource src;
|
||||||
|
src.mSource = StaticValue;
|
||||||
|
src.mStaticValue = value;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( const QString ¶meterName )
|
||||||
|
{
|
||||||
|
ChildParameterSource src;
|
||||||
|
src.mSource = ModelParameter;
|
||||||
|
src.mParameterName = parameterName;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( const QString &childId, const QString &outputName )
|
||||||
|
{
|
||||||
|
ChildParameterSource src;
|
||||||
|
src.mSource = ChildOutput;
|
||||||
|
src.mChildId = childId;
|
||||||
|
src.mOutputName = outputName;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::Source QgsProcessingModelAlgorithm::ChildParameterSource::source() const
|
||||||
|
{
|
||||||
|
return mSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &description )
|
||||||
|
: QgsProcessingModelAlgorithm::Component( description )
|
||||||
|
{}
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter::ModelParameter( const QString ¶meterName )
|
||||||
|
: QgsProcessingModelAlgorithm::Component()
|
||||||
|
, mParameterName( parameterName )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
622
src/core/processing/qgsprocessingmodelalgorithm.h
Normal file
622
src/core/processing/qgsprocessingmodelalgorithm.h
Normal file
@ -0,0 +1,622 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsprocessingmodelalgorithm.h
|
||||||
|
-----------------------------
|
||||||
|
begin : June 2017
|
||||||
|
copyright : (C) 2017 by Nyall Dawson
|
||||||
|
email : nyall dot dawson at gmail dot com
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSPROCESSINGMODELALGORITHM_H
|
||||||
|
#define QGSPROCESSINGMODELALGORITHM_H
|
||||||
|
|
||||||
|
#include "qgis_core.h"
|
||||||
|
#include "qgis.h"
|
||||||
|
#include "qgsprocessingalgorithm.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class QgsProcessingModelAlgorithm
|
||||||
|
* \ingroup core
|
||||||
|
* Model based algorithm with processing.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source for the value of a parameter for a child algorithm within a model.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
* \ingroup core
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT ChildParameterSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Possible parameter value sources
|
||||||
|
enum Source
|
||||||
|
{
|
||||||
|
ModelParameter, //!< Parameter value is taken from a parent model parameter
|
||||||
|
ChildOutput, //!< Parameter value is taken from an output generated by a child algorithm
|
||||||
|
StaticValue, //!< Parameter value is a static value
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ChildParameterSource. It is recommended that the static methods
|
||||||
|
* fromStaticValue(), fromModelParameter() and fromChildOutput() are used instead.
|
||||||
|
*/
|
||||||
|
ChildParameterSource() = default;
|
||||||
|
|
||||||
|
bool operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||||
|
bool operator!=( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const
|
||||||
|
{
|
||||||
|
return !operator==( other );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new ChildParameterSource which takes its value from a static \a value.
|
||||||
|
* \see fromModelParameter()
|
||||||
|
* \see fromChildOutput()
|
||||||
|
*/
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromStaticValue( const QVariant &value );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new ChildParameterSource which takes its value from a parent model parameter.
|
||||||
|
* \see fromStaticValue()
|
||||||
|
* \see fromChildOutput()
|
||||||
|
*/
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromModelParameter( const QString ¶meterName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new ChildParameterSource which takes its value from an output generated by a child algorithm.
|
||||||
|
* \see fromStaticValue()
|
||||||
|
* \see fromModelParameter()
|
||||||
|
*/
|
||||||
|
static QgsProcessingModelAlgorithm::ChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parameter value's source.
|
||||||
|
*/
|
||||||
|
Source source() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the source's static value. This is only used when the source() is StaticValue.
|
||||||
|
* \see setStaticValue()
|
||||||
|
*/
|
||||||
|
QVariant staticValue() const { return mStaticValue; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the source's static value. Calling this will also change the source() to StaticValue.
|
||||||
|
* \see staticValue()
|
||||||
|
*/
|
||||||
|
void setStaticValue( const QVariant &value ) { mStaticValue = value; mSource = StaticValue; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the source's model parameter name. This is only used when the source() is ModelParameter.
|
||||||
|
* \see setParameterName()
|
||||||
|
*/
|
||||||
|
QString parameterName() const { return mParameterName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the source's model parameter \a name. Calling this will also change the source() to ModelParameter.
|
||||||
|
* \see parameterName()
|
||||||
|
*/
|
||||||
|
void setParameterName( const QString &name ) { mParameterName = name; mSource = ModelParameter; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the source's child algorithm ID from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||||
|
* \see setOutputChildId()
|
||||||
|
* \see outputName()
|
||||||
|
*/
|
||||||
|
QString outputChildId() const { return mChildId; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the source's child algorithm \a id from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||||
|
* \see parameterName()
|
||||||
|
* \see setOutputName()
|
||||||
|
*/
|
||||||
|
void setOutputChildId( const QString &id ) { mChildId = id; mSource = ChildOutput; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the source's child algorithm output name from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||||
|
* \see setOutputName()
|
||||||
|
* \see outputChildId()
|
||||||
|
*/
|
||||||
|
QString outputName() const { return mOutputName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the source's child algorithm output \a name from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||||
|
* \see outputName()
|
||||||
|
* \see setOutputChildId()
|
||||||
|
*/
|
||||||
|
void setOutputName( const QString &name ) { mOutputName = name; mSource = ChildOutput; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Source mSource = StaticValue;
|
||||||
|
QVariant mStaticValue;
|
||||||
|
QString mParameterName;
|
||||||
|
QString mChildId;
|
||||||
|
QString mOutputName;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a component of a model algorithm.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
* \ingroup core
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the friendly description text for the component.
|
||||||
|
* \see setDescription()
|
||||||
|
*/
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the friendly \a description text for the component.
|
||||||
|
* \see description()
|
||||||
|
*/
|
||||||
|
void setDescription( const QString &description );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the model component within the graphical modeler.
|
||||||
|
* \see setPosition()
|
||||||
|
*/
|
||||||
|
QPointF position() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the \a position of the model component within the graphical modeler.
|
||||||
|
* \see position()
|
||||||
|
*/
|
||||||
|
void setPosition( const QPointF &position );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Only subclasses can be created
|
||||||
|
Component( const QString &description = QString() );
|
||||||
|
|
||||||
|
//! Copies are protected to avoid slicing
|
||||||
|
Component( const QgsProcessingModelAlgorithm::Component &other ) = default;
|
||||||
|
|
||||||
|
//! Copies are protected to avoid slicing
|
||||||
|
Component &operator=( const QgsProcessingModelAlgorithm::Component &other ) = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//! Position of component within model
|
||||||
|
QPointF mPosition;
|
||||||
|
|
||||||
|
QString mDescription;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an input parameter used by the model.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
* \ingroup core
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT ModelParameter : public QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ModelParameter. The parameter name should match one of the
|
||||||
|
* parameters from the parent model.
|
||||||
|
*/
|
||||||
|
ModelParameter( const QString ¶meterName = QString() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the associated parameter name. The parameter name should match one of the
|
||||||
|
* parameters from the parent model.
|
||||||
|
* \see parameterName()
|
||||||
|
*/
|
||||||
|
QString parameterName() const { return mParameterName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the associated parameter name. The parameter name should match one of the
|
||||||
|
* parameters from the parent model.
|
||||||
|
* \see parameterName()
|
||||||
|
*/
|
||||||
|
void setParameterName( const QString &name ) { mParameterName = name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mParameterName;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a final output created by the model.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
* \ingroup core
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT ModelOutput : public QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ModelOutput with the specified \a description.
|
||||||
|
*/
|
||||||
|
ModelOutput( const QString &description = QString() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the child algorithm ID from which this output is generated.
|
||||||
|
* \see setChildId()
|
||||||
|
*/
|
||||||
|
QString childId() const { return mChildId; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the child algorithm \a id from which this output is generated.
|
||||||
|
* \see childId()
|
||||||
|
*/
|
||||||
|
void setChildId( const QString &id ) { mChildId = id; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the child algorithm output name from which this output is generated.
|
||||||
|
* \see setOutputName()
|
||||||
|
*/
|
||||||
|
QString outputName() const { return mOutputName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the child algorithm output \a name from which this output is generated.
|
||||||
|
* \see outputName()
|
||||||
|
*/
|
||||||
|
void setOutputName( const QString &name ) { mOutputName = name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mChildId;
|
||||||
|
QString mOutputName;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child algorithm representing a single component of a QgsProcessingModelAlgorithm.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
* \ingroup core
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT ChildAlgorithm : public QgsProcessingModelAlgorithm::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ChildAlgorithm. The \a algorithmId parameter
|
||||||
|
* should be set to a QgsProcessingAlgorithm algorithm ID.
|
||||||
|
*/
|
||||||
|
ChildAlgorithm( const QString &algorithmId = QString() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the child algorithm's unique ID string, used the identify
|
||||||
|
* this child algorithm within its parent model.
|
||||||
|
* \see setChildId()
|
||||||
|
* \see generateChildId()
|
||||||
|
*/
|
||||||
|
QString childId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the child algorithm's unique \a id string, used the identify
|
||||||
|
* this child algorithm within its parent model.
|
||||||
|
* \see childId()
|
||||||
|
* \see generateChildId()
|
||||||
|
*/
|
||||||
|
void setChildId( const QString &id );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically generates a unique childId() for the algorithm,
|
||||||
|
* avoiding child IDs which are already present in \a model.
|
||||||
|
* \see childId()
|
||||||
|
* \see setChildId()
|
||||||
|
*/
|
||||||
|
void generateChildId( const QgsProcessingModelAlgorithm &model );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying child algorithm's ID.
|
||||||
|
* \see algorithm()
|
||||||
|
* \see setAlgorithmId()
|
||||||
|
*/
|
||||||
|
QString algorithmId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the underlying child algorithm's ID. This
|
||||||
|
* should be set to an existing QgsProcessingAlgorithm algorithm ID.
|
||||||
|
* \see algorithm()
|
||||||
|
* \see algorithmId()
|
||||||
|
*/
|
||||||
|
void setAlgorithmId( const QString &algorithmId );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying child algorithm, or a nullptr
|
||||||
|
* if a matching algorithm is not available.
|
||||||
|
* \see algorithmId()
|
||||||
|
*/
|
||||||
|
const QgsProcessingAlgorithm *algorithm() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of parameter sources. The keys are the child algorithm
|
||||||
|
* parameter names, the values are the source for that parameter.
|
||||||
|
* \see setParameterSources()
|
||||||
|
* \see addParameterSource()
|
||||||
|
*/
|
||||||
|
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > parameterSources() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the map of parameter \a sources. The keys are the child algorithm
|
||||||
|
* parameter names, the values are the source for that parameter.
|
||||||
|
* \see parameterSources()
|
||||||
|
* \see addParameterSource()
|
||||||
|
*/
|
||||||
|
void setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > &sources );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a parameter source. The \a name argument should match
|
||||||
|
* one of the child algorithm's parameter names, and the \a source
|
||||||
|
* argument is used to set the source for that parameter.
|
||||||
|
*
|
||||||
|
* Any existing parameter source with matching name will be replaced.
|
||||||
|
* \see parameterSources()
|
||||||
|
* \see setParameterSources()
|
||||||
|
*/
|
||||||
|
void addParameterSource( const QString &name, const QgsProcessingModelAlgorithm::ChildParameterSource &source );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the child algorithm is active.
|
||||||
|
* \see setActive()
|
||||||
|
*/
|
||||||
|
bool isActive() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the child algorithm is active.
|
||||||
|
* \see isActive()
|
||||||
|
*/
|
||||||
|
void setActive( bool active );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of child algorithms from the parent model on which this
|
||||||
|
* algorithm is dependent. The returned list contains the id() of the
|
||||||
|
* dependent algorithms.
|
||||||
|
* \see setDependencies()
|
||||||
|
*/
|
||||||
|
QStringList dependencies() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of child algorithms from the parent model on which this
|
||||||
|
* algorithm is dependent. The list should contain the id() of the
|
||||||
|
* dependent algorithms.
|
||||||
|
* \see dependencies()
|
||||||
|
*/
|
||||||
|
void setDependencies( const QStringList &dependencies );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the list of parameters for this algorithm should be collapsed
|
||||||
|
* in the graphical modeller.
|
||||||
|
* \see setParametersCollapsed()
|
||||||
|
* \see outputsCollapsed()
|
||||||
|
*/
|
||||||
|
bool parametersCollapsed() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the list of parameters for this algorithm should be collapsed
|
||||||
|
* in the graphical modeller.
|
||||||
|
* \see parametersCollapsed()
|
||||||
|
* \see setOutputsCollapsed()
|
||||||
|
*/
|
||||||
|
void setParametersCollapsed( bool collapsed );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the list of outputs for this algorithm should be collapsed
|
||||||
|
* in the graphical modeller.
|
||||||
|
* \see setParametersCollapsed()
|
||||||
|
* \see parametersCollapsed()
|
||||||
|
*/
|
||||||
|
bool outputsCollapsed() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the list of outputs for this algorithm should be collapsed
|
||||||
|
* in the graphical modeller.
|
||||||
|
* \see outputsCollapsed()
|
||||||
|
* \see setParametersCollapsed()
|
||||||
|
*/
|
||||||
|
void setOutputsCollapsed( bool collapsed );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of final model outputs which are generated by this child algorithm.
|
||||||
|
* The keys are the output names from this child algorithm. Only outputs which are
|
||||||
|
* part of the final outputs from the model are included in this map.
|
||||||
|
* \see setModelOutputs()
|
||||||
|
* \see modelOutput()
|
||||||
|
*/
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> modelOutputs() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the final model output with matching \a name. If no output
|
||||||
|
* exists with the name, a new one will be created and returned.
|
||||||
|
* \see modelOutputs()
|
||||||
|
* \see setModelOutputs()
|
||||||
|
*/
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput &modelOutput( const QString &name );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the map of final model \a outputs which are generated by this child algorithm.
|
||||||
|
* The keys are the output names from this child algorithm. Only outputs which are
|
||||||
|
* part of the final outputs from the model should be included in this map.
|
||||||
|
* \see modelOutputs()
|
||||||
|
*/
|
||||||
|
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mId;
|
||||||
|
|
||||||
|
QString mAlgorithmId;
|
||||||
|
|
||||||
|
//! A map of parameter sources. Keys are algorithm parameter names.
|
||||||
|
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > mParams;
|
||||||
|
|
||||||
|
//! A map of ModelOutput for final model outputs generated by this child algorithm. Keys are output names from the child algorithm.
|
||||||
|
QMap< QString, QgsProcessingModelAlgorithm::ModelOutput > mModelOutputs;
|
||||||
|
|
||||||
|
bool mActive = true;
|
||||||
|
|
||||||
|
//! List of child algorithms from the parent model on which this algorithm is dependent
|
||||||
|
QStringList mDependencies;
|
||||||
|
|
||||||
|
//! Whether list of parameters should be collapsed in the graphical modeller
|
||||||
|
bool mParametersCollapsed = true;
|
||||||
|
//! Whether list of outputs should be collapsed in the graphical modeller
|
||||||
|
bool mOutputsCollapsed = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for QgsProcessingModelAlgorithm.
|
||||||
|
*/
|
||||||
|
QgsProcessingModelAlgorithm( const QString &name = QString(), const QString &group = QString() );
|
||||||
|
|
||||||
|
QString name() const override;
|
||||||
|
QString displayName() const override;
|
||||||
|
QString group() const override;
|
||||||
|
QIcon icon() const override;
|
||||||
|
QString svgIconPath() const override;
|
||||||
|
|
||||||
|
bool canExecute( QString *errorMessage SIP_OUT = nullptr ) const override;
|
||||||
|
QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||||
|
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of child algorithms contained in the model. The keys
|
||||||
|
* are the child algorithm ids (see QgsProcessingModelAlgorithm::ChildAlgorithm::childId()).
|
||||||
|
* \see childAlgorithm()
|
||||||
|
* \see setChildAlgorithms()
|
||||||
|
* \see addChildAlgorithm()
|
||||||
|
*/
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> childAlgorithms() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the map of child algorithms contained in the model. The keys
|
||||||
|
* are the child algorithm ids (see QgsProcessingModelAlgorithm::ChildAlgorithm::childId()).
|
||||||
|
* All existing child algorithms will be replaced.
|
||||||
|
* \see childAlgorithms()
|
||||||
|
* \see childAlgorithm()
|
||||||
|
* \see setChildAlgorithm()
|
||||||
|
* \see addChildAlgorithm()
|
||||||
|
*/
|
||||||
|
void setChildAlgorithms( const QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> &childAlgorithms );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the child \a algorithm within the model. If a child algorithm already
|
||||||
|
* exists in the model with the same child ID then that algorithm will be replaced.
|
||||||
|
* \see addChildAlgorithm()
|
||||||
|
* \see setChildAlgorithms()
|
||||||
|
*/
|
||||||
|
void setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new child \a algorithm to the model. If a child algorithm already exists
|
||||||
|
* in the model with the same child ID then \a algorithm will be assigned a new
|
||||||
|
* autogenerated unique ID.
|
||||||
|
* The assigned child ID will be returned.
|
||||||
|
* \see childAlgorithms()
|
||||||
|
* \see childAlgorithm()
|
||||||
|
* \see setChildAlgorithm()
|
||||||
|
* \see setChildAlgorithms()
|
||||||
|
*/
|
||||||
|
QString addChildAlgorithm( QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the child algorithm with matching \a id. If no child algorithm exists with
|
||||||
|
* this ID a new algorithm will be added to the model and returned.
|
||||||
|
* \see addChildAlgorithm()
|
||||||
|
* \see childAlgorithms()
|
||||||
|
*/
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm &childAlgorithm( const QString &id );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new parameter to the model, with the specified \a definition and graphical \a component.
|
||||||
|
* Ownership of \a definition is transferred to the model.
|
||||||
|
* \see updateModelParameter()
|
||||||
|
* \see removeModelParameter()
|
||||||
|
*/
|
||||||
|
void addModelParameter( QgsProcessingParameterDefinition *definition SIP_TRANSFER, const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the definition of an existing parameter (by parameter name) with a new \a definition. Ownership of
|
||||||
|
* \a definition is transferred to the model, and any existing parameter is deleted.
|
||||||
|
* \see addModelParameter()
|
||||||
|
* \see removeModelParameter()
|
||||||
|
*/
|
||||||
|
void updateModelParameter( QgsProcessingParameterDefinition *definition SIP_TRANSFER );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an existing model parameter by \a name. The definition of the matching parameter
|
||||||
|
* is deleted.
|
||||||
|
* \see addModelParameter()
|
||||||
|
* \see updateModelParameter()
|
||||||
|
*/
|
||||||
|
void removeModelParameter( const QString &name );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of parameter components used by the model. The keys
|
||||||
|
* should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||||
|
* \see setParameterComponent()
|
||||||
|
* \see parameterComponent()
|
||||||
|
*/
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> parameterComponents() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the map of parameter components used by the model. The keys
|
||||||
|
* should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||||
|
* All existing parameter components will be replaced.
|
||||||
|
* \see parameterComponents()
|
||||||
|
* \see setParameterComponent()
|
||||||
|
* \see parameterComponent()
|
||||||
|
*/
|
||||||
|
void setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a parameter \a component for the model. If a parameter component already
|
||||||
|
* exists in the model with the same parameter name then that component will be replaced.
|
||||||
|
* \see parameterComponents()
|
||||||
|
* \see setParameterComponents()
|
||||||
|
* \see parameterComponent()
|
||||||
|
*/
|
||||||
|
void setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parameter component with matching \a name. If no parameter component exists with
|
||||||
|
* this name a new component will be added to the model and returned.
|
||||||
|
* \see parameterComponents()
|
||||||
|
* \see setParameterComponents()
|
||||||
|
* \see setParameterComponent()
|
||||||
|
*/
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter ¶meterComponent( const QString &name );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QStringList dependentChildAlgorithms( const QString &childId ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mModelName;
|
||||||
|
QString mModelGroup;
|
||||||
|
|
||||||
|
QMap< QString, ChildAlgorithm > mChildAlgorithms;
|
||||||
|
|
||||||
|
//! Map of parameter name to model parameter component
|
||||||
|
QMap< QString, ModelParameter > mParameterComponents;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSPROCESSINGMODELALGORITHM_H
|
||||||
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
|||||||
#include "qgsprocessingutils.h"
|
#include "qgsprocessingutils.h"
|
||||||
#include "qgsprocessingalgorithm.h"
|
#include "qgsprocessingalgorithm.h"
|
||||||
#include "qgsprocessingcontext.h"
|
#include "qgsprocessingcontext.h"
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtTest/QSignalSpy>
|
#include <QtTest/QSignalSpy>
|
||||||
#include "qgis.h"
|
#include "qgis.h"
|
||||||
@ -103,6 +104,13 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
|
|||||||
QgsProcessingParameterFeatureSink *p6 = new QgsProcessingParameterFeatureSink( "p6" );
|
QgsProcessingParameterFeatureSink *p6 = new QgsProcessingParameterFeatureSink( "p6" );
|
||||||
QVERIFY( addParameter( p6 ) );
|
QVERIFY( addParameter( p6 ) );
|
||||||
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 << p6 );
|
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 << p6 );
|
||||||
|
|
||||||
|
// remove parameter
|
||||||
|
removeParameter( "non existent" );
|
||||||
|
removeParameter( "p6" );
|
||||||
|
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 );
|
||||||
|
removeParameter( "p5" );
|
||||||
|
QVERIFY( destinationParameterDefinitions().isEmpty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void runOutputChecks()
|
void runOutputChecks()
|
||||||
@ -318,6 +326,7 @@ class TestQgsProcessing: public QObject
|
|||||||
void validateInputCrs();
|
void validateInputCrs();
|
||||||
void generateIteratingDestination();
|
void generateIteratingDestination();
|
||||||
void asPythonCommand();
|
void asPythonCommand();
|
||||||
|
void modelerAlgorithm();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -2918,5 +2927,250 @@ void TestQgsProcessing::asPythonCommand()
|
|||||||
alg.runAsPythonCommandChecks();
|
alg.runAsPythonCommandChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestQgsProcessing::modelerAlgorithm()
|
||||||
|
{
|
||||||
|
//static value source
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource svSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||||
|
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||||
|
QCOMPARE( svSource.staticValue().toInt(), 5 );
|
||||||
|
svSource.setStaticValue( 7 );
|
||||||
|
QCOMPARE( svSource.staticValue().toInt(), 7 );
|
||||||
|
svSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "a" );
|
||||||
|
// check that calling setStaticValue flips source to StaticValue
|
||||||
|
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||||
|
svSource.setStaticValue( 7 );
|
||||||
|
QCOMPARE( svSource.staticValue().toInt(), 7 );
|
||||||
|
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||||
|
|
||||||
|
// model parameter source
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource mpSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "a" );
|
||||||
|
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||||
|
QCOMPARE( mpSource.parameterName(), QStringLiteral( "a" ) );
|
||||||
|
mpSource.setParameterName( "b" );
|
||||||
|
QCOMPARE( mpSource.parameterName(), QStringLiteral( "b" ) );
|
||||||
|
mpSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||||
|
// check that calling setParameterName flips source to ModelParameter
|
||||||
|
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||||
|
mpSource.setParameterName( "c" );
|
||||||
|
QCOMPARE( mpSource.parameterName(), QStringLiteral( "c" ) );
|
||||||
|
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||||
|
|
||||||
|
// child alg output source
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "a", "b" );
|
||||||
|
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||||
|
QCOMPARE( oSource.outputChildId(), QStringLiteral( "a" ) );
|
||||||
|
QCOMPARE( oSource.outputName(), QStringLiteral( "b" ) );
|
||||||
|
oSource.setOutputChildId( "c" );
|
||||||
|
QCOMPARE( oSource.outputChildId(), QStringLiteral( "c" ) );
|
||||||
|
oSource.setOutputName( "d" );
|
||||||
|
QCOMPARE( oSource.outputName(), QStringLiteral( "d" ) );
|
||||||
|
oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||||
|
// check that calling setOutputChildId flips source to ChildOutput
|
||||||
|
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||||
|
oSource.setOutputChildId( "c" );
|
||||||
|
QCOMPARE( oSource.outputChildId(), QStringLiteral( "c" ) );
|
||||||
|
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||||
|
oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||||
|
// check that calling setOutputName flips source to ChildOutput
|
||||||
|
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||||
|
oSource.setOutputName( "d" );
|
||||||
|
QCOMPARE( oSource.outputName(), QStringLiteral( "d" ) );
|
||||||
|
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||||
|
|
||||||
|
// source equality operator
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) ==
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 7 ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) ==
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "b" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) ==
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg2" ), QStringLiteral( "out" ) ) );
|
||||||
|
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) !=
|
||||||
|
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out2" ) ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm child( QStringLiteral( "some_id" ) );
|
||||||
|
QCOMPARE( child.algorithmId(), QStringLiteral( "some_id" ) );
|
||||||
|
QVERIFY( !child.algorithm() );
|
||||||
|
child.setAlgorithmId( QStringLiteral( "native:centroids" ) );
|
||||||
|
QVERIFY( child.algorithm() );
|
||||||
|
QCOMPARE( child.algorithm()->id(), QStringLiteral( "native:centroids" ) );
|
||||||
|
child.setDescription( QStringLiteral( "desc" ) );
|
||||||
|
QCOMPARE( child.description(), QStringLiteral( "desc" ) );
|
||||||
|
QVERIFY( child.isActive() );
|
||||||
|
child.setActive( false );
|
||||||
|
QVERIFY( !child.isActive() );
|
||||||
|
child.setPosition( QPointF( 1, 2 ) );
|
||||||
|
QCOMPARE( child.position(), QPointF( 1, 2 ) );
|
||||||
|
QVERIFY( child.parametersCollapsed() );
|
||||||
|
child.setParametersCollapsed( false );
|
||||||
|
QVERIFY( !child.parametersCollapsed() );
|
||||||
|
QVERIFY( child.outputsCollapsed() );
|
||||||
|
child.setOutputsCollapsed( false );
|
||||||
|
QVERIFY( !child.outputsCollapsed() );
|
||||||
|
|
||||||
|
child.setChildId( QStringLiteral( "my_id" ) );
|
||||||
|
QCOMPARE( child.childId(), QStringLiteral( "my_id" ) );
|
||||||
|
|
||||||
|
child.setDependencies( QStringList() << "a" << "b" );
|
||||||
|
QCOMPARE( child.dependencies(), QStringList() << "a" << "b" );
|
||||||
|
|
||||||
|
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > sources;
|
||||||
|
sources.insert( QStringLiteral( "a" ), QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) );
|
||||||
|
child.setParameterSources( sources );
|
||||||
|
QCOMPARE( child.parameterSources().value( QStringLiteral( "a" ) ).staticValue().toInt(), 5 );
|
||||||
|
child.addParameterSource( QStringLiteral( "b" ), QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 7 ) );
|
||||||
|
QCOMPARE( child.parameterSources().value( QStringLiteral( "a" ) ).staticValue().toInt(), 5 );
|
||||||
|
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).staticValue().toInt(), 7 );
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput testModelOut;
|
||||||
|
testModelOut.setChildId( QStringLiteral( "my_id" ) );
|
||||||
|
QCOMPARE( testModelOut.childId(), QStringLiteral( "my_id" ) );
|
||||||
|
testModelOut.setOutputName( QStringLiteral( "my_output" ) );
|
||||||
|
QCOMPARE( testModelOut.outputName(), QStringLiteral( "my_output" ) );
|
||||||
|
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs;
|
||||||
|
QgsProcessingModelAlgorithm::ModelOutput out1;
|
||||||
|
out1.setDescription( QStringLiteral( "my output" ) );
|
||||||
|
outputs.insert( QStringLiteral( "a" ), out1 );
|
||||||
|
child.setModelOutputs( outputs );
|
||||||
|
QCOMPARE( child.modelOutputs().count(), 1 );
|
||||||
|
QCOMPARE( child.modelOutputs().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "my output" ) );
|
||||||
|
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output" ) );
|
||||||
|
child.modelOutput( "a" ).setDescription( QStringLiteral( "my output 2" ) );
|
||||||
|
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output 2" ) );
|
||||||
|
// no existent
|
||||||
|
child.modelOutput( "b" ).setDescription( QStringLiteral( "my output 3" ) );
|
||||||
|
QCOMPARE( child.modelOutput( "b" ).description(), QStringLiteral( "my output 3" ) );
|
||||||
|
QCOMPARE( child.modelOutputs().count(), 2 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// model algorithm tests
|
||||||
|
|
||||||
|
|
||||||
|
QgsProcessingModelAlgorithm alg( "test", "testGroup" );
|
||||||
|
QCOMPARE( alg.name(), QStringLiteral( "test" ) );
|
||||||
|
QCOMPARE( alg.displayName(), QStringLiteral( "test" ) );
|
||||||
|
QCOMPARE( alg.group(), QStringLiteral( "testGroup" ) );
|
||||||
|
|
||||||
|
// child algorithms
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> algs;
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm a1;
|
||||||
|
a1.setDescription( QStringLiteral( "alg1" ) );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm a2;
|
||||||
|
a2.setDescription( QStringLiteral( "alg2" ) );
|
||||||
|
algs.insert( QStringLiteral( "a" ), a1 );
|
||||||
|
algs.insert( QStringLiteral( "b" ), a2 );
|
||||||
|
alg.setChildAlgorithms( algs );
|
||||||
|
QCOMPARE( alg.childAlgorithms().count(), 2 );
|
||||||
|
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "alg1" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "b" ) ).description(), QStringLiteral( "alg2" ) );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm a3;
|
||||||
|
a3.setChildId( QStringLiteral( "c" ) );
|
||||||
|
a3.setDescription( QStringLiteral( "alg3" ) );
|
||||||
|
QCOMPARE( alg.addChildAlgorithm( a3 ), QStringLiteral( "c" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithms().count(), 3 );
|
||||||
|
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "alg1" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "b" ) ).description(), QStringLiteral( "alg2" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "c" ) ).description(), QStringLiteral( "alg3" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithm( "a" ).description(), QStringLiteral( "alg1" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithm( "b" ).description(), QStringLiteral( "alg2" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithm( "c" ).description(), QStringLiteral( "alg3" ) );
|
||||||
|
// initially non-existent
|
||||||
|
QVERIFY( alg.childAlgorithm( "d" ).description().isEmpty() );
|
||||||
|
alg.childAlgorithm( "d" ).setDescription( QStringLiteral( "alg4" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithm( "d" ).description(), QStringLiteral( "alg4" ) );
|
||||||
|
// overwrite existing
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm a4a;
|
||||||
|
a4a.setChildId( "d" );
|
||||||
|
a4a.setDescription( "new" );
|
||||||
|
alg.setChildAlgorithm( a4a );
|
||||||
|
QCOMPARE( alg.childAlgorithm( "d" ).description(), QStringLiteral( "new" ) );
|
||||||
|
|
||||||
|
// generating child ids
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c1;
|
||||||
|
c1.setAlgorithmId( QStringLiteral( "buffer" ) );
|
||||||
|
c1.generateChildId( alg );
|
||||||
|
QCOMPARE( c1.childId(), QStringLiteral( "buffer_1" ) );
|
||||||
|
QCOMPARE( alg.addChildAlgorithm( c1 ), QStringLiteral( "buffer_1" ) );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c2;
|
||||||
|
c2.setAlgorithmId( QStringLiteral( "buffer" ) );
|
||||||
|
c2.generateChildId( alg );
|
||||||
|
QCOMPARE( c2.childId(), QStringLiteral( "buffer_2" ) );
|
||||||
|
QCOMPARE( alg.addChildAlgorithm( c2 ), QStringLiteral( "buffer_2" ) );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c3;
|
||||||
|
c3.setAlgorithmId( QStringLiteral( "centroid" ) );
|
||||||
|
c3.generateChildId( alg );
|
||||||
|
QCOMPARE( c3.childId(), QStringLiteral( "centroid_1" ) );
|
||||||
|
QCOMPARE( alg.addChildAlgorithm( c3 ), QStringLiteral( "centroid_1" ) );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c4;
|
||||||
|
c4.setAlgorithmId( QStringLiteral( "centroid" ) );
|
||||||
|
c4.setChildId( QStringLiteral( "centroid_1" ) );// dupe id
|
||||||
|
QCOMPARE( alg.addChildAlgorithm( c4 ), QStringLiteral( "centroid_2" ) );
|
||||||
|
QCOMPARE( alg.childAlgorithm( QStringLiteral( "centroid_2" ) ).childId(), QStringLiteral( "centroid_2" ) );
|
||||||
|
|
||||||
|
// parameter components
|
||||||
|
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> pComponents;
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter pc1;
|
||||||
|
pc1.setParameterName( QStringLiteral( "my_param" ) );
|
||||||
|
QCOMPARE( pc1.parameterName(), QStringLiteral( "my_param" ) );
|
||||||
|
pComponents.insert( QStringLiteral( "my_param" ), pc1 );
|
||||||
|
alg.setParameterComponents( pComponents );
|
||||||
|
QCOMPARE( alg.parameterComponents().count(), 1 );
|
||||||
|
QCOMPARE( alg.parameterComponents().value( QStringLiteral( "my_param" ) ).parameterName(), QStringLiteral( "my_param" ) );
|
||||||
|
QCOMPARE( alg.parameterComponent( "my_param" ).parameterName(), QStringLiteral( "my_param" ) );
|
||||||
|
alg.parameterComponent( "my_param" ).setDescription( QStringLiteral( "my param 2" ) );
|
||||||
|
QCOMPARE( alg.parameterComponent( "my_param" ).description(), QStringLiteral( "my param 2" ) );
|
||||||
|
// no existent
|
||||||
|
alg.parameterComponent( "b" ).setDescription( QStringLiteral( "my param 3" ) );
|
||||||
|
QCOMPARE( alg.parameterComponent( "b" ).description(), QStringLiteral( "my param 3" ) );
|
||||||
|
QCOMPARE( alg.parameterComponent( "b" ).parameterName(), QStringLiteral( "b" ) );
|
||||||
|
QCOMPARE( alg.parameterComponents().count(), 2 );
|
||||||
|
|
||||||
|
// parameter definitions
|
||||||
|
QgsProcessingModelAlgorithm alg1a( "test", "testGroup" );
|
||||||
|
QgsProcessingModelAlgorithm::ModelParameter bool1;
|
||||||
|
bool1.setPosition( QPointF( 1, 2 ) );
|
||||||
|
alg1a.addModelParameter( new QgsProcessingParameterBoolean( "p1", "desc" ), bool1 );
|
||||||
|
QCOMPARE( alg1a.parameterDefinitions().count(), 1 );
|
||||||
|
QCOMPARE( alg1a.parameterDefinition( "p1" )->type(), QStringLiteral( "boolean" ) );
|
||||||
|
QCOMPARE( alg1a.parameterComponent( "p1" ).position().x(), 1.0 );
|
||||||
|
QCOMPARE( alg1a.parameterComponent( "p1" ).position().y(), 2.0 );
|
||||||
|
alg1a.updateModelParameter( new QgsProcessingParameterBoolean( "p1", "descx" ) );
|
||||||
|
QCOMPARE( alg1a.parameterDefinition( "p1" )->description(), QStringLiteral( "descx" ) );
|
||||||
|
alg1a.removeModelParameter( "bad" );
|
||||||
|
QCOMPARE( alg1a.parameterDefinitions().count(), 1 );
|
||||||
|
alg1a.removeModelParameter( "p1" );
|
||||||
|
QVERIFY( alg1a.parameterDefinitions().isEmpty() );
|
||||||
|
QVERIFY( alg1a.parameterComponents().isEmpty() );
|
||||||
|
|
||||||
|
|
||||||
|
// test canExecute
|
||||||
|
QgsProcessingModelAlgorithm alg2( "test", "testGroup" );
|
||||||
|
QVERIFY( alg2.canExecute() );
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c5;
|
||||||
|
c5.setAlgorithmId( "native:centroids" );
|
||||||
|
alg2.addChildAlgorithm( c5 );
|
||||||
|
QVERIFY( alg2.canExecute() );
|
||||||
|
// non-existing alg
|
||||||
|
QgsProcessingModelAlgorithm::ChildAlgorithm c6;
|
||||||
|
c6.setAlgorithmId( "i'm not an alg" );
|
||||||
|
alg2.addChildAlgorithm( c6 );
|
||||||
|
QVERIFY( !alg2.canExecute() );
|
||||||
|
}
|
||||||
|
|
||||||
QGSTEST_MAIN( TestQgsProcessing )
|
QGSTEST_MAIN( TestQgsProcessing )
|
||||||
#include "testqgsprocessing.moc"
|
#include "testqgsprocessing.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user