35#include <QRegularExpression>
39#include "moc_qgsprocessingmodelalgorithm.cpp"
41using namespace Qt::StringLiterals;
45QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
46 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
47 , mModelGroup( group )
48 , mModelGroupId( groupId )
51void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
60 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
61 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
72QString QgsProcessingModelAlgorithm::name()
const
77QString QgsProcessingModelAlgorithm::displayName()
const
82QString QgsProcessingModelAlgorithm::group()
const
87QString QgsProcessingModelAlgorithm::groupId()
const
92QIcon QgsProcessingModelAlgorithm::icon()
const
97QString QgsProcessingModelAlgorithm::svgIconPath()
const
102QString QgsProcessingModelAlgorithm::shortHelpString()
const
104 if ( mHelpContent.empty() )
110QString QgsProcessingModelAlgorithm::shortDescription()
const
112 return mHelpContent.value( u
"SHORT_DESCRIPTION"_s ).toString();
115QString QgsProcessingModelAlgorithm::helpUrl()
const
117 return mHelpContent.value( u
"HELP_URL"_s ).toString();
120QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
125 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
127 QString expressionText;
128 QVariantList paramParts;
129 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
131 switch ( source.source() )
134 paramParts << source.staticValue();
138 paramParts << modelParameters.value( source.parameterName() );
143 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
144 paramParts << linkedChildResults.value( source.outputName() );
151 paramParts << exp.evaluate( &expressionContext );
152 if ( exp.hasEvalError() )
154 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
169 if ( ! expressionText.isEmpty() )
171 return expressionText;
173 else if ( paramParts.count() == 1 )
174 return paramParts.at( 0 );
180 QVariantMap childParams;
181 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
184 if ( !def->isDestination() )
186 if ( !child.parameterSources().contains( def->name() ) )
189 const QVariant value = evaluateSources( def );
190 childParams.insert( def->name(), value );
197 bool isFinalOutput =
false;
198 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
199 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
200 for ( ; outputIt != outputs.constEnd(); ++outputIt )
202 if ( outputIt->childOutputName() == destParam->
name() )
204 QString paramName = child.childId() +
':' + outputIt.key();
205 bool foundParam =
false;
209 if ( modelParameters.contains( paramName ) )
211 value = modelParameters.value( paramName );
220 if ( modelParameters.contains( modelParam->name() ) )
222 value = modelParameters.value( modelParam->name() );
230 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
235 value = QVariant::fromValue( fromVar );
238 childParams.insert( destParam->
name(), value );
240 isFinalOutput =
true;
245 bool hasExplicitDefinition =
false;
246 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
249 const QVariant value = evaluateSources( def );
250 if ( value.isValid() )
252 childParams.insert( def->name(), value );
253 hasExplicitDefinition =
true;
257 if ( !isFinalOutput && !hasExplicitDefinition )
262 bool required =
true;
265 required = childOutputIsRequired( child.childId(), destParam->
name() );
277const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
281 if ( !definition->isDestination() )
284 const QString modelChildId = definition->metadata().value( u
"_modelChildId"_s ).toString();
285 const QString modelOutputName = definition->metadata().value( u
"_modelChildOutputName"_s ).toString();
287 if ( modelChildId == childId && modelOutputName == childOutputName )
293bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
296 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
297 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
299 if ( childIt->childId() == childId || !childIt->isActive() )
303 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
304 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
305 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
307 const auto constValue = childParamIt.value();
308 for (
const QgsProcessingModelChildParameterSource &source : constValue )
311 && source.outputChildId() == childId
312 && source.outputName() == outputName )
324 QSet< QString > toExecute;
325 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
326 QSet< QString > broken;
328 const bool useSubsetOfChildren = !childSubset.empty();
329 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
331 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
333 if ( childIt->algorithm() )
334 toExecute.insert( childIt->childId() );
336 broken.insert( childIt->childId() );
340 if ( !broken.empty() )
341 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken,
", "_L1 ) ) );
343 QElapsedTimer totalTime;
352 QMap< QString, QgsProcessingModelChildAlgorithmResult > &contextChildResults = context.
modelResult().
childResults();
358 childInputs = config->initialChildInputs();
359 childResults = config->initialChildOutputs();
360 executed = config->previouslyExecutedChildAlgorithms();
364 if ( useSubsetOfChildren )
366 executed.subtract( childSubset );
369 QVariantMap finalResults;
371 bool executedAlg =
true;
372 int previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
373 int countExecuted = 0;
374 while ( executedAlg && countExecuted < toExecute.count() )
377 for (
const QString &childId : std::as_const( toExecute ) )
382 if ( executed.contains( childId ) )
387 bool canExecute =
true;
388 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
389 for (
const QString &dependency : dependencies )
391 if ( !executed.contains( dependency ) )
405 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
406 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
408 bool skipGenericLogging =
true;
413 skipGenericLogging =
true;
423 skipGenericLogging =
false;
427 if ( feedback && !skipGenericLogging )
428 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
432 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
436 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
437 if ( !error.isEmpty() )
440 if ( feedback && !skipGenericLogging )
441 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
446 childInputs.insert( childId, thisChildParams );
447 childResult.
setInputs( thisChildParams );
450 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
452 params << u
"%1: %2"_s.arg( childParamIt.key(),
453 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
456 if ( feedback && !skipGenericLogging )
458 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
459 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
462 QElapsedTimer childTime;
465 QVariantMap outerScopeChildInputs = childInputs;
466 QVariantMap outerScopePrevChildResults = childResults;
467 QSet< QString > outerScopeExecuted = executed;
468 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
469 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
473 childResults.clear();
475 contextChildResults.clear();
480 QThread *modelThread = QThread::currentThread();
482 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
484 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
485 ok = childAlg->prepare( childParams, context, &modelFeedback );
486 context.pushToThread( modelThread );
490 if ( modelThread == qApp->thread() )
491 ok = childAlg->prepare( childParams, context, &modelFeedback );
494 context.pushToThread( qApp->thread() );
496#ifndef __clang_analyzer__
497 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
501 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
511 bool runResult =
false;
517 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
519 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
520 results = childAlg->runPrepared( childParams, context, &modelFeedback );
521 context.pushToThread( modelThread );
524 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
525 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
527 context.pushToThread( qApp->thread() );
529#ifndef __clang_analyzer__
530 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
536 results = childAlg->runPrepared( childParams, context, &modelFeedback );
547 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
550 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult]
552 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
553 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
554 context.pushToThread( modelThread );
558 if ( modelThread == qApp->thread() )
559 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
562 context.pushToThread( qApp->thread() );
564#ifndef __clang_analyzer__
565 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
569 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
571 if ( !ppRes.isEmpty() )
574 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
576 childInputs = outerScopeChildInputs;
577 childResults = outerScopePrevChildResults;
578 executed = outerScopeExecuted;
579 contextChildResults = outerScopeContextChildResult;
582 childResults.insert( childId, results );
587 if ( feedback && !skipGenericLogging )
590 QStringList formattedOutputs;
591 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
593 formattedOutputs << u
"%1: %2"_s.arg( displayOutputIt.key(),
596 feedback->
pushInfo( QObject::tr(
"Results:" ) );
597 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
602 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
603 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
605 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
606 switch ( mInternalVersion )
608 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
609 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
611 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
614 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
619 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
620 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
624 if ( outputSortKey > 0 )
629 executed.insert( childId );
631 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
632 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
634 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
635 for (
const QString &targetId : toPrune )
637 if ( executed.contains( targetId ) )
640 executed.insert( targetId );
641 pruneAlgorithmBranchRecursive( targetId, branch );
651 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
659 for (
const QString &candidateId : std::as_const( toExecute ) )
661 if ( executed.contains( candidateId ) )
666 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
667 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
668 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
670 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
672 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
677 if ( !results.contains( source.outputName() ) )
682 executed.insert( candidateId );
684 pruneAlgorithmBranchRecursive( candidateId, QString() );
695 childAlg.reset(
nullptr );
697 modelFeedback.setCurrentStep( countExecuted );
698 if ( feedback && !skipGenericLogging )
700 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
705 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
706 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
710 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
711 const QString formattedRunTime = 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 );
713 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
714 context.modelResult().childResults().insert( childId, childResult );
720 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
721 context.modelResult().childResults().insert( childId, childResult );
729 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 ) );
731 mResults = finalResults;
732 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
733 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
737QString QgsProcessingModelAlgorithm::sourceFilePath()
const
742void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
744 mSourceFile = sourceFile;
747bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
749 if ( mSourceFile.isEmpty() )
752 const QFileInfo fi( mSourceFile );
753 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
758 QStringList fileDocString;
759 fileDocString << u
"\"\"\""_s;
760 fileDocString << u
"Model exported as python."_s;
761 fileDocString << u
"Name : %1"_s.arg( displayName() );
762 fileDocString << u
"Group : %1"_s.arg( group() );
764 fileDocString << u
"\"\"\""_s;
765 fileDocString << QString();
768 QString indent = QString(
' ' ).repeated( indentSize );
769 QString currentIndent;
771 QMap< QString, QString> friendlyChildNames;
772 QMap< QString, QString> friendlyOutputNames;
773 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
775 const QString base = safeName( name, capitalize );
776 QString candidate = base;
779 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
782 candidate = u
"%1_%2"_s.arg( base ).arg( i );
787 const QString algorithmClassName = safeName( name(),
true );
789 QSet< QString > toExecute;
790 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
792 if ( childIt->isActive() && childIt->algorithm() )
794 toExecute.insert( childIt->childId() );
795 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
798 const int totalSteps = toExecute.count();
800 QStringList importLines;
801 switch ( outputType )
806 const auto params = parameterDefinitions();
807 importLines.reserve( params.count() + 6 );
808 importLines << u
"from typing import Any, Optional"_s;
809 importLines << QString();
810 importLines << u
"from qgis.core import QgsProcessing"_s;
811 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
812 importLines << u
"from qgis.core import QgsProcessingContext"_s;
813 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
815 bool hasAdvancedParams =
false;
819 hasAdvancedParams =
true;
823 const QString importString = type->pythonImportString();
824 if ( !importString.isEmpty() && !importLines.contains( importString ) )
825 importLines << importString;
829 if ( hasAdvancedParams )
830 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
832 lines << u
"from qgis import processing"_s;
833 lines << QString() << QString();
835 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
839 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
840 if ( params.empty() )
842 lines << indent + indent + u
"pass"_s;
846 lines.reserve( lines.size() + params.size() );
849 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
851 if ( defClone->isDestination() )
853 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
854 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
855 friendlyOutputNames.insert( uniqueChildName, friendlyName );
856 defClone->setName( friendlyName );
860 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
862 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
863 for (
const QString &part : parts )
865 lines << indent + indent + u
"# %1"_s.arg( part );
872 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
873 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
874 lines << indent + indent + u
"self.addParameter(param)"_s;
878 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
884 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
885 currentIndent = indent + indent;
887 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
888 lines << currentIndent + u
"# overall progress through the model"_s;
889 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
897 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
898 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
900 QString name = paramIt.value().parameterName();
901 if ( parameterDefinition( name ) )
904 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
908 if ( !params.isEmpty() )
910 lines << u
"parameters = {"_s;
911 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
913 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
919 lines << u
"context = QgsProcessingContext()"_s
920 << u
"context.setProject(QgsProject.instance())"_s
921 << u
"feedback = QgsProcessingFeedback()"_s
930 lines << currentIndent + u
"results = {}"_s;
931 lines << currentIndent + u
"outputs = {}"_s;
934 QSet< QString > executed;
935 bool executedAlg =
true;
937 while ( executedAlg && executed.count() < toExecute.count() )
940 const auto constToExecute = toExecute;
941 for (
const QString &childId : constToExecute )
943 if ( executed.contains( childId ) )
946 bool canExecute =
true;
947 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
948 for (
const QString &dependency : constDependsOnChildAlgorithms )
950 if ( !executed.contains( dependency ) )
962 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
969 if ( def->isDestination() )
974 bool isFinalOutput =
false;
975 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
976 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
977 for ( ; outputIt != outputs.constEnd(); ++outputIt )
979 if ( outputIt->childOutputName() == destParam->
name() )
981 QString paramName = child.childId() +
':' + outputIt.key();
982 paramName = friendlyOutputNames.value( paramName, paramName );
983 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
984 isFinalOutput =
true;
989 if ( !isFinalOutput )
994 bool required =
true;
997 required = childOutputIsRequired( child.childId(), destParam->
name() );
1003 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1009 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1011 if ( currentStep < totalSteps )
1014 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1015 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1016 lines << currentIndent + indent + u
"return {}"_s;
1019 executed.insert( childId );
1023 switch ( outputType )
1026 lines << currentIndent + u
"return results"_s;
1030 lines << indent + u
"def name(self) -> str:"_s;
1031 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1033 lines << indent + u
"def displayName(self) -> str:"_s;
1034 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1038 lines << indent + u
"def group(self) -> str:"_s;
1039 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1041 lines << indent + u
"def groupId(self) -> str:"_s;
1042 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1046 if ( !shortHelpString().isEmpty() )
1048 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1049 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1052 if ( !helpUrl().isEmpty() )
1054 lines << indent + u
"def helpUrl(self) -> str:"_s;
1055 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1060 lines << indent + u
"def createInstance(self):"_s;
1061 lines << indent + indent + u
"return self.__class__()"_s;
1064 static QMap< QString, QString > sAdditionalImports
1066 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1067 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1068 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1069 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1070 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1071 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1072 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1073 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1074 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1075 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1076 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1077 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1078 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1079 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1080 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1081 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1082 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1083 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1084 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1085 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1088 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1090 if ( importLines.contains( it.value() ) )
1097 for (
const QString &line : std::as_const( lines ) )
1099 if ( line.contains( it.key() ) )
1107 importLines << it.value();
1111 lines = fileDocString + importLines + lines;
1120QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1122 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1124 auto safeName = [](
const QString & name )->QString
1127 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1128 return s.replace( safeNameRe, u
"_"_s );
1165 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1169 QString description;
1170 switch ( source.source() )
1174 name = source.parameterName();
1175 value = modelParameters.value( source.parameterName() );
1176 description = parameterDefinition( source.parameterName() )->description();
1181 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1182 name = u
"%1_%2"_s.arg( child.description().isEmpty() ?
1183 source.outputChildId() : child.description(), source.outputName() );
1186 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1187 child.description() );
1189 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1199 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1203 sources = availableSourcesForChild( childId, QStringList()
1210 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1214 QString description;
1216 switch ( source.source() )
1220 name = source.parameterName();
1221 value = modelParameters.value( source.parameterName() );
1222 description = parameterDefinition( source.parameterName() )->description();
1227 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1228 name = u
"%1_%2"_s.arg( child.description().isEmpty() ?
1229 source.outputChildId() : child.description(), source.outputName() );
1230 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1233 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1234 child.description() );
1247 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1250 value = fromVar.
sink;
1251 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1259 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1264 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1265 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1266 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1267 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1268 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1271 sources = availableSourcesForChild( childId, QStringList()
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() ?
1292 source.outputChildId() : child.description(), source.outputName() );
1293 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1296 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1297 child.description() );
1311 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1316 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1319 value = fromVar.
sink;
1320 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1325 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1327 featureSource = layer;
1329 if ( context && !featureSource )
1335 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1336 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1337 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1338 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1339 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1345QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1347 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1348 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1349 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1350 for ( ; varIt != variables.constEnd(); ++varIt )
1354 return scope.release();
1357QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1361 return QgsProcessingModelChildParameterSources();
1365QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1367 QgsProcessingModelChildParameterSources sources;
1370 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1371 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1377 if ( parameterTypes.contains( def->
type() ) )
1379 if ( !dataTypes.isEmpty() )
1395 bool ok = sourceDef->
dataTypes().isEmpty();
1396 const auto constDataTypes = sourceDef->
dataTypes();
1397 for (
int type : constDataTypes )
1412 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1416 QSet< QString > dependents;
1417 if ( !childId.isEmpty() )
1419 dependents = dependentChildAlgorithms( childId );
1420 dependents << childId;
1423 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1424 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1426 if ( dependents.contains( childIt->childId() ) )
1436 if ( outputTypes.contains( out->type() ) )
1438 if ( !dataTypes.isEmpty() )
1444 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1451 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1459QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1461 return mHelpContent;
1464void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1466 mHelpContent = helpContent;
1469void QgsProcessingModelAlgorithm::setName(
const QString &name )
1474void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1476 mModelGroup = group;
1479bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1484 if ( mChildAlgorithms.empty() )
1487 issues << QObject::tr(
"Model does not contain any algorithms" );
1490 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1492 QStringList childIssues;
1493 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1495 for (
const QString &issue : std::as_const( childIssues ) )
1497 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1503QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1505 return mChildAlgorithms;
1508void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1510 mParameterComponents = parameterComponents;
1513void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1515 mParameterComponents.insert( component.parameterName(), component );
1518QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1520 if ( !mParameterComponents.contains( name ) )
1522 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1523 component.setParameterName( name );
1526 return mParameterComponents[ name ];
1529QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1531 QList< QgsProcessingModelParameter > res;
1532 QSet< QString > found;
1533 for (
const QString ¶meter : mParameterOrder )
1535 if ( mParameterComponents.contains( parameter ) )
1537 res << mParameterComponents.value( parameter );
1543 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1545 if ( !found.contains( it.key() ) )
1553void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1555 mParameterOrder = order;
1558QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1560 QList< QgsProcessingModelOutput > res;
1561 QSet< QString > found;
1563 for (
const QString &output : mOutputOrder )
1565 bool foundOutput =
false;
1566 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1568 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1569 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1571 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1573 res << outputIt.value();
1575 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1584 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1586 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1587 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1589 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1591 res << outputIt.value();
1599void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1601 mOutputOrder = order;
1604QString QgsProcessingModelAlgorithm::outputGroup()
const
1606 return mOutputGroup;
1609void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1611 mOutputGroup = group;
1614void QgsProcessingModelAlgorithm::updateDestinationParameters()
1617 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1618 while ( it.hasNext() )
1628 qDeleteAll( mOutputs );
1632 QSet< QString > usedFriendlyNames;
1633 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1635 const QString base = safeName( name,
false );
1636 QString candidate = base;
1638 while ( usedFriendlyNames.contains( candidate ) )
1641 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1643 usedFriendlyNames.insert( candidate );
1647 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1648 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1650 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1651 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1652 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1654 if ( !childIt->isActive() || !childIt->algorithm() )
1662 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1666 if ( outputIt->isMandatory() )
1668 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1670 QString friendlyName = uniqueSafeName( outputIt->description() );
1671 param->
setName( friendlyName );
1675 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1678 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1679 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1680 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1686 if ( addParameter( param.release() ) && newDestParam )
1693 newDestParam->mOriginalProvider = provider;
1700void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1702 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1705QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1707 return mGroupBoxes.values();
1710void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1712 mGroupBoxes.remove( uuid );
1715QVariant QgsProcessingModelAlgorithm::toVariant()
const
1718 map.insert( u
"model_name"_s, mModelName );
1719 map.insert( u
"model_group"_s, mModelGroup );
1720 map.insert( u
"help"_s, mHelpContent );
1723 QVariantMap childMap;
1724 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1725 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1727 childMap.insert( childIt.key(), childIt.value().toVariant() );
1729 map.insert( u
"children"_s, childMap );
1731 QVariantMap paramMap;
1732 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1733 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1735 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1737 map.insert( u
"parameters"_s, paramMap );
1739 QVariantMap paramDefMap;
1744 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1746 QVariantList groupBoxDefs;
1747 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1749 groupBoxDefs.append( it.value().toVariant() );
1751 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1753 map.insert( u
"modelVariables"_s, mVariables );
1755 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1757 map.insert( u
"parameterOrder"_s, mParameterOrder );
1758 map.insert( u
"outputOrder"_s, mOutputOrder );
1759 map.insert( u
"outputGroup"_s, mOutputGroup );
1764bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1766 QVariantMap map = model.toMap();
1768 mModelName = map.value( u
"model_name"_s ).toString();
1769 mModelGroup = map.value( u
"model_group"_s ).toString();
1770 mModelGroupId = map.value( u
"model_group"_s ).toString();
1771 mHelpContent = map.value( u
"help"_s ).toMap();
1773 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1775 mVariables = map.value( u
"modelVariables"_s ).toMap();
1776 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1778 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1779 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1780 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1782 mChildAlgorithms.clear();
1783 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1784 QVariantMap::const_iterator childIt = childMap.constBegin();
1785 for ( ; childIt != childMap.constEnd(); ++childIt )
1787 QgsProcessingModelChildAlgorithm child;
1791 if ( !child.loadVariant( childIt.value() ) )
1794 mChildAlgorithms.insert( child.childId(), child );
1797 mParameterComponents.clear();
1798 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1799 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1800 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1802 QgsProcessingModelParameter param;
1803 if ( !param.loadVariant( paramIt.value().toMap() ) )
1806 mParameterComponents.insert( param.parameterName(), param );
1809 qDeleteAll( mParameters );
1810 mParameters.clear();
1811 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1813 auto addParam = [
this](
const QVariant & value )
1821 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1825 param->setHelp( mHelpContent.value( param->name() ).toString() );
1828 addParameter( param.release() );
1832 QVariantMap map = value.toMap();
1833 QString type = map.value( u
"parameter_type"_s ).toString();
1834 QString name = map.value( u
"name"_s ).toString();
1836 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1840 QSet< QString > loadedParams;
1842 for (
const QString &name : std::as_const( mParameterOrder ) )
1844 if ( paramDefMap.contains( name ) )
1846 addParam( paramDefMap.value( name ) );
1847 loadedParams << name;
1851 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1852 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1854 if ( !loadedParams.contains( paramDefIt.key() ) )
1855 addParam( paramDefIt.value() );
1858 mGroupBoxes.clear();
1859 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1860 for (
const QVariant &groupBoxDef : groupBoxList )
1862 QgsProcessingModelGroupBox groupBox;
1863 groupBox.loadVariant( groupBoxDef.toMap() );
1864 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1867 updateDestinationParameters();
1872bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1877 return ( acceptableDataTypes.empty()
1878 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1889void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1891 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1892 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1894 if ( !childIt->algorithm() )
1895 childIt->reattach();
1899bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1901 QDomDocument doc = QDomDocument( u
"model"_s );
1903 doc.appendChild( elem );
1906 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1908 QTextStream stream( &file );
1909 doc.save( stream, 2 );
1916bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1921 if ( file.open( QFile::ReadOnly ) )
1923 if ( !doc.setContent( &file ) )
1934 return loadVariant( props );
1937void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1939 mChildAlgorithms = childAlgorithms;
1940 updateDestinationParameters();
1943void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1946 updateDestinationParameters();
1949QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1951 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1955 updateDestinationParameters();
1959QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1961 return mChildAlgorithms[ childId ];
1964bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1966 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1969 mChildAlgorithms.remove(
id );
1970 updateDestinationParameters();
1974void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1976 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1977 for (
const QString &child : constDependentChildAlgorithms )
1979 childAlgorithm( child ).setActive(
false );
1981 childAlgorithm(
id ).setActive(
false );
1982 updateDestinationParameters();
1985bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1987 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1988 for (
const QString &child : constDependsOnChildAlgorithms )
1990 if ( !childAlgorithm( child ).isActive() )
1993 childAlgorithm(
id ).setActive(
true );
1994 updateDestinationParameters();
2000 if ( addParameter( definition ) )
2001 mParameterComponents.insert( definition->
name(), component );
2006 removeParameter( definition->
name() );
2007 addParameter( definition );
2010void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2012 removeParameter( name );
2013 mParameterComponents.remove( name );
2016void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2021 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
2024 expression.prepare( &expressionContext );
2025 QSet<QString> variables = expression.referencedVariables();
2026 if ( variables.contains( oldName ) )
2028 QString newExpression = expressionString;
2029 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2030 return {
true, newExpression };
2032 return {
false, QString() };
2035 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2036 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2038 bool changed =
false;
2039 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2040 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2041 for ( ; paramIt != childParams.end(); ++paramIt )
2043 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2044 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2046 switch ( valueIt->source() )
2050 if ( valueIt->parameterName() == oldName )
2052 valueIt->setParameterName( newName );
2060 bool updatedExpression =
false;
2061 QString newExpression;
2062 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2063 if ( updatedExpression )
2065 valueIt->setExpression( newExpression );
2073 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2078 bool updatedExpression =
false;
2079 QString newExpression;
2080 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2081 if ( updatedExpression )
2083 property.setExpressionString( newExpression );
2084 valueIt->setStaticValue( property );
2100 childIt->setParameterSources( childParams );
2104bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2106 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2107 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2110 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2111 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2112 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2114 const auto constValue = paramIt.value();
2115 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2118 && source.parameterName() == name )
2128bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2130 const auto constMParameters = mParameters;
2133 if ( def->
name() == name )
2142QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2144 return mParameterComponents;
2147void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2149 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2150 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2152 if ( depends.contains( childIt->childId() ) )
2156 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2157 bool hasDependency =
false;
2158 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2160 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2162 hasDependency =
true;
2167 if ( hasDependency )
2169 depends.insert( childIt->childId() );
2170 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2175 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2176 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2177 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2179 const auto constValue = paramIt.value();
2180 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2183 && source.outputChildId() == childId )
2185 depends.insert( childIt->childId() );
2186 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2194QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2196 QSet< QString > algs;
2200 algs.insert( childId );
2202 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2205 algs.remove( childId );
2211void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2213 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2216 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2217 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2219 if ( !depends.contains( val.childId ) )
2221 depends.insert( val.childId );
2222 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2227 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2228 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2229 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2231 const auto constValue = paramIt.value();
2232 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2234 switch ( source.source() )
2237 if ( !depends.contains( source.outputChildId() ) )
2239 depends.insert( source.outputChildId() );
2240 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2247 const QSet<QString> vars = exp.referencedVariables();
2252 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2253 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2259 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2263 depends.insert( childVarIt->source.outputChildId() );
2264 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2279QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2281 QSet< QString > algs;
2285 algs.insert( childId );
2287 dependsOnChildAlgorithmsRecursive( childId, algs );
2290 algs.remove( childId );
2295QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2297 QSet< QString > dependent;
2298 if ( !childId.isEmpty() )
2300 dependent.unite( dependentChildAlgorithms( childId ) );
2301 dependent.insert( childId );
2304 QList<QgsProcessingModelChildDependency> res;
2305 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2307 if ( !dependent.contains( it->childId() ) )
2310 bool hasBranches =
false;
2311 if ( it->algorithm() )
2319 QgsProcessingModelChildDependency alg;
2320 alg.childId = it->childId();
2321 alg.conditionalBranch = def->
name();
2329 QgsProcessingModelChildDependency alg;
2330 alg.childId = it->childId();
2338bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2341 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2342 if ( childIt != mChildAlgorithms.constEnd() )
2344 if ( !childIt->algorithm() )
2346 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2355 if ( childIt->parameterSources().contains( def->
name() ) )
2358 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2359 for (
const QgsProcessingModelChildParameterSource &source : sources )
2361 switch ( source.source() )
2367 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2372 if ( !parameterComponents().contains( source.parameterName() ) )
2375 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2380 if ( !childAlgorithms().contains( source.outputChildId() ) )
2383 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2405 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2414 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2419bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2421 reattachAlgorithms();
2422 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2423 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2425 if ( !childIt->algorithm() )
2429 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2437QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2439 if ( mSourceFile.isEmpty() )
2454 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2455 alg->loadVariant( toVariant() );
2456 alg->setProvider( provider() );
2457 alg->setSourceFilePath( sourceFilePath() );
2461QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2463 QString n = name.toLower().trimmed();
2464 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2465 n.replace( rx, QString() );
2466 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2467 n.replace( rx2, QString() );
2469 n = n.replace(
' ',
'_' );
2473QVariantMap QgsProcessingModelAlgorithm::variables()
const
2478void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2480 mVariables = variables;
2483QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2485 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.
Base class for all map layer types.
virtual 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())
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.
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.
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.
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.