Update QgsProcessingModelChildAlgorithm::asPythonCode for 3.x API

This commit is contained in:
Nyall Dawson 2019-02-01 11:28:57 +10:00
parent 946687c87b
commit fb519ead46
4 changed files with 54 additions and 19 deletions

View File

@ -298,9 +298,15 @@ Loads this child from a QVariant.
.. seealso:: :py:func:`toVariant`
%End
QString asPythonCode() const;
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize ) const;
%Docstring
Attempts to convert the child to executable Python code.
Attempts to convert the child to executable Python code, and returns a list of the generated lines of code.
The ``outputType`` argument specifies the type of script to generate.
Additional parameters to be passed to the child algorithm are specified in the ``extraParameters`` argument.
The ``currentIndent`` and ``indentSize`` are used to set the base line indent and size of further indented lines respectively.
%End
};

View File

@ -162,39 +162,53 @@ bool QgsProcessingModelChildAlgorithm::loadVariant( const QVariant &child )
return true;
}
QString QgsProcessingModelChildAlgorithm::asPythonCode() const
QStringList QgsProcessingModelChildAlgorithm::asPythonCode( const QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize ) const
{
QStringList lines;
const QString baseIndent = QString( ' ' ).repeated( currentIndent );
const QString lineIndent = QString( ' ' ).repeated( indentSize );
if ( !algorithm() )
return QString();
return QStringList();
QStringList paramParts;
QMap< QString, QgsProcessingModelChildParameterSources >::const_iterator paramIt = mParams.constBegin();
for ( ; paramIt != mParams.constEnd(); ++paramIt )
for ( auto paramIt = mParams.constBegin(); paramIt != mParams.constEnd(); ++paramIt )
{
QStringList sourceParts;
Q_FOREACH ( const QgsProcessingModelChildParameterSource &source, paramIt.value() )
const QgsProcessingParameterDefinition *def = algorithm() ? algorithm()->parameterDefinition( paramIt.key() ) : nullptr;
const auto parts = paramIt.value();
for ( const QgsProcessingModelChildParameterSource &source : parts )
{
QString part = source.asPythonCode();
QString part = source.asPythonCode( outputType, def );
if ( !part.isEmpty() )
sourceParts << QStringLiteral( "'%1':%2" ).arg( paramIt.key(), part );
sourceParts << part;
}
if ( sourceParts.count() == 1 )
paramParts << sourceParts.at( 0 );
paramParts << QStringLiteral( "'%1':%2" ).arg( paramIt.key(), sourceParts.at( 0 ) );
else
paramParts << QStringLiteral( "[%1]" ).arg( paramParts.join( ',' ) );
paramParts << QStringLiteral( "'%1':[%2]" ).arg( paramIt.key(), sourceParts.join( ',' ) );
}
lines << QStringLiteral( "outputs['%1']=processing.run('%2', {%3}, context=context, feedback=feedback)" ).arg( mId, mAlgorithmId, paramParts.join( ',' ) );
QMap< QString, QgsProcessingModelOutput >::const_iterator outputIt = mModelOutputs.constBegin();
for ( ; outputIt != mModelOutputs.constEnd(); ++outputIt )
lines << baseIndent + QStringLiteral( "alg_params = {" );
lines.reserve( lines.size() + paramParts.size() );
for ( const QString &p : qgis::as_const( paramParts ) )
{
lines << QStringLiteral( "results['%1']=outputs['%2']['%3']" ).arg( outputIt.key(), mId, outputIt.value().childOutputName() );
lines << baseIndent + lineIndent + p + ',';
}
for ( auto it = extraParameters.constBegin(); it != extraParameters.constEnd(); ++it )
{
lines << baseIndent + lineIndent + QgsProcessingUtils::stringToPythonLiteral( it.key() ) + ':' + it.value() + ',';
}
lines << baseIndent + QStringLiteral( "}" );
lines << baseIndent + QStringLiteral( "outputs['%1']=processing.run('%2', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ).arg( mId, mAlgorithmId );
for ( auto outputIt = mModelOutputs.constBegin(); outputIt != mModelOutputs.constEnd(); ++outputIt )
{
lines << baseIndent + QStringLiteral( "results['%1:%2']=outputs['%1']['%3']" ).arg( mId, outputIt.key(), outputIt.value().childOutputName() );
}
return lines.join( '\n' );
return lines;
}
QVariantMap QgsProcessingModelChildAlgorithm::configuration() const

View File

@ -278,9 +278,15 @@ class CORE_EXPORT QgsProcessingModelChildAlgorithm : public QgsProcessingModelCo
bool loadVariant( const QVariant &child );
/**
* Attempts to convert the child to executable Python code.
* Attempts to convert the child to executable Python code, and returns a list of the generated lines of code.
*
* The \a outputType argument specifies the type of script to generate.
*
* Additional parameters to be passed to the child algorithm are specified in the \a extraParameters argument.
*
* The \a currentIndent and \a indentSize are used to set the base line indent and size of further indented lines respectively.
*/
QString asPythonCode() const;
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize ) const;
private:

View File

@ -6152,6 +6152,11 @@ void TestQgsProcessing::modelerAlgorithm()
QVERIFY( child.setAlgorithmId( QStringLiteral( "native:centroids" ) ) );
QVERIFY( child.algorithm() );
QCOMPARE( child.algorithm()->id(), QStringLiteral( "native:centroids" ) );
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, QgsStringMap(), 4, 2 ).join( '\n' ), QStringLiteral( " alg_params = {\n }\n outputs['']=processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ) );
QgsStringMap extraParams;
extraParams[QStringLiteral( "SOMETHING" )] = QStringLiteral( "SOMETHING_ELSE" );
extraParams[QStringLiteral( "SOMETHING2" )] = QStringLiteral( "SOMETHING_ELSE2" );
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2 ).join( '\n' ), QStringLiteral( " alg_params = {\n 'SOMETHING':SOMETHING_ELSE,\n 'SOMETHING2':SOMETHING_ELSE2,\n }\n outputs['']=processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ) );
// bit of a hack -- but try to simulate an algorithm not originally available!
child.mAlgorithm.reset();
QVERIFY( !child.algorithm() );
@ -6194,6 +6199,8 @@ void TestQgsProcessing::modelerAlgorithm()
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).at( 0 ).staticValue().toInt(), 7 );
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).at( 1 ).staticValue().toInt(), 9 );
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2 ).join( '\n' ), QStringLiteral( " alg_params = {\n 'a':5,\n 'b':[7,9],\n 'SOMETHING':SOMETHING_ELSE,\n 'SOMETHING2':SOMETHING_ELSE2,\n }\n outputs['my_id']=processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ) );
QgsProcessingModelOutput testModelOut;
testModelOut.setChildId( QStringLiteral( "my_id" ) );
QCOMPARE( testModelOut.childId(), QStringLiteral( "my_id" ) );
@ -6228,6 +6235,8 @@ void TestQgsProcessing::modelerAlgorithm()
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" ) );
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2 ).join( '\n' ), QStringLiteral( " alg_params = {\n 'a':5,\n 'b':[7,9],\n 'SOMETHING':SOMETHING_ELSE,\n 'SOMETHING2':SOMETHING_ELSE2,\n }\n outputs['my_id']=processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)\n results['my_id:a']=outputs['my_id']['']" ) );
// no existent
child.modelOutput( "b" ).setDescription( QStringLiteral( "my output 3" ) );
QCOMPARE( child.modelOutput( "b" ).description(), QStringLiteral( "my output 3" ) );