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() );
171 if ( !expressionText.isEmpty() )
173 return expressionText;
175 else if ( paramParts.count() == 1 )
176 return paramParts.at( 0 );
182 QVariantMap childParams;
183 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
186 if ( !def->isDestination() )
188 if ( !child.parameterSources().contains( def->name() ) )
191 const QVariant value = evaluateSources( def );
192 childParams.insert( def->name(), value );
199 bool isFinalOutput =
false;
200 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
201 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
202 for ( ; outputIt != outputs.constEnd(); ++outputIt )
204 if ( outputIt->childOutputName() == destParam->
name() )
206 QString paramName = child.childId() +
':' + outputIt.key();
207 bool foundParam =
false;
211 if ( modelParameters.contains( paramName ) )
213 value = modelParameters.value( paramName );
222 if ( modelParameters.contains( modelParam->name() ) )
224 value = modelParameters.value( modelParam->name() );
232 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
237 value = QVariant::fromValue( fromVar );
240 childParams.insert( destParam->
name(), value );
242 isFinalOutput =
true;
247 bool hasExplicitDefinition =
false;
248 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
251 const QVariant value = evaluateSources( def );
252 if ( value.isValid() )
254 childParams.insert( def->name(), value );
255 hasExplicitDefinition =
true;
259 if ( !isFinalOutput && !hasExplicitDefinition )
264 bool required =
true;
267 required = childOutputIsRequired( child.childId(), destParam->
name() );
279const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
283 if ( !definition->isDestination() )
286 const QString modelChildId = definition->metadata().value( u
"_modelChildId"_s ).toString();
287 const QString modelOutputName = definition->metadata().value( u
"_modelChildOutputName"_s ).toString();
289 if ( modelChildId == childId && modelOutputName == childOutputName )
295bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
298 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
299 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
301 if ( childIt->childId() == childId || !childIt->isActive() )
305 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
306 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
307 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
309 const auto constValue = childParamIt.value();
310 for (
const QgsProcessingModelChildParameterSource &source : constValue )
328 QSet< QString > toExecute;
329 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
330 QSet< QString > broken;
332 const bool useSubsetOfChildren = !childSubset.empty();
333 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
335 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
337 if ( childIt->algorithm() )
338 toExecute.insert( childIt->childId() );
340 broken.insert( childIt->childId() );
344 if ( !broken.empty() )
351 QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken,
", "_L1 ) )
355 QElapsedTimer totalTime;
364 QMap< QString, QgsProcessingModelChildAlgorithmResult > &contextChildResults = context.
modelResult().
childResults();
370 childInputs = config->initialChildInputs();
371 childResults = config->initialChildOutputs();
372 executed = config->previouslyExecutedChildAlgorithms();
376 if ( useSubsetOfChildren )
378 executed.subtract( childSubset );
381 QVariantMap finalResults;
383 bool executedAlg =
true;
384 int previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
385 int countExecuted = 0;
386 while ( executedAlg && countExecuted < toExecute.count() )
389 for (
const QString &childId : std::as_const( toExecute ) )
394 if ( executed.contains( childId ) )
399 bool canExecute =
true;
400 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
401 for (
const QString &dependency : dependencies )
403 if ( !executed.contains( dependency ) )
417 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
418 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
420 bool skipGenericLogging =
true;
425 skipGenericLogging =
true;
435 skipGenericLogging =
false;
439 childAlgorithmFeedback.resetFeatureSinkCounts();
441 if ( feedback && !skipGenericLogging )
443 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
455 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
456 if ( !error.isEmpty() )
465 if ( feedback && !skipGenericLogging )
466 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
471 childInputs.insert( childId, thisChildParams );
472 childResult.
setInputs( thisChildParams );
475 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
477 params << u
"%1: %2"_s.arg( childParamIt.key(), child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
480 if ( feedback && !skipGenericLogging )
482 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
483 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
486 QElapsedTimer childTime;
489 QVariantMap outerScopeChildInputs = childInputs;
490 QVariantMap outerScopePrevChildResults = childResults;
491 QSet< QString > outerScopeExecuted = executed;
492 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
493 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
497 childResults.clear();
499 contextChildResults.clear();
504 QThread *modelThread = QThread::currentThread();
506 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &childAlgorithmFeedback] {
507 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
508 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
509 context.pushToThread( modelThread );
513 if ( modelThread == qApp->thread() )
514 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
517 context.pushToThread( qApp->thread() );
519#ifndef __clang_analyzer__
520 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
524 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
543 bool runResult =
false;
553 childProgressConnection = QObject::connect( &childAlgorithmFeedback, &
QgsFeedback::progressChanged, &childAlgorithmFeedback, [&modelFeedback, &childId](
double progress ) {
556 childSinkCountChangedConnection
561 childSourceLoadedConnection = QObject::connect( feedback, &
QgsProcessingFeedback::sourceLoaded, feedback, [&modelFeedback, &childId](
const QString ¶meterName,
long long featureCount ) {
569 bool exceptionFromMainThread =
false;
570 auto runOnMainThread = [modelThread, &context, &childAlgorithmFeedback, &results, &childAlg, &childParams, &exceptionFromMainThread, &child, &error, &childResult] {
571 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
574 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
580 exceptionFromMainThread =
true;
582 context.pushToThread( modelThread );
585 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
586 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
588 context.pushToThread( qApp->thread() );
590#ifndef __clang_analyzer__
591 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
593 if ( !exceptionFromMainThread )
602 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
613 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
616 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &childAlgorithmFeedback, runResult] {
617 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
618 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
619 context.pushToThread( modelThread );
623 if ( modelThread == qApp->thread() )
624 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
627 context.pushToThread( qApp->thread() );
629#ifndef __clang_analyzer__
630 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
634 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
636 if ( !ppRes.isEmpty() )
639 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
641 childInputs = outerScopeChildInputs;
642 childResults = outerScopePrevChildResults;
643 executed = outerScopeExecuted;
644 contextChildResults = outerScopeContextChildResult;
647 childResults.insert( childId, results );
663 if ( feedback && !skipGenericLogging )
666 QStringList formattedOutputs;
667 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
672 feedback->
pushInfo( QObject::tr(
"Results:" ) );
673 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
678 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
679 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
681 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
682 switch ( mInternalVersion )
684 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
685 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
687 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
690 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
695 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
696 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
700 if ( outputSortKey > 0 )
705 executed.insert( childId );
707 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
708 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
709 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
710 for (
const QString &targetId : toPrune )
712 if ( executed.contains( targetId ) )
715 executed.insert( targetId );
720 pruneAlgorithmBranchRecursive( targetId, branch );
730 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
738 for (
const QString &candidateId : std::as_const( toExecute ) )
740 if ( executed.contains( candidateId ) )
745 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
746 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
747 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
749 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
751 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
756 if ( !results.contains( source.outputName() ) )
761 executed.insert( candidateId );
767 pruneAlgorithmBranchRecursive( candidateId, QString() );
778 childAlg.reset(
nullptr );
780 childAlgorithmFeedback.setCurrentStep( countExecuted );
781 if ( feedback && !skipGenericLogging )
783 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
788 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
789 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
793 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
794 const QString formattedRunTime
795 = 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 );
797 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
798 context.modelResult().childResults().insert( childId, childResult );
809 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
810 context.modelResult().childResults().insert( childId, childResult );
823 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 ) );
825 mResults = finalResults;
826 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
827 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
831QString QgsProcessingModelAlgorithm::sourceFilePath()
const
836void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
838 mSourceFile = sourceFile;
841bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
843 if ( mSourceFile.isEmpty() )
846 const QFileInfo fi( mSourceFile );
847 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
852 QStringList fileDocString;
853 fileDocString << u
"\"\"\""_s;
854 fileDocString << u
"Model exported as python."_s;
855 fileDocString << u
"Name : %1"_s.arg( displayName() );
856 fileDocString << u
"Group : %1"_s.arg( group() );
858 fileDocString << u
"\"\"\""_s;
859 fileDocString << QString();
862 QString indent = QString(
' ' ).repeated( indentSize );
863 QString currentIndent;
865 QMap< QString, QString> friendlyChildNames;
866 QMap< QString, QString> friendlyOutputNames;
867 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
868 const QString base = safeName( name, capitalize );
869 QString candidate = base;
872 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
875 candidate = u
"%1_%2"_s.arg( base ).arg( i );
880 const QString algorithmClassName = safeName( name(),
true );
882 QSet< QString > toExecute;
883 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
885 if ( childIt->isActive() && childIt->algorithm() )
887 toExecute.insert( childIt->childId() );
888 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
891 const int totalSteps = toExecute.count();
893 QStringList importLines;
894 switch ( outputType )
899 const auto params = parameterDefinitions();
900 importLines.reserve( params.count() + 6 );
901 importLines << u
"from typing import Any, Optional"_s;
902 importLines << QString();
903 importLines << u
"from qgis.core import QgsProcessing"_s;
904 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
905 importLines << u
"from qgis.core import QgsProcessingContext"_s;
906 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
908 bool hasAdvancedParams =
false;
912 hasAdvancedParams =
true;
916 const QString importString = type->pythonImportString();
917 if ( !importString.isEmpty() && !importLines.contains( importString ) )
918 importLines << importString;
922 if ( hasAdvancedParams )
923 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
925 lines << u
"from qgis import processing"_s;
926 lines << QString() << QString();
928 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
932 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
933 if ( params.empty() )
935 lines << indent + indent + u
"pass"_s;
939 lines.reserve( lines.size() + params.size() );
942 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
944 if ( defClone->isDestination() )
946 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
947 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
948 friendlyOutputNames.insert( uniqueChildName, friendlyName );
949 defClone->setName( friendlyName );
953 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
955 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
956 for (
const QString &part : parts )
958 lines << indent + indent + u
"# %1"_s.arg( part );
965 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
966 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
967 lines << indent + indent + u
"self.addParameter(param)"_s;
971 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
977 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
978 currentIndent = indent + indent;
980 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
981 lines << currentIndent + u
"# overall progress through the model"_s;
982 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
990 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
991 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
993 QString name = paramIt.value().parameterName();
994 if ( parameterDefinition( name ) )
997 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
1001 if ( !params.isEmpty() )
1003 lines << u
"parameters = {"_s;
1004 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
1006 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
1012 lines << u
"context = QgsProcessingContext()"_s
1013 << u
"context.setProject(QgsProject.instance())"_s
1014 << u
"feedback = QgsProcessingFeedback()"_s
1022 lines << currentIndent + u
"results = {}"_s;
1023 lines << currentIndent + u
"outputs = {}"_s;
1026 QSet< QString > executed;
1027 bool executedAlg =
true;
1028 int currentStep = 0;
1029 while ( executedAlg && executed.count() < toExecute.count() )
1031 executedAlg =
false;
1032 const auto constToExecute = toExecute;
1033 for (
const QString &childId : constToExecute )
1035 if ( executed.contains( childId ) )
1038 bool canExecute =
true;
1039 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
1040 for (
const QString &dependency : constDependsOnChildAlgorithms )
1042 if ( !executed.contains( dependency ) )
1054 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
1061 if ( def->isDestination() )
1066 bool isFinalOutput =
false;
1067 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
1068 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1069 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1071 if ( outputIt->childOutputName() == destParam->
name() )
1073 QString paramName = child.childId() +
':' + outputIt.key();
1074 paramName = friendlyOutputNames.value( paramName, paramName );
1075 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
1076 isFinalOutput =
true;
1081 if ( !isFinalOutput )
1086 bool required =
true;
1089 required = childOutputIsRequired( child.childId(), destParam->
name() );
1095 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1101 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1103 if ( currentStep < totalSteps )
1106 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1107 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1108 lines << currentIndent + indent + u
"return {}"_s;
1111 executed.insert( childId );
1115 switch ( outputType )
1118 lines << currentIndent + u
"return results"_s;
1122 lines << indent + u
"def name(self) -> str:"_s;
1123 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1125 lines << indent + u
"def displayName(self) -> str:"_s;
1126 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1130 lines << indent + u
"def group(self) -> str:"_s;
1131 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1133 lines << indent + u
"def groupId(self) -> str:"_s;
1134 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1138 if ( !shortHelpString().isEmpty() )
1140 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1141 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1144 if ( !helpUrl().isEmpty() )
1146 lines << indent + u
"def helpUrl(self) -> str:"_s;
1147 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1152 lines << indent + u
"def createInstance(self):"_s;
1153 lines << indent + indent + u
"return self.__class__()"_s;
1156 static QMap< QString, QString > sAdditionalImports {
1157 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1158 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1159 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1160 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1161 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1162 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1163 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1164 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1165 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1166 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1167 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1168 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1169 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1170 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1171 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1172 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1173 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1174 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1175 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1176 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1179 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1181 if ( importLines.contains( it.value() ) )
1188 for (
const QString &line : std::as_const( lines ) )
1190 if ( line.contains( it.key() ) )
1198 importLines << it.value();
1202 lines = fileDocString + importLines + lines;
1211QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1212 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1215 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1217 auto safeName = [](
const QString &name ) -> QString {
1219 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1220 return s.replace( safeNameRe, u
"_"_s );
1224 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1258 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1262 QString description;
1263 switch ( source.source() )
1267 name = source.parameterName();
1268 value = modelParameters.value( source.parameterName() );
1269 description = parameterDefinition( source.parameterName() )->description();
1274 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1275 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1278 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1280 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1290 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1294 sources = availableSourcesForChild(
1300 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1304 QString description;
1306 switch ( source.source() )
1310 name = source.parameterName();
1311 value = modelParameters.value( source.parameterName() );
1312 description = parameterDefinition( source.parameterName() )->description();
1317 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1318 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1319 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1322 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1334 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1337 value = fromVar.
sink;
1338 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1346 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1351 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1352 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1353 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1354 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1355 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1359 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1363 QString description;
1365 switch ( source.source() )
1369 name = source.parameterName();
1370 value = modelParameters.value( source.parameterName() );
1371 description = parameterDefinition( source.parameterName() )->description();
1376 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1377 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1378 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1381 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1394 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1399 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1402 value = fromVar.
sink;
1403 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1408 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1410 featureSource = layer;
1412 if ( context && !featureSource )
1418 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1419 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1420 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1421 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1422 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1429 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1432 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1433 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1434 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1435 for ( ; varIt != variables.constEnd(); ++varIt )
1439 return scope.release();
1442QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1446 return QgsProcessingModelChildParameterSources();
1450QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1451 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1454 QgsProcessingModelChildParameterSources sources;
1457 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1458 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1464 if ( parameterTypes.contains( def->
type() ) )
1466 if ( !dataTypes.isEmpty() )
1482 bool ok = sourceDef->
dataTypes().isEmpty();
1483 const auto constDataTypes = sourceDef->
dataTypes();
1484 for (
int type : constDataTypes )
1486 if ( dataTypes.contains( type )
1504 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1508 QSet< QString > dependents;
1509 if ( !childId.isEmpty() )
1511 dependents = dependentChildAlgorithms( childId );
1512 dependents << childId;
1515 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1516 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1518 if ( dependents.contains( childIt->childId() ) )
1528 if ( outputTypes.contains( out->type() ) )
1530 if ( !dataTypes.isEmpty() )
1536 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1543 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1551QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1553 return mHelpContent;
1556void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1558 mHelpContent = helpContent;
1561void QgsProcessingModelAlgorithm::setName(
const QString &name )
1566void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1568 mModelGroup = group;
1571bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1576 if ( mChildAlgorithms.empty() )
1579 issues << QObject::tr(
"Model does not contain any algorithms" );
1582 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1584 QStringList childIssues;
1585 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1587 for (
const QString &issue : std::as_const( childIssues ) )
1589 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1595QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1597 return mChildAlgorithms;
1600void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1602 mParameterComponents = parameterComponents;
1605void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1607 mParameterComponents.insert( component.parameterName(), component );
1610QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1612 if ( !mParameterComponents.contains( name ) )
1614 QgsProcessingModelParameter &component = mParameterComponents[name];
1615 component.setParameterName( name );
1618 return mParameterComponents[name];
1621QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1623 QList< QgsProcessingModelParameter > res;
1624 QSet< QString > found;
1625 for (
const QString ¶meter : mParameterOrder )
1627 if ( mParameterComponents.contains( parameter ) )
1629 res << mParameterComponents.value( parameter );
1635 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1637 if ( !found.contains( it.key() ) )
1645void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1647 mParameterOrder = order;
1650QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1652 QList< QgsProcessingModelOutput > res;
1653 QSet< QString > found;
1655 for (
const QString &output : mOutputOrder )
1657 bool foundOutput =
false;
1658 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1660 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1661 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1663 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1665 res << outputIt.value();
1667 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1676 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1678 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1679 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1681 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1683 res << outputIt.value();
1691void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1693 mOutputOrder = order;
1696QString QgsProcessingModelAlgorithm::outputGroup()
const
1698 return mOutputGroup;
1701void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1703 mOutputGroup = group;
1706void QgsProcessingModelAlgorithm::updateDestinationParameters()
1709 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1710 while ( it.hasNext() )
1720 qDeleteAll( mOutputs );
1724 QSet< QString > usedFriendlyNames;
1725 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1726 const QString base = safeName( name,
false );
1727 QString candidate = base;
1729 while ( usedFriendlyNames.contains( candidate ) )
1732 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1734 usedFriendlyNames.insert( candidate );
1738 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1739 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1741 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1742 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1743 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1745 if ( !childIt->isActive() || !childIt->algorithm() )
1753 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1757 if ( outputIt->isMandatory() )
1759 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1761 QString friendlyName = uniqueSafeName( outputIt->description() );
1762 param->
setName( friendlyName );
1766 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1769 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1770 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1771 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1777 if ( addParameter( param.release() ) && newDestParam )
1784 newDestParam->mOriginalProvider = provider;
1791void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1793 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1796QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1798 return mGroupBoxes.values();
1801void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1803 mGroupBoxes.remove( uuid );
1806QVariant QgsProcessingModelAlgorithm::toVariant()
const
1809 map.insert( u
"model_name"_s, mModelName );
1810 map.insert( u
"model_group"_s, mModelGroup );
1811 map.insert( u
"help"_s, mHelpContent );
1814 QVariantMap childMap;
1815 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1816 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1818 childMap.insert( childIt.key(), childIt.value().toVariant() );
1820 map.insert( u
"children"_s, childMap );
1822 QVariantMap paramMap;
1823 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1824 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1826 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1828 map.insert( u
"parameters"_s, paramMap );
1830 QVariantMap paramDefMap;
1835 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1837 QVariantList groupBoxDefs;
1838 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1840 groupBoxDefs.append( it.value().toVariant() );
1842 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1844 map.insert( u
"modelVariables"_s, mVariables );
1846 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1848 map.insert( u
"parameterOrder"_s, mParameterOrder );
1849 map.insert( u
"outputOrder"_s, mOutputOrder );
1850 map.insert( u
"outputGroup"_s, mOutputGroup );
1855bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1857 QVariantMap map = model.toMap();
1859 mModelName = map.value( u
"model_name"_s ).toString();
1860 mModelGroup = map.value( u
"model_group"_s ).toString();
1861 mModelGroupId = map.value( u
"model_group"_s ).toString();
1862 mHelpContent = map.value( u
"help"_s ).toMap();
1864 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1866 mVariables = map.value( u
"modelVariables"_s ).toMap();
1867 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1869 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1870 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1871 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1873 mChildAlgorithms.clear();
1874 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1875 QVariantMap::const_iterator childIt = childMap.constBegin();
1876 for ( ; childIt != childMap.constEnd(); ++childIt )
1878 QgsProcessingModelChildAlgorithm child;
1882 if ( !child.loadVariant( childIt.value() ) )
1885 mChildAlgorithms.insert( child.childId(), child );
1888 mParameterComponents.clear();
1889 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1890 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1891 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1893 QgsProcessingModelParameter param;
1894 if ( !param.loadVariant( paramIt.value().toMap() ) )
1897 mParameterComponents.insert( param.parameterName(), param );
1900 qDeleteAll( mParameters );
1901 mParameters.clear();
1902 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1904 auto addParam = [
this](
const QVariant &value ) {
1911 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1915 param->setHelp( mHelpContent.value( param->name() ).toString() );
1918 addParameter( param.release() );
1922 QVariantMap map = value.toMap();
1923 QString type = map.value( u
"parameter_type"_s ).toString();
1924 QString name = map.value( u
"name"_s ).toString();
1926 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1930 QSet< QString > loadedParams;
1932 for (
const QString &name : std::as_const( mParameterOrder ) )
1934 if ( paramDefMap.contains( name ) )
1936 addParam( paramDefMap.value( name ) );
1937 loadedParams << name;
1941 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1942 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1944 if ( !loadedParams.contains( paramDefIt.key() ) )
1945 addParam( paramDefIt.value() );
1948 mGroupBoxes.clear();
1949 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1950 for (
const QVariant &groupBoxDef : groupBoxList )
1952 QgsProcessingModelGroupBox groupBox;
1953 groupBox.loadVariant( groupBoxDef.toMap() );
1954 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1957 updateDestinationParameters();
1962bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1968 acceptableDataTypes.empty()
1969 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1979void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1981 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1982 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1984 if ( !childIt->algorithm() )
1985 childIt->reattach();
1989bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1991 QDomDocument doc = QDomDocument( u
"model"_s );
1993 doc.appendChild( elem );
1996 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1998 QTextStream stream( &file );
1999 doc.save( stream, 2 );
2006bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
2011 if ( file.open( QFile::ReadOnly ) )
2013 if ( !doc.setContent( &file ) )
2024 return loadVariant( props );
2027void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
2029 mChildAlgorithms = childAlgorithms;
2030 updateDestinationParameters();
2033void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
2036 updateDestinationParameters();
2039QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
2041 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
2045 updateDestinationParameters();
2049QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
2051 return mChildAlgorithms[childId];
2054bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
2056 if ( !dependentChildAlgorithms(
id ).isEmpty() )
2059 mChildAlgorithms.remove(
id );
2060 updateDestinationParameters();
2064void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
2066 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
2067 for (
const QString &child : constDependentChildAlgorithms )
2069 childAlgorithm( child ).setActive(
false );
2071 childAlgorithm(
id ).setActive(
false );
2072 updateDestinationParameters();
2075bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
2077 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
2078 for (
const QString &child : constDependsOnChildAlgorithms )
2080 if ( !childAlgorithm( child ).isActive() )
2083 childAlgorithm(
id ).setActive(
true );
2084 updateDestinationParameters();
2090 if ( addParameter( definition ) )
2091 mParameterComponents.insert( definition->
name(), component );
2096 removeParameter( definition->
name() );
2097 addParameter( definition );
2100void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2102 removeParameter( name );
2103 mParameterComponents.remove( name );
2106void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2111 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2113 expression.prepare( &expressionContext );
2114 QSet<QString> variables = expression.referencedVariables();
2115 if ( variables.contains( oldName ) )
2117 QString newExpression = expressionString;
2118 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2119 return {
true, newExpression };
2121 return {
false, QString() };
2124 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2125 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2127 bool changed =
false;
2128 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2129 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2130 for ( ; paramIt != childParams.end(); ++paramIt )
2132 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2133 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2135 switch ( valueIt->source() )
2139 if ( valueIt->parameterName() == oldName )
2141 valueIt->setParameterName( newName );
2149 bool updatedExpression =
false;
2150 QString newExpression;
2151 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2152 if ( updatedExpression )
2154 valueIt->setExpression( newExpression );
2162 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2167 bool updatedExpression =
false;
2168 QString newExpression;
2169 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2170 if ( updatedExpression )
2172 property.setExpressionString( newExpression );
2173 valueIt->setStaticValue( property );
2189 childIt->setParameterSources( childParams );
2193bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2195 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2196 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2199 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2200 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2201 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2203 const auto constValue = paramIt.value();
2204 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2216bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2218 const auto constMParameters = mParameters;
2221 if ( def->
name() == name )
2230QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2232 return mParameterComponents;
2235void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2237 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2238 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2240 if ( depends.contains( childIt->childId() ) )
2244 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2245 bool hasDependency =
false;
2246 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2248 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2250 hasDependency =
true;
2255 if ( hasDependency )
2257 depends.insert( childIt->childId() );
2258 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2263 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2264 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2265 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2267 const auto constValue = paramIt.value();
2268 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2272 depends.insert( childIt->childId() );
2273 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2281QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2283 QSet< QString > algs;
2287 algs.insert( childId );
2289 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2292 algs.remove( childId );
2298void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2300 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2303 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2304 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2306 if ( !depends.contains( val.childId ) )
2308 depends.insert( val.childId );
2309 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2314 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2315 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2316 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2318 const auto constValue = paramIt.value();
2319 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2321 switch ( source.source() )
2324 if ( !depends.contains( source.outputChildId() ) )
2326 depends.insert( source.outputChildId() );
2327 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2334 const QSet<QString> vars = exp.referencedVariables();
2339 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2340 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2346 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2350 depends.insert( childVarIt->source.outputChildId() );
2351 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2366QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2368 QSet< QString > algs;
2372 algs.insert( childId );
2374 dependsOnChildAlgorithmsRecursive( childId, algs );
2377 algs.remove( childId );
2382QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2384 QSet< QString > dependent;
2385 if ( !childId.isEmpty() )
2387 dependent.unite( dependentChildAlgorithms( childId ) );
2388 dependent.insert( childId );
2391 QList<QgsProcessingModelChildDependency> res;
2392 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2394 if ( !dependent.contains( it->childId() ) )
2397 bool hasBranches =
false;
2398 if ( it->algorithm() )
2406 QgsProcessingModelChildDependency alg;
2407 alg.childId = it->childId();
2408 alg.conditionalBranch = def->
name();
2416 QgsProcessingModelChildDependency alg;
2417 alg.childId = it->childId();
2425bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2428 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2429 if ( childIt != mChildAlgorithms.constEnd() )
2431 if ( !childIt->algorithm() )
2433 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2442 if ( childIt->parameterSources().contains( def->
name() ) )
2445 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2446 for (
const QgsProcessingModelChildParameterSource &source : sources )
2448 switch ( source.source() )
2454 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2459 if ( !parameterComponents().contains( source.parameterName() ) )
2462 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2467 if ( !childAlgorithms().contains( source.outputChildId() ) )
2470 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2492 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2501 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2506bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2508 reattachAlgorithms();
2509 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2510 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2512 if ( !childIt->algorithm() )
2516 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2524QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2526 if ( mSourceFile.isEmpty() )
2541 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2542 alg->loadVariant( toVariant() );
2543 alg->setProvider( provider() );
2544 alg->setSourceFilePath( sourceFilePath() );
2548QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2550 QString n = name.toLower().trimmed();
2551 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2552 n.replace( rx, QString() );
2553 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2554 n.replace( rx2, QString() );
2556 n = n.replace(
' ',
'_' );
2560QVariantMap QgsProcessingModelAlgorithm::variables()
const
2565void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2567 mVariables = variables;
2570QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2572 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.
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.
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.