@@ -284,20 +284,81 @@ QString QgsProcessingModelAlgorithm::svgIconPath() const
284284 return QgsApplication::iconPath ( QStringLiteral ( " processingModel.svg" ) );
285285}
286286
287+ QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm ( const ChildAlgorithm &child, const QVariantMap &modelParameters, const QMap< QString, QVariantMap > &results ) const
288+ {
289+ QVariantMap childParams;
290+ Q_FOREACH ( const QgsProcessingParameterDefinition *def, child.algorithm ()->parameterDefinitions () )
291+ {
292+ if ( def->flags () & QgsProcessingParameterDefinition::FlagHidden )
293+ continue ;
294+
295+ if ( !def->isDestination () )
296+ {
297+ if ( !child.parameterSources ().contains ( def->name () ) )
298+ continue ; // use default value
299+
300+ ChildParameterSource paramSource = child.parameterSources ().value ( def->name () );
301+ switch ( paramSource.source () )
302+ {
303+ case ChildParameterSource::StaticValue:
304+ childParams.insert ( def->name (), paramSource.staticValue () );
305+ break ;
306+
307+ case ChildParameterSource::ModelParameter:
308+ childParams.insert ( def->name (), modelParameters.value ( paramSource.parameterName () ) );
309+ break ;
310+
311+ case ChildParameterSource::ChildOutput:
312+ {
313+ QVariantMap linkedChildResults = results.value ( paramSource.outputChildId () );
314+ childParams.insert ( def->name (), linkedChildResults.value ( paramSource.outputName () ) );
315+ break ;
316+ }
317+ }
318+ }
319+ else
320+ {
321+ // is destination linked to one of the final outputs from this model?
322+ if ( child.modelOutputs ().contains ( def->name () ) )
323+ {
324+ QString outputName = child.modelOutputs ().value ( def->name () ).outputName ();
325+ QString paramName = child.childId () + ' :' + outputName;
326+ if ( modelParameters.contains ( paramName ) )
327+ childParams.insert ( def->name (), modelParameters.value ( paramName ) );
328+ }
329+ else
330+ {
331+ // output is temporary
332+ // TODO - skip if this output is optional and not used elsewhere in the model
333+ childParams.insert ( def->name (), " memory:" );
334+
335+
336+ }
337+ }
338+ }
339+ return childParams;
340+ }
341+
287342QVariantMap QgsProcessingModelAlgorithm::processAlgorithm ( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
288343{
289344 QSet< QString > toExecute;
290345 QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms .constBegin ();
291346 for ( ; childIt != mChildAlgorithms .constEnd (); ++childIt )
292347 {
293- if ( childIt->isActive () )
348+ if ( childIt->isActive () && childIt-> algorithm () )
294349 toExecute.insert ( childIt->childId () );
295350 }
296351
297- QMap< QString, QVariantMap > resultsMap;
352+ QTime totalTime;
353+ totalTime.start ();
354+
355+ QMap< QString, QVariantMap > childResults;
356+ QVariantMap finalResults;
298357 QSet< QString > executed;
299- while ( executed.count () < toExecute.count () )
358+ bool executedAlg = true ;
359+ while ( executedAlg && executed.count () < toExecute.count () )
300360 {
361+ executedAlg = false ;
301362 Q_FOREACH ( const QString &childId, toExecute )
302363 {
303364 if ( executed.contains ( childId ) )
@@ -316,47 +377,47 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
316377 if ( !canExecute )
317378 continue ;
318379
380+ executedAlg = true ;
319381 feedback->pushDebugInfo ( QObject::tr ( " Prepare algorithm: %1" ).arg ( childId ) );
320382
321383 const ChildAlgorithm &child = mChildAlgorithms [ childId ];
322384
323- // self.prepareAlgorithm( alg )
324-
385+ QVariantMap childParams = parametersForChildAlgorithm ( child, parameters, childResults );
325386 feedback->setProgressText ( QObject::tr ( " Running %1 [%2/%3]" ).arg ( child.description () ).arg ( executed.count () + 1 ).arg ( toExecute.count () ) );
326387 // feedback->pushDebugInfo( "Parameters: " + ', '.join( [str( p ).strip() +
327388 // '=' + str( p.value ) for p in alg.algorithm.parameters] ) )
328- // t0 = time.time()
329- QVariantMap results = child.algorithm ()->run ( parameters, context, feedback );
330- resultsMap.insert ( childId, results );
331389
332- // dt = time.time() - t0
333- # if 0
390+ QTime childTime;
391+ childTime. start ();
334392
335- # copy algorithm output value(s) back to model in case the algorithm modified those
336- for out in alg.algorithm().outputs :
337- if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
338- if out.name() in alg.modelOutputs():
339- modelOut = self.getOutputFromName( self.getSafeNameForOutput( alg.childId(), out.name() ) )
340- if modelOut:
341- modelOut.value = out.value
342- #endif
393+ QVariantMap results = child.algorithm ()->run ( childParams, context, feedback );
394+ childResults.insert ( childId, results );
343395
344- executed.insert ( childId );
345- // feedback->pushDebugInfo( QObject::tr( "OK. Execution took %1 ms (%2 outputs)." ).arg( dt, len( alg.algorithm.modelOutputs() ) ) )
396+ // look through child alg's outputs to determine whether any of these should be copied
397+ // to the final model outputs
398+ QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs = child.modelOutputs ();
399+ QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin ();
400+ for ( ; outputIt != outputs.constEnd (); ++outputIt )
401+ {
402+ finalResults.insert ( childId + ' :' + outputIt->outputName (), results.value ( outputIt->outputName () ) );
403+ }
404+
405+ executed.insert ( childId );
406+ feedback->pushDebugInfo ( QObject::tr ( " OK. Execution took %1 s (%2 outputs)." ).arg ( childTime.elapsed () / 1000.0 ).arg ( results.count () ) );
346407#if 0
347- except GeoAlgorithmExecutionException as e:
348- feedback.pushDebugInfo( self.tr( 'Failed', 'ModelerAlgorithm' ) )
349- raise GeoAlgorithmExecutionException(
350- self.tr( 'Error executing algorithm {0}\n{1}', 'ModelerAlgorithm' ).format( alg.description, e.msg ) )
408+ except GeoAlgorithmExecutionException as e:
409+ feedback.pushDebugInfo( self.tr( 'Failed', 'ModelerAlgorithm' ) )
410+ raise GeoAlgorithmExecutionException(
411+ self.tr( 'Error executing algorithm {0}\n{1}', 'ModelerAlgorithm' ).format( alg.description, e.msg ) )
351412#endif
352- }
353413 }
354- feedback->pushDebugInfo ( QObject::tr ( " Model processed ok. Executed %1 algorithms total" ).arg ( executed.count () ) );
355-
356- return QVariantMap ();
357414 }
415+ feedback->pushDebugInfo ( QObject::tr ( " Model processed ok. Executed %1 algorithms total in %2 s." ).arg ( executed.count () ).arg ( totalTime.elapsed () / 1000.0 ) );
416+
417+ return finalResults;
418+ }
358419
359- void QgsProcessingModelAlgorithm::setName ( const QString &name )
420+ void QgsProcessingModelAlgorithm::setName ( const QString &name )
360421{
361422 mModelName = name;
362423}
@@ -434,7 +495,9 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
434495 {
435496 QgsProcessingOutputDefinition *output = destParam->toOutputDefinition ();
436497 if ( output )
498+ {
437499 addOutput ( output );
500+ }
438501 }
439502 }
440503 }
0 commit comments