37#include <QRegularExpression>
41#include "moc_qgsprocessingmodelalgorithm.cpp"
43using namespace Qt::StringLiterals;
47QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
48 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
49 , mModelGroup( group )
50 , mModelGroupId( groupId )
53void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
61 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
62 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
73QString QgsProcessingModelAlgorithm::name()
const
78QString QgsProcessingModelAlgorithm::displayName()
const
83QString QgsProcessingModelAlgorithm::group()
const
88QString QgsProcessingModelAlgorithm::groupId()
const
93QIcon QgsProcessingModelAlgorithm::icon()
const
98QString QgsProcessingModelAlgorithm::svgIconPath()
const
103QString QgsProcessingModelAlgorithm::shortHelpString()
const
105 if ( mHelpContent.empty() )
111QString QgsProcessingModelAlgorithm::shortDescription()
const
113 return mHelpContent.value( u
"SHORT_DESCRIPTION"_s ).toString();
116QString QgsProcessingModelAlgorithm::helpUrl()
const
118 return mHelpContent.value( u
"HELP_URL"_s ).toString();
121QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
122 const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context
127 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
129 QString expressionText;
130 QVariantList paramParts;
131 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
133 switch ( source.source() )
136 paramParts << source.staticValue();
140 paramParts << modelParameters.value( source.parameterName() );
145 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
146 paramParts << linkedChildResults.value( source.outputName() );
153 paramParts << exp.evaluate( &expressionContext );
154 if ( exp.hasEvalError() )
156 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
173 if ( !expressionText.isEmpty() )
175 return expressionText;
177 else if ( paramParts.count() == 1 )
178 return paramParts.at( 0 );
184 QVariantMap childParams;
185 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
188 if ( !def->isDestination() )
190 if ( !child.parameterSources().contains( def->name() ) )
193 const QVariant value = evaluateSources( def );
194 childParams.insert( def->name(), value );
201 bool isFinalOutput =
false;
202 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
203 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
204 for ( ; outputIt != outputs.constEnd(); ++outputIt )
206 if ( outputIt->childOutputName() == destParam->
name() )
208 QString paramName = child.childId() +
':' + outputIt.key();
209 bool foundParam =
false;
213 if ( modelParameters.contains( paramName ) )
215 value = modelParameters.value( paramName );
224 if ( modelParameters.contains( modelParam->name() ) )
226 value = modelParameters.value( modelParam->name() );
234 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
239 value = QVariant::fromValue( fromVar );
242 childParams.insert( destParam->
name(), value );
244 isFinalOutput =
true;
249 bool hasExplicitDefinition =
false;
250 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
253 const QVariant value = evaluateSources( def );
254 if ( value.isValid() )
256 childParams.insert( def->name(), value );
257 hasExplicitDefinition =
true;
261 if ( !isFinalOutput && !hasExplicitDefinition )
266 bool required =
true;
269 required = childOutputIsRequired( child.childId(), destParam->
name() );
281const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
285 if ( !definition->isDestination() )
288 const QString modelChildId = definition->metadata().value( u
"_modelChildId"_s ).toString();
289 const QString modelOutputName = definition->metadata().value( u
"_modelChildOutputName"_s ).toString();
291 if ( modelChildId == childId && modelOutputName == childOutputName )
297bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
300 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
301 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
303 if ( childIt->childId() == childId || !childIt->isActive() )
307 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
308 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
309 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
311 const auto constValue = childParamIt.value();
312 for (
const QgsProcessingModelChildParameterSource &source : constValue )
330 QSet< QString > toExecute;
331 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
332 QSet< QString > broken;
334 const bool useSubsetOfChildren = !childSubset.empty();
335 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
337 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
339 if ( childIt->algorithm() )
340 toExecute.insert( childIt->childId() );
342 broken.insert( childIt->childId() );
346 if ( !broken.empty() )
353 QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken,
", "_L1 ) )
357 QElapsedTimer totalTime;
366 QMap< QString, QgsProcessingModelChildAlgorithmResult > &contextChildResults = context.
modelResult().
childResults();
372 childInputs = config->initialChildInputs();
373 childResults = config->initialChildOutputs();
374 executed = config->previouslyExecutedChildAlgorithms();
378 if ( useSubsetOfChildren )
380 executed.subtract( childSubset );
383 QVariantMap finalResults;
385 bool executedAlg =
true;
386 int previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
387 int countExecuted = 0;
388 while ( executedAlg && countExecuted < toExecute.count() )
391 for (
const QString &childId : std::as_const( toExecute ) )
396 if ( executed.contains( childId ) )
401 bool canExecute =
true;
402 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
403 for (
const QString &dependency : dependencies )
405 if ( !executed.contains( dependency ) )
419 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
420 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
422 bool skipGenericLogging =
true;
427 skipGenericLogging =
true;
437 skipGenericLogging =
false;
441 childAlgorithmFeedback.resetFeatureSinkCounts();
443 if ( feedback && !skipGenericLogging )
445 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
455 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults ).release();
459 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
460 if ( !error.isEmpty() )
469 if ( feedback && !skipGenericLogging )
470 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
475 childInputs.insert( childId, thisChildParams );
476 childResult.
setInputs( thisChildParams );
479 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
481 params << u
"%1: %2"_s.arg( childParamIt.key(), child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
484 if ( feedback && !skipGenericLogging )
486 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
487 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
490 QElapsedTimer childTime;
493 QVariantMap outerScopeChildInputs = childInputs;
494 QVariantMap outerScopePrevChildResults = childResults;
495 QSet< QString > outerScopeExecuted = executed;
496 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
497 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
501 childResults.clear();
503 contextChildResults.clear();
508 QThread *modelThread = QThread::currentThread();
510 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &childAlgorithmFeedback] {
511 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
512 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
513 context.pushToThread( modelThread );
517 if ( modelThread == qApp->thread() )
518 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
521 context.pushToThread( qApp->thread() );
523#ifndef __clang_analyzer__
524 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
528 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
547 bool runResult =
false;
557 childProgressConnection = QObject::connect( &childAlgorithmFeedback, &
QgsFeedback::progressChanged, &childAlgorithmFeedback, [&modelFeedback, &childId](
double progress ) {
560 childSinkCountChangedConnection
565 childSourceLoadedConnection = QObject::connect( feedback, &
QgsProcessingFeedback::sourceLoaded, feedback, [&modelFeedback, &childId](
const QString ¶meterName,
long long featureCount ) {
573 bool exceptionFromMainThread =
false;
574 auto runOnMainThread = [modelThread, &context, &childAlgorithmFeedback, &results, &childAlg, &childParams, &exceptionFromMainThread, &child, &error, &childResult] {
575 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
578 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
584 exceptionFromMainThread =
true;
586 context.pushToThread( modelThread );
589 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
590 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
592 context.pushToThread( qApp->thread() );
594#ifndef __clang_analyzer__
595 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
597 if ( !exceptionFromMainThread )
606 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
617 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
620 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &childAlgorithmFeedback, runResult] {
621 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
622 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
623 context.pushToThread( modelThread );
627 if ( modelThread == qApp->thread() )
628 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
631 context.pushToThread( qApp->thread() );
633#ifndef __clang_analyzer__
634 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
638 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
640 if ( !ppRes.isEmpty() )
643 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
645 childInputs = outerScopeChildInputs;
646 childResults = outerScopePrevChildResults;
647 executed = outerScopeExecuted;
648 contextChildResults = outerScopeContextChildResult;
651 childResults.insert( childId, results );
667 if ( feedback && !skipGenericLogging )
670 QStringList formattedOutputs;
671 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
676 feedback->
pushInfo( QObject::tr(
"Results:" ) );
677 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
682 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
683 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
685 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
686 switch ( mInternalVersion )
688 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
689 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
691 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
694 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
699 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
700 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
704 if ( outputSortKey > 0 )
709 executed.insert( childId );
711 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
712 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
713 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
714 for (
const QString &targetId : toPrune )
716 if ( executed.contains( targetId ) )
719 executed.insert( targetId );
724 pruneAlgorithmBranchRecursive( targetId, branch );
734 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
742 for (
const QString &candidateId : std::as_const( toExecute ) )
744 if ( executed.contains( candidateId ) )
749 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
750 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
751 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
753 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
755 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
760 if ( !results.contains( source.outputName() ) )
765 executed.insert( candidateId );
771 pruneAlgorithmBranchRecursive( candidateId, QString() );
782 childAlg.reset(
nullptr );
784 childAlgorithmFeedback.setCurrentStep( countExecuted );
785 if ( feedback && !skipGenericLogging )
787 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
792 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
793 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
797 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
798 const QString formattedRunTime
799 = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( QObject::tr(
"Failed after %1 s." ).arg( childTime.elapsed() / 1000.0 ).toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
801 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
802 context.modelResult().childResults().insert( childId, childResult );
813 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
814 context.modelResult().childResults().insert( childId, childResult );
827 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 ) );
829 mResults = finalResults;
830 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
831 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
835QString QgsProcessingModelAlgorithm::sourceFilePath()
const
840void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
842 mSourceFile = sourceFile;
845bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
847 if ( mSourceFile.isEmpty() )
850 const QFileInfo fi( mSourceFile );
851 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
856 QStringList fileDocString;
857 fileDocString << u
"\"\"\""_s;
858 fileDocString << u
"Model exported as python."_s;
859 fileDocString << u
"Name : %1"_s.arg( displayName() );
860 fileDocString << u
"Group : %1"_s.arg( group() );
862 fileDocString << u
"\"\"\""_s;
863 fileDocString << QString();
866 QString indent = QString(
' ' ).repeated( indentSize );
867 QString currentIndent;
869 QMap< QString, QString> friendlyChildNames;
870 QMap< QString, QString> friendlyOutputNames;
871 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
872 const QString base = safeName( name, capitalize );
873 QString candidate = base;
876 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
879 candidate = u
"%1_%2"_s.arg( base ).arg( i );
884 const QString algorithmClassName = safeName( name(),
true );
886 QSet< QString > toExecute;
887 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
889 if ( childIt->isActive() && childIt->algorithm() )
891 toExecute.insert( childIt->childId() );
892 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
895 const int totalSteps = toExecute.count();
897 QStringList importLines;
898 switch ( outputType )
903 const auto params = parameterDefinitions();
904 importLines.reserve( params.count() + 6 );
905 importLines << u
"from typing import Any, Optional"_s;
906 importLines << QString();
907 importLines << u
"from qgis.core import QgsProcessing"_s;
908 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
909 importLines << u
"from qgis.core import QgsProcessingContext"_s;
910 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
912 bool hasAdvancedParams =
false;
916 hasAdvancedParams =
true;
920 const QString importString = type->pythonImportString();
921 if ( !importString.isEmpty() && !importLines.contains( importString ) )
922 importLines << importString;
926 if ( hasAdvancedParams )
927 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
929 lines << u
"from qgis import processing"_s;
930 lines << QString() << QString();
932 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
936 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
937 if ( params.empty() )
939 lines << indent + indent + u
"pass"_s;
943 lines.reserve( lines.size() + params.size() );
946 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
948 if ( defClone->isDestination() )
950 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
951 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
952 friendlyOutputNames.insert( uniqueChildName, friendlyName );
953 defClone->setName( friendlyName );
957 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
959 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
960 for (
const QString &part : parts )
962 lines << indent + indent + u
"# %1"_s.arg( part );
969 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
970 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
971 lines << indent + indent + u
"self.addParameter(param)"_s;
975 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
981 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
982 currentIndent = indent + indent;
984 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
985 lines << currentIndent + u
"# overall progress through the model"_s;
986 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
994 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
995 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
997 QString name = paramIt.value().parameterName();
998 if ( parameterDefinition( name ) )
1001 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
1005 if ( !params.isEmpty() )
1007 lines << u
"parameters = {"_s;
1008 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
1010 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
1016 lines << u
"context = QgsProcessingContext()"_s
1017 << u
"context.setProject(QgsProject.instance())"_s
1018 << u
"feedback = QgsProcessingFeedback()"_s
1026 lines << currentIndent + u
"results = {}"_s;
1027 lines << currentIndent + u
"outputs = {}"_s;
1030 QSet< QString > executed;
1031 bool executedAlg =
true;
1032 int currentStep = 0;
1033 while ( executedAlg && executed.count() < toExecute.count() )
1035 executedAlg =
false;
1036 const auto constToExecute = toExecute;
1037 for (
const QString &childId : constToExecute )
1039 if ( executed.contains( childId ) )
1042 bool canExecute =
true;
1043 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
1044 for (
const QString &dependency : constDependsOnChildAlgorithms )
1046 if ( !executed.contains( dependency ) )
1058 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
1065 if ( def->isDestination() )
1070 bool isFinalOutput =
false;
1071 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
1072 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1073 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1075 if ( outputIt->childOutputName() == destParam->
name() )
1077 QString paramName = child.childId() +
':' + outputIt.key();
1078 paramName = friendlyOutputNames.value( paramName, paramName );
1079 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
1080 isFinalOutput =
true;
1085 if ( !isFinalOutput )
1090 bool required =
true;
1093 required = childOutputIsRequired( child.childId(), destParam->
name() );
1099 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1105 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1107 if ( currentStep < totalSteps )
1110 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1111 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1112 lines << currentIndent + indent + u
"return {}"_s;
1115 executed.insert( childId );
1119 switch ( outputType )
1122 lines << currentIndent + u
"return results"_s;
1126 lines << indent + u
"def name(self) -> str:"_s;
1127 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1129 lines << indent + u
"def displayName(self) -> str:"_s;
1130 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1134 lines << indent + u
"def group(self) -> str:"_s;
1135 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1137 lines << indent + u
"def groupId(self) -> str:"_s;
1138 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1142 if ( !shortHelpString().isEmpty() )
1144 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1145 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1148 if ( !helpUrl().isEmpty() )
1150 lines << indent + u
"def helpUrl(self) -> str:"_s;
1151 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1156 lines << indent + u
"def createInstance(self):"_s;
1157 lines << indent + indent + u
"return self.__class__()"_s;
1160 static QMap< QString, QString > sAdditionalImports {
1161 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1162 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1163 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1164 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1165 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1166 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1167 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1168 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1169 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1170 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1171 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1172 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1173 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1174 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1175 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1176 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1177 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1178 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1179 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1180 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1183 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1185 if ( importLines.contains( it.value() ) )
1192 for (
const QString &line : std::as_const( lines ) )
1194 if ( line.contains( it.key() ) )
1202 importLines << it.value();
1206 lines = fileDocString + importLines + lines;
1215QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1216 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1219 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1221 auto safeName = [](
const QString &name ) -> QString {
1223 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1224 return s.replace( safeNameRe, u
"_"_s );
1228 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1262 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1266 QString description;
1267 switch ( source.source() )
1271 name = source.parameterName();
1272 value = modelParameters.value( source.parameterName() );
1273 description = parameterDefinition( source.parameterName() )->description();
1278 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1279 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1282 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1284 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1294 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1298 sources = availableSourcesForChild(
1304 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1308 QString description;
1310 switch ( source.source() )
1314 name = source.parameterName();
1315 value = modelParameters.value( source.parameterName() );
1316 description = parameterDefinition( source.parameterName() )->description();
1321 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1322 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1323 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1326 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1338 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1341 value = fromVar.
sink;
1342 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1350 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1355 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1356 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1357 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1358 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1359 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1363 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1367 QString description;
1369 switch ( source.source() )
1373 name = source.parameterName();
1374 value = modelParameters.value( source.parameterName() );
1375 description = parameterDefinition( source.parameterName() )->description();
1380 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1381 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1382 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1385 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1398 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1403 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1406 value = fromVar.
sink;
1407 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1412 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1414 featureSource = layer;
1416 if ( context && !featureSource )
1422 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1423 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1424 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1425 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1426 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1432std::unique_ptr<QgsExpressionContextScope> QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
1433 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1436 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1437 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1438 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1439 for ( ; varIt != variables.constEnd(); ++varIt )
1446QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1450 return QgsProcessingModelChildParameterSources();
1454QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1455 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1458 QgsProcessingModelChildParameterSources sources;
1461 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1462 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1468 if ( parameterTypes.contains( def->
type() ) )
1470 if ( !dataTypes.isEmpty() )
1486 bool ok = sourceDef->
dataTypes().isEmpty();
1487 const auto constDataTypes = sourceDef->
dataTypes();
1488 for (
int type : constDataTypes )
1490 if ( dataTypes.contains( type )
1508 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1512 QSet< QString > dependents;
1513 if ( !childId.isEmpty() )
1515 dependents = dependentChildAlgorithms( childId );
1516 dependents << childId;
1519 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1520 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1522 if ( dependents.contains( childIt->childId() ) )
1532 if ( outputTypes.contains( out->type() ) )
1534 if ( !dataTypes.isEmpty() )
1540 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1547 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1555QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1557 return mHelpContent;
1560void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1562 mHelpContent = helpContent;
1565void QgsProcessingModelAlgorithm::setName(
const QString &name )
1570void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1572 mModelGroup = group;
1575bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1580 if ( mChildAlgorithms.empty() )
1583 issues << QObject::tr(
"Model does not contain any algorithms" );
1586 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1588 QStringList childIssues;
1589 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1591 for (
const QString &issue : std::as_const( childIssues ) )
1593 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1599QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1601 return mChildAlgorithms;
1604void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1606 mParameterComponents = parameterComponents;
1609void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1611 mParameterComponents.insert( component.parameterName(), component );
1614QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1616 if ( !mParameterComponents.contains( name ) )
1618 QgsProcessingModelParameter &component = mParameterComponents[name];
1619 component.setParameterName( name );
1622 return mParameterComponents[name];
1625QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1627 QList< QgsProcessingModelParameter > res;
1628 QSet< QString > found;
1629 for (
const QString ¶meter : mParameterOrder )
1631 if ( mParameterComponents.contains( parameter ) )
1633 res << mParameterComponents.value( parameter );
1639 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1641 if ( !found.contains( it.key() ) )
1649void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1651 mParameterOrder = order;
1654QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1656 QList< QgsProcessingModelOutput > res;
1657 QSet< QString > found;
1659 for (
const QString &output : mOutputOrder )
1661 bool foundOutput =
false;
1662 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1664 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1665 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1667 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1669 res << outputIt.value();
1671 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1680 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1682 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1683 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1685 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1687 res << outputIt.value();
1695void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1697 mOutputOrder = order;
1700QString QgsProcessingModelAlgorithm::outputGroup()
const
1702 return mOutputGroup;
1705void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1707 mOutputGroup = group;
1710void QgsProcessingModelAlgorithm::updateDestinationParameters()
1713 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1714 while ( it.hasNext() )
1724 qDeleteAll( mOutputs );
1728 QSet< QString > usedFriendlyNames;
1729 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1730 const QString base = safeName( name,
false );
1731 QString candidate = base;
1733 while ( usedFriendlyNames.contains( candidate ) )
1736 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1738 usedFriendlyNames.insert( candidate );
1742 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1743 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1745 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1746 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1747 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1749 if ( !childIt->isActive() || !childIt->algorithm() )
1757 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1761 if ( outputIt->isMandatory() )
1763 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1765 QString friendlyName = uniqueSafeName( outputIt->description() );
1766 param->
setName( friendlyName );
1770 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1773 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1774 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1775 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1781 if ( addParameter( param.release() ) && newDestParam )
1788 newDestParam->mOriginalProvider = provider;
1795void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1797 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1800QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1802 return mGroupBoxes.values();
1805void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1807 mGroupBoxes.remove( uuid );
1810QVariant QgsProcessingModelAlgorithm::toVariant()
const
1813 map.insert( u
"model_name"_s, mModelName );
1814 map.insert( u
"model_group"_s, mModelGroup );
1815 map.insert( u
"help"_s, mHelpContent );
1818 QVariantMap childMap;
1819 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1820 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1822 childMap.insert( childIt.key(), childIt.value().toVariant() );
1824 map.insert( u
"children"_s, childMap );
1826 QVariantMap paramMap;
1827 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1828 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1830 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1832 map.insert( u
"parameters"_s, paramMap );
1834 QVariantMap paramDefMap;
1839 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1841 QVariantList groupBoxDefs;
1842 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1844 groupBoxDefs.append( it.value().toVariant() );
1846 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1848 map.insert( u
"modelVariables"_s, mVariables );
1850 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1852 map.insert( u
"parameterOrder"_s, mParameterOrder );
1853 map.insert( u
"outputOrder"_s, mOutputOrder );
1854 map.insert( u
"outputGroup"_s, mOutputGroup );
1859bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1861 QVariantMap map = model.toMap();
1863 mModelName = map.value( u
"model_name"_s ).toString();
1864 mModelGroup = map.value( u
"model_group"_s ).toString();
1865 mModelGroupId = map.value( u
"model_group"_s ).toString();
1866 mHelpContent = map.value( u
"help"_s ).toMap();
1868 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1870 mVariables = map.value( u
"modelVariables"_s ).toMap();
1871 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1873 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1874 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1875 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1877 mChildAlgorithms.clear();
1878 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1879 QVariantMap::const_iterator childIt = childMap.constBegin();
1880 for ( ; childIt != childMap.constEnd(); ++childIt )
1882 QgsProcessingModelChildAlgorithm child;
1886 if ( !child.loadVariant( childIt.value() ) )
1889 mChildAlgorithms.insert( child.childId(), child );
1892 mParameterComponents.clear();
1893 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1894 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1895 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1897 QgsProcessingModelParameter param;
1898 if ( !param.loadVariant( paramIt.value().toMap() ) )
1901 mParameterComponents.insert( param.parameterName(), param );
1904 qDeleteAll( mParameters );
1905 mParameters.clear();
1906 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1908 auto addParam = [
this](
const QVariant &value ) {
1915 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1919 param->setHelp( mHelpContent.value( param->name() ).toString() );
1922 addParameter( param.release() );
1926 QVariantMap map = value.toMap();
1927 QString type = map.value( u
"parameter_type"_s ).toString();
1928 QString name = map.value( u
"name"_s ).toString();
1930 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1934 QSet< QString > loadedParams;
1936 for (
const QString &name : std::as_const( mParameterOrder ) )
1938 if ( paramDefMap.contains( name ) )
1940 addParam( paramDefMap.value( name ) );
1941 loadedParams << name;
1945 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1946 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1948 if ( !loadedParams.contains( paramDefIt.key() ) )
1949 addParam( paramDefIt.value() );
1952 mGroupBoxes.clear();
1953 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1954 for (
const QVariant &groupBoxDef : groupBoxList )
1956 QgsProcessingModelGroupBox groupBox;
1957 groupBox.loadVariant( groupBoxDef.toMap() );
1958 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1961 updateDestinationParameters();
1966bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1972 acceptableDataTypes.empty()
1973 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1983void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1985 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1986 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1988 if ( !childIt->algorithm() )
1989 childIt->reattach();
1993bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1995 QDomDocument doc = QDomDocument( u
"model"_s );
1997 doc.appendChild( elem );
2000 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
2002 QTextStream stream( &file );
2003 doc.save( stream, 2 );
2010bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
2015 if ( file.open( QFile::ReadOnly ) )
2017 if ( !doc.setContent( &file ) )
2028 return loadVariant( props );
2031void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
2033 mChildAlgorithms = childAlgorithms;
2034 updateDestinationParameters();
2037void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
2040 updateDestinationParameters();
2043QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
2045 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
2049 updateDestinationParameters();
2053QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
2055 return mChildAlgorithms[childId];
2058bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
2060 if ( !dependentChildAlgorithms(
id ).isEmpty() )
2063 mChildAlgorithms.remove(
id );
2064 updateDestinationParameters();
2068void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
2070 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
2071 for (
const QString &child : constDependentChildAlgorithms )
2073 childAlgorithm( child ).setActive(
false );
2075 childAlgorithm(
id ).setActive(
false );
2076 updateDestinationParameters();
2079bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
2081 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
2082 for (
const QString &child : constDependsOnChildAlgorithms )
2084 if ( !childAlgorithm( child ).isActive() )
2087 childAlgorithm(
id ).setActive(
true );
2088 updateDestinationParameters();
2094 if ( addParameter( definition ) )
2095 mParameterComponents.insert( definition->
name(), component );
2100 removeParameter( definition->
name() );
2101 addParameter( definition );
2104void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2106 removeParameter( name );
2107 mParameterComponents.remove( name );
2110void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2115 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2117 expression.prepare( &expressionContext );
2118 QSet<QString> variables = expression.referencedVariables();
2119 if ( variables.contains( oldName ) )
2121 QString newExpression = expressionString;
2122 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2123 return {
true, newExpression };
2125 return {
false, QString() };
2128 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2129 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2131 bool changed =
false;
2132 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2133 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2134 for ( ; paramIt != childParams.end(); ++paramIt )
2136 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2137 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2139 switch ( valueIt->source() )
2143 if ( valueIt->parameterName() == oldName )
2145 valueIt->setParameterName( newName );
2153 bool updatedExpression =
false;
2154 QString newExpression;
2155 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2156 if ( updatedExpression )
2158 valueIt->setExpression( newExpression );
2166 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2171 bool updatedExpression =
false;
2172 QString newExpression;
2173 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2174 if ( updatedExpression )
2176 property.setExpressionString( newExpression );
2177 valueIt->setStaticValue( property );
2193 childIt->setParameterSources( childParams );
2197bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2199 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2200 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2203 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2204 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2205 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2207 const auto constValue = paramIt.value();
2208 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2220bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2222 const auto constMParameters = mParameters;
2225 if ( def->
name() == name )
2234QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2236 return mParameterComponents;
2239void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2241 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2242 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2244 if ( depends.contains( childIt->childId() ) )
2248 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2249 bool hasDependency =
false;
2250 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2252 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2254 hasDependency =
true;
2259 if ( hasDependency )
2261 depends.insert( childIt->childId() );
2262 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2267 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2268 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2269 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2271 const auto constValue = paramIt.value();
2272 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2276 depends.insert( childIt->childId() );
2277 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2285QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2287 QSet< QString > algs;
2291 algs.insert( childId );
2293 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2296 algs.remove( childId );
2302void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2304 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2307 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2308 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2310 if ( !depends.contains( val.childId ) )
2312 depends.insert( val.childId );
2313 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2318 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2319 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2320 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2322 const auto constValue = paramIt.value();
2323 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2325 switch ( source.source() )
2328 if ( !depends.contains( source.outputChildId() ) )
2330 depends.insert( source.outputChildId() );
2331 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2338 const QSet<QString> vars = exp.referencedVariables();
2343 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2344 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2350 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2354 depends.insert( childVarIt->source.outputChildId() );
2355 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2370QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2372 QSet< QString > algs;
2376 algs.insert( childId );
2378 dependsOnChildAlgorithmsRecursive( childId, algs );
2381 algs.remove( childId );
2386QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2388 QSet< QString > dependent;
2389 if ( !childId.isEmpty() )
2391 dependent.unite( dependentChildAlgorithms( childId ) );
2392 dependent.insert( childId );
2395 QList<QgsProcessingModelChildDependency> res;
2396 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2398 if ( !dependent.contains( it->childId() ) )
2401 bool hasBranches =
false;
2402 if ( it->algorithm() )
2410 QgsProcessingModelChildDependency alg;
2411 alg.childId = it->childId();
2412 alg.conditionalBranch = def->
name();
2420 QgsProcessingModelChildDependency alg;
2421 alg.childId = it->childId();
2429bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2432 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2433 if ( childIt != mChildAlgorithms.constEnd() )
2435 if ( !childIt->algorithm() )
2437 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2446 if ( childIt->parameterSources().contains( def->
name() ) )
2449 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2450 for (
const QgsProcessingModelChildParameterSource &source : sources )
2452 switch ( source.source() )
2458 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2463 if ( !parameterComponents().contains( source.parameterName() ) )
2466 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2471 if ( !childAlgorithms().contains( source.outputChildId() ) )
2474 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2496 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2505 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2510bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2512 reattachAlgorithms();
2513 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2514 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2516 if ( !childIt->algorithm() )
2520 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2528QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2530 if ( mSourceFile.isEmpty() )
2545 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2546 alg->loadVariant( toVariant() );
2547 alg->setProvider( provider() );
2548 alg->setSourceFilePath( sourceFilePath() );
2552QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2554 QString n = name.toLower().trimmed();
2555 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2556 n.replace( rx, QString() );
2557 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2558 n.replace( rx2, QString() );
2560 n = n.replace(
' ',
'_' );
2564QVariantMap QgsProcessingModelAlgorithm::variables()
const
2569void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2571 mVariables = variables;
2574QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2576 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.
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.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
Base class for all map layer types.
virtual Q_INVOKABLE 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(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
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.
void sinkFeatureCountChanged(const QString &output, long long featureCount)
Emitted when the count of features pushed to a sink has changed.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
void sourceLoaded(const QString ¶meterName, long long featureCount)
Emitted when a feature source was retrieved for the specified algorithm input parameter.
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.
Qgis::ProcessingModelChildAlgorithmExecutionStatus executionStatus() const
Returns 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.
A Processing feedback class with extra signals and properties specific to feedback from Processing mo...
void reportChildExecutionFailure(const QString &childId, const QString &error)
Report an error which occurred while executing a child algorithm.
void reportChildResult(const QString &childId, const QgsProcessingModelChildAlgorithmResult &result)
Reports the result of the execution of a child algorithm.
void reportBrokenChildAlgorithms(const QSet< QString > &childIds)
Report a set of child algorithms as broken (e.g.
void reportChildSinkFeatureCountChanged(const QString &childId, const QString &childOutput, long long featureCount)
Reports that the count of features pushed to a child algorithm's sink has changed.
void reportChildPreparationFailure(const QString &childId, const QString &error)
Report an error which occurred while preparing a child algorithm.
void reportPreparingChild(const QString &childId)
Report a child algorithm as undergoing the preparation step.
void reportChildExecutionSuccess(const QString &childId, const QVariantMap &childResults)
Report that a child algorithm successfully executed.
void reportChildProgress(const QString &childId, double progress)
Reports the progress of a running child algorithm.
void reportChildStarted(const QString &childId, const QVariantMap &childParameters)
Report a child algorithm as started execution.
void reportChildPruned(const QString &childId)
Report that a child algorithm was pruned from the pending children (i.e.
void reportChildSourceLoaded(const QString &childId, const QString ¶meterName, long long featureCount)
Reports that a feature source was retrieved for the specified child algorithm input parameter.
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.
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.
Keeps a reference to a Qt connection (a QMetaObject::Connection) and disconnects it whenever this obj...
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.
#define Q_NOWARN_DEPRECATED_POP
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.
#define Q_NOWARN_DEPRECATED_PUSH
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.