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 auto runOnMainThread = [modelThread, &context, &childAlgorithmFeedback, &results, &childAlg, &childParams] {
570 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
571 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
572 context.pushToThread( modelThread );
575 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
576 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
578 context.pushToThread( qApp->thread() );
580#ifndef __clang_analyzer__
581 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
587 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
598 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
601 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &childAlgorithmFeedback, runResult] {
602 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
603 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
604 context.pushToThread( modelThread );
608 if ( modelThread == qApp->thread() )
609 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
612 context.pushToThread( qApp->thread() );
614#ifndef __clang_analyzer__
615 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
619 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
621 if ( !ppRes.isEmpty() )
624 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
626 childInputs = outerScopeChildInputs;
627 childResults = outerScopePrevChildResults;
628 executed = outerScopeExecuted;
629 contextChildResults = outerScopeContextChildResult;
632 childResults.insert( childId, results );
648 if ( feedback && !skipGenericLogging )
651 QStringList formattedOutputs;
652 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
657 feedback->
pushInfo( QObject::tr(
"Results:" ) );
658 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
663 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
664 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
666 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
667 switch ( mInternalVersion )
669 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
670 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
672 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
675 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
680 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
681 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
685 if ( outputSortKey > 0 )
690 executed.insert( childId );
692 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
693 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
694 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
695 for (
const QString &targetId : toPrune )
697 if ( executed.contains( targetId ) )
700 executed.insert( targetId );
705 pruneAlgorithmBranchRecursive( targetId, branch );
715 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
723 for (
const QString &candidateId : std::as_const( toExecute ) )
725 if ( executed.contains( candidateId ) )
730 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
731 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
732 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
734 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
736 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
741 if ( !results.contains( source.outputName() ) )
746 executed.insert( candidateId );
752 pruneAlgorithmBranchRecursive( candidateId, QString() );
763 childAlg.reset(
nullptr );
765 childAlgorithmFeedback.setCurrentStep( countExecuted );
766 if ( feedback && !skipGenericLogging )
768 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
773 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
774 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
778 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
779 const QString formattedRunTime
780 = 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 );
782 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
783 context.modelResult().childResults().insert( childId, childResult );
794 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
795 context.modelResult().childResults().insert( childId, childResult );
808 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 ) );
810 mResults = finalResults;
811 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
812 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
816QString QgsProcessingModelAlgorithm::sourceFilePath()
const
821void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
823 mSourceFile = sourceFile;
826bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
828 if ( mSourceFile.isEmpty() )
831 const QFileInfo fi( mSourceFile );
832 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
837 QStringList fileDocString;
838 fileDocString << u
"\"\"\""_s;
839 fileDocString << u
"Model exported as python."_s;
840 fileDocString << u
"Name : %1"_s.arg( displayName() );
841 fileDocString << u
"Group : %1"_s.arg( group() );
843 fileDocString << u
"\"\"\""_s;
844 fileDocString << QString();
847 QString indent = QString(
' ' ).repeated( indentSize );
848 QString currentIndent;
850 QMap< QString, QString> friendlyChildNames;
851 QMap< QString, QString> friendlyOutputNames;
852 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
853 const QString base = safeName( name, capitalize );
854 QString candidate = base;
857 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
860 candidate = u
"%1_%2"_s.arg( base ).arg( i );
865 const QString algorithmClassName = safeName( name(),
true );
867 QSet< QString > toExecute;
868 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
870 if ( childIt->isActive() && childIt->algorithm() )
872 toExecute.insert( childIt->childId() );
873 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
876 const int totalSteps = toExecute.count();
878 QStringList importLines;
879 switch ( outputType )
884 const auto params = parameterDefinitions();
885 importLines.reserve( params.count() + 6 );
886 importLines << u
"from typing import Any, Optional"_s;
887 importLines << QString();
888 importLines << u
"from qgis.core import QgsProcessing"_s;
889 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
890 importLines << u
"from qgis.core import QgsProcessingContext"_s;
891 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
893 bool hasAdvancedParams =
false;
897 hasAdvancedParams =
true;
901 const QString importString = type->pythonImportString();
902 if ( !importString.isEmpty() && !importLines.contains( importString ) )
903 importLines << importString;
907 if ( hasAdvancedParams )
908 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
910 lines << u
"from qgis import processing"_s;
911 lines << QString() << QString();
913 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
917 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
918 if ( params.empty() )
920 lines << indent + indent + u
"pass"_s;
924 lines.reserve( lines.size() + params.size() );
927 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
929 if ( defClone->isDestination() )
931 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
932 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
933 friendlyOutputNames.insert( uniqueChildName, friendlyName );
934 defClone->setName( friendlyName );
938 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
940 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
941 for (
const QString &part : parts )
943 lines << indent + indent + u
"# %1"_s.arg( part );
950 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
951 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
952 lines << indent + indent + u
"self.addParameter(param)"_s;
956 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
962 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
963 currentIndent = indent + indent;
965 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
966 lines << currentIndent + u
"# overall progress through the model"_s;
967 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
975 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
976 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
978 QString name = paramIt.value().parameterName();
979 if ( parameterDefinition( name ) )
982 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
986 if ( !params.isEmpty() )
988 lines << u
"parameters = {"_s;
989 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
991 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
997 lines << u
"context = QgsProcessingContext()"_s
998 << u
"context.setProject(QgsProject.instance())"_s
999 << u
"feedback = QgsProcessingFeedback()"_s
1007 lines << currentIndent + u
"results = {}"_s;
1008 lines << currentIndent + u
"outputs = {}"_s;
1011 QSet< QString > executed;
1012 bool executedAlg =
true;
1013 int currentStep = 0;
1014 while ( executedAlg && executed.count() < toExecute.count() )
1016 executedAlg =
false;
1017 const auto constToExecute = toExecute;
1018 for (
const QString &childId : constToExecute )
1020 if ( executed.contains( childId ) )
1023 bool canExecute =
true;
1024 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
1025 for (
const QString &dependency : constDependsOnChildAlgorithms )
1027 if ( !executed.contains( dependency ) )
1039 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
1046 if ( def->isDestination() )
1051 bool isFinalOutput =
false;
1052 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
1053 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1054 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1056 if ( outputIt->childOutputName() == destParam->
name() )
1058 QString paramName = child.childId() +
':' + outputIt.key();
1059 paramName = friendlyOutputNames.value( paramName, paramName );
1060 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
1061 isFinalOutput =
true;
1066 if ( !isFinalOutput )
1071 bool required =
true;
1074 required = childOutputIsRequired( child.childId(), destParam->
name() );
1080 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1086 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1088 if ( currentStep < totalSteps )
1091 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1092 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1093 lines << currentIndent + indent + u
"return {}"_s;
1096 executed.insert( childId );
1100 switch ( outputType )
1103 lines << currentIndent + u
"return results"_s;
1107 lines << indent + u
"def name(self) -> str:"_s;
1108 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1110 lines << indent + u
"def displayName(self) -> str:"_s;
1111 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1115 lines << indent + u
"def group(self) -> str:"_s;
1116 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1118 lines << indent + u
"def groupId(self) -> str:"_s;
1119 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1123 if ( !shortHelpString().isEmpty() )
1125 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1126 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1129 if ( !helpUrl().isEmpty() )
1131 lines << indent + u
"def helpUrl(self) -> str:"_s;
1132 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1137 lines << indent + u
"def createInstance(self):"_s;
1138 lines << indent + indent + u
"return self.__class__()"_s;
1141 static QMap< QString, QString > sAdditionalImports {
1142 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1143 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1144 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1145 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1146 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1147 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1148 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1149 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1150 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1151 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1152 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1153 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1154 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1155 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1156 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1157 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1158 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1159 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1160 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1161 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1164 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1166 if ( importLines.contains( it.value() ) )
1173 for (
const QString &line : std::as_const( lines ) )
1175 if ( line.contains( it.key() ) )
1183 importLines << it.value();
1187 lines = fileDocString + importLines + lines;
1196QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1197 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1200 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1202 auto safeName = [](
const QString &name ) -> QString {
1204 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1205 return s.replace( safeNameRe, u
"_"_s );
1209 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1243 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1247 QString description;
1248 switch ( source.source() )
1252 name = source.parameterName();
1253 value = modelParameters.value( source.parameterName() );
1254 description = parameterDefinition( source.parameterName() )->description();
1259 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1260 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1263 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1265 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1275 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1279 sources = availableSourcesForChild(
1285 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1289 QString description;
1291 switch ( source.source() )
1295 name = source.parameterName();
1296 value = modelParameters.value( source.parameterName() );
1297 description = parameterDefinition( source.parameterName() )->description();
1302 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1303 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1304 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1307 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1319 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1322 value = fromVar.
sink;
1323 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1331 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1336 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1337 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1338 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1339 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1340 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1344 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1348 QString description;
1350 switch ( source.source() )
1354 name = source.parameterName();
1355 value = modelParameters.value( source.parameterName() );
1356 description = parameterDefinition( source.parameterName() )->description();
1361 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1362 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1363 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1366 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1379 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1384 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1387 value = fromVar.
sink;
1388 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1393 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1395 featureSource = layer;
1397 if ( context && !featureSource )
1403 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1404 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1405 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1406 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1407 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1414 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1417 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1418 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1419 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1420 for ( ; varIt != variables.constEnd(); ++varIt )
1424 return scope.release();
1427QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1431 return QgsProcessingModelChildParameterSources();
1435QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1436 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1439 QgsProcessingModelChildParameterSources sources;
1442 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1443 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1449 if ( parameterTypes.contains( def->
type() ) )
1451 if ( !dataTypes.isEmpty() )
1467 bool ok = sourceDef->
dataTypes().isEmpty();
1468 const auto constDataTypes = sourceDef->
dataTypes();
1469 for (
int type : constDataTypes )
1471 if ( dataTypes.contains( type )
1489 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1493 QSet< QString > dependents;
1494 if ( !childId.isEmpty() )
1496 dependents = dependentChildAlgorithms( childId );
1497 dependents << childId;
1500 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1501 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1503 if ( dependents.contains( childIt->childId() ) )
1513 if ( outputTypes.contains( out->type() ) )
1515 if ( !dataTypes.isEmpty() )
1521 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1528 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1536QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1538 return mHelpContent;
1541void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1543 mHelpContent = helpContent;
1546void QgsProcessingModelAlgorithm::setName(
const QString &name )
1551void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1553 mModelGroup = group;
1556bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1561 if ( mChildAlgorithms.empty() )
1564 issues << QObject::tr(
"Model does not contain any algorithms" );
1567 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1569 QStringList childIssues;
1570 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1572 for (
const QString &issue : std::as_const( childIssues ) )
1574 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1580QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1582 return mChildAlgorithms;
1585void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1587 mParameterComponents = parameterComponents;
1590void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1592 mParameterComponents.insert( component.parameterName(), component );
1595QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1597 if ( !mParameterComponents.contains( name ) )
1599 QgsProcessingModelParameter &component = mParameterComponents[name];
1600 component.setParameterName( name );
1603 return mParameterComponents[name];
1606QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1608 QList< QgsProcessingModelParameter > res;
1609 QSet< QString > found;
1610 for (
const QString ¶meter : mParameterOrder )
1612 if ( mParameterComponents.contains( parameter ) )
1614 res << mParameterComponents.value( parameter );
1620 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1622 if ( !found.contains( it.key() ) )
1630void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1632 mParameterOrder = order;
1635QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1637 QList< QgsProcessingModelOutput > res;
1638 QSet< QString > found;
1640 for (
const QString &output : mOutputOrder )
1642 bool foundOutput =
false;
1643 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1645 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1646 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1648 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1650 res << outputIt.value();
1652 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1661 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1663 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1664 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1666 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1668 res << outputIt.value();
1676void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1678 mOutputOrder = order;
1681QString QgsProcessingModelAlgorithm::outputGroup()
const
1683 return mOutputGroup;
1686void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1688 mOutputGroup = group;
1691void QgsProcessingModelAlgorithm::updateDestinationParameters()
1694 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1695 while ( it.hasNext() )
1705 qDeleteAll( mOutputs );
1709 QSet< QString > usedFriendlyNames;
1710 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1711 const QString base = safeName( name,
false );
1712 QString candidate = base;
1714 while ( usedFriendlyNames.contains( candidate ) )
1717 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1719 usedFriendlyNames.insert( candidate );
1723 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1724 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1726 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1727 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1728 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1730 if ( !childIt->isActive() || !childIt->algorithm() )
1738 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1742 if ( outputIt->isMandatory() )
1744 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1746 QString friendlyName = uniqueSafeName( outputIt->description() );
1747 param->
setName( friendlyName );
1751 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1754 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1755 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1756 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1762 if ( addParameter( param.release() ) && newDestParam )
1769 newDestParam->mOriginalProvider = provider;
1776void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1778 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1781QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1783 return mGroupBoxes.values();
1786void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1788 mGroupBoxes.remove( uuid );
1791QVariant QgsProcessingModelAlgorithm::toVariant()
const
1794 map.insert( u
"model_name"_s, mModelName );
1795 map.insert( u
"model_group"_s, mModelGroup );
1796 map.insert( u
"help"_s, mHelpContent );
1799 QVariantMap childMap;
1800 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1801 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1803 childMap.insert( childIt.key(), childIt.value().toVariant() );
1805 map.insert( u
"children"_s, childMap );
1807 QVariantMap paramMap;
1808 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1809 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1811 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1813 map.insert( u
"parameters"_s, paramMap );
1815 QVariantMap paramDefMap;
1820 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1822 QVariantList groupBoxDefs;
1823 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1825 groupBoxDefs.append( it.value().toVariant() );
1827 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1829 map.insert( u
"modelVariables"_s, mVariables );
1831 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1833 map.insert( u
"parameterOrder"_s, mParameterOrder );
1834 map.insert( u
"outputOrder"_s, mOutputOrder );
1835 map.insert( u
"outputGroup"_s, mOutputGroup );
1840bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1842 QVariantMap map = model.toMap();
1844 mModelName = map.value( u
"model_name"_s ).toString();
1845 mModelGroup = map.value( u
"model_group"_s ).toString();
1846 mModelGroupId = map.value( u
"model_group"_s ).toString();
1847 mHelpContent = map.value( u
"help"_s ).toMap();
1849 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1851 mVariables = map.value( u
"modelVariables"_s ).toMap();
1852 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1854 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1855 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1856 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1858 mChildAlgorithms.clear();
1859 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1860 QVariantMap::const_iterator childIt = childMap.constBegin();
1861 for ( ; childIt != childMap.constEnd(); ++childIt )
1863 QgsProcessingModelChildAlgorithm child;
1867 if ( !child.loadVariant( childIt.value() ) )
1870 mChildAlgorithms.insert( child.childId(), child );
1873 mParameterComponents.clear();
1874 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1875 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1876 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1878 QgsProcessingModelParameter param;
1879 if ( !param.loadVariant( paramIt.value().toMap() ) )
1882 mParameterComponents.insert( param.parameterName(), param );
1885 qDeleteAll( mParameters );
1886 mParameters.clear();
1887 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1889 auto addParam = [
this](
const QVariant &value ) {
1896 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1900 param->setHelp( mHelpContent.value( param->name() ).toString() );
1903 addParameter( param.release() );
1907 QVariantMap map = value.toMap();
1908 QString type = map.value( u
"parameter_type"_s ).toString();
1909 QString name = map.value( u
"name"_s ).toString();
1911 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1915 QSet< QString > loadedParams;
1917 for (
const QString &name : std::as_const( mParameterOrder ) )
1919 if ( paramDefMap.contains( name ) )
1921 addParam( paramDefMap.value( name ) );
1922 loadedParams << name;
1926 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1927 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1929 if ( !loadedParams.contains( paramDefIt.key() ) )
1930 addParam( paramDefIt.value() );
1933 mGroupBoxes.clear();
1934 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1935 for (
const QVariant &groupBoxDef : groupBoxList )
1937 QgsProcessingModelGroupBox groupBox;
1938 groupBox.loadVariant( groupBoxDef.toMap() );
1939 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1942 updateDestinationParameters();
1947bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1953 acceptableDataTypes.empty()
1954 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1964void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1966 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1967 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1969 if ( !childIt->algorithm() )
1970 childIt->reattach();
1974bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1976 QDomDocument doc = QDomDocument( u
"model"_s );
1978 doc.appendChild( elem );
1981 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1983 QTextStream stream( &file );
1984 doc.save( stream, 2 );
1991bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1996 if ( file.open( QFile::ReadOnly ) )
1998 if ( !doc.setContent( &file ) )
2009 return loadVariant( props );
2012void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
2014 mChildAlgorithms = childAlgorithms;
2015 updateDestinationParameters();
2018void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
2021 updateDestinationParameters();
2024QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
2026 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
2030 updateDestinationParameters();
2034QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
2036 return mChildAlgorithms[childId];
2039bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
2041 if ( !dependentChildAlgorithms(
id ).isEmpty() )
2044 mChildAlgorithms.remove(
id );
2045 updateDestinationParameters();
2049void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
2051 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
2052 for (
const QString &child : constDependentChildAlgorithms )
2054 childAlgorithm( child ).setActive(
false );
2056 childAlgorithm(
id ).setActive(
false );
2057 updateDestinationParameters();
2060bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
2062 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
2063 for (
const QString &child : constDependsOnChildAlgorithms )
2065 if ( !childAlgorithm( child ).isActive() )
2068 childAlgorithm(
id ).setActive(
true );
2069 updateDestinationParameters();
2075 if ( addParameter( definition ) )
2076 mParameterComponents.insert( definition->
name(), component );
2081 removeParameter( definition->
name() );
2082 addParameter( definition );
2085void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2087 removeParameter( name );
2088 mParameterComponents.remove( name );
2091void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2096 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2098 expression.prepare( &expressionContext );
2099 QSet<QString> variables = expression.referencedVariables();
2100 if ( variables.contains( oldName ) )
2102 QString newExpression = expressionString;
2103 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2104 return {
true, newExpression };
2106 return {
false, QString() };
2109 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2110 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2112 bool changed =
false;
2113 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2114 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2115 for ( ; paramIt != childParams.end(); ++paramIt )
2117 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2118 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2120 switch ( valueIt->source() )
2124 if ( valueIt->parameterName() == oldName )
2126 valueIt->setParameterName( newName );
2134 bool updatedExpression =
false;
2135 QString newExpression;
2136 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2137 if ( updatedExpression )
2139 valueIt->setExpression( newExpression );
2147 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2152 bool updatedExpression =
false;
2153 QString newExpression;
2154 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2155 if ( updatedExpression )
2157 property.setExpressionString( newExpression );
2158 valueIt->setStaticValue( property );
2174 childIt->setParameterSources( childParams );
2178bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2180 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2181 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2184 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2185 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2186 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2188 const auto constValue = paramIt.value();
2189 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2201bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2203 const auto constMParameters = mParameters;
2206 if ( def->
name() == name )
2215QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2217 return mParameterComponents;
2220void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2222 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2223 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2225 if ( depends.contains( childIt->childId() ) )
2229 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2230 bool hasDependency =
false;
2231 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2233 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2235 hasDependency =
true;
2240 if ( hasDependency )
2242 depends.insert( childIt->childId() );
2243 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2248 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2249 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2250 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2252 const auto constValue = paramIt.value();
2253 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2257 depends.insert( childIt->childId() );
2258 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2266QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2268 QSet< QString > algs;
2272 algs.insert( childId );
2274 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2277 algs.remove( childId );
2283void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2285 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2288 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2289 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2291 if ( !depends.contains( val.childId ) )
2293 depends.insert( val.childId );
2294 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2299 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2300 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2301 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2303 const auto constValue = paramIt.value();
2304 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2306 switch ( source.source() )
2309 if ( !depends.contains( source.outputChildId() ) )
2311 depends.insert( source.outputChildId() );
2312 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2319 const QSet<QString> vars = exp.referencedVariables();
2324 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2325 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2331 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2335 depends.insert( childVarIt->source.outputChildId() );
2336 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2351QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2353 QSet< QString > algs;
2357 algs.insert( childId );
2359 dependsOnChildAlgorithmsRecursive( childId, algs );
2362 algs.remove( childId );
2367QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2369 QSet< QString > dependent;
2370 if ( !childId.isEmpty() )
2372 dependent.unite( dependentChildAlgorithms( childId ) );
2373 dependent.insert( childId );
2376 QList<QgsProcessingModelChildDependency> res;
2377 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2379 if ( !dependent.contains( it->childId() ) )
2382 bool hasBranches =
false;
2383 if ( it->algorithm() )
2391 QgsProcessingModelChildDependency alg;
2392 alg.childId = it->childId();
2393 alg.conditionalBranch = def->
name();
2401 QgsProcessingModelChildDependency alg;
2402 alg.childId = it->childId();
2410bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2413 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2414 if ( childIt != mChildAlgorithms.constEnd() )
2416 if ( !childIt->algorithm() )
2418 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2427 if ( childIt->parameterSources().contains( def->
name() ) )
2430 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2431 for (
const QgsProcessingModelChildParameterSource &source : sources )
2433 switch ( source.source() )
2439 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2444 if ( !parameterComponents().contains( source.parameterName() ) )
2447 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2452 if ( !childAlgorithms().contains( source.outputChildId() ) )
2455 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2477 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2486 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2491bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2493 reattachAlgorithms();
2494 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2495 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2497 if ( !childIt->algorithm() )
2501 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2509QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2511 if ( mSourceFile.isEmpty() )
2526 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2527 alg->loadVariant( toVariant() );
2528 alg->setProvider( provider() );
2529 alg->setSourceFilePath( sourceFilePath() );
2533QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2535 QString n = name.toLower().trimmed();
2536 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2537 n.replace( rx, QString() );
2538 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2539 n.replace( rx2, QString() );
2541 n = n.replace(
' ',
'_' );
2545QVariantMap QgsProcessingModelAlgorithm::variables()
const
2550void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2552 mVariables = variables;
2555QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2557 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.