Skip to content
Permalink
Browse files

Fix generation of destination parameters for models

  • Loading branch information
nyalldawson committed Jun 21, 2017
1 parent c36169a commit fe0f2498d482af7e7ea93e444ad02c1bb40b1c88
@@ -502,6 +502,10 @@ Copies are protected to avoid slicing
%Docstring
Returns the final model output with matching ``name``. If no output
exists with the name, a new one will be created and returned.

If child model outputs are altered by this method, QgsProcessingModelAlgorithm.updateDestinationParameters()
must be called on the parent model.

.. seealso:: modelOutputs()
.. seealso:: setModelOutputs()
:rtype: QgsProcessingModelAlgorithm.ModelOutput
@@ -512,6 +516,10 @@ Copies are protected to avoid slicing
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.

If child model outputs are altered by this method, QgsProcessingModelAlgorithm.updateDestinationParameters()
must be called on the parent model.

.. seealso:: modelOutputs()
%End

@@ -728,6 +736,13 @@ Copies are protected to avoid slicing
:rtype: QgsProcessingModelAlgorithm.ModelParameter
%End

void updateDestinationParameters();
%Docstring
Updates the model's parameter definitions to include all relevant destination
parameters as required by child algorithm ModelOutputs.
Must be called whenever child algorithm ModelOutputs are altered.
%End

bool toFile( const QString &path ) const;
%Docstring
Writes the model to a file, at the specified ``path``.
@@ -327,6 +327,43 @@ QgsProcessingModelAlgorithm::ModelParameter &QgsProcessingModelAlgorithm::parame
return mParameterComponents[ name ];
}

void QgsProcessingModelAlgorithm::updateDestinationParameters()
{
//delete existing destination parameters
QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
while ( it.hasNext() )
{
const QgsProcessingParameterDefinition *def = it.next();
if ( def->isDestination() )
{
delete def;
it.remove();
}
}

QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
{
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs = childIt->modelOutputs();
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin();
for ( ; outputIt != outputs.constEnd(); ++outputIt )
{
if ( !childIt->isActive() || !childIt->algorithm() )
continue;

// child algorithm has a destination parameter set, copy it to the model
const QgsProcessingParameterDefinition *source = childIt->algorithm()->parameterDefinition( outputIt->outputName() );
if ( !source )
continue;

QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( source->toVariantMap() );
param->setName( outputIt->childId() + ':' + outputIt->outputName() );
param->setDescription( outputIt->description() );
addParameter( param );
}
}
}

QVariant QgsProcessingModelAlgorithm::toVariant() const
{
QVariantMap map;
@@ -403,6 +440,8 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
addParameter( param );
}

updateDestinationParameters();

return true;
}

@@ -443,11 +482,13 @@ bool QgsProcessingModelAlgorithm::fromFile( const QString &path )
void QgsProcessingModelAlgorithm::setChildAlgorithms( const QMap<QString, ChildAlgorithm> &childAlgorithms )
{
mChildAlgorithms = childAlgorithms;
updateDestinationParameters();
}

void QgsProcessingModelAlgorithm::setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm )
{
mChildAlgorithms.insert( algorithm.childId(), algorithm );
updateDestinationParameters();
}

QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorithm )
@@ -456,6 +497,7 @@ QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorith
algorithm.generateChildId( *this );

mChildAlgorithms.insert( algorithm.childId(), algorithm );
updateDestinationParameters();
return algorithm.childId();
}

@@ -470,6 +512,7 @@ bool QgsProcessingModelAlgorithm::removeChildAlgorithm( const QString &id )
return false;

mChildAlgorithms.remove( id );
updateDestinationParameters();
return true;
}

@@ -480,6 +523,7 @@ void QgsProcessingModelAlgorithm::deactivateChildAlgorithm( const QString &id )
childAlgorithm( child ).setActive( false );
}
childAlgorithm( id ).setActive( false );
updateDestinationParameters();
}

bool QgsProcessingModelAlgorithm::activateChildAlgorithm( const QString &id )
@@ -490,6 +534,7 @@ bool QgsProcessingModelAlgorithm::activateChildAlgorithm( const QString &id )
return false;
}
childAlgorithm( id ).setActive( true );
updateDestinationParameters();
return true;
}

@@ -491,6 +491,10 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
/**
* Returns the final model output with matching \a name. If no output
* exists with the name, a new one will be created and returned.
*
* If child model outputs are altered by this method, QgsProcessingModelAlgorithm::updateDestinationParameters()
* must be called on the parent model.
*
* \see modelOutputs()
* \see setModelOutputs()
*/
@@ -500,6 +504,10 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
* 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.
*
* If child model outputs are altered by this method, QgsProcessingModelAlgorithm::updateDestinationParameters()
* must be called on the parent model.
*
* \see modelOutputs()
*/
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
@@ -720,6 +728,13 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
*/
QgsProcessingModelAlgorithm::ModelParameter &parameterComponent( const QString &name );

/**
* Updates the model's parameter definitions to include all relevant destination
* parameters as required by child algorithm ModelOutputs.
* Must be called whenever child algorithm ModelOutputs are altered.
*/
void updateDestinationParameters();

/**
* Writes the model to a file, at the specified \a path.
* \see fromFile()
@@ -3752,6 +3752,47 @@ void TestQgsProcessing::modelerAlgorithm()
QCOMPARE( alg6.parameterDefinitions().count(), 1 );
QCOMPARE( alg6.parameterDefinitions().at( 0 )->type(), QStringLiteral( "boolean" ) );

// destination parameters
QgsProcessingModelAlgorithm alg7( "test", "testGroup" );
QgsProcessingModelAlgorithm::ChildAlgorithm alg7c1;
alg7c1.setChildId( "cx1" );
alg7c1.setAlgorithmId( "native:centroids" );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c1outputs;
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1;
alg7c1out1.setChildId( "cx1" );
alg7c1out1.setOutputName( "OUTPUT_LAYER" );
alg7c1out1.setDescription( QStringLiteral( "my output" ) );
alg7c1outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c1out1 );
alg7c1.setModelOutputs( alg7c1outputs );
alg7.addChildAlgorithm( alg7c1 );
// verify that model has destination parameter created
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );

QgsProcessingModelAlgorithm::ChildAlgorithm alg7c2;
alg7c2.setChildId( "cx2" );
alg7c2.setAlgorithmId( "native:centroids" );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c2outputs;
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1;
alg7c2out1.setChildId( "cx2" );
alg7c2out1.setOutputName( "OUTPUT_LAYER" );
alg7c2out1.setDescription( QStringLiteral( "my output2" ) );
alg7c2outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c2out1 );
alg7c2.setModelOutputs( alg7c2outputs );
alg7.addChildAlgorithm( alg7c2 );

QCOMPARE( alg7.destinationParameterDefinitions().count(), 2 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->description(), QStringLiteral( "my output2" ) );

alg7.removeChildAlgorithm( "cx1" );
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output2" ) );

}

QGSTEST_MAIN( TestQgsProcessing )

0 comments on commit fe0f249

Please sign in to comment.
You can’t perform that action at this time.