Skip to content

Commit 7418c18

Browse files
committedFeb 14, 2019
[processing] Also generate friendly names for outputs when converting models to scripts
1 parent d342ce9 commit 7418c18

File tree

5 files changed

+38
-19
lines changed

5 files changed

+38
-19
lines changed
 

‎python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ Loads this child from a QVariant.
298298
.. seealso:: :py:func:`toVariant`
299299
%End
300300

301-
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize, const QMap<QString, QString> &friendlyChildNames ) const;
301+
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize,
302+
const QMap<QString, QString> &friendlyChildNames, const QMap<QString, QString> &friendlyOutputNames ) const;
302303
%Docstring
303304
Attempts to convert the child to executable Python code, and returns a list of the generated lines of code.
304305

‎src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
362362
QString currentIndent;
363363

364364
QMap< QString, QString> friendlyChildNames;
365+
QMap< QString, QString> friendlyOutputNames;
365366
auto safeName = []( const QString & name, bool capitalize )->QString
366367
{
367368
QString n = name.toLower().trimmed();
@@ -374,12 +375,12 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
374375
return capitalize ? QgsStringUtils::capitalize( n, QgsStringUtils::UpperCamelCase ) : n;
375376
};
376377

377-
auto uniqueSafeName = [&friendlyChildNames, &safeName ]( const QString & name, bool capitalize )->QString
378+
auto uniqueSafeName = [ &safeName ]( const QString & name, bool capitalize, const QMap< QString, QString > &friendlyNames )->QString
378379
{
379380
const QString base = safeName( name, capitalize );
380381
QString candidate = base;
381382
int i = 1;
382-
while ( friendlyChildNames.contains( candidate ) )
383+
while ( friendlyNames.contains( candidate ) )
383384
{
384385
i++;
385386
candidate = QStringLiteral( "%1_%2" ).arg( base ).arg( i );
@@ -395,7 +396,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
395396
if ( childIt->isActive() && childIt->algorithm() )
396397
{
397398
toExecute.insert( childIt->childId() );
398-
friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty() ) );
399+
friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
399400
}
400401
}
401402
const int totalSteps = toExecute.count();
@@ -429,7 +430,16 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
429430
lines.reserve( lines.size() + params.size() );
430431
for ( const QgsProcessingParameterDefinition *def : params )
431432
{
432-
lines << indent + indent + QStringLiteral( "self.addParameter(%1)" ).arg( def->asPythonString() );
433+
std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
434+
435+
if ( defClone->isDestination() )
436+
{
437+
const QString &friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(), true, friendlyOutputNames ) : defClone->name();
438+
friendlyOutputNames.insert( defClone->name(), friendlyName );
439+
defClone->setName( friendlyName );
440+
}
441+
442+
lines << indent + indent + QStringLiteral( "self.addParameter(%1)" ).arg( defClone->asPythonString() );
433443
}
434444

435445
lines << QString();
@@ -529,6 +539,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
529539
if ( outputIt->childOutputName() == destParam->name() )
530540
{
531541
QString paramName = child.childId() + ':' + outputIt.key();
542+
paramName = friendlyOutputNames.value( paramName, paramName );
532543
childParams.insert( destParam->name(), QStringLiteral( "parameters['%1']" ).arg( paramName ) );
533544
isFinalOutput = true;
534545
break;
@@ -556,7 +567,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
556567
}
557568
}
558569

559-
lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames );
570+
lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
560571
currentStep++;
561572
if ( currentStep < totalSteps )
562573
{

‎src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ bool QgsProcessingModelChildAlgorithm::loadVariant( const QVariant &child )
162162
return true;
163163
}
164164

165-
QStringList QgsProcessingModelChildAlgorithm::asPythonCode( const QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize, const QMap<QString, QString> &friendlyChildNames ) const
165+
QStringList QgsProcessingModelChildAlgorithm::asPythonCode( const QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters,
166+
int currentIndent, int indentSize, const QMap<QString, QString> &friendlyChildNames, const QMap<QString, QString> &friendlyOutputNames ) const
166167
{
167168
QStringList lines;
168169
const QString baseIndent = QString( ' ' ).repeated( currentIndent );
@@ -211,7 +212,9 @@ QStringList QgsProcessingModelChildAlgorithm::asPythonCode( const QgsProcessing:
211212

212213
for ( auto outputIt = mModelOutputs.constBegin(); outputIt != mModelOutputs.constEnd(); ++outputIt )
213214
{
214-
lines << baseIndent + QStringLiteral( "results['%1:%2'] = outputs['%3']['%4']" ).arg( mId, outputIt.key(), friendlyChildNames.value( mId, mId ), outputIt.value().childOutputName() );
215+
QString outputName = QStringLiteral( "%1:%2" ).arg( mId, outputIt.key() );
216+
outputName = friendlyOutputNames.value( outputName, outputName );
217+
lines << baseIndent + QStringLiteral( "results['%1'] = outputs['%2']['%3']" ).arg( outputName, friendlyChildNames.value( mId, mId ), outputIt.value().childOutputName() );
215218
}
216219

217220
return lines;

‎src/core/processing/models/qgsprocessingmodelchildalgorithm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ class CORE_EXPORT QgsProcessingModelChildAlgorithm : public QgsProcessingModelCo
288288
*
289289
* The \a friendlyChildNames argument gives a map of child id to a friendly algorithm name, to be used in the code to identify that algorithm instead of the raw child id.
290290
*/
291-
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize, const QMap<QString, QString> &friendlyChildNames ) const;
291+
QStringList asPythonCode( QgsProcessing::PythonOutputType outputType, const QgsStringMap &extraParameters, int currentIndent, int indentSize,
292+
const QMap<QString, QString> &friendlyChildNames, const QMap<QString, QString> &friendlyOutputNames ) const;
292293

293294
private:
294295

‎tests/src/analysis/testqgsprocessing.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6182,7 +6182,7 @@ void TestQgsProcessing::modelerAlgorithm()
61826182
QVERIFY( QgsProcessingModelChildParameterSource::fromExpression( QStringLiteral( "a" ) ) !=
61836183
QgsProcessingModelChildParameterSource::fromStaticValue( QStringLiteral( "b" ) ) );
61846184

6185-
6185+
QMap< QString, QString > friendlyOutputNames;
61866186
QgsProcessingModelChildAlgorithm child( QStringLiteral( "some_id" ) );
61876187
QCOMPARE( child.algorithmId(), QStringLiteral( "some_id" ) );
61886188
QVERIFY( !child.algorithm() );
@@ -6191,11 +6191,11 @@ void TestQgsProcessing::modelerAlgorithm()
61916191
QVERIFY( child.setAlgorithmId( QStringLiteral( "native:centroids" ) ) );
61926192
QVERIFY( child.algorithm() );
61936193
QCOMPARE( child.algorithm()->id(), QStringLiteral( "native:centroids" ) );
6194-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, QgsStringMap(), 4, 2, friendlyNames ).join( '\n' ), QStringLiteral( " alg_params = {\n }\n outputs[''] = processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ) );
6194+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, QgsStringMap(), 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' ), QStringLiteral( " alg_params = {\n }\n outputs[''] = processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ) );
61956195
QgsStringMap extraParams;
61966196
extraParams[QStringLiteral( "SOMETHING" )] = QStringLiteral( "SOMETHING_ELSE" );
61976197
extraParams[QStringLiteral( "SOMETHING2" )] = QStringLiteral( "SOMETHING_ELSE2" );
6198-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames ).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)" ) );
6198+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).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)" ) );
61996199
// bit of a hack -- but try to simulate an algorithm not originally available!
62006200
child.mAlgorithm.reset();
62016201
QVERIFY( !child.algorithm() );
@@ -6238,7 +6238,7 @@ void TestQgsProcessing::modelerAlgorithm()
62386238
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).at( 0 ).staticValue().toInt(), 7 );
62396239
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).at( 1 ).staticValue().toInt(), 9 );
62406240

6241-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames ).join( '\n' ), QStringLiteral( " # desc\n 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)" ) );
6241+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' ), QStringLiteral( " # desc\n 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)" ) );
62426242

62436243
QgsProcessingModelOutput testModelOut;
62446244
testModelOut.setChildId( QStringLiteral( "my_id" ) );
@@ -6274,13 +6274,14 @@ void TestQgsProcessing::modelerAlgorithm()
62746274
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output" ) );
62756275
child.modelOutput( "a" ).setDescription( QStringLiteral( "my output 2" ) );
62766276
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output 2" ) );
6277-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames ).join( '\n' ), QStringLiteral( " # desc\n 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']['']" ) );
6277+
qDebug() << child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' );
6278+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' ), QStringLiteral( " # desc\n 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']['']" ) );
62786279

62796280
// ensure friendly name is used if present
62806281
child.addParameterSources( QStringLiteral( "b" ), QgsProcessingModelChildParameterSources() << QgsProcessingModelChildParameterSource::fromChildOutput( "a", "out" ) );
6281-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames ).join( '\n' ), QStringLiteral( " # desc\n alg_params = {\n 'a': 5,\n 'b': outputs['alga']['out'],\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']['']" ) );
6282+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' ), QStringLiteral( " # desc\n alg_params = {\n 'a': 5,\n 'b': outputs['alga']['out'],\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']['']" ) );
62826283
friendlyNames.remove( "a" );
6283-
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames ).join( '\n' ), QStringLiteral( " # desc\n alg_params = {\n 'a': 5,\n 'b': outputs['a']['out'],\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']['']" ) );
6284+
QCOMPARE( child.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, extraParams, 4, 2, friendlyNames, friendlyOutputNames ).join( '\n' ), QStringLiteral( " # desc\n alg_params = {\n 'a': 5,\n 'b': outputs['a']['out'],\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']['']" ) );
62846285

62856286
// no existent
62866287
child.modelOutput( "b" ).setDescription( QStringLiteral( "my output 3" ) );
@@ -6992,6 +6993,8 @@ void TestQgsProcessing::modelExecution()
69926993
QGSCOMPARENEAR( variables.value( "SOURCE_LAYER_maxy" ).value.toDouble(), 46.8719, 0.001 );
69936994

69946995
model2.setName( QStringLiteral( "2my model" ) );
6996+
model2.childAlgorithm( "cx1" ).modelOutput( QStringLiteral( "MODEL_OUT_LAYER" ) ).setDescription( "my model output" );
6997+
model2.updateDestinationParameters();
69956998
model2.childAlgorithm( "cx1" ).setDescription( "first step in my model" );
69966999
QStringList actualParts = model2.asPythonCode( QgsProcessing::PythonQgsProcessingAlgorithmSubclass, 2 );
69977000
QgsDebugMsg( actualParts.join( '\n' ) );
@@ -7009,7 +7012,7 @@ void TestQgsProcessing::modelExecution()
70097012
" def initAlgorithm(self, config=None):\n"
70107013
" self.addParameter(QgsProcessingParameterFeatureSource('SOURCE_LAYER', '', defaultValue=None))\n"
70117014
" self.addParameter(QgsProcessingParameterNumber('DIST', '', type=QgsProcessingParameterNumber.Double, defaultValue=None))\n"
7012-
" self.addParameter(QgsProcessingParameterFeatureSink('cx1:MODEL_OUT_LAYER', '', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))\n"
7015+
" self.addParameter(QgsProcessingParameterFeatureSink('MyModelOutput', 'my model output', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))\n"
70137016
" self.addParameter(QgsProcessingParameterFeatureSink('cx3:MY_OUT', '', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))\n"
70147017
"\n"
70157018
" def processAlgorithm(self, parameters, context, model_feedback):\n"
@@ -7027,10 +7030,10 @@ void TestQgsProcessing::modelExecution()
70277030
" 'INPUT': parameters['SOURCE_LAYER'],\n"
70287031
" 'JOIN_STYLE': 2,\n"
70297032
" 'SEGMENTS': QgsExpression('@myvar*2').evaluate(),\n"
7030-
" 'OUTPUT': parameters['cx1:MODEL_OUT_LAYER']\n"
7033+
" 'OUTPUT': parameters['MyModelOutput']\n"
70317034
" }\n"
70327035
" outputs['FirstStepInMyModel'] = processing.run('native:buffer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)\n"
7033-
" results['cx1:MODEL_OUT_LAYER'] = outputs['FirstStepInMyModel']['OUTPUT']\n"
7036+
" results['MyModelOutput'] = outputs['FirstStepInMyModel']['OUTPUT']\n"
70347037
"\n"
70357038
" feedback.setCurrentStep(1)\n"
70367039
" if feedback.isCanceled():\n"

0 commit comments

Comments
 (0)
Please sign in to comment.