35#include <QRegularExpression>
38#include "moc_qgsprocessingmodelalgorithm.cpp"
42QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
43 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
44 , mModelGroup( group )
45 , mModelGroupId( groupId )
48void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
57 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
58 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
69QString QgsProcessingModelAlgorithm::name()
const
74QString QgsProcessingModelAlgorithm::displayName()
const
79QString QgsProcessingModelAlgorithm::group()
const
84QString QgsProcessingModelAlgorithm::groupId()
const
89QIcon QgsProcessingModelAlgorithm::icon()
const
94QString QgsProcessingModelAlgorithm::svgIconPath()
const
99QString QgsProcessingModelAlgorithm::shortHelpString()
const
101 if ( mHelpContent.empty() )
107QString QgsProcessingModelAlgorithm::shortDescription()
const
109 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
112QString QgsProcessingModelAlgorithm::helpUrl()
const
114 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
117QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
122 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
124 QString expressionText;
125 QVariantList paramParts;
126 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
128 switch ( source.source() )
131 paramParts << source.staticValue();
135 paramParts << modelParameters.value( source.parameterName() );
140 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
141 paramParts << linkedChildResults.value( source.outputName() );
148 paramParts << exp.evaluate( &expressionContext );
149 if ( exp.hasEvalError() )
151 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
166 if ( ! expressionText.isEmpty() )
168 return expressionText;
170 else if ( paramParts.count() == 1 )
171 return paramParts.at( 0 );
177 QVariantMap childParams;
178 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
181 if ( !def->isDestination() )
183 if ( !child.parameterSources().contains( def->name() ) )
186 const QVariant value = evaluateSources( def );
187 childParams.insert( def->name(), value );
194 bool isFinalOutput =
false;
195 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
196 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
197 for ( ; outputIt != outputs.constEnd(); ++outputIt )
199 if ( outputIt->childOutputName() == destParam->
name() )
201 QString paramName = child.childId() +
':' + outputIt.key();
202 bool foundParam =
false;
206 if ( modelParameters.contains( paramName ) )
208 value = modelParameters.value( paramName );
217 if ( modelParameters.contains( modelParam->name() ) )
219 value = modelParameters.value( modelParam->name() );
227 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
232 value = QVariant::fromValue( fromVar );
235 childParams.insert( destParam->
name(), value );
237 isFinalOutput =
true;
242 bool hasExplicitDefinition =
false;
243 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
246 const QVariant value = evaluateSources( def );
247 if ( value.isValid() )
249 childParams.insert( def->name(), value );
250 hasExplicitDefinition =
true;
254 if ( !isFinalOutput && !hasExplicitDefinition )
259 bool required =
true;
262 required = childOutputIsRequired( child.childId(), destParam->
name() );
274const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
278 if ( !definition->isDestination() )
281 const QString modelChildId = definition->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
282 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
284 if ( modelChildId == childId && modelOutputName == childOutputName )
290bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
293 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
294 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
296 if ( childIt->childId() == childId || !childIt->isActive() )
300 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
301 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
302 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
304 const auto constValue = childParamIt.value();
305 for (
const QgsProcessingModelChildParameterSource &source : constValue )
308 && source.outputChildId() == childId
309 && source.outputName() == outputName )
321 QSet< QString > toExecute;
322 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
323 QSet< QString > broken;
325 const bool useSubsetOfChildren = !childSubset.empty();
326 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
328 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
330 if ( childIt->algorithm() )
331 toExecute.insert( childIt->childId() );
333 broken.insert( childIt->childId() );
337 if ( !broken.empty() )
338 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
340 QElapsedTimer totalTime;
349 QMap< QString, QgsProcessingModelChildAlgorithmResult > &contextChildResults = context.
modelResult().
childResults();
355 childInputs = config->initialChildInputs();
356 childResults = config->initialChildOutputs();
357 executed = config->previouslyExecutedChildAlgorithms();
361 if ( useSubsetOfChildren )
363 executed.subtract( childSubset );
366 QVariantMap finalResults;
368 bool executedAlg =
true;
369 int previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
370 int countExecuted = 0;
371 while ( executedAlg && countExecuted < toExecute.count() )
374 for (
const QString &childId : std::as_const( toExecute ) )
379 if ( executed.contains( childId ) )
384 bool canExecute =
true;
385 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
386 for (
const QString &dependency : dependencies )
388 if ( !executed.contains( dependency ) )
402 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
403 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
405 bool skipGenericLogging =
true;
410 skipGenericLogging =
true;
420 skipGenericLogging =
false;
424 if ( feedback && !skipGenericLogging )
425 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
429 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
433 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
434 if ( !error.isEmpty() )
437 if ( feedback && !skipGenericLogging )
438 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
443 childInputs.insert( childId, thisChildParams );
444 childResult.
setInputs( thisChildParams );
447 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
449 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
450 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
453 if ( feedback && !skipGenericLogging )
455 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
456 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
459 QElapsedTimer childTime;
462 QVariantMap outerScopeChildInputs = childInputs;
463 QVariantMap outerScopePrevChildResults = childResults;
464 QSet< QString > outerScopeExecuted = executed;
465 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
466 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
470 childResults.clear();
472 contextChildResults.clear();
477 QThread *modelThread = QThread::currentThread();
479 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
481 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
482 ok = childAlg->prepare( childParams, context, &modelFeedback );
483 context.pushToThread( modelThread );
487 if ( modelThread == qApp->thread() )
488 ok = childAlg->prepare( childParams, context, &modelFeedback );
491 context.pushToThread( qApp->thread() );
493#ifndef __clang_analyzer__
494 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
498 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
508 bool runResult =
false;
514 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
516 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
517 results = childAlg->runPrepared( childParams, context, &modelFeedback );
518 context.pushToThread( modelThread );
521 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
522 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
524 context.pushToThread( qApp->thread() );
526#ifndef __clang_analyzer__
527 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
533 results = childAlg->runPrepared( childParams, context, &modelFeedback );
544 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
547 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult]
549 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
550 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
551 context.pushToThread( modelThread );
555 if ( modelThread == qApp->thread() )
556 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
559 context.pushToThread( qApp->thread() );
561#ifndef __clang_analyzer__
562 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
566 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
568 if ( !ppRes.isEmpty() )
571 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
573 childInputs = outerScopeChildInputs;
574 childResults = outerScopePrevChildResults;
575 executed = outerScopeExecuted;
576 contextChildResults = outerScopeContextChildResult;
579 childResults.insert( childId, results );
584 if ( feedback && !skipGenericLogging )
587 QStringList formattedOutputs;
588 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
590 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
593 feedback->
pushInfo( QObject::tr(
"Results:" ) );
594 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
599 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
600 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
602 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
603 switch ( mInternalVersion )
605 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
606 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
608 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
611 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
616 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
617 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
621 if ( outputSortKey > 0 )
626 executed.insert( childId );
628 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
629 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
631 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
632 for (
const QString &targetId : toPrune )
634 if ( executed.contains( targetId ) )
637 executed.insert( targetId );
638 pruneAlgorithmBranchRecursive( targetId, branch );
648 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
656 for (
const QString &candidateId : std::as_const( toExecute ) )
658 if ( executed.contains( candidateId ) )
663 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
664 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
665 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
667 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
669 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
674 if ( !results.contains( source.outputName() ) )
679 executed.insert( candidateId );
681 pruneAlgorithmBranchRecursive( candidateId, QString() );
692 childAlg.reset(
nullptr );
694 modelFeedback.setCurrentStep( countExecuted );
695 if ( feedback && !skipGenericLogging )
697 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
702 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
703 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
707 const QString formattedException = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( error.toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
708 const QString formattedRunTime = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( QObject::tr(
"Failed after %1 s." ).arg( childTime.elapsed() / 1000.0 ).toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
710 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
711 context.modelResult().childResults().insert( childId, childResult );
717 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
718 context.modelResult().childResults().insert( childId, childResult );
726 feedback->
pushDebugInfo( QObject::tr(
"Model processed OK. Executed %n algorithm(s) total in %1 s.",
nullptr, countExecuted ).arg(
static_cast< double >( totalTime.elapsed() ) / 1000.0 ) );
728 mResults = finalResults;
729 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
730 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
734QString QgsProcessingModelAlgorithm::sourceFilePath()
const
739void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
741 mSourceFile = sourceFile;
744bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
746 if ( mSourceFile.isEmpty() )
749 const QFileInfo fi( mSourceFile );
750 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
755 QStringList fileDocString;
756 fileDocString << QStringLiteral(
"\"\"\"" );
757 fileDocString << QStringLiteral(
"Model exported as python." );
758 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
759 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
760 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
761 fileDocString << QStringLiteral(
"\"\"\"" );
762 fileDocString << QString();
765 QString indent = QString(
' ' ).repeated( indentSize );
766 QString currentIndent;
768 QMap< QString, QString> friendlyChildNames;
769 QMap< QString, QString> friendlyOutputNames;
770 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
772 const QString base = safeName( name, capitalize );
773 QString candidate = base;
776 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
779 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
784 const QString algorithmClassName = safeName( name(),
true );
786 QSet< QString > toExecute;
787 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
789 if ( childIt->isActive() && childIt->algorithm() )
791 toExecute.insert( childIt->childId() );
792 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
795 const int totalSteps = toExecute.count();
797 QStringList importLines;
798 switch ( outputType )
803 const auto params = parameterDefinitions();
804 importLines.reserve( params.count() + 6 );
805 importLines << QStringLiteral(
"from typing import Any, Optional" );
806 importLines << QString();
807 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
808 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
809 importLines << QStringLiteral(
"from qgis.core import QgsProcessingContext" );
810 importLines << QStringLiteral(
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback" );
812 bool hasAdvancedParams =
false;
816 hasAdvancedParams =
true;
819 if ( !importString.isEmpty() && !importLines.contains( importString ) )
820 importLines << importString;
823 if ( hasAdvancedParams )
824 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
826 lines << QStringLiteral(
"from qgis import processing" );
827 lines << QString() << QString();
829 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
833 lines << indent + QStringLiteral(
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):" );
834 if ( params.empty() )
836 lines << indent + indent + QStringLiteral(
"pass" );
840 lines.reserve( lines.size() + params.size() );
843 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
845 if ( defClone->isDestination() )
847 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
848 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
849 friendlyOutputNames.insert( uniqueChildName, friendlyName );
850 defClone->setName( friendlyName );
854 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
856 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
857 for (
const QString &part : parts )
859 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
866 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
867 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
868 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
872 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
878 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:" );
879 currentIndent = indent + indent;
881 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
882 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
883 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
891 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
892 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
894 QString name = paramIt.value().parameterName();
895 if ( parameterDefinition( name ) )
898 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
902 if ( !params.isEmpty() )
904 lines << QStringLiteral(
"parameters = {" );
905 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
907 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
909 lines << QStringLiteral(
"}" )
913 lines << QStringLiteral(
"context = QgsProcessingContext()" )
914 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
915 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
924 lines << currentIndent + QStringLiteral(
"results = {}" );
925 lines << currentIndent + QStringLiteral(
"outputs = {}" );
928 QSet< QString > executed;
929 bool executedAlg =
true;
931 while ( executedAlg && executed.count() < toExecute.count() )
934 const auto constToExecute = toExecute;
935 for (
const QString &childId : constToExecute )
937 if ( executed.contains( childId ) )
940 bool canExecute =
true;
941 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
942 for (
const QString &dependency : constDependsOnChildAlgorithms )
944 if ( !executed.contains( dependency ) )
956 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
963 if ( def->isDestination() )
968 bool isFinalOutput =
false;
969 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
970 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
971 for ( ; outputIt != outputs.constEnd(); ++outputIt )
973 if ( outputIt->childOutputName() == destParam->
name() )
975 QString paramName = child.childId() +
':' + outputIt.key();
976 paramName = friendlyOutputNames.value( paramName, paramName );
977 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
978 isFinalOutput =
true;
983 if ( !isFinalOutput )
988 bool required =
true;
991 required = childOutputIsRequired( child.childId(), destParam->
name() );
997 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
1003 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1005 if ( currentStep < totalSteps )
1008 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
1009 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
1010 lines << currentIndent + indent + QStringLiteral(
"return {}" );
1013 executed.insert( childId );
1017 switch ( outputType )
1020 lines << currentIndent + QStringLiteral(
"return results" );
1024 lines << indent + QStringLiteral(
"def name(self) -> str:" );
1025 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
1027 lines << indent + QStringLiteral(
"def displayName(self) -> str:" );
1028 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
1032 lines << indent + QStringLiteral(
"def group(self) -> str:" );
1033 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
1035 lines << indent + QStringLiteral(
"def groupId(self) -> str:" );
1036 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
1040 if ( !shortHelpString().isEmpty() )
1042 lines << indent + QStringLiteral(
"def shortHelpString(self) -> str:" );
1043 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
1046 if ( !helpUrl().isEmpty() )
1048 lines << indent + QStringLiteral(
"def helpUrl(self) -> str:" );
1049 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
1054 lines << indent + QStringLiteral(
"def createInstance(self):" );
1055 lines << indent + indent + QStringLiteral(
"return self.__class__()" );
1058 static QMap< QString, QString > sAdditionalImports
1060 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
1061 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
1062 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
1063 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
1064 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
1065 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
1066 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
1067 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
1068 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
1069 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
1070 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
1071 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
1072 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
1073 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
1074 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
1075 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
1076 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
1077 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
1078 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
1079 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
1082 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1084 if ( importLines.contains( it.value() ) )
1091 for (
const QString &line : std::as_const( lines ) )
1093 if ( line.contains( it.key() ) )
1101 importLines << it.value();
1105 lines = fileDocString + importLines + lines;
1114QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1116 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1118 auto safeName = [](
const QString & name )->QString
1121 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1122 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1159 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1163 QString description;
1164 switch ( source.source() )
1168 name = source.parameterName();
1169 value = modelParameters.value( source.parameterName() );
1170 description = parameterDefinition( source.parameterName() )->description();
1175 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1176 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1177 source.outputChildId() : child.description(), source.outputName() );
1180 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1181 child.description() );
1183 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1193 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1197 sources = availableSourcesForChild( childId, QStringList()
1204 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1208 QString description;
1210 switch ( source.source() )
1214 name = source.parameterName();
1215 value = modelParameters.value( source.parameterName() );
1216 description = parameterDefinition( source.parameterName() )->description();
1221 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1222 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1223 source.outputChildId() : child.description(), source.outputName() );
1224 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1227 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1228 child.description() );
1241 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1244 value = fromVar.
sink;
1245 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1253 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1258 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1259 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1260 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1261 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1262 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1265 sources = availableSourcesForChild( childId, QStringList()
1267 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1271 QString description;
1273 switch ( source.source() )
1277 name = source.parameterName();
1278 value = modelParameters.value( source.parameterName() );
1279 description = parameterDefinition( source.parameterName() )->description();
1284 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1285 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1286 source.outputChildId() : child.description(), source.outputName() );
1287 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1290 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1291 child.description() );
1305 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1310 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1313 value = fromVar.
sink;
1314 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1319 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1321 featureSource = layer;
1323 if ( context && !featureSource )
1329 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1330 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1331 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1332 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1333 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1339QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1341 auto scope = std::make_unique<QgsExpressionContextScope>( QStringLiteral(
"algorithm_inputs" ) );
1342 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1343 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1344 for ( ; varIt != variables.constEnd(); ++varIt )
1348 return scope.release();
1351QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1355 return QgsProcessingModelChildParameterSources();
1359QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1361 QgsProcessingModelChildParameterSources sources;
1364 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1365 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1371 if ( parameterTypes.contains( def->
type() ) )
1373 if ( !dataTypes.isEmpty() )
1389 bool ok = sourceDef->
dataTypes().isEmpty();
1390 const auto constDataTypes = sourceDef->
dataTypes();
1391 for (
int type : constDataTypes )
1406 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1410 QSet< QString > dependents;
1411 if ( !childId.isEmpty() )
1413 dependents = dependentChildAlgorithms( childId );
1414 dependents << childId;
1417 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1418 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1420 if ( dependents.contains( childIt->childId() ) )
1430 if ( outputTypes.contains( out->type() ) )
1432 if ( !dataTypes.isEmpty() )
1438 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1445 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1453QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1455 return mHelpContent;
1458void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1460 mHelpContent = helpContent;
1463void QgsProcessingModelAlgorithm::setName(
const QString &name )
1468void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1470 mModelGroup = group;
1473bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1478 if ( mChildAlgorithms.empty() )
1481 issues << QObject::tr(
"Model does not contain any algorithms" );
1484 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1486 QStringList childIssues;
1487 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1489 for (
const QString &issue : std::as_const( childIssues ) )
1491 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1497QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1499 return mChildAlgorithms;
1502void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1504 mParameterComponents = parameterComponents;
1507void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1509 mParameterComponents.insert( component.parameterName(), component );
1512QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1514 if ( !mParameterComponents.contains( name ) )
1516 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1517 component.setParameterName( name );
1520 return mParameterComponents[ name ];
1523QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1525 QList< QgsProcessingModelParameter > res;
1526 QSet< QString > found;
1527 for (
const QString ¶meter : mParameterOrder )
1529 if ( mParameterComponents.contains( parameter ) )
1531 res << mParameterComponents.value( parameter );
1537 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1539 if ( !found.contains( it.key() ) )
1547void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1549 mParameterOrder = order;
1552QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1554 QList< QgsProcessingModelOutput > res;
1555 QSet< QString > found;
1557 for (
const QString &output : mOutputOrder )
1559 bool foundOutput =
false;
1560 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1562 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1563 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1565 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1567 res << outputIt.value();
1569 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1578 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1580 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1581 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1583 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1585 res << outputIt.value();
1593void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1595 mOutputOrder = order;
1598QString QgsProcessingModelAlgorithm::outputGroup()
const
1600 return mOutputGroup;
1603void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1605 mOutputGroup = group;
1608void QgsProcessingModelAlgorithm::updateDestinationParameters()
1611 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1612 while ( it.hasNext() )
1622 qDeleteAll( mOutputs );
1626 QSet< QString > usedFriendlyNames;
1627 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1629 const QString base = safeName( name,
false );
1630 QString candidate = base;
1632 while ( usedFriendlyNames.contains( candidate ) )
1635 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1637 usedFriendlyNames.insert( candidate );
1641 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1642 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1644 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1645 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1646 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1648 if ( !childIt->isActive() || !childIt->algorithm() )
1656 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1660 if ( outputIt->isMandatory() )
1662 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1664 QString friendlyName = uniqueSafeName( outputIt->description() );
1665 param->
setName( friendlyName );
1669 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1672 param->
metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1673 param->
metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1674 param->
metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1680 if ( addParameter( param.release() ) && newDestParam )
1687 newDestParam->mOriginalProvider = provider;
1694void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1696 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1699QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1701 return mGroupBoxes.values();
1704void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1706 mGroupBoxes.remove( uuid );
1709QVariant QgsProcessingModelAlgorithm::toVariant()
const
1712 map.insert( QStringLiteral(
"model_name" ), mModelName );
1713 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1714 map.insert( QStringLiteral(
"help" ), mHelpContent );
1715 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1717 QVariantMap childMap;
1718 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1719 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1721 childMap.insert( childIt.key(), childIt.value().toVariant() );
1723 map.insert( QStringLiteral(
"children" ), childMap );
1725 QVariantMap paramMap;
1726 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1727 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1729 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1731 map.insert( QStringLiteral(
"parameters" ), paramMap );
1733 QVariantMap paramDefMap;
1738 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1740 QVariantList groupBoxDefs;
1741 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1743 groupBoxDefs.append( it.value().toVariant() );
1745 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1747 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1749 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1751 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1752 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1753 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1758bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1760 QVariantMap map = model.toMap();
1762 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1763 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1764 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1765 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1767 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1769 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1770 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1772 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1773 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1774 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1776 mChildAlgorithms.clear();
1777 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1778 QVariantMap::const_iterator childIt = childMap.constBegin();
1779 for ( ; childIt != childMap.constEnd(); ++childIt )
1781 QgsProcessingModelChildAlgorithm child;
1785 if ( !child.loadVariant( childIt.value() ) )
1788 mChildAlgorithms.insert( child.childId(), child );
1791 mParameterComponents.clear();
1792 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1793 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1794 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1796 QgsProcessingModelParameter param;
1797 if ( !param.loadVariant( paramIt.value().toMap() ) )
1800 mParameterComponents.insert( param.parameterName(), param );
1803 qDeleteAll( mParameters );
1804 mParameters.clear();
1805 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1807 auto addParam = [
this](
const QVariant & value )
1815 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1819 param->setHelp( mHelpContent.value( param->name() ).toString() );
1822 addParameter( param.release() );
1826 QVariantMap map = value.toMap();
1827 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1828 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1830 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1834 QSet< QString > loadedParams;
1836 for (
const QString &name : std::as_const( mParameterOrder ) )
1838 if ( paramDefMap.contains( name ) )
1840 addParam( paramDefMap.value( name ) );
1841 loadedParams << name;
1845 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1846 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1848 if ( !loadedParams.contains( paramDefIt.key() ) )
1849 addParam( paramDefIt.value() );
1852 mGroupBoxes.clear();
1853 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1854 for (
const QVariant &groupBoxDef : groupBoxList )
1856 QgsProcessingModelGroupBox groupBox;
1857 groupBox.loadVariant( groupBoxDef.toMap() );
1858 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1861 updateDestinationParameters();
1866bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1871 return ( acceptableDataTypes.empty()
1872 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1883void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1885 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1886 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1888 if ( !childIt->algorithm() )
1889 childIt->reattach();
1893bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1895 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1897 doc.appendChild( elem );
1900 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1902 QTextStream stream( &file );
1903 doc.save( stream, 2 );
1910bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1915 if ( file.open( QFile::ReadOnly ) )
1917 if ( !doc.setContent( &file ) )
1928 return loadVariant( props );
1931void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1933 mChildAlgorithms = childAlgorithms;
1934 updateDestinationParameters();
1937void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1940 updateDestinationParameters();
1943QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1945 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1949 updateDestinationParameters();
1953QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1955 return mChildAlgorithms[ childId ];
1958bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1960 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1963 mChildAlgorithms.remove(
id );
1964 updateDestinationParameters();
1968void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1970 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1971 for (
const QString &child : constDependentChildAlgorithms )
1973 childAlgorithm( child ).setActive(
false );
1975 childAlgorithm(
id ).setActive(
false );
1976 updateDestinationParameters();
1979bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1981 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1982 for (
const QString &child : constDependsOnChildAlgorithms )
1984 if ( !childAlgorithm( child ).isActive() )
1987 childAlgorithm(
id ).setActive(
true );
1988 updateDestinationParameters();
1994 if ( addParameter( definition ) )
1995 mParameterComponents.insert( definition->
name(), component );
2000 removeParameter( definition->
name() );
2001 addParameter( definition );
2004void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2006 removeParameter( name );
2007 mParameterComponents.remove( name );
2010void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2015 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
2018 expression.prepare( &expressionContext );
2019 QSet<QString> variables = expression.referencedVariables();
2020 if ( variables.contains( oldName ) )
2022 QString newExpression = expressionString;
2023 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
2024 return {
true, newExpression };
2026 return {
false, QString() };
2029 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2030 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2032 bool changed =
false;
2033 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2034 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2035 for ( ; paramIt != childParams.end(); ++paramIt )
2037 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2038 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2040 switch ( valueIt->source() )
2044 if ( valueIt->parameterName() == oldName )
2046 valueIt->setParameterName( newName );
2054 bool updatedExpression =
false;
2055 QString newExpression;
2056 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2057 if ( updatedExpression )
2059 valueIt->setExpression( newExpression );
2067 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2072 bool updatedExpression =
false;
2073 QString newExpression;
2074 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2075 if ( updatedExpression )
2077 property.setExpressionString( newExpression );
2078 valueIt->setStaticValue( property );
2094 childIt->setParameterSources( childParams );
2098bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2100 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2101 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2104 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2105 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2106 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2108 const auto constValue = paramIt.value();
2109 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2112 && source.parameterName() == name )
2122bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2124 const auto constMParameters = mParameters;
2127 if ( def->
name() == name )
2136QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2138 return mParameterComponents;
2141void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2143 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2144 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2146 if ( depends.contains( childIt->childId() ) )
2150 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2151 bool hasDependency =
false;
2152 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2154 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2156 hasDependency =
true;
2161 if ( hasDependency )
2163 depends.insert( childIt->childId() );
2164 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2169 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2170 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2171 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2173 const auto constValue = paramIt.value();
2174 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2177 && source.outputChildId() == childId )
2179 depends.insert( childIt->childId() );
2180 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2188QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2190 QSet< QString > algs;
2194 algs.insert( childId );
2196 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2199 algs.remove( childId );
2205void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2207 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2210 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2211 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2213 if ( !depends.contains( val.childId ) )
2215 depends.insert( val.childId );
2216 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2221 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2222 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2223 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2225 const auto constValue = paramIt.value();
2226 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2228 switch ( source.source() )
2231 if ( !depends.contains( source.outputChildId() ) )
2233 depends.insert( source.outputChildId() );
2234 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2241 const QSet<QString> vars = exp.referencedVariables();
2246 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2247 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2253 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2257 depends.insert( childVarIt->source.outputChildId() );
2258 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2273QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2275 QSet< QString > algs;
2279 algs.insert( childId );
2281 dependsOnChildAlgorithmsRecursive( childId, algs );
2284 algs.remove( childId );
2289QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2291 QSet< QString > dependent;
2292 if ( !childId.isEmpty() )
2294 dependent.unite( dependentChildAlgorithms( childId ) );
2295 dependent.insert( childId );
2298 QList<QgsProcessingModelChildDependency> res;
2299 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2301 if ( !dependent.contains( it->childId() ) )
2304 bool hasBranches =
false;
2305 if ( it->algorithm() )
2313 QgsProcessingModelChildDependency alg;
2314 alg.childId = it->childId();
2315 alg.conditionalBranch = def->
name();
2323 QgsProcessingModelChildDependency alg;
2324 alg.childId = it->childId();
2332bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2335 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2336 if ( childIt != mChildAlgorithms.constEnd() )
2338 if ( !childIt->algorithm() )
2340 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2349 if ( childIt->parameterSources().contains( def->
name() ) )
2352 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2353 for (
const QgsProcessingModelChildParameterSource &source : sources )
2355 switch ( source.source() )
2361 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2366 if ( !parameterComponents().contains( source.parameterName() ) )
2369 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2374 if ( !childAlgorithms().contains( source.outputChildId() ) )
2377 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2399 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2408 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2413bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2415 reattachAlgorithms();
2416 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2417 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2419 if ( !childIt->algorithm() )
2423 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2431QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2433 if ( mSourceFile.isEmpty() )
2448 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2449 alg->loadVariant( toVariant() );
2450 alg->setProvider( provider() );
2451 alg->setSourceFilePath( sourceFilePath() );
2455QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2457 QString n = name.toLower().trimmed();
2458 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2459 n.replace( rx, QString() );
2460 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2461 n.replace( rx2, QString() );
2463 n = n.replace(
' ',
'_' );
2467QVariantMap QgsProcessingModelAlgorithm::variables()
const
2472void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2474 mVariables = variables;
2477QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2479 return mDesignerParameterValues;
ProcessingSourceType
Processing data source types.
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ MapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer).
@ VectorAnyGeometry
Any vector layer with geometry.
@ VectorPoint
Vector point layers.
@ VectorPolygon
Vector polygon layers.
@ VectorLine
Vector line layers.
@ Success
Child was successfully executed.
@ Failed
Child encountered an error while executing.
@ Expression
Expression based property.
@ UpperCamelCase
Convert the string to upper camel case. Note that this method does not unaccent characters.
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
@ ExpressionText
Parameter value is taken from a text with expressions, evaluated just before the algorithm runs.
@ ModelOutput
Parameter value is linked to an output parameter for the model.
@ ChildOutput
Parameter value is taken from an output generated by a child algorithm.
@ ModelParameter
Parameter value is taken from a parent model parameter.
@ StaticValue
Parameter value is a static value.
@ Expression
Parameter value is taken from an expression, evaluated just before the algorithm runs.
@ SkipGenericModelLogging
When running as part of a model, the generic algorithm setup and results logging should be skipped.
@ CustomException
Algorithm raises custom exception notices, don't use the standard ones.
@ NoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
@ SecurityRisk
The algorithm represents a potential security risk if executed with untrusted inputs.
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Optional
Parameter is optional.
@ DefaultLevel
Default logging level.
@ Verbose
Verbose logging.
@ ModelDebug
Model debug level logging. Includes verbose logging and other outputs useful for debugging models.
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * processingModelAlgorithmScope(const QgsProcessingModelAlgorithm *model, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing model algorithm,...
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm,...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
An interface for objects which provide features via a getFeatures method.
virtual QgsRectangle sourceExtent() const
Returns the extent of all geometries from the source.
bool isCanceled() const
Tells whether the operation has been canceled already.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Abstract base class for processing algorithms.
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
virtual Qgis::ProcessingAlgorithmFlags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
virtual QgsExpressionContext createExpressionContext(const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeatureSource *source=nullptr) const
Creates an expression context relating to the algorithm.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &name) const
Returns a matching parameter by name.
virtual QString asPythonCommand(const QVariantMap ¶meters, QgsProcessingContext &context) const
Returns a Python command string which can be executed to run the algorithm using the specified parame...
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
Details for layers to load into projects.
int layerSortKey
Optional sorting key for sorting output layers when loading them into a project.
QString groupName
Optional name for a layer tree group under which to place the layer when loading it into a project.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QgsProcessingModelResult modelResult() const
Returns the model results, populated when the context is used to run a model algorithm.
QgsProcessingModelInitialRunConfig * modelInitialRunConfig()
Returns a reference to the model initial run configuration, used to run a model algorithm.
Qgis::ProcessingLogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
void setModelInitialRunConfig(std::unique_ptr< QgsProcessingModelInitialRunConfig > config)
Sets the model initial run configuration, used to run a model algorithm.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString generateTemporaryDestination(const QgsProcessingContext *context=nullptr) const
Generates a temporary destination value for this parameter.
void setSupportsNonFileBasedOutput(bool supportsNonFileBasedOutput)
Sets whether the destination parameter supports non filed-based outputs, such as memory layers or dir...
Custom exception class for processing related exceptions.
Encapsulates settings relating to a feature source input to a processing algorithm.
QgsProperty source
Source definition.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
Encapsulates the results of running a child algorithm within a model.
void setOutputs(const QVariantMap &outputs)
Sets the outputs generated by child algorithm.
void setExecutionStatus(Qgis::ProcessingModelChildAlgorithmExecutionStatus status)
Sets the status of executing the child algorithm.
void setInputs(const QVariantMap &inputs)
Sets the inputs used for the child algorithm.
void setHtmlLog(const QString &log)
Sets the HTML formatted contents of logged messages which occurred while running the child.
Configuration settings which control how a Processing model is executed.
QSet< QString > childAlgorithmSubset() const
Returns the subset of child algorithms to run (by child ID).
QVariantMap & rawChildOutputs()
Returns a reference to the map of raw child algorithm outputs.
QVariantMap & rawChildInputs()
Returns a reference to the map of raw child algorithm inputs.
QSet< QString > & executedChildIds()
Returns a reference to the set of child algorithm IDs which were executed during the model execution.
QMap< QString, QgsProcessingModelChildAlgorithmResult > childResults() const
Returns the map of child algorithm results.
Processing feedback object for multi-step operations.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
Base class for the definition of processing outputs.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
QgsProperty sink
Sink/layer definition.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
A vector layer output for processing algorithms.
Qgis::ProcessingSourceType dataType() const
Returns the layer type for the output layer.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Base class for the definition of processing parameters.
void setDefaultValue(const QVariant &value)
Sets the default value for the parameter.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
void setFlags(Qgis::ProcessingParameterFlags flags)
Sets the flags associated with the parameter.
QVariantMap metadata() const
Returns the parameter's freeform metadata.
virtual bool isDestination() const
Returns true if this parameter represents a file or layer destination, e.g.
void setDescription(const QString &description)
Sets the description for the parameter.
void setName(const QString &name)
Sets the name of the parameter.
virtual QgsProcessingParameterDefinition * clone() const =0
Creates a clone of the parameter definition.
virtual QString type() const =0
Unique parameter type name.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QString name() const
Returns the name of the parameter.
virtual QStringList dependsOnOtherParameters() const
Returns a list of other parameter names on which this parameter is dependent (e.g.
Qgis::ProcessingParameterFlags flags() const
Returns any flags associated with the parameter.
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
A vector layer or feature source field parameter for processing algorithms.
Qgis::ProcessingFieldParameterDataType dataType() const
Returns the acceptable data type for the field.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Can be inherited by parameters which require limits to their acceptable data types.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Makes metadata of processing parameters available.
virtual QStringList acceptedOutputTypes() const =0
Returns a list of compatible Processing output types for inputs for this parameter type.
virtual QList< int > acceptedDataTypes(const QgsProcessingParameterDefinition *parameter) const
Returns a list of compatible Processing data types for inputs for this parameter type for the specifi...
virtual QStringList acceptedParameterTypes() const =0
Returns a list of compatible Processing parameter types for inputs for this parameter type.
virtual QString pythonImportString() const
Returns a valid Python import string for importing the corresponding parameter type,...
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map.
Abstract base class for processing providers.
const QgsProcessingAlgorithm * algorithm(const QString &name) const
Returns the matching algorithm by name, or nullptr if no matching algorithm is contained by this prov...
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
static QString formatHelpMapAsHtml(const QVariantMap &map, const QgsProcessingAlgorithm *algorithm)
Returns a HTML formatted version of the help text encoded in a variant map for a specified algorithm.
@ Vector
Vector layer type.
static QString variantToPythonLiteral(const QVariant &value)
Converts a variant to a Python literal.
static QVariantMap removePointerValuesFromMap(const QVariantMap &map)
Removes any raw pointer values from an input map, replacing them with appropriate string values where...
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers=true, QgsProcessingUtils::LayerHint typeHint=QgsProcessingUtils::LayerHint::UnknownType, QgsProcessing::LayerOptionsFlags flags=QgsProcessing::LayerOptionsFlags())
Interprets a string as a map layer within the supplied context.
PythonOutputType
Available Python output types.
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
A store for object properties.
QVariant staticValue() const
Returns the current static value for the property.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
Represents a vector layer which manages a vector based dataset.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
QString qgsSetJoin(const QSet< T > &set, const QString &separator)
Joins all the set values into a single string with each element separated by the given separator.
QMap< QString, QString > QgsStringMap
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefinitions
List of processing parameters.
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.
Single variable definition for use within a QgsExpressionContextScope.