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 if ( feedback && !skipGenericLogging )
441 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
453 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
454 if ( !error.isEmpty() )
463 if ( feedback && !skipGenericLogging )
464 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
469 childInputs.insert( childId, thisChildParams );
470 childResult.
setInputs( thisChildParams );
473 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
475 params << u
"%1: %2"_s.arg( childParamIt.key(), child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
478 if ( feedback && !skipGenericLogging )
480 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
481 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
484 QElapsedTimer childTime;
487 QVariantMap outerScopeChildInputs = childInputs;
488 QVariantMap outerScopePrevChildResults = childResults;
489 QSet< QString > outerScopeExecuted = executed;
490 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
491 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
495 childResults.clear();
497 contextChildResults.clear();
502 QThread *modelThread = QThread::currentThread();
504 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &childAlgorithmFeedback] {
505 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
506 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
507 context.pushToThread( modelThread );
511 if ( modelThread == qApp->thread() )
512 ok = childAlg->prepare( childParams, context, &childAlgorithmFeedback );
515 context.pushToThread( qApp->thread() );
517#ifndef __clang_analyzer__
518 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
522 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
541 bool runResult =
false;
549 childProgressConnection = QObject::connect( &childAlgorithmFeedback, &
QgsFeedback::progressChanged, &childAlgorithmFeedback, [&modelFeedback, &childId](
double progress ) {
557 auto runOnMainThread = [modelThread, &context, &childAlgorithmFeedback, &results, &childAlg, &childParams] {
558 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
559 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
560 context.pushToThread( modelThread );
563 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
564 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
566 context.pushToThread( qApp->thread() );
568#ifndef __clang_analyzer__
569 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
575 results = childAlg->runPrepared( childParams, context, &childAlgorithmFeedback );
586 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
589 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &childAlgorithmFeedback, runResult] {
590 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
591 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
592 context.pushToThread( modelThread );
596 if ( modelThread == qApp->thread() )
597 ppRes = childAlg->postProcess( context, &childAlgorithmFeedback, runResult );
600 context.pushToThread( qApp->thread() );
602#ifndef __clang_analyzer__
603 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
607 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
609 if ( !ppRes.isEmpty() )
612 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
614 childInputs = outerScopeChildInputs;
615 childResults = outerScopePrevChildResults;
616 executed = outerScopeExecuted;
617 contextChildResults = outerScopeContextChildResult;
620 childResults.insert( childId, results );
636 if ( feedback && !skipGenericLogging )
639 QStringList formattedOutputs;
640 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
645 feedback->
pushInfo( QObject::tr(
"Results:" ) );
646 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
651 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
652 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
654 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
655 switch ( mInternalVersion )
657 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
658 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
660 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
663 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
668 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
669 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
673 if ( outputSortKey > 0 )
678 executed.insert( childId );
680 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
681 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
682 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
683 for (
const QString &targetId : toPrune )
685 if ( executed.contains( targetId ) )
688 executed.insert( targetId );
693 pruneAlgorithmBranchRecursive( targetId, branch );
703 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
711 for (
const QString &candidateId : std::as_const( toExecute ) )
713 if ( executed.contains( candidateId ) )
718 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
719 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
720 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
722 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
724 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
729 if ( !results.contains( source.outputName() ) )
734 executed.insert( candidateId );
740 pruneAlgorithmBranchRecursive( candidateId, QString() );
751 childAlg.reset(
nullptr );
753 childAlgorithmFeedback.setCurrentStep( countExecuted );
754 if ( feedback && !skipGenericLogging )
756 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
761 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
762 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
766 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
767 const QString formattedRunTime
768 = 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 );
770 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
771 context.modelResult().childResults().insert( childId, childResult );
782 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
783 context.modelResult().childResults().insert( childId, childResult );
796 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 ) );
798 mResults = finalResults;
799 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
800 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
804QString QgsProcessingModelAlgorithm::sourceFilePath()
const
809void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
811 mSourceFile = sourceFile;
814bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
816 if ( mSourceFile.isEmpty() )
819 const QFileInfo fi( mSourceFile );
820 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
825 QStringList fileDocString;
826 fileDocString << u
"\"\"\""_s;
827 fileDocString << u
"Model exported as python."_s;
828 fileDocString << u
"Name : %1"_s.arg( displayName() );
829 fileDocString << u
"Group : %1"_s.arg( group() );
831 fileDocString << u
"\"\"\""_s;
832 fileDocString << QString();
835 QString indent = QString(
' ' ).repeated( indentSize );
836 QString currentIndent;
838 QMap< QString, QString> friendlyChildNames;
839 QMap< QString, QString> friendlyOutputNames;
840 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
841 const QString base = safeName( name, capitalize );
842 QString candidate = base;
845 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
848 candidate = u
"%1_%2"_s.arg( base ).arg( i );
853 const QString algorithmClassName = safeName( name(),
true );
855 QSet< QString > toExecute;
856 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
858 if ( childIt->isActive() && childIt->algorithm() )
860 toExecute.insert( childIt->childId() );
861 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
864 const int totalSteps = toExecute.count();
866 QStringList importLines;
867 switch ( outputType )
872 const auto params = parameterDefinitions();
873 importLines.reserve( params.count() + 6 );
874 importLines << u
"from typing import Any, Optional"_s;
875 importLines << QString();
876 importLines << u
"from qgis.core import QgsProcessing"_s;
877 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
878 importLines << u
"from qgis.core import QgsProcessingContext"_s;
879 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
881 bool hasAdvancedParams =
false;
885 hasAdvancedParams =
true;
889 const QString importString = type->pythonImportString();
890 if ( !importString.isEmpty() && !importLines.contains( importString ) )
891 importLines << importString;
895 if ( hasAdvancedParams )
896 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
898 lines << u
"from qgis import processing"_s;
899 lines << QString() << QString();
901 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
905 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
906 if ( params.empty() )
908 lines << indent + indent + u
"pass"_s;
912 lines.reserve( lines.size() + params.size() );
915 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
917 if ( defClone->isDestination() )
919 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
920 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
921 friendlyOutputNames.insert( uniqueChildName, friendlyName );
922 defClone->setName( friendlyName );
926 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
928 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
929 for (
const QString &part : parts )
931 lines << indent + indent + u
"# %1"_s.arg( part );
938 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
939 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
940 lines << indent + indent + u
"self.addParameter(param)"_s;
944 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
950 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
951 currentIndent = indent + indent;
953 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
954 lines << currentIndent + u
"# overall progress through the model"_s;
955 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
963 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
964 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
966 QString name = paramIt.value().parameterName();
967 if ( parameterDefinition( name ) )
970 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
974 if ( !params.isEmpty() )
976 lines << u
"parameters = {"_s;
977 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
979 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
985 lines << u
"context = QgsProcessingContext()"_s
986 << u
"context.setProject(QgsProject.instance())"_s
987 << u
"feedback = QgsProcessingFeedback()"_s
995 lines << currentIndent + u
"results = {}"_s;
996 lines << currentIndent + u
"outputs = {}"_s;
999 QSet< QString > executed;
1000 bool executedAlg =
true;
1001 int currentStep = 0;
1002 while ( executedAlg && executed.count() < toExecute.count() )
1004 executedAlg =
false;
1005 const auto constToExecute = toExecute;
1006 for (
const QString &childId : constToExecute )
1008 if ( executed.contains( childId ) )
1011 bool canExecute =
true;
1012 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
1013 for (
const QString &dependency : constDependsOnChildAlgorithms )
1015 if ( !executed.contains( dependency ) )
1027 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
1034 if ( def->isDestination() )
1039 bool isFinalOutput =
false;
1040 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
1041 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1042 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1044 if ( outputIt->childOutputName() == destParam->
name() )
1046 QString paramName = child.childId() +
':' + outputIt.key();
1047 paramName = friendlyOutputNames.value( paramName, paramName );
1048 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
1049 isFinalOutput =
true;
1054 if ( !isFinalOutput )
1059 bool required =
true;
1062 required = childOutputIsRequired( child.childId(), destParam->
name() );
1068 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1074 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1076 if ( currentStep < totalSteps )
1079 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1080 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1081 lines << currentIndent + indent + u
"return {}"_s;
1084 executed.insert( childId );
1088 switch ( outputType )
1091 lines << currentIndent + u
"return results"_s;
1095 lines << indent + u
"def name(self) -> str:"_s;
1096 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1098 lines << indent + u
"def displayName(self) -> str:"_s;
1099 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1103 lines << indent + u
"def group(self) -> str:"_s;
1104 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1106 lines << indent + u
"def groupId(self) -> str:"_s;
1107 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1111 if ( !shortHelpString().isEmpty() )
1113 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1114 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1117 if ( !helpUrl().isEmpty() )
1119 lines << indent + u
"def helpUrl(self) -> str:"_s;
1120 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1125 lines << indent + u
"def createInstance(self):"_s;
1126 lines << indent + indent + u
"return self.__class__()"_s;
1129 static QMap< QString, QString > sAdditionalImports {
1130 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1131 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1132 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1133 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1134 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1135 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1136 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1137 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1138 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1139 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1140 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1141 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1142 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1143 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1144 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1145 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1146 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1147 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1148 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1149 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1152 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1154 if ( importLines.contains( it.value() ) )
1161 for (
const QString &line : std::as_const( lines ) )
1163 if ( line.contains( it.key() ) )
1171 importLines << it.value();
1175 lines = fileDocString + importLines + lines;
1184QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1185 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1188 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1190 auto safeName = [](
const QString &name ) -> QString {
1192 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1193 return s.replace( safeNameRe, u
"_"_s );
1197 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1231 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1235 QString description;
1236 switch ( source.source() )
1240 name = source.parameterName();
1241 value = modelParameters.value( source.parameterName() );
1242 description = parameterDefinition( source.parameterName() )->description();
1247 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1248 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1251 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1253 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1263 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1267 sources = availableSourcesForChild(
1273 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1277 QString description;
1279 switch ( source.source() )
1283 name = source.parameterName();
1284 value = modelParameters.value( source.parameterName() );
1285 description = parameterDefinition( source.parameterName() )->description();
1290 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1291 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1292 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1295 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1307 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1310 value = fromVar.
sink;
1311 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1319 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1324 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1325 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1326 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1327 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1328 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1332 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1336 QString description;
1338 switch ( source.source() )
1342 name = source.parameterName();
1343 value = modelParameters.value( source.parameterName() );
1344 description = parameterDefinition( source.parameterName() )->description();
1349 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1350 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1351 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1354 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1367 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1372 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1375 value = fromVar.
sink;
1376 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1381 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1383 featureSource = layer;
1385 if ( context && !featureSource )
1391 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1392 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1393 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1394 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1395 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1402 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1405 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1406 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1407 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1408 for ( ; varIt != variables.constEnd(); ++varIt )
1412 return scope.release();
1415QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1419 return QgsProcessingModelChildParameterSources();
1423QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1424 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1427 QgsProcessingModelChildParameterSources sources;
1430 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1431 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1437 if ( parameterTypes.contains( def->
type() ) )
1439 if ( !dataTypes.isEmpty() )
1455 bool ok = sourceDef->
dataTypes().isEmpty();
1456 const auto constDataTypes = sourceDef->
dataTypes();
1457 for (
int type : constDataTypes )
1459 if ( dataTypes.contains( type )
1477 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1481 QSet< QString > dependents;
1482 if ( !childId.isEmpty() )
1484 dependents = dependentChildAlgorithms( childId );
1485 dependents << childId;
1488 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1489 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1491 if ( dependents.contains( childIt->childId() ) )
1501 if ( outputTypes.contains( out->type() ) )
1503 if ( !dataTypes.isEmpty() )
1509 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1516 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1524QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1526 return mHelpContent;
1529void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1531 mHelpContent = helpContent;
1534void QgsProcessingModelAlgorithm::setName(
const QString &name )
1539void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1541 mModelGroup = group;
1544bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1549 if ( mChildAlgorithms.empty() )
1552 issues << QObject::tr(
"Model does not contain any algorithms" );
1555 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1557 QStringList childIssues;
1558 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1560 for (
const QString &issue : std::as_const( childIssues ) )
1562 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1568QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1570 return mChildAlgorithms;
1573void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1575 mParameterComponents = parameterComponents;
1578void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1580 mParameterComponents.insert( component.parameterName(), component );
1583QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1585 if ( !mParameterComponents.contains( name ) )
1587 QgsProcessingModelParameter &component = mParameterComponents[name];
1588 component.setParameterName( name );
1591 return mParameterComponents[name];
1594QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1596 QList< QgsProcessingModelParameter > res;
1597 QSet< QString > found;
1598 for (
const QString ¶meter : mParameterOrder )
1600 if ( mParameterComponents.contains( parameter ) )
1602 res << mParameterComponents.value( parameter );
1608 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1610 if ( !found.contains( it.key() ) )
1618void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1620 mParameterOrder = order;
1623QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1625 QList< QgsProcessingModelOutput > res;
1626 QSet< QString > found;
1628 for (
const QString &output : mOutputOrder )
1630 bool foundOutput =
false;
1631 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1633 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1634 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1636 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1638 res << outputIt.value();
1640 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1649 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1651 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1652 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1654 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1656 res << outputIt.value();
1664void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1666 mOutputOrder = order;
1669QString QgsProcessingModelAlgorithm::outputGroup()
const
1671 return mOutputGroup;
1674void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1676 mOutputGroup = group;
1679void QgsProcessingModelAlgorithm::updateDestinationParameters()
1682 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1683 while ( it.hasNext() )
1693 qDeleteAll( mOutputs );
1697 QSet< QString > usedFriendlyNames;
1698 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1699 const QString base = safeName( name,
false );
1700 QString candidate = base;
1702 while ( usedFriendlyNames.contains( candidate ) )
1705 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1707 usedFriendlyNames.insert( candidate );
1711 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1712 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1714 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1715 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1716 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1718 if ( !childIt->isActive() || !childIt->algorithm() )
1726 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1730 if ( outputIt->isMandatory() )
1732 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1734 QString friendlyName = uniqueSafeName( outputIt->description() );
1735 param->
setName( friendlyName );
1739 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1742 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1743 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1744 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1750 if ( addParameter( param.release() ) && newDestParam )
1757 newDestParam->mOriginalProvider = provider;
1764void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1766 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1769QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1771 return mGroupBoxes.values();
1774void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1776 mGroupBoxes.remove( uuid );
1779QVariant QgsProcessingModelAlgorithm::toVariant()
const
1782 map.insert( u
"model_name"_s, mModelName );
1783 map.insert( u
"model_group"_s, mModelGroup );
1784 map.insert( u
"help"_s, mHelpContent );
1787 QVariantMap childMap;
1788 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1789 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1791 childMap.insert( childIt.key(), childIt.value().toVariant() );
1793 map.insert( u
"children"_s, childMap );
1795 QVariantMap paramMap;
1796 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1797 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1799 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1801 map.insert( u
"parameters"_s, paramMap );
1803 QVariantMap paramDefMap;
1808 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1810 QVariantList groupBoxDefs;
1811 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1813 groupBoxDefs.append( it.value().toVariant() );
1815 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1817 map.insert( u
"modelVariables"_s, mVariables );
1819 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1821 map.insert( u
"parameterOrder"_s, mParameterOrder );
1822 map.insert( u
"outputOrder"_s, mOutputOrder );
1823 map.insert( u
"outputGroup"_s, mOutputGroup );
1828bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1830 QVariantMap map = model.toMap();
1832 mModelName = map.value( u
"model_name"_s ).toString();
1833 mModelGroup = map.value( u
"model_group"_s ).toString();
1834 mModelGroupId = map.value( u
"model_group"_s ).toString();
1835 mHelpContent = map.value( u
"help"_s ).toMap();
1837 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1839 mVariables = map.value( u
"modelVariables"_s ).toMap();
1840 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1842 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1843 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1844 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1846 mChildAlgorithms.clear();
1847 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1848 QVariantMap::const_iterator childIt = childMap.constBegin();
1849 for ( ; childIt != childMap.constEnd(); ++childIt )
1851 QgsProcessingModelChildAlgorithm child;
1855 if ( !child.loadVariant( childIt.value() ) )
1858 mChildAlgorithms.insert( child.childId(), child );
1861 mParameterComponents.clear();
1862 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1863 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1864 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1866 QgsProcessingModelParameter param;
1867 if ( !param.loadVariant( paramIt.value().toMap() ) )
1870 mParameterComponents.insert( param.parameterName(), param );
1873 qDeleteAll( mParameters );
1874 mParameters.clear();
1875 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1877 auto addParam = [
this](
const QVariant &value ) {
1884 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1888 param->setHelp( mHelpContent.value( param->name() ).toString() );
1891 addParameter( param.release() );
1895 QVariantMap map = value.toMap();
1896 QString type = map.value( u
"parameter_type"_s ).toString();
1897 QString name = map.value( u
"name"_s ).toString();
1899 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1903 QSet< QString > loadedParams;
1905 for (
const QString &name : std::as_const( mParameterOrder ) )
1907 if ( paramDefMap.contains( name ) )
1909 addParam( paramDefMap.value( name ) );
1910 loadedParams << name;
1914 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1915 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1917 if ( !loadedParams.contains( paramDefIt.key() ) )
1918 addParam( paramDefIt.value() );
1921 mGroupBoxes.clear();
1922 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1923 for (
const QVariant &groupBoxDef : groupBoxList )
1925 QgsProcessingModelGroupBox groupBox;
1926 groupBox.loadVariant( groupBoxDef.toMap() );
1927 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1930 updateDestinationParameters();
1935bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1941 acceptableDataTypes.empty()
1942 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1952void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1954 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1955 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1957 if ( !childIt->algorithm() )
1958 childIt->reattach();
1962bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1964 QDomDocument doc = QDomDocument( u
"model"_s );
1966 doc.appendChild( elem );
1969 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1971 QTextStream stream( &file );
1972 doc.save( stream, 2 );
1979bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1984 if ( file.open( QFile::ReadOnly ) )
1986 if ( !doc.setContent( &file ) )
1997 return loadVariant( props );
2000void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
2002 mChildAlgorithms = childAlgorithms;
2003 updateDestinationParameters();
2006void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
2009 updateDestinationParameters();
2012QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
2014 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
2018 updateDestinationParameters();
2022QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
2024 return mChildAlgorithms[childId];
2027bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
2029 if ( !dependentChildAlgorithms(
id ).isEmpty() )
2032 mChildAlgorithms.remove(
id );
2033 updateDestinationParameters();
2037void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
2039 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
2040 for (
const QString &child : constDependentChildAlgorithms )
2042 childAlgorithm( child ).setActive(
false );
2044 childAlgorithm(
id ).setActive(
false );
2045 updateDestinationParameters();
2048bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
2050 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
2051 for (
const QString &child : constDependsOnChildAlgorithms )
2053 if ( !childAlgorithm( child ).isActive() )
2056 childAlgorithm(
id ).setActive(
true );
2057 updateDestinationParameters();
2063 if ( addParameter( definition ) )
2064 mParameterComponents.insert( definition->
name(), component );
2069 removeParameter( definition->
name() );
2070 addParameter( definition );
2073void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2075 removeParameter( name );
2076 mParameterComponents.remove( name );
2079void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2084 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2086 expression.prepare( &expressionContext );
2087 QSet<QString> variables = expression.referencedVariables();
2088 if ( variables.contains( oldName ) )
2090 QString newExpression = expressionString;
2091 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2092 return {
true, newExpression };
2094 return {
false, QString() };
2097 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2098 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2100 bool changed =
false;
2101 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2102 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2103 for ( ; paramIt != childParams.end(); ++paramIt )
2105 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2106 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2108 switch ( valueIt->source() )
2112 if ( valueIt->parameterName() == oldName )
2114 valueIt->setParameterName( newName );
2122 bool updatedExpression =
false;
2123 QString newExpression;
2124 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2125 if ( updatedExpression )
2127 valueIt->setExpression( newExpression );
2135 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2140 bool updatedExpression =
false;
2141 QString newExpression;
2142 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2143 if ( updatedExpression )
2145 property.setExpressionString( newExpression );
2146 valueIt->setStaticValue( property );
2162 childIt->setParameterSources( childParams );
2166bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2168 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2169 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2172 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2173 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2174 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2176 const auto constValue = paramIt.value();
2177 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2189bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2191 const auto constMParameters = mParameters;
2194 if ( def->
name() == name )
2203QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2205 return mParameterComponents;
2208void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2210 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2211 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2213 if ( depends.contains( childIt->childId() ) )
2217 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2218 bool hasDependency =
false;
2219 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2221 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2223 hasDependency =
true;
2228 if ( hasDependency )
2230 depends.insert( childIt->childId() );
2231 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2236 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2237 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2238 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2240 const auto constValue = paramIt.value();
2241 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2245 depends.insert( childIt->childId() );
2246 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2254QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2256 QSet< QString > algs;
2260 algs.insert( childId );
2262 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2265 algs.remove( childId );
2271void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2273 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2276 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2277 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2279 if ( !depends.contains( val.childId ) )
2281 depends.insert( val.childId );
2282 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2287 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2288 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2289 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2291 const auto constValue = paramIt.value();
2292 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2294 switch ( source.source() )
2297 if ( !depends.contains( source.outputChildId() ) )
2299 depends.insert( source.outputChildId() );
2300 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2307 const QSet<QString> vars = exp.referencedVariables();
2312 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2313 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2319 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2323 depends.insert( childVarIt->source.outputChildId() );
2324 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2339QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2341 QSet< QString > algs;
2345 algs.insert( childId );
2347 dependsOnChildAlgorithmsRecursive( childId, algs );
2350 algs.remove( childId );
2355QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2357 QSet< QString > dependent;
2358 if ( !childId.isEmpty() )
2360 dependent.unite( dependentChildAlgorithms( childId ) );
2361 dependent.insert( childId );
2364 QList<QgsProcessingModelChildDependency> res;
2365 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2367 if ( !dependent.contains( it->childId() ) )
2370 bool hasBranches =
false;
2371 if ( it->algorithm() )
2379 QgsProcessingModelChildDependency alg;
2380 alg.childId = it->childId();
2381 alg.conditionalBranch = def->
name();
2389 QgsProcessingModelChildDependency alg;
2390 alg.childId = it->childId();
2398bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2401 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2402 if ( childIt != mChildAlgorithms.constEnd() )
2404 if ( !childIt->algorithm() )
2406 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2415 if ( childIt->parameterSources().contains( def->
name() ) )
2418 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2419 for (
const QgsProcessingModelChildParameterSource &source : sources )
2421 switch ( source.source() )
2427 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2432 if ( !parameterComponents().contains( source.parameterName() ) )
2435 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2440 if ( !childAlgorithms().contains( source.outputChildId() ) )
2443 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2465 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2474 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2479bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2481 reattachAlgorithms();
2482 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2483 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2485 if ( !childIt->algorithm() )
2489 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2497QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2499 if ( mSourceFile.isEmpty() )
2514 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2515 alg->loadVariant( toVariant() );
2516 alg->setProvider( provider() );
2517 alg->setSourceFilePath( sourceFilePath() );
2521QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2523 QString n = name.toLower().trimmed();
2524 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2525 n.replace( rx, QString() );
2526 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2527 n.replace( rx2, QString() );
2529 n = n.replace(
' ',
'_' );
2533QVariantMap QgsProcessingModelAlgorithm::variables()
const
2538void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2540 mVariables = variables;
2543QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2545 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.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
Encapsulates the results of running a child algorithm within a model.
void setOutputs(const QVariantMap &outputs)
Sets the outputs generated by child algorithm.
void setExecutionStatus(Qgis::ProcessingModelChildAlgorithmExecutionStatus status)
Sets the status of executing the child algorithm.
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 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.
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.