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 ) );
457 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
458 if ( !error.isEmpty() )
467 if ( feedback && !skipGenericLogging )
468 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
473 childInputs.insert( childId, thisChildParams );
474 childResult.
setInputs( thisChildParams );
477 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
479 params << u
"%1: %2"_s.arg( childParamIt.key(), child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
482 if ( feedback && !skipGenericLogging )
484 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
485 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
488 QElapsedTimer childTime;
491 QVariantMap outerScopeChildInputs = childInputs;
492 QVariantMap outerScopePrevChildResults = childResults;
493 QSet< QString > outerScopeExecuted = executed;
494 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
495 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
499 childResults.clear();
501 contextChildResults.clear();
506 QThread *modelThread = QThread::currentThread();
508 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &childAlgorithmFeedback] {
509 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
510 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
511 context.pushToThread( modelThread );
515 if ( modelThread == qApp->thread() )
516 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
519 context.pushToThread( qApp->thread() );
521#ifndef __clang_analyzer__
522 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
526 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
545 bool runResult =
false;
555 childProgressConnection = QObject::connect( &childAlgorithmFeedback, &
QgsFeedback::progressChanged, &childAlgorithmFeedback, [&modelFeedback, &childId](
double progress ) {
558 childSinkCountChangedConnection
563 childSourceLoadedConnection = QObject::connect( feedback, &
QgsProcessingFeedback::sourceLoaded, feedback, [&modelFeedback, &childId](
const QString ¶meterName,
long long featureCount ) {
571 bool exceptionFromMainThread =
false;
572 auto runOnMainThread = [modelThread, &context, &childAlgorithmFeedback, &results, &childAlg, &childParams, &exceptionFromMainThread, &child, &error, &childResult] {
573 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
576 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
582 exceptionFromMainThread =
true;
584 context.pushToThread( modelThread );
587 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
588 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
590 context.pushToThread( qApp->thread() );
592#ifndef __clang_analyzer__
593 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
595 if ( !exceptionFromMainThread )
604 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
615 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
618 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &childAlgorithmFeedback, runResult] {
619 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
620 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
621 context.pushToThread( modelThread );
625 if ( modelThread == qApp->thread() )
626 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
629 context.pushToThread( qApp->thread() );
631#ifndef __clang_analyzer__
632 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
636 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
638 if ( !ppRes.isEmpty() )
641 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
643 childInputs = outerScopeChildInputs;
644 childResults = outerScopePrevChildResults;
645 executed = outerScopeExecuted;
646 contextChildResults = outerScopeContextChildResult;
649 childResults.insert( childId, results );
665 if ( feedback && !skipGenericLogging )
668 QStringList formattedOutputs;
669 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
674 feedback->
pushInfo( QObject::tr(
"Results:" ) );
675 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
680 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
681 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
683 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
684 switch ( mInternalVersion )
686 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
687 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
689 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
692 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
697 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
698 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
702 if ( outputSortKey > 0 )
707 executed.insert( childId );
709 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
710 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
711 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
712 for (
const QString &targetId : toPrune )
714 if ( executed.contains( targetId ) )
717 executed.insert( targetId );
722 pruneAlgorithmBranchRecursive( targetId, branch );
732 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
740 for (
const QString &candidateId : std::as_const( toExecute ) )
742 if ( executed.contains( candidateId ) )
747 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
748 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
749 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
751 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
753 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
758 if ( !results.contains( source.outputName() ) )
763 executed.insert( candidateId );
769 pruneAlgorithmBranchRecursive( candidateId, QString() );
780 childAlg.reset(
nullptr );
782 childAlgorithmFeedback.setCurrentStep( countExecuted );
783 if ( feedback && !skipGenericLogging )
785 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
790 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
791 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
795 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
796 const QString formattedRunTime
797 = 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 );
799 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
800 context.modelResult().childResults().insert( childId, childResult );
811 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
812 context.modelResult().childResults().insert( childId, childResult );
825 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 ) );
827 mResults = finalResults;
828 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
829 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
833QString QgsProcessingModelAlgorithm::sourceFilePath()
const
838void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
840 mSourceFile = sourceFile;
843bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
845 if ( mSourceFile.isEmpty() )
848 const QFileInfo fi( mSourceFile );
849 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
854 QStringList fileDocString;
855 fileDocString << u
"\"\"\""_s;
856 fileDocString << u
"Model exported as python."_s;
857 fileDocString << u
"Name : %1"_s.arg( displayName() );
858 fileDocString << u
"Group : %1"_s.arg( group() );
860 fileDocString << u
"\"\"\""_s;
861 fileDocString << QString();
864 QString indent = QString(
' ' ).repeated( indentSize );
865 QString currentIndent;
867 QMap< QString, QString> friendlyChildNames;
868 QMap< QString, QString> friendlyOutputNames;
869 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
870 const QString base = safeName( name, capitalize );
871 QString candidate = base;
874 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
877 candidate = u
"%1_%2"_s.arg( base ).arg( i );
882 const QString algorithmClassName = safeName( name(),
true );
884 QSet< QString > toExecute;
885 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
887 if ( childIt->isActive() && childIt->algorithm() )
889 toExecute.insert( childIt->childId() );
890 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
893 const int totalSteps = toExecute.count();
895 QStringList importLines;
896 switch ( outputType )
901 const auto params = parameterDefinitions();
902 importLines.reserve( params.count() + 6 );
903 importLines << u
"from typing import Any, Optional"_s;
904 importLines << QString();
905 importLines << u
"from qgis.core import QgsProcessing"_s;
906 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
907 importLines << u
"from qgis.core import QgsProcessingContext"_s;
908 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
910 bool hasAdvancedParams =
false;
914 hasAdvancedParams =
true;
918 const QString importString = type->pythonImportString();
919 if ( !importString.isEmpty() && !importLines.contains( importString ) )
920 importLines << importString;
924 if ( hasAdvancedParams )
925 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
927 lines << u
"from qgis import processing"_s;
928 lines << QString() << QString();
930 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
934 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
935 if ( params.empty() )
937 lines << indent + indent + u
"pass"_s;
941 lines.reserve( lines.size() + params.size() );
944 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
946 if ( defClone->isDestination() )
948 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
949 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
950 friendlyOutputNames.insert( uniqueChildName, friendlyName );
951 defClone->setName( friendlyName );
955 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
957 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
958 for (
const QString &part : parts )
960 lines << indent + indent + u
"# %1"_s.arg( part );
967 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
968 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
969 lines << indent + indent + u
"self.addParameter(param)"_s;
973 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
979 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
980 currentIndent = indent + indent;
982 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
983 lines << currentIndent + u
"# overall progress through the model"_s;
984 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
992 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
993 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
995 QString name = paramIt.value().parameterName();
996 if ( parameterDefinition( name ) )
999 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
1003 if ( !params.isEmpty() )
1005 lines << u
"parameters = {"_s;
1006 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
1008 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
1014 lines << u
"context = QgsProcessingContext()"_s
1015 << u
"context.setProject(QgsProject.instance())"_s
1016 << u
"feedback = QgsProcessingFeedback()"_s
1024 lines << currentIndent + u
"results = {}"_s;
1025 lines << currentIndent + u
"outputs = {}"_s;
1028 QSet< QString > executed;
1029 bool executedAlg =
true;
1030 int currentStep = 0;
1031 while ( executedAlg && executed.count() < toExecute.count() )
1033 executedAlg =
false;
1034 const auto constToExecute = toExecute;
1035 for (
const QString &childId : constToExecute )
1037 if ( executed.contains( childId ) )
1040 bool canExecute =
true;
1041 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
1042 for (
const QString &dependency : constDependsOnChildAlgorithms )
1044 if ( !executed.contains( dependency ) )
1056 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
1063 if ( def->isDestination() )
1068 bool isFinalOutput =
false;
1069 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
1070 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1071 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1073 if ( outputIt->childOutputName() == destParam->
name() )
1075 QString paramName = child.childId() +
':' + outputIt.key();
1076 paramName = friendlyOutputNames.value( paramName, paramName );
1077 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
1078 isFinalOutput =
true;
1083 if ( !isFinalOutput )
1088 bool required =
true;
1091 required = childOutputIsRequired( child.childId(), destParam->
name() );
1097 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1103 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1105 if ( currentStep < totalSteps )
1108 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1109 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1110 lines << currentIndent + indent + u
"return {}"_s;
1113 executed.insert( childId );
1117 switch ( outputType )
1120 lines << currentIndent + u
"return results"_s;
1124 lines << indent + u
"def name(self) -> str:"_s;
1125 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1127 lines << indent + u
"def displayName(self) -> str:"_s;
1128 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1132 lines << indent + u
"def group(self) -> str:"_s;
1133 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1135 lines << indent + u
"def groupId(self) -> str:"_s;
1136 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1140 if ( !shortHelpString().isEmpty() )
1142 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1143 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1146 if ( !helpUrl().isEmpty() )
1148 lines << indent + u
"def helpUrl(self) -> str:"_s;
1149 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1154 lines << indent + u
"def createInstance(self):"_s;
1155 lines << indent + indent + u
"return self.__class__()"_s;
1158 static QMap< QString, QString > sAdditionalImports {
1159 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1160 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1161 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1162 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1163 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1164 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1165 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1166 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1167 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1168 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1169 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1170 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1171 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1172 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1173 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1174 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1175 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1176 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1177 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1178 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1181 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1183 if ( importLines.contains( it.value() ) )
1190 for (
const QString &line : std::as_const( lines ) )
1192 if ( line.contains( it.key() ) )
1200 importLines << it.value();
1204 lines = fileDocString + importLines + lines;
1213QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1214 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1217 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1219 auto safeName = [](
const QString &name ) -> QString {
1221 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1222 return s.replace( safeNameRe, u
"_"_s );
1226 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1260 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1264 QString description;
1265 switch ( source.source() )
1269 name = source.parameterName();
1270 value = modelParameters.value( source.parameterName() );
1271 description = parameterDefinition( source.parameterName() )->description();
1276 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1277 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1280 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1282 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1292 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1296 sources = availableSourcesForChild(
1302 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1306 QString description;
1308 switch ( source.source() )
1312 name = source.parameterName();
1313 value = modelParameters.value( source.parameterName() );
1314 description = parameterDefinition( source.parameterName() )->description();
1319 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1320 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1321 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1324 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1336 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1339 value = fromVar.
sink;
1340 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1348 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1353 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1354 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1355 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1356 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1357 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1361 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1365 QString description;
1367 switch ( source.source() )
1371 name = source.parameterName();
1372 value = modelParameters.value( source.parameterName() );
1373 description = parameterDefinition( source.parameterName() )->description();
1378 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1379 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1380 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1383 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1396 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1401 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1404 value = fromVar.
sink;
1405 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1410 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1412 featureSource = layer;
1414 if ( context && !featureSource )
1420 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1421 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1422 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1423 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1424 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1431 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1434 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1435 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1436 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1437 for ( ; varIt != variables.constEnd(); ++varIt )
1441 return scope.release();
1444QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1448 return QgsProcessingModelChildParameterSources();
1452QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1453 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1456 QgsProcessingModelChildParameterSources sources;
1459 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1460 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1466 if ( parameterTypes.contains( def->
type() ) )
1468 if ( !dataTypes.isEmpty() )
1484 bool ok = sourceDef->
dataTypes().isEmpty();
1485 const auto constDataTypes = sourceDef->
dataTypes();
1486 for (
int type : constDataTypes )
1488 if ( dataTypes.contains( type )
1506 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1510 QSet< QString > dependents;
1511 if ( !childId.isEmpty() )
1513 dependents = dependentChildAlgorithms( childId );
1514 dependents << childId;
1517 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1518 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1520 if ( dependents.contains( childIt->childId() ) )
1530 if ( outputTypes.contains( out->type() ) )
1532 if ( !dataTypes.isEmpty() )
1538 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1545 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1553QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1555 return mHelpContent;
1558void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1560 mHelpContent = helpContent;
1563void QgsProcessingModelAlgorithm::setName(
const QString &name )
1568void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1570 mModelGroup = group;
1573bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1578 if ( mChildAlgorithms.empty() )
1581 issues << QObject::tr(
"Model does not contain any algorithms" );
1584 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1586 QStringList childIssues;
1587 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1589 for (
const QString &issue : std::as_const( childIssues ) )
1591 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1597QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1599 return mChildAlgorithms;
1602void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1604 mParameterComponents = parameterComponents;
1607void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1609 mParameterComponents.insert( component.parameterName(), component );
1612QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1614 if ( !mParameterComponents.contains( name ) )
1616 QgsProcessingModelParameter &component = mParameterComponents[name];
1617 component.setParameterName( name );
1620 return mParameterComponents[name];
1623QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1625 QList< QgsProcessingModelParameter > res;
1626 QSet< QString > found;
1627 for (
const QString ¶meter : mParameterOrder )
1629 if ( mParameterComponents.contains( parameter ) )
1631 res << mParameterComponents.value( parameter );
1637 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1639 if ( !found.contains( it.key() ) )
1647void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1649 mParameterOrder = order;
1652QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1654 QList< QgsProcessingModelOutput > res;
1655 QSet< QString > found;
1657 for (
const QString &output : mOutputOrder )
1659 bool foundOutput =
false;
1660 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1662 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1663 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1665 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1667 res << outputIt.value();
1669 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1678 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1680 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1681 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1683 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1685 res << outputIt.value();
1693void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1695 mOutputOrder = order;
1698QString QgsProcessingModelAlgorithm::outputGroup()
const
1700 return mOutputGroup;
1703void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1705 mOutputGroup = group;
1708void QgsProcessingModelAlgorithm::updateDestinationParameters()
1711 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1712 while ( it.hasNext() )
1722 qDeleteAll( mOutputs );
1726 QSet< QString > usedFriendlyNames;
1727 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1728 const QString base = safeName( name,
false );
1729 QString candidate = base;
1731 while ( usedFriendlyNames.contains( candidate ) )
1734 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1736 usedFriendlyNames.insert( candidate );
1740 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1741 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1743 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1744 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1745 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1747 if ( !childIt->isActive() || !childIt->algorithm() )
1755 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1759 if ( outputIt->isMandatory() )
1761 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1763 QString friendlyName = uniqueSafeName( outputIt->description() );
1764 param->
setName( friendlyName );
1768 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1771 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1772 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1773 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1779 if ( addParameter( param.release() ) && newDestParam )
1786 newDestParam->mOriginalProvider = provider;
1793void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1795 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1798QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1800 return mGroupBoxes.values();
1803void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1805 mGroupBoxes.remove( uuid );
1808QVariant QgsProcessingModelAlgorithm::toVariant()
const
1811 map.insert( u
"model_name"_s, mModelName );
1812 map.insert( u
"model_group"_s, mModelGroup );
1813 map.insert( u
"help"_s, mHelpContent );
1816 QVariantMap childMap;
1817 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1818 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1820 childMap.insert( childIt.key(), childIt.value().toVariant() );
1822 map.insert( u
"children"_s, childMap );
1824 QVariantMap paramMap;
1825 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1826 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1828 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1830 map.insert( u
"parameters"_s, paramMap );
1832 QVariantMap paramDefMap;
1837 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1839 QVariantList groupBoxDefs;
1840 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1842 groupBoxDefs.append( it.value().toVariant() );
1844 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1846 map.insert( u
"modelVariables"_s, mVariables );
1848 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1850 map.insert( u
"parameterOrder"_s, mParameterOrder );
1851 map.insert( u
"outputOrder"_s, mOutputOrder );
1852 map.insert( u
"outputGroup"_s, mOutputGroup );
1857bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1859 QVariantMap map = model.toMap();
1861 mModelName = map.value( u
"model_name"_s ).toString();
1862 mModelGroup = map.value( u
"model_group"_s ).toString();
1863 mModelGroupId = map.value( u
"model_group"_s ).toString();
1864 mHelpContent = map.value( u
"help"_s ).toMap();
1866 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1868 mVariables = map.value( u
"modelVariables"_s ).toMap();
1869 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1871 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1872 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1873 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1875 mChildAlgorithms.clear();
1876 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1877 QVariantMap::const_iterator childIt = childMap.constBegin();
1878 for ( ; childIt != childMap.constEnd(); ++childIt )
1880 QgsProcessingModelChildAlgorithm child;
1884 if ( !child.loadVariant( childIt.value() ) )
1887 mChildAlgorithms.insert( child.childId(), child );
1890 mParameterComponents.clear();
1891 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1892 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1893 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1895 QgsProcessingModelParameter param;
1896 if ( !param.loadVariant( paramIt.value().toMap() ) )
1899 mParameterComponents.insert( param.parameterName(), param );
1902 qDeleteAll( mParameters );
1903 mParameters.clear();
1904 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1906 auto addParam = [
this](
const QVariant &value ) {
1913 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1917 param->setHelp( mHelpContent.value( param->name() ).toString() );
1920 addParameter( param.release() );
1924 QVariantMap map = value.toMap();
1925 QString type = map.value( u
"parameter_type"_s ).toString();
1926 QString name = map.value( u
"name"_s ).toString();
1928 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1932 QSet< QString > loadedParams;
1934 for (
const QString &name : std::as_const( mParameterOrder ) )
1936 if ( paramDefMap.contains( name ) )
1938 addParam( paramDefMap.value( name ) );
1939 loadedParams << name;
1943 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1944 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1946 if ( !loadedParams.contains( paramDefIt.key() ) )
1947 addParam( paramDefIt.value() );
1950 mGroupBoxes.clear();
1951 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1952 for (
const QVariant &groupBoxDef : groupBoxList )
1954 QgsProcessingModelGroupBox groupBox;
1955 groupBox.loadVariant( groupBoxDef.toMap() );
1956 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1959 updateDestinationParameters();
1964bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1970 acceptableDataTypes.empty()
1971 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1981void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1983 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1984 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1986 if ( !childIt->algorithm() )
1987 childIt->reattach();
1991bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1993 QDomDocument doc = QDomDocument( u
"model"_s );
1995 doc.appendChild( elem );
1998 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
2000 QTextStream stream( &file );
2001 doc.save( stream, 2 );
2008bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
2013 if ( file.open( QFile::ReadOnly ) )
2015 if ( !doc.setContent( &file ) )
2026 return loadVariant( props );
2029void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
2031 mChildAlgorithms = childAlgorithms;
2032 updateDestinationParameters();
2035void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
2038 updateDestinationParameters();
2041QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
2043 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
2047 updateDestinationParameters();
2051QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
2053 return mChildAlgorithms[childId];
2056bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
2058 if ( !dependentChildAlgorithms(
id ).isEmpty() )
2061 mChildAlgorithms.remove(
id );
2062 updateDestinationParameters();
2066void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
2068 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
2069 for (
const QString &child : constDependentChildAlgorithms )
2071 childAlgorithm( child ).setActive(
false );
2073 childAlgorithm(
id ).setActive(
false );
2074 updateDestinationParameters();
2077bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
2079 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
2080 for (
const QString &child : constDependsOnChildAlgorithms )
2082 if ( !childAlgorithm( child ).isActive() )
2085 childAlgorithm(
id ).setActive(
true );
2086 updateDestinationParameters();
2092 if ( addParameter( definition ) )
2093 mParameterComponents.insert( definition->
name(), component );
2098 removeParameter( definition->
name() );
2099 addParameter( definition );
2102void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2104 removeParameter( name );
2105 mParameterComponents.remove( name );
2108void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2113 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2115 expression.prepare( &expressionContext );
2116 QSet<QString> variables = expression.referencedVariables();
2117 if ( variables.contains( oldName ) )
2119 QString newExpression = expressionString;
2120 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2121 return {
true, newExpression };
2123 return {
false, QString() };
2126 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2127 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2129 bool changed =
false;
2130 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2131 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2132 for ( ; paramIt != childParams.end(); ++paramIt )
2134 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2135 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2137 switch ( valueIt->source() )
2141 if ( valueIt->parameterName() == oldName )
2143 valueIt->setParameterName( newName );
2151 bool updatedExpression =
false;
2152 QString newExpression;
2153 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2154 if ( updatedExpression )
2156 valueIt->setExpression( newExpression );
2164 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2169 bool updatedExpression =
false;
2170 QString newExpression;
2171 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2172 if ( updatedExpression )
2174 property.setExpressionString( newExpression );
2175 valueIt->setStaticValue( property );
2191 childIt->setParameterSources( childParams );
2195bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2197 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2198 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2201 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2202 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2203 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2205 const auto constValue = paramIt.value();
2206 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2218bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2220 const auto constMParameters = mParameters;
2223 if ( def->
name() == name )
2232QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2234 return mParameterComponents;
2237void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2239 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2240 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2242 if ( depends.contains( childIt->childId() ) )
2246 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2247 bool hasDependency =
false;
2248 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2250 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2252 hasDependency =
true;
2257 if ( hasDependency )
2259 depends.insert( childIt->childId() );
2260 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2265 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2266 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2267 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2269 const auto constValue = paramIt.value();
2270 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2274 depends.insert( childIt->childId() );
2275 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2283QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2285 QSet< QString > algs;
2289 algs.insert( childId );
2291 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2294 algs.remove( childId );
2300void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2302 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2305 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2306 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2308 if ( !depends.contains( val.childId ) )
2310 depends.insert( val.childId );
2311 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2316 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2317 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2318 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2320 const auto constValue = paramIt.value();
2321 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2323 switch ( source.source() )
2326 if ( !depends.contains( source.outputChildId() ) )
2328 depends.insert( source.outputChildId() );
2329 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2336 const QSet<QString> vars = exp.referencedVariables();
2341 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2342 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2348 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2352 depends.insert( childVarIt->source.outputChildId() );
2353 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2368QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2370 QSet< QString > algs;
2374 algs.insert( childId );
2376 dependsOnChildAlgorithmsRecursive( childId, algs );
2379 algs.remove( childId );
2384QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2386 QSet< QString > dependent;
2387 if ( !childId.isEmpty() )
2389 dependent.unite( dependentChildAlgorithms( childId ) );
2390 dependent.insert( childId );
2393 QList<QgsProcessingModelChildDependency> res;
2394 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2396 if ( !dependent.contains( it->childId() ) )
2399 bool hasBranches =
false;
2400 if ( it->algorithm() )
2408 QgsProcessingModelChildDependency alg;
2409 alg.childId = it->childId();
2410 alg.conditionalBranch = def->
name();
2418 QgsProcessingModelChildDependency alg;
2419 alg.childId = it->childId();
2427bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2430 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2431 if ( childIt != mChildAlgorithms.constEnd() )
2433 if ( !childIt->algorithm() )
2435 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2444 if ( childIt->parameterSources().contains( def->
name() ) )
2447 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2448 for (
const QgsProcessingModelChildParameterSource &source : sources )
2450 switch ( source.source() )
2456 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2461 if ( !parameterComponents().contains( source.parameterName() ) )
2464 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2469 if ( !childAlgorithms().contains( source.outputChildId() ) )
2472 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2494 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2503 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2508bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2510 reattachAlgorithms();
2511 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2512 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2514 if ( !childIt->algorithm() )
2518 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2526QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2528 if ( mSourceFile.isEmpty() )
2543 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2544 alg->loadVariant( toVariant() );
2545 alg->setProvider( provider() );
2546 alg->setSourceFilePath( sourceFilePath() );
2550QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2552 QString n = name.toLower().trimmed();
2553 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2554 n.replace( rx, QString() );
2555 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2556 n.replace( rx2, QString() );
2558 n = n.replace(
' ',
'_' );
2562QVariantMap QgsProcessingModelAlgorithm::variables()
const
2567void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2569 mVariables = variables;
2572QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2574 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.
#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.