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 & )
59 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
60 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
71QString QgsProcessingModelAlgorithm::name()
const
76QString QgsProcessingModelAlgorithm::displayName()
const
81QString QgsProcessingModelAlgorithm::group()
const
86QString QgsProcessingModelAlgorithm::groupId()
const
91QIcon QgsProcessingModelAlgorithm::icon()
const
96QString QgsProcessingModelAlgorithm::svgIconPath()
const
101QString QgsProcessingModelAlgorithm::shortHelpString()
const
103 if ( mHelpContent.empty() )
109QString QgsProcessingModelAlgorithm::shortDescription()
const
111 return mHelpContent.value( u
"SHORT_DESCRIPTION"_s ).toString();
114QString QgsProcessingModelAlgorithm::helpUrl()
const
116 return mHelpContent.value( u
"HELP_URL"_s ).toString();
119QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
120 const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context
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 )
322 QSet< QString > toExecute;
323 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
324 QSet< QString > broken;
326 const bool useSubsetOfChildren = !childSubset.empty();
327 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
329 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
331 if ( childIt->algorithm() )
332 toExecute.insert( childIt->childId() );
334 broken.insert( childIt->childId() );
338 if ( !broken.empty() )
340 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 ) );
435 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
436 if ( !error.isEmpty() )
439 if ( feedback && !skipGenericLogging )
440 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
445 childInputs.insert( childId, thisChildParams );
446 childResult.
setInputs( thisChildParams );
449 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
451 params << u
"%1: %2"_s.arg( childParamIt.key(), child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
454 if ( feedback && !skipGenericLogging )
456 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
457 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( params.join(
", "_L1 ) ) );
460 QElapsedTimer childTime;
463 QVariantMap outerScopeChildInputs = childInputs;
464 QVariantMap outerScopePrevChildResults = childResults;
465 QSet< QString > outerScopeExecuted = executed;
466 QMap< QString, QgsProcessingModelChildAlgorithmResult > outerScopeContextChildResult = contextChildResults;
467 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
471 childResults.clear();
473 contextChildResults.clear();
478 QThread *modelThread = QThread::currentThread();
480 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback] {
481 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
482 ok = childAlg->prepare( childParams, context, &modelFeedback );
483 context.pushToThread( modelThread );
487 if ( modelThread == qApp->thread() )
488 ok = childAlg->prepare( childParams, context, &modelFeedback );
491 context.pushToThread( qApp->thread() );
493#ifndef __clang_analyzer__
494 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
498 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
508 bool runResult =
false;
514 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams] {
515 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
516 results = childAlg->runPrepared( childParams, context, &modelFeedback );
517 context.pushToThread( modelThread );
520 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
521 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
523 context.pushToThread( qApp->thread() );
525#ifndef __clang_analyzer__
526 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
532 results = childAlg->runPrepared( childParams, context, &modelFeedback );
543 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
546 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult] {
547 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
548 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
549 context.pushToThread( modelThread );
553 if ( modelThread == qApp->thread() )
554 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
557 context.pushToThread( qApp->thread() );
559#ifndef __clang_analyzer__
560 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
564 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
566 if ( !ppRes.isEmpty() )
569 if (
dynamic_cast< QgsProcessingModelAlgorithm *
>( childAlg.get() ) )
571 childInputs = outerScopeChildInputs;
572 childResults = outerScopePrevChildResults;
573 executed = outerScopeExecuted;
574 contextChildResults = outerScopeContextChildResult;
577 childResults.insert( childId, results );
582 if ( feedback && !skipGenericLogging )
585 QStringList formattedOutputs;
586 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
591 feedback->
pushInfo( QObject::tr(
"Results:" ) );
592 feedback->
pushCommandInfo( u
"{ %1 }"_s.arg( formattedOutputs.join(
", "_L1 ) ) );
597 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
598 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
600 const int outputSortKey = mOutputOrder.indexOf( u
"%1:%2"_s.arg( childId, outputIt->childOutputName() ) );
601 switch ( mInternalVersion )
603 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
604 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
606 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
609 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
614 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
615 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
619 if ( outputSortKey > 0 )
624 executed.insert( childId );
626 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
627 pruneAlgorithmBranchRecursive = [&](
const QString &id,
const QString &branch = QString() ) {
628 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
629 for (
const QString &targetId : toPrune )
631 if ( executed.contains( targetId ) )
634 executed.insert( targetId );
635 pruneAlgorithmBranchRecursive( targetId, branch );
645 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
653 for (
const QString &candidateId : std::as_const( toExecute ) )
655 if ( executed.contains( candidateId ) )
660 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[candidateId];
661 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
662 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
664 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
666 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
671 if ( !results.contains( source.outputName() ) )
676 executed.insert( candidateId );
678 pruneAlgorithmBranchRecursive( candidateId, QString() );
689 childAlg.reset(
nullptr );
691 modelFeedback.setCurrentStep( countExecuted );
692 if ( feedback && !skipGenericLogging )
694 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
699 const QString thisAlgorithmHtmlLog = feedback ? feedback->
htmlLog().mid( previousHtmlLogLength ) : QString();
700 previousHtmlLogLength = feedback ? feedback->
htmlLog().length() : 0;
704 const QString formattedException = u
"<span style=\"color:red\">%1</span><br/>"_s.arg( error.toHtmlEscaped() ).replace(
'\n',
"<br>"_L1 );
705 const QString formattedRunTime
706 = 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 );
708 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
709 context.modelResult().childResults().insert( childId, childResult );
715 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
716 context.modelResult().childResults().insert( childId, childResult );
724 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 ) );
726 mResults = finalResults;
727 mResults.insert( u
"CHILD_RESULTS"_s, childResults );
728 mResults.insert( u
"CHILD_INPUTS"_s, childInputs );
732QString QgsProcessingModelAlgorithm::sourceFilePath()
const
737void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
739 mSourceFile = sourceFile;
742bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
744 if ( mSourceFile.isEmpty() )
747 const QFileInfo fi( mSourceFile );
748 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
753 QStringList fileDocString;
754 fileDocString << u
"\"\"\""_s;
755 fileDocString << u
"Model exported as python."_s;
756 fileDocString << u
"Name : %1"_s.arg( displayName() );
757 fileDocString << u
"Group : %1"_s.arg( group() );
759 fileDocString << u
"\"\"\""_s;
760 fileDocString << QString();
763 QString indent = QString(
' ' ).repeated( indentSize );
764 QString currentIndent;
766 QMap< QString, QString> friendlyChildNames;
767 QMap< QString, QString> friendlyOutputNames;
768 auto uniqueSafeName = [](
const QString &name,
bool capitalize,
const QMap< QString, QString > &friendlyNames ) -> QString {
769 const QString base = safeName( name, capitalize );
770 QString candidate = base;
773 while ( std::find( friendlyNames.cbegin(), friendlyNames.cend(), candidate ) != friendlyNames.cend() )
776 candidate = u
"%1_%2"_s.arg( base ).arg( i );
781 const QString algorithmClassName = safeName( name(),
true );
783 QSet< QString > toExecute;
784 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
786 if ( childIt->isActive() && childIt->algorithm() )
788 toExecute.insert( childIt->childId() );
789 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
792 const int totalSteps = toExecute.count();
794 QStringList importLines;
795 switch ( outputType )
800 const auto params = parameterDefinitions();
801 importLines.reserve( params.count() + 6 );
802 importLines << u
"from typing import Any, Optional"_s;
803 importLines << QString();
804 importLines << u
"from qgis.core import QgsProcessing"_s;
805 importLines << u
"from qgis.core import QgsProcessingAlgorithm"_s;
806 importLines << u
"from qgis.core import QgsProcessingContext"_s;
807 importLines << u
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback"_s;
809 bool hasAdvancedParams =
false;
813 hasAdvancedParams =
true;
817 const QString importString = type->pythonImportString();
818 if ( !importString.isEmpty() && !importLines.contains( importString ) )
819 importLines << importString;
823 if ( hasAdvancedParams )
824 importLines << u
"from qgis.core import QgsProcessingParameterDefinition"_s;
826 lines << u
"from qgis import processing"_s;
827 lines << QString() << QString();
829 lines << u
"class %1(QgsProcessingAlgorithm):"_s.arg( algorithmClassName );
833 lines << indent + u
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):"_s;
834 if ( params.empty() )
836 lines << indent + indent + u
"pass"_s;
840 lines.reserve( lines.size() + params.size() );
843 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
845 if ( defClone->isDestination() )
847 const QString uniqueChildName = defClone->metadata().value( u
"_modelChildId"_s ).toString() +
':' + defClone->metadata().value( u
"_modelChildOutputName"_s ).toString();
848 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
849 friendlyOutputNames.insert( uniqueChildName, friendlyName );
850 defClone->setName( friendlyName );
854 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
856 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( u
"\n"_s );
857 for (
const QString &part : parts )
859 lines << indent + indent + u
"# %1"_s.arg( part );
866 lines << indent + indent + u
"param = %1"_s.arg( defClone->asPythonString() );
867 lines << indent + indent + u
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)"_s;
868 lines << indent + indent + u
"self.addParameter(param)"_s;
872 lines << indent + indent + u
"self.addParameter(%1)"_s.arg( defClone->asPythonString() );
878 lines << indent + u
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:"_s;
879 currentIndent = indent + indent;
881 lines << currentIndent + u
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the"_s;
882 lines << currentIndent + u
"# overall progress through the model"_s;
883 lines << currentIndent + u
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)"_s.arg( totalSteps );
891 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
892 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
894 QString name = paramIt.value().parameterName();
895 if ( parameterDefinition( name ) )
898 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
902 if ( !params.isEmpty() )
904 lines << u
"parameters = {"_s;
905 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
907 lines << u
" '%1':%2,"_s.arg( it.key(), it.value() );
913 lines << u
"context = QgsProcessingContext()"_s
914 << u
"context.setProject(QgsProject.instance())"_s
915 << u
"feedback = QgsProcessingFeedback()"_s
923 lines << currentIndent + u
"results = {}"_s;
924 lines << currentIndent + u
"outputs = {}"_s;
927 QSet< QString > executed;
928 bool executedAlg =
true;
930 while ( executedAlg && executed.count() < toExecute.count() )
933 const auto constToExecute = toExecute;
934 for (
const QString &childId : constToExecute )
936 if ( executed.contains( childId ) )
939 bool canExecute =
true;
940 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
941 for (
const QString &dependency : constDependsOnChildAlgorithms )
943 if ( !executed.contains( dependency ) )
955 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[childId];
962 if ( def->isDestination() )
967 bool isFinalOutput =
false;
968 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
969 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
970 for ( ; outputIt != outputs.constEnd(); ++outputIt )
972 if ( outputIt->childOutputName() == destParam->
name() )
974 QString paramName = child.childId() +
':' + outputIt.key();
975 paramName = friendlyOutputNames.value( paramName, paramName );
976 childParams.insert( destParam->
name(), u
"parameters['%1']"_s.arg( paramName ) );
977 isFinalOutput =
true;
982 if ( !isFinalOutput )
987 bool required =
true;
990 required = childOutputIsRequired( child.childId(), destParam->
name() );
996 childParams.insert( destParam->
name(), u
"QgsProcessing.TEMPORARY_OUTPUT"_s );
1002 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
1004 if ( currentStep < totalSteps )
1007 lines << currentIndent + u
"feedback.setCurrentStep(%1)"_s.arg( currentStep );
1008 lines << currentIndent + u
"if feedback.isCanceled():"_s;
1009 lines << currentIndent + indent + u
"return {}"_s;
1012 executed.insert( childId );
1016 switch ( outputType )
1019 lines << currentIndent + u
"return results"_s;
1023 lines << indent + u
"def name(self) -> str:"_s;
1024 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1026 lines << indent + u
"def displayName(self) -> str:"_s;
1027 lines << indent + indent + u
"return '%1'"_s.arg( mModelName );
1031 lines << indent + u
"def group(self) -> str:"_s;
1032 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroup );
1034 lines << indent + u
"def groupId(self) -> str:"_s;
1035 lines << indent + indent + u
"return '%1'"_s.arg( mModelGroupId );
1039 if ( !shortHelpString().isEmpty() )
1041 lines << indent + u
"def shortHelpString(self) -> str:"_s;
1042 lines << indent + indent + u
"return \"\"\"%1\"\"\""_s.arg( shortHelpString() );
1045 if ( !helpUrl().isEmpty() )
1047 lines << indent + u
"def helpUrl(self) -> str:"_s;
1048 lines << indent + indent + u
"return '%1'"_s.arg( helpUrl() );
1053 lines << indent + u
"def createInstance(self):"_s;
1054 lines << indent + indent + u
"return self.__class__()"_s;
1057 static QMap< QString, QString > sAdditionalImports {
1058 { u
"QgsCoordinateReferenceSystem"_s, u
"from qgis.core import QgsCoordinateReferenceSystem"_s },
1059 { u
"QgsExpression"_s, u
"from qgis.core import QgsExpression"_s },
1060 { u
"QgsRectangle"_s, u
"from qgis.core import QgsRectangle"_s },
1061 { u
"QgsReferencedRectangle"_s, u
"from qgis.core import QgsReferencedRectangle"_s },
1062 { u
"QgsPoint"_s, u
"from qgis.core import QgsPoint"_s },
1063 { u
"QgsReferencedPoint"_s, u
"from qgis.core import QgsReferencedPoint"_s },
1064 { u
"QgsProperty"_s, u
"from qgis.core import QgsProperty"_s },
1065 { u
"QgsRasterLayer"_s, u
"from qgis.core import QgsRasterLayer"_s },
1066 { u
"QgsMeshLayer"_s, u
"from qgis.core import QgsMeshLayer"_s },
1067 { u
"QgsVectorLayer"_s, u
"from qgis.core import QgsVectorLayer"_s },
1068 { u
"QgsMapLayer"_s, u
"from qgis.core import QgsMapLayer"_s },
1069 { u
"QgsProcessingFeatureSourceDefinition"_s, u
"from qgis.core import QgsProcessingFeatureSourceDefinition"_s },
1070 { u
"QgsPointXY"_s, u
"from qgis.core import QgsPointXY"_s },
1071 { u
"QgsReferencedPointXY"_s, u
"from qgis.core import QgsReferencedPointXY"_s },
1072 { u
"QgsGeometry"_s, u
"from qgis.core import QgsGeometry"_s },
1073 { u
"QgsProcessingOutputLayerDefinition"_s, u
"from qgis.core import QgsProcessingOutputLayerDefinition"_s },
1074 { u
"QColor"_s, u
"from qgis.PyQt.QtGui import QColor"_s },
1075 { u
"QDateTime"_s, u
"from qgis.PyQt.QtCore import QDateTime"_s },
1076 { u
"QDate"_s, u
"from qgis.PyQt.QtCore import QDate"_s },
1077 { u
"QTime"_s, u
"from qgis.PyQt.QtCore import QTime"_s },
1080 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1082 if ( importLines.contains( it.value() ) )
1089 for (
const QString &line : std::as_const( lines ) )
1091 if ( line.contains( it.key() ) )
1099 importLines << it.value();
1103 lines = fileDocString + importLines + lines;
1112QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
1113 const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results
1116 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1118 auto safeName = [](
const QString &name ) -> QString {
1120 const thread_local QRegularExpression safeNameRe( u
"[\\s'\"\\(\\):\\.]"_s );
1121 return s.replace( safeNameRe, u
"_"_s );
1125 QgsProcessingModelChildParameterSources sources = availableSourcesForChild(
1159 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1163 QString description;
1164 switch ( source.source() )
1168 name = source.parameterName();
1169 value = modelParameters.value( source.parameterName() );
1170 description = parameterDefinition( source.parameterName() )->description();
1175 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1176 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1179 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1181 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1191 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1195 sources = availableSourcesForChild(
1201 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1205 QString description;
1207 switch ( source.source() )
1211 name = source.parameterName();
1212 value = modelParameters.value( source.parameterName() );
1213 description = parameterDefinition( source.parameterName() )->description();
1218 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1219 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1220 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1223 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1235 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1238 value = fromVar.
sink;
1239 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1247 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1252 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1253 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1254 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1255 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1256 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1260 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1264 QString description;
1266 switch ( source.source() )
1270 name = source.parameterName();
1271 value = modelParameters.value( source.parameterName() );
1272 description = parameterDefinition( source.parameterName() )->description();
1277 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1278 name = u
"%1_%2"_s.arg( child.description().isEmpty() ? source.outputChildId() : child.description(), source.outputName() );
1279 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1282 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(), child.description() );
1295 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1300 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1303 value = fromVar.
sink;
1304 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1309 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1311 featureSource = layer;
1313 if ( context && !featureSource )
1319 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1320 variables.insert( safeName( u
"%1_minx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1321 variables.insert( safeName( u
"%1_miny"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1322 variables.insert( safeName( u
"%1_maxx"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1323 variables.insert( safeName( u
"%1_maxy"_s.arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1330 const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results
1333 auto scope = std::make_unique<QgsExpressionContextScope>( u
"algorithm_inputs"_s );
1334 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1335 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1336 for ( ; varIt != variables.constEnd(); ++varIt )
1340 return scope.release();
1343QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QgsProcessingParameterDefinition *param )
const
1347 return QgsProcessingModelChildParameterSources();
1351QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
1352 const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes
1355 QgsProcessingModelChildParameterSources sources;
1358 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1359 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1365 if ( parameterTypes.contains( def->
type() ) )
1367 if ( !dataTypes.isEmpty() )
1383 bool ok = sourceDef->
dataTypes().isEmpty();
1384 const auto constDataTypes = sourceDef->
dataTypes();
1385 for (
int type : constDataTypes )
1387 if ( dataTypes.contains( type )
1405 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1409 QSet< QString > dependents;
1410 if ( !childId.isEmpty() )
1412 dependents = dependentChildAlgorithms( childId );
1413 dependents << childId;
1416 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1417 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1419 if ( dependents.contains( childIt->childId() ) )
1429 if ( outputTypes.contains( out->type() ) )
1431 if ( !dataTypes.isEmpty() )
1437 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1444 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1452QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1454 return mHelpContent;
1457void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1459 mHelpContent = helpContent;
1462void QgsProcessingModelAlgorithm::setName(
const QString &name )
1467void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1469 mModelGroup = group;
1472bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1477 if ( mChildAlgorithms.empty() )
1480 issues << QObject::tr(
"Model does not contain any algorithms" );
1483 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1485 QStringList childIssues;
1486 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1488 for (
const QString &issue : std::as_const( childIssues ) )
1490 issues << u
"<b>%1</b>: %2"_s.arg( it->description(), issue );
1496QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1498 return mChildAlgorithms;
1501void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1503 mParameterComponents = parameterComponents;
1506void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1508 mParameterComponents.insert( component.parameterName(), component );
1511QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1513 if ( !mParameterComponents.contains( name ) )
1515 QgsProcessingModelParameter &component = mParameterComponents[name];
1516 component.setParameterName( name );
1519 return mParameterComponents[name];
1522QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1524 QList< QgsProcessingModelParameter > res;
1525 QSet< QString > found;
1526 for (
const QString ¶meter : mParameterOrder )
1528 if ( mParameterComponents.contains( parameter ) )
1530 res << mParameterComponents.value( parameter );
1536 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1538 if ( !found.contains( it.key() ) )
1546void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1548 mParameterOrder = order;
1551QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1553 QList< QgsProcessingModelOutput > res;
1554 QSet< QString > found;
1556 for (
const QString &output : mOutputOrder )
1558 bool foundOutput =
false;
1559 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1561 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1562 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1564 if ( output == u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) )
1566 res << outputIt.value();
1568 found.insert( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) );
1577 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1579 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1580 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1582 if ( !found.contains( u
"%1:%2"_s.arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1584 res << outputIt.value();
1592void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1594 mOutputOrder = order;
1597QString QgsProcessingModelAlgorithm::outputGroup()
const
1599 return mOutputGroup;
1602void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1604 mOutputGroup = group;
1607void QgsProcessingModelAlgorithm::updateDestinationParameters()
1610 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1611 while ( it.hasNext() )
1621 qDeleteAll( mOutputs );
1625 QSet< QString > usedFriendlyNames;
1626 auto uniqueSafeName = [&usedFriendlyNames](
const QString &name ) -> QString {
1627 const QString base = safeName( name,
false );
1628 QString candidate = base;
1630 while ( usedFriendlyNames.contains( candidate ) )
1633 candidate = u
"%1_%2"_s.arg( base ).arg( i );
1635 usedFriendlyNames.insert( candidate );
1639 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1640 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1642 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1643 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1644 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1646 if ( !childIt->isActive() || !childIt->algorithm() )
1654 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1658 if ( outputIt->isMandatory() )
1660 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1662 QString friendlyName = uniqueSafeName( outputIt->description() );
1663 param->
setName( friendlyName );
1667 param->
setName( outputIt->childId() +
':' + outputIt->name() );
1670 param->
metadata().insert( u
"_modelChildId"_s, outputIt->childId() );
1671 param->
metadata().insert( u
"_modelChildOutputName"_s, outputIt->name() );
1672 param->
metadata().insert( u
"_modelChildProvider"_s, childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1678 if ( addParameter( param.release() ) && newDestParam )
1685 newDestParam->mOriginalProvider = provider;
1692void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1694 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1697QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1699 return mGroupBoxes.values();
1702void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1704 mGroupBoxes.remove( uuid );
1707QVariant QgsProcessingModelAlgorithm::toVariant()
const
1710 map.insert( u
"model_name"_s, mModelName );
1711 map.insert( u
"model_group"_s, mModelGroup );
1712 map.insert( u
"help"_s, mHelpContent );
1715 QVariantMap childMap;
1716 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1717 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1719 childMap.insert( childIt.key(), childIt.value().toVariant() );
1721 map.insert( u
"children"_s, childMap );
1723 QVariantMap paramMap;
1724 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1725 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1727 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1729 map.insert( u
"parameters"_s, paramMap );
1731 QVariantMap paramDefMap;
1736 map.insert( u
"parameterDefinitions"_s, paramDefMap );
1738 QVariantList groupBoxDefs;
1739 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1741 groupBoxDefs.append( it.value().toVariant() );
1743 map.insert( u
"groupBoxes"_s, groupBoxDefs );
1745 map.insert( u
"modelVariables"_s, mVariables );
1747 map.insert( u
"designerParameterValues"_s, mDesignerParameterValues );
1749 map.insert( u
"parameterOrder"_s, mParameterOrder );
1750 map.insert( u
"outputOrder"_s, mOutputOrder );
1751 map.insert( u
"outputGroup"_s, mOutputGroup );
1756bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1758 QVariantMap map = model.toMap();
1760 mModelName = map.value( u
"model_name"_s ).toString();
1761 mModelGroup = map.value( u
"model_group"_s ).toString();
1762 mModelGroupId = map.value( u
"model_group"_s ).toString();
1763 mHelpContent = map.value( u
"help"_s ).toMap();
1765 mInternalVersion =
qgsEnumKeyToValue( map.value( u
"internal_version"_s ).toString(), InternalVersion::Version1 );
1767 mVariables = map.value( u
"modelVariables"_s ).toMap();
1768 mDesignerParameterValues = map.value( u
"designerParameterValues"_s ).toMap();
1770 mParameterOrder = map.value( u
"parameterOrder"_s ).toStringList();
1771 mOutputOrder = map.value( u
"outputOrder"_s ).toStringList();
1772 mOutputGroup = map.value( u
"outputGroup"_s ).toString();
1774 mChildAlgorithms.clear();
1775 QVariantMap childMap = map.value( u
"children"_s ).toMap();
1776 QVariantMap::const_iterator childIt = childMap.constBegin();
1777 for ( ; childIt != childMap.constEnd(); ++childIt )
1779 QgsProcessingModelChildAlgorithm child;
1783 if ( !child.loadVariant( childIt.value() ) )
1786 mChildAlgorithms.insert( child.childId(), child );
1789 mParameterComponents.clear();
1790 QVariantMap paramMap = map.value( u
"parameters"_s ).toMap();
1791 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1792 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1794 QgsProcessingModelParameter param;
1795 if ( !param.loadVariant( paramIt.value().toMap() ) )
1798 mParameterComponents.insert( param.parameterName(), param );
1801 qDeleteAll( mParameters );
1802 mParameters.clear();
1803 QVariantMap paramDefMap = map.value( u
"parameterDefinitions"_s ).toMap();
1805 auto addParam = [
this](
const QVariant &value ) {
1812 if ( param->name() ==
"VERBOSE_LOG"_L1 )
1816 param->setHelp( mHelpContent.value( param->name() ).toString() );
1819 addParameter( param.release() );
1823 QVariantMap map = value.toMap();
1824 QString type = map.value( u
"parameter_type"_s ).toString();
1825 QString name = map.value( u
"name"_s ).toString();
1827 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1831 QSet< QString > loadedParams;
1833 for (
const QString &name : std::as_const( mParameterOrder ) )
1835 if ( paramDefMap.contains( name ) )
1837 addParam( paramDefMap.value( name ) );
1838 loadedParams << name;
1842 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1843 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1845 if ( !loadedParams.contains( paramDefIt.key() ) )
1846 addParam( paramDefIt.value() );
1849 mGroupBoxes.clear();
1850 const QVariantList groupBoxList = map.value( u
"groupBoxes"_s ).toList();
1851 for (
const QVariant &groupBoxDef : groupBoxList )
1853 QgsProcessingModelGroupBox groupBox;
1854 groupBox.loadVariant( groupBoxDef.toMap() );
1855 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1858 updateDestinationParameters();
1863bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1869 acceptableDataTypes.empty()
1870 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1880void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1882 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1883 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1885 if ( !childIt->algorithm() )
1886 childIt->reattach();
1890bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1892 QDomDocument doc = QDomDocument( u
"model"_s );
1894 doc.appendChild( elem );
1897 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1899 QTextStream stream( &file );
1900 doc.save( stream, 2 );
1907bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1912 if ( file.open( QFile::ReadOnly ) )
1914 if ( !doc.setContent( &file ) )
1925 return loadVariant( props );
1928void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1930 mChildAlgorithms = childAlgorithms;
1931 updateDestinationParameters();
1934void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1937 updateDestinationParameters();
1940QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1942 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1946 updateDestinationParameters();
1950QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1952 return mChildAlgorithms[childId];
1955bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1957 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1960 mChildAlgorithms.remove(
id );
1961 updateDestinationParameters();
1965void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1967 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1968 for (
const QString &child : constDependentChildAlgorithms )
1970 childAlgorithm( child ).setActive(
false );
1972 childAlgorithm(
id ).setActive(
false );
1973 updateDestinationParameters();
1976bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1978 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1979 for (
const QString &child : constDependsOnChildAlgorithms )
1981 if ( !childAlgorithm( child ).isActive() )
1984 childAlgorithm(
id ).setActive(
true );
1985 updateDestinationParameters();
1991 if ( addParameter( definition ) )
1992 mParameterComponents.insert( definition->
name(), component );
1997 removeParameter( definition->
name() );
1998 addParameter( definition );
2001void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
2003 removeParameter( name );
2004 mParameterComponents.remove( name );
2007void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
2012 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString &expressionString ) -> std::tuple< bool, QString > {
2014 expression.prepare( &expressionContext );
2015 QSet<QString> variables = expression.referencedVariables();
2016 if ( variables.contains( oldName ) )
2018 QString newExpression = expressionString;
2019 newExpression.replace( u
"@%1"_s.arg( oldName ), u
"@%2"_s.arg( newName ) );
2020 return {
true, newExpression };
2022 return {
false, QString() };
2025 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
2026 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
2028 bool changed =
false;
2029 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2030 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2031 for ( ; paramIt != childParams.end(); ++paramIt )
2033 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2034 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2036 switch ( valueIt->source() )
2040 if ( valueIt->parameterName() == oldName )
2042 valueIt->setParameterName( newName );
2050 bool updatedExpression =
false;
2051 QString newExpression;
2052 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2053 if ( updatedExpression )
2055 valueIt->setExpression( newExpression );
2063 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2068 bool updatedExpression =
false;
2069 QString newExpression;
2070 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2071 if ( updatedExpression )
2073 property.setExpressionString( newExpression );
2074 valueIt->setStaticValue( property );
2090 childIt->setParameterSources( childParams );
2094bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2096 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2097 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2100 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2101 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2102 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2104 const auto constValue = paramIt.value();
2105 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2117bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2119 const auto constMParameters = mParameters;
2122 if ( def->
name() == name )
2131QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2133 return mParameterComponents;
2136void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2138 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2139 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2141 if ( depends.contains( childIt->childId() ) )
2145 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2146 bool hasDependency =
false;
2147 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2149 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2151 hasDependency =
true;
2156 if ( hasDependency )
2158 depends.insert( childIt->childId() );
2159 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2164 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2165 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2166 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2168 const auto constValue = paramIt.value();
2169 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2173 depends.insert( childIt->childId() );
2174 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2182QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2184 QSet< QString > algs;
2188 algs.insert( childId );
2190 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2193 algs.remove( childId );
2199void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2201 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2204 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2205 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2207 if ( !depends.contains( val.childId ) )
2209 depends.insert( val.childId );
2210 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2215 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2216 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2217 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2219 const auto constValue = paramIt.value();
2220 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2222 switch ( source.source() )
2225 if ( !depends.contains( source.outputChildId() ) )
2227 depends.insert( source.outputChildId() );
2228 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2235 const QSet<QString> vars = exp.referencedVariables();
2240 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2241 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2247 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2251 depends.insert( childVarIt->source.outputChildId() );
2252 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2267QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2269 QSet< QString > algs;
2273 algs.insert( childId );
2275 dependsOnChildAlgorithmsRecursive( childId, algs );
2278 algs.remove( childId );
2283QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2285 QSet< QString > dependent;
2286 if ( !childId.isEmpty() )
2288 dependent.unite( dependentChildAlgorithms( childId ) );
2289 dependent.insert( childId );
2292 QList<QgsProcessingModelChildDependency> res;
2293 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2295 if ( !dependent.contains( it->childId() ) )
2298 bool hasBranches =
false;
2299 if ( it->algorithm() )
2307 QgsProcessingModelChildDependency alg;
2308 alg.childId = it->childId();
2309 alg.conditionalBranch = def->
name();
2317 QgsProcessingModelChildDependency alg;
2318 alg.childId = it->childId();
2326bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2329 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2330 if ( childIt != mChildAlgorithms.constEnd() )
2332 if ( !childIt->algorithm() )
2334 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2343 if ( childIt->parameterSources().contains( def->
name() ) )
2346 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2347 for (
const QgsProcessingModelChildParameterSource &source : sources )
2349 switch ( source.source() )
2355 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2360 if ( !parameterComponents().contains( source.parameterName() ) )
2363 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2368 if ( !childAlgorithms().contains( source.outputChildId() ) )
2371 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2393 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2402 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2407bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2409 reattachAlgorithms();
2410 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2411 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2413 if ( !childIt->algorithm() )
2417 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2425QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2427 if ( mSourceFile.isEmpty() )
2442 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2443 alg->loadVariant( toVariant() );
2444 alg->setProvider( provider() );
2445 alg->setSourceFilePath( sourceFilePath() );
2449QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2451 QString n = name.toLower().trimmed();
2452 const thread_local QRegularExpression rx( u
"[^\\sa-z_A-Z0-9]"_s );
2453 n.replace( rx, QString() );
2454 const thread_local QRegularExpression rx2( u
"^\\d*"_s );
2455 n.replace( rx2, QString() );
2457 n = n.replace(
' ',
'_' );
2461QVariantMap QgsProcessingModelAlgorithm::variables()
const
2466void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2468 mVariables = variables;
2471QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2473 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(), 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.
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.