19#include "moc_qgsprocessingmodelalgorithm.cpp"
36#include <QRegularExpression>
39QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
40 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
41 , mModelGroup( group )
42 , mModelGroupId( groupId )
45void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
54 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
55 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
66QString QgsProcessingModelAlgorithm::name()
const
71QString QgsProcessingModelAlgorithm::displayName()
const
76QString QgsProcessingModelAlgorithm::group()
const
81QString QgsProcessingModelAlgorithm::groupId()
const
86QIcon QgsProcessingModelAlgorithm::icon()
const
91QString QgsProcessingModelAlgorithm::svgIconPath()
const
96QString QgsProcessingModelAlgorithm::shortHelpString()
const
98 if ( mHelpContent.empty() )
104QString QgsProcessingModelAlgorithm::shortDescription()
const
106 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
109QString QgsProcessingModelAlgorithm::helpUrl()
const
111 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
114QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
119 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
121 QString expressionText;
122 QVariantList paramParts;
123 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
125 switch ( source.source() )
128 paramParts << source.staticValue();
132 paramParts << modelParameters.value( source.parameterName() );
137 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
138 paramParts << linkedChildResults.value( source.outputName() );
145 paramParts << exp.evaluate( &expressionContext );
146 if ( exp.hasEvalError() )
148 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
163 if ( ! expressionText.isEmpty() )
165 return expressionText;
167 else if ( paramParts.count() == 1 )
168 return paramParts.at( 0 );
174 QVariantMap childParams;
175 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
178 if ( !def->isDestination() )
180 if ( !child.parameterSources().contains( def->name() ) )
183 const QVariant value = evaluateSources( def );
184 childParams.insert( def->name(), value );
191 bool isFinalOutput =
false;
192 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
193 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
194 for ( ; outputIt != outputs.constEnd(); ++outputIt )
196 if ( outputIt->childOutputName() == destParam->
name() )
198 QString paramName = child.childId() +
':' + outputIt.key();
199 bool foundParam =
false;
203 if ( modelParameters.contains( paramName ) )
205 value = modelParameters.value( paramName );
214 if ( modelParameters.contains( modelParam->name() ) )
216 value = modelParameters.value( modelParam->name() );
224 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
229 value = QVariant::fromValue( fromVar );
232 childParams.insert( destParam->
name(), value );
234 isFinalOutput =
true;
239 bool hasExplicitDefinition =
false;
240 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
243 const QVariant value = evaluateSources( def );
244 if ( value.isValid() )
246 childParams.insert( def->name(), value );
247 hasExplicitDefinition =
true;
251 if ( !isFinalOutput && !hasExplicitDefinition )
256 bool required =
true;
259 required = childOutputIsRequired( child.childId(), destParam->
name() );
271const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
275 if ( !definition->isDestination() )
278 const QString modelChildId = definition->
metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
279 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
281 if ( modelChildId == childId && modelOutputName == childOutputName )
287bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
290 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
291 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
293 if ( childIt->childId() == childId || !childIt->isActive() )
297 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
298 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
299 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
301 const auto constValue = childParamIt.value();
302 for (
const QgsProcessingModelChildParameterSource &source : constValue )
305 && source.outputChildId() == childId
306 && source.outputName() == outputName )
318 QSet< QString > toExecute;
319 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
320 QSet< QString > broken;
322 const bool useSubsetOfChildren = !childSubset.empty();
323 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
325 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
327 if ( childIt->algorithm() )
328 toExecute.insert( childIt->childId() );
330 broken.insert( childIt->childId() );
334 if ( !broken.empty() )
335 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
337 QElapsedTimer totalTime;
351 childInputs = config->initialChildInputs();
352 childResults = config->initialChildOutputs();
353 executed = config->previouslyExecutedChildAlgorithms();
357 if ( useSubsetOfChildren )
359 executed.subtract( childSubset );
362 QVariantMap finalResults;
364 bool executedAlg =
true;
365 int previousHtmlLogLength = feedback->
htmlLog().length();
366 int countExecuted = 0;
367 while ( executedAlg && countExecuted < toExecute.count() )
370 for (
const QString &childId : std::as_const( toExecute ) )
375 if ( executed.contains( childId ) )
380 bool canExecute =
true;
381 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
382 for (
const QString &dependency : dependencies )
384 if ( !executed.contains( dependency ) )
398 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
399 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
401 bool skipGenericLogging =
true;
406 skipGenericLogging =
true;
416 skipGenericLogging =
false;
420 if ( feedback && !skipGenericLogging )
421 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
425 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
429 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
430 if ( !error.isEmpty() )
433 if ( feedback && !skipGenericLogging )
434 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
439 childInputs.insert( childId, thisChildParams );
440 childResult.
setInputs( thisChildParams );
443 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
445 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
446 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
449 if ( feedback && !skipGenericLogging )
451 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
452 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
455 QElapsedTimer childTime;
460 QThread *modelThread = QThread::currentThread();
462 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
464 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
465 ok = childAlg->prepare( childParams, context, &modelFeedback );
466 context.pushToThread( modelThread );
470 if ( modelThread == qApp->thread() )
471 ok = childAlg->prepare( childParams, context, &modelFeedback );
474 context.pushToThread( qApp->thread() );
476#ifndef __clang_analyzer__
477 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
481 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
491 bool runResult =
false;
497 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
499 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
500 results = childAlg->runPrepared( childParams, context, &modelFeedback );
501 context.pushToThread( modelThread );
504 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
505 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
507 context.pushToThread( qApp->thread() );
509#ifndef __clang_analyzer__
510 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
516 results = childAlg->runPrepared( childParams, context, &modelFeedback );
527 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
530 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult]
532 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
533 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
534 context.pushToThread( modelThread );
538 if ( modelThread == qApp->thread() )
539 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
542 context.pushToThread( qApp->thread() );
544#ifndef __clang_analyzer__
545 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
549 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
551 if ( !ppRes.isEmpty() )
554 childResults.insert( childId, results );
559 if ( feedback && !skipGenericLogging )
562 QStringList formattedOutputs;
563 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
565 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
568 feedback->
pushInfo( QObject::tr(
"Results:" ) );
569 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
574 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
575 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
577 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
578 switch ( mInternalVersion )
580 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
581 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
583 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
586 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
591 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
592 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
596 if ( outputSortKey > 0 )
601 executed.insert( childId );
603 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
604 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
606 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
607 for (
const QString &targetId : toPrune )
609 if ( executed.contains( targetId ) )
612 executed.insert( targetId );
613 pruneAlgorithmBranchRecursive( targetId, branch );
623 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
631 for (
const QString &candidateId : std::as_const( toExecute ) )
633 if ( executed.contains( candidateId ) )
638 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
639 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
640 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
642 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
644 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
649 if ( !results.contains( source.outputName() ) )
654 executed.insert( candidateId );
656 pruneAlgorithmBranchRecursive( candidateId, QString() );
667 childAlg.reset(
nullptr );
669 modelFeedback.setCurrentStep( countExecuted );
670 if ( feedback && !skipGenericLogging )
672 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
677 const QString thisAlgorithmHtmlLog = feedback->
htmlLog().mid( previousHtmlLogLength );
678 previousHtmlLogLength = feedback->
htmlLog().length();
682 const QString formattedException = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( error.toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
683 const QString formattedRunTime = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( QObject::tr(
"Failed after %1 s." ).arg( childTime.elapsed() / 1000.0 ).toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
685 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
686 context.modelResult().childResults().insert( childId, childResult );
692 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
693 context.modelResult().childResults().insert( childId, childResult );
701 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 ) );
703 mResults = finalResults;
704 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
705 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
709QString QgsProcessingModelAlgorithm::sourceFilePath()
const
714void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
716 mSourceFile = sourceFile;
719bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
721 if ( mSourceFile.isEmpty() )
724 const QFileInfo fi( mSourceFile );
725 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
730 QStringList fileDocString;
731 fileDocString << QStringLiteral(
"\"\"\"" );
732 fileDocString << QStringLiteral(
"Model exported as python." );
733 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
734 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
735 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
736 fileDocString << QStringLiteral(
"\"\"\"" );
737 fileDocString << QString();
740 QString indent = QString(
' ' ).repeated( indentSize );
741 QString currentIndent;
743 QMap< QString, QString> friendlyChildNames;
744 QMap< QString, QString> friendlyOutputNames;
745 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
747 const QString base = safeName( name, capitalize );
748 QString candidate = base;
750 while ( friendlyNames.contains( candidate ) )
753 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
758 const QString algorithmClassName = safeName( name(),
true );
760 QSet< QString > toExecute;
761 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
763 if ( childIt->isActive() && childIt->algorithm() )
765 toExecute.insert( childIt->childId() );
766 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
769 const int totalSteps = toExecute.count();
771 QStringList importLines;
772 switch ( outputType )
777 const auto params = parameterDefinitions();
778 importLines.reserve( params.count() + 6 );
779 importLines << QStringLiteral(
"from typing import Any, Optional" );
780 importLines << QString();
781 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
782 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
783 importLines << QStringLiteral(
"from qgis.core import QgsProcessingContext" );
784 importLines << QStringLiteral(
"from qgis.core import QgsProcessingFeedback, QgsProcessingMultiStepFeedback" );
786 bool hasAdvancedParams =
false;
790 hasAdvancedParams =
true;
793 if ( !importString.isEmpty() && !importLines.contains( importString ) )
794 importLines << importString;
797 if ( hasAdvancedParams )
798 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
800 lines << QStringLiteral(
"from qgis import processing" );
801 lines << QString() << QString();
803 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
807 lines << indent + QStringLiteral(
"def initAlgorithm(self, config: Optional[dict[str, Any]] = None):" );
808 if ( params.empty() )
810 lines << indent + indent + QStringLiteral(
"pass" );
814 lines.reserve( lines.size() + params.size() );
817 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
819 if ( defClone->isDestination() )
821 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
822 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
823 friendlyOutputNames.insert( uniqueChildName, friendlyName );
824 defClone->setName( friendlyName );
828 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
830 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
831 for (
const QString &part : parts )
833 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
840 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
841 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
842 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
846 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
852 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters: dict[str, Any], context: QgsProcessingContext, model_feedback: QgsProcessingFeedback) -> dict[str, Any]:" );
853 currentIndent = indent + indent;
855 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
856 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
857 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
865 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
866 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
868 QString name = paramIt.value().parameterName();
869 if ( parameterDefinition( name ) )
872 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
876 if ( !params.isEmpty() )
878 lines << QStringLiteral(
"parameters = {" );
879 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
881 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
883 lines << QStringLiteral(
"}" )
887 lines << QStringLiteral(
"context = QgsProcessingContext()" )
888 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
889 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
898 lines << currentIndent + QStringLiteral(
"results = {}" );
899 lines << currentIndent + QStringLiteral(
"outputs = {}" );
902 QSet< QString > executed;
903 bool executedAlg =
true;
905 while ( executedAlg && executed.count() < toExecute.count() )
908 const auto constToExecute = toExecute;
909 for (
const QString &childId : constToExecute )
911 if ( executed.contains( childId ) )
914 bool canExecute =
true;
915 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
916 for (
const QString &dependency : constDependsOnChildAlgorithms )
918 if ( !executed.contains( dependency ) )
930 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
937 if ( def->isDestination() )
942 bool isFinalOutput =
false;
943 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
944 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
945 for ( ; outputIt != outputs.constEnd(); ++outputIt )
947 if ( outputIt->childOutputName() == destParam->
name() )
949 QString paramName = child.childId() +
':' + outputIt.key();
950 paramName = friendlyOutputNames.value( paramName, paramName );
951 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
952 isFinalOutput =
true;
957 if ( !isFinalOutput )
962 bool required =
true;
965 required = childOutputIsRequired( child.childId(), destParam->
name() );
971 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
977 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
979 if ( currentStep < totalSteps )
982 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
983 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
984 lines << currentIndent + indent + QStringLiteral(
"return {}" );
987 executed.insert( childId );
991 switch ( outputType )
994 lines << currentIndent + QStringLiteral(
"return results" );
998 lines << indent + QStringLiteral(
"def name(self) -> str:" );
999 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
1001 lines << indent + QStringLiteral(
"def displayName(self) -> str:" );
1002 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
1006 lines << indent + QStringLiteral(
"def group(self) -> str:" );
1007 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
1009 lines << indent + QStringLiteral(
"def groupId(self) -> str:" );
1010 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
1014 if ( !shortHelpString().isEmpty() )
1016 lines << indent + QStringLiteral(
"def shortHelpString(self) -> str:" );
1017 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
1020 if ( !helpUrl().isEmpty() )
1022 lines << indent + QStringLiteral(
"def helpUrl(self) -> str:" );
1023 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
1028 lines << indent + QStringLiteral(
"def createInstance(self):" );
1029 lines << indent + indent + QStringLiteral(
"return self.__class__()" );
1032 static QMap< QString, QString > sAdditionalImports
1034 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
1035 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
1036 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
1037 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
1038 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
1039 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
1040 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
1041 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
1042 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
1043 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
1044 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
1045 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
1046 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
1047 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
1048 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
1049 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
1050 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
1051 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
1052 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
1053 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
1056 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1058 if ( importLines.contains( it.value() ) )
1065 for (
const QString &line : std::as_const( lines ) )
1067 if ( line.contains( it.key() ) )
1075 importLines << it.value();
1079 lines = fileDocString + importLines + lines;
1088QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1090 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1092 auto safeName = [](
const QString & name )->QString
1095 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1096 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1133 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1137 QString description;
1138 switch ( source.source() )
1142 name = source.parameterName();
1143 value = modelParameters.value( source.parameterName() );
1144 description = parameterDefinition( source.parameterName() )->description();
1149 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1150 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1151 source.outputChildId() : child.description(), source.outputName() );
1154 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1155 child.description() );
1157 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1167 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1171 sources = availableSourcesForChild( childId, QStringList()
1178 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1182 QString description;
1184 switch ( source.source() )
1188 name = source.parameterName();
1189 value = modelParameters.value( source.parameterName() );
1190 description = parameterDefinition( source.parameterName() )->description();
1195 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1196 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1197 source.outputChildId() : child.description(), source.outputName() );
1198 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1201 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1202 child.description() );
1215 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1218 value = fromVar.
sink;
1219 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1227 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1232 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1233 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1234 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1235 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1236 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1239 sources = availableSourcesForChild( childId, QStringList()
1241 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1245 QString description;
1247 switch ( source.source() )
1251 name = source.parameterName();
1252 value = modelParameters.value( source.parameterName() );
1253 description = parameterDefinition( source.parameterName() )->description();
1258 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1259 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1260 source.outputChildId() : child.description(), source.outputName() );
1261 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1264 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1265 child.description() );
1279 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1284 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1287 value = fromVar.
sink;
1288 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1293 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1295 featureSource = layer;
1297 if ( context && !featureSource )
1303 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1304 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1305 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1306 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1307 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1313QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1315 auto scope = std::make_unique<QgsExpressionContextScope>( QStringLiteral(
"algorithm_inputs" ) );
1316 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1317 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1318 for ( ; varIt != variables.constEnd(); ++varIt )
1322 return scope.release();
1325QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1327 QgsProcessingModelChildParameterSources sources;
1330 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1331 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1337 if ( parameterTypes.contains( def->
type() ) )
1339 if ( !dataTypes.isEmpty() )
1355 bool ok = sourceDef->
dataTypes().isEmpty();
1356 const auto constDataTypes = sourceDef->
dataTypes();
1357 for (
int type : constDataTypes )
1372 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1376 QSet< QString > dependents;
1377 if ( !childId.isEmpty() )
1379 dependents = dependentChildAlgorithms( childId );
1380 dependents << childId;
1383 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1384 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1386 if ( dependents.contains( childIt->childId() ) )
1396 if ( outputTypes.contains( out->type() ) )
1398 if ( !dataTypes.isEmpty() )
1404 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1411 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1419QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1421 return mHelpContent;
1424void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1426 mHelpContent = helpContent;
1429void QgsProcessingModelAlgorithm::setName(
const QString &name )
1434void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1436 mModelGroup = group;
1439bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1444 if ( mChildAlgorithms.empty() )
1447 issues << QObject::tr(
"Model does not contain any algorithms" );
1450 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1452 QStringList childIssues;
1453 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1455 for (
const QString &issue : std::as_const( childIssues ) )
1457 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1463QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1465 return mChildAlgorithms;
1468void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1470 mParameterComponents = parameterComponents;
1473void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1475 mParameterComponents.insert( component.parameterName(), component );
1478QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1480 if ( !mParameterComponents.contains( name ) )
1482 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1483 component.setParameterName( name );
1486 return mParameterComponents[ name ];
1489QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1491 QList< QgsProcessingModelParameter > res;
1492 QSet< QString > found;
1493 for (
const QString ¶meter : mParameterOrder )
1495 if ( mParameterComponents.contains( parameter ) )
1497 res << mParameterComponents.value( parameter );
1503 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1505 if ( !found.contains( it.key() ) )
1513void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1515 mParameterOrder = order;
1518QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1520 QList< QgsProcessingModelOutput > res;
1521 QSet< QString > found;
1523 for (
const QString &output : mOutputOrder )
1525 bool foundOutput =
false;
1526 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1528 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1529 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1531 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1533 res << outputIt.value();
1535 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1544 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1546 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1547 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1549 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1551 res << outputIt.value();
1559void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1561 mOutputOrder = order;
1564QString QgsProcessingModelAlgorithm::outputGroup()
const
1566 return mOutputGroup;
1569void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1571 mOutputGroup = group;
1574void QgsProcessingModelAlgorithm::updateDestinationParameters()
1577 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1578 while ( it.hasNext() )
1588 qDeleteAll( mOutputs );
1592 QSet< QString > usedFriendlyNames;
1593 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1595 const QString base = safeName( name,
false );
1596 QString candidate = base;
1598 while ( usedFriendlyNames.contains( candidate ) )
1601 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1603 usedFriendlyNames.insert( candidate );
1607 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1608 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1610 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1611 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1612 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1614 if ( !childIt->isActive() || !childIt->algorithm() )
1622 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1626 if ( outputIt->isMandatory() )
1628 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1630 QString friendlyName = uniqueSafeName( outputIt->description() );
1631 param->setName( friendlyName );
1635 param->setName( outputIt->childId() +
':' + outputIt->name() );
1638 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1639 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1640 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1642 param->setDescription( outputIt->description() );
1643 param->setDefaultValue( outputIt->defaultValue() );
1646 if ( addParameter( param.release() ) && newDestParam )
1653 newDestParam->mOriginalProvider = provider;
1660void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1662 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1665QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1667 return mGroupBoxes.values();
1670void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1672 mGroupBoxes.remove( uuid );
1675QVariant QgsProcessingModelAlgorithm::toVariant()
const
1678 map.insert( QStringLiteral(
"model_name" ), mModelName );
1679 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1680 map.insert( QStringLiteral(
"help" ), mHelpContent );
1681 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1683 QVariantMap childMap;
1684 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1685 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1687 childMap.insert( childIt.key(), childIt.value().toVariant() );
1689 map.insert( QStringLiteral(
"children" ), childMap );
1691 QVariantMap paramMap;
1692 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1693 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1695 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1697 map.insert( QStringLiteral(
"parameters" ), paramMap );
1699 QVariantMap paramDefMap;
1704 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1706 QVariantList groupBoxDefs;
1707 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1709 groupBoxDefs.append( it.value().toVariant() );
1711 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1713 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1715 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1717 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1718 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1719 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1724bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1726 QVariantMap map = model.toMap();
1728 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1729 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1730 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1731 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1733 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1735 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1736 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1738 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1739 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1740 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1742 mChildAlgorithms.clear();
1743 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1744 QVariantMap::const_iterator childIt = childMap.constBegin();
1745 for ( ; childIt != childMap.constEnd(); ++childIt )
1747 QgsProcessingModelChildAlgorithm child;
1751 if ( !child.loadVariant( childIt.value() ) )
1754 mChildAlgorithms.insert( child.childId(), child );
1757 mParameterComponents.clear();
1758 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1759 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1760 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1762 QgsProcessingModelParameter param;
1763 if ( !param.loadVariant( paramIt.value().toMap() ) )
1766 mParameterComponents.insert( param.parameterName(), param );
1769 qDeleteAll( mParameters );
1770 mParameters.clear();
1771 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1773 auto addParam = [
this](
const QVariant & value )
1781 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1785 param->setHelp( mHelpContent.value( param->name() ).toString() );
1788 addParameter( param.release() );
1792 QVariantMap map = value.toMap();
1793 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1794 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1796 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1800 QSet< QString > loadedParams;
1802 for (
const QString &name : std::as_const( mParameterOrder ) )
1804 if ( paramDefMap.contains( name ) )
1806 addParam( paramDefMap.value( name ) );
1807 loadedParams << name;
1811 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1812 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1814 if ( !loadedParams.contains( paramDefIt.key() ) )
1815 addParam( paramDefIt.value() );
1818 mGroupBoxes.clear();
1819 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1820 for (
const QVariant &groupBoxDef : groupBoxList )
1822 QgsProcessingModelGroupBox groupBox;
1823 groupBox.loadVariant( groupBoxDef.toMap() );
1824 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1827 updateDestinationParameters();
1832bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1837 return ( acceptableDataTypes.empty()
1838 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1849void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1851 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1852 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1854 if ( !childIt->algorithm() )
1855 childIt->reattach();
1859bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1861 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1863 doc.appendChild( elem );
1866 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1868 QTextStream stream( &file );
1869 doc.save( stream, 2 );
1876bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1881 if ( file.open( QFile::ReadOnly ) )
1883 if ( !doc.setContent( &file ) )
1894 return loadVariant( props );
1897void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1899 mChildAlgorithms = childAlgorithms;
1900 updateDestinationParameters();
1903void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1906 updateDestinationParameters();
1909QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1911 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1915 updateDestinationParameters();
1919QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1921 return mChildAlgorithms[ childId ];
1924bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1926 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1929 mChildAlgorithms.remove(
id );
1930 updateDestinationParameters();
1934void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1936 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1937 for (
const QString &child : constDependentChildAlgorithms )
1939 childAlgorithm( child ).setActive(
false );
1941 childAlgorithm(
id ).setActive(
false );
1942 updateDestinationParameters();
1945bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1947 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1948 for (
const QString &child : constDependsOnChildAlgorithms )
1950 if ( !childAlgorithm( child ).isActive() )
1953 childAlgorithm(
id ).setActive(
true );
1954 updateDestinationParameters();
1960 if ( addParameter( definition ) )
1961 mParameterComponents.insert( definition->
name(), component );
1966 removeParameter( definition->
name() );
1967 addParameter( definition );
1970void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1972 removeParameter( name );
1973 mParameterComponents.remove( name );
1976void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1981 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1984 expression.prepare( &expressionContext );
1985 QSet<QString> variables = expression.referencedVariables();
1986 if ( variables.contains( oldName ) )
1988 QString newExpression = expressionString;
1989 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1990 return {
true, newExpression };
1992 return {
false, QString() };
1995 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1996 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1998 bool changed =
false;
1999 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2000 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
2001 for ( ; paramIt != childParams.end(); ++paramIt )
2003 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
2004 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
2006 switch ( valueIt->source() )
2010 if ( valueIt->parameterName() == oldName )
2012 valueIt->setParameterName( newName );
2020 bool updatedExpression =
false;
2021 QString newExpression;
2022 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2023 if ( updatedExpression )
2025 valueIt->setExpression( newExpression );
2033 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2038 bool updatedExpression =
false;
2039 QString newExpression;
2040 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2041 if ( updatedExpression )
2043 property.setExpressionString( newExpression );
2044 valueIt->setStaticValue( property );
2060 childIt->setParameterSources( childParams );
2064bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2066 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2067 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2070 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2071 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2072 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2074 const auto constValue = paramIt.value();
2075 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2078 && source.parameterName() == name )
2088bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2090 const auto constMParameters = mParameters;
2093 if ( def->
name() == name )
2102QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2104 return mParameterComponents;
2107void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2109 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2110 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2112 if ( depends.contains( childIt->childId() ) )
2116 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2117 bool hasDependency =
false;
2118 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2120 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2122 hasDependency =
true;
2127 if ( hasDependency )
2129 depends.insert( childIt->childId() );
2130 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2135 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2136 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2137 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2139 const auto constValue = paramIt.value();
2140 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2143 && source.outputChildId() == childId )
2145 depends.insert( childIt->childId() );
2146 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2154QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2156 QSet< QString > algs;
2160 algs.insert( childId );
2162 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2165 algs.remove( childId );
2171void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2173 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2176 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2177 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2179 if ( !depends.contains( val.childId ) )
2181 depends.insert( val.childId );
2182 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2187 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2188 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2189 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2191 const auto constValue = paramIt.value();
2192 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2194 switch ( source.source() )
2197 if ( !depends.contains( source.outputChildId() ) )
2199 depends.insert( source.outputChildId() );
2200 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2207 const QSet<QString> vars = exp.referencedVariables();
2212 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2213 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2219 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2223 depends.insert( childVarIt->source.outputChildId() );
2224 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2239QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2241 QSet< QString > algs;
2245 algs.insert( childId );
2247 dependsOnChildAlgorithmsRecursive( childId, algs );
2250 algs.remove( childId );
2255QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2257 QSet< QString > dependent;
2258 if ( !childId.isEmpty() )
2260 dependent.unite( dependentChildAlgorithms( childId ) );
2261 dependent.insert( childId );
2264 QList<QgsProcessingModelChildDependency> res;
2265 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2267 if ( !dependent.contains( it->childId() ) )
2270 bool hasBranches =
false;
2271 if ( it->algorithm() )
2279 QgsProcessingModelChildDependency alg;
2280 alg.childId = it->childId();
2281 alg.conditionalBranch = def->
name();
2289 QgsProcessingModelChildDependency alg;
2290 alg.childId = it->childId();
2298bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2301 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2302 if ( childIt != mChildAlgorithms.constEnd() )
2304 if ( !childIt->algorithm() )
2306 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2315 if ( childIt->parameterSources().contains( def->
name() ) )
2318 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2319 for (
const QgsProcessingModelChildParameterSource &source : sources )
2321 switch ( source.source() )
2327 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2332 if ( !parameterComponents().contains( source.parameterName() ) )
2335 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2340 if ( !childAlgorithms().contains( source.outputChildId() ) )
2343 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2365 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2374 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2379bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2381 reattachAlgorithms();
2382 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2383 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2385 if ( !childIt->algorithm() )
2389 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2397QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2399 if ( mSourceFile.isEmpty() )
2414 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2415 alg->loadVariant( toVariant() );
2416 alg->setProvider( provider() );
2417 alg->setSourceFilePath( sourceFilePath() );
2421QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2423 QString n = name.toLower().trimmed();
2424 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2425 n.replace( rx, QString() );
2426 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2427 n.replace( rx2, QString() );
2429 n = n.replace(
' ',
'_' );
2433QVariantMap QgsProcessingModelAlgorithm::variables()
const
2438void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2440 mVariables = variables;
2443QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2445 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...
Class for 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.
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.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this 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.
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.
virtual QString pythonImportString() const
Returns a valid Python import string for importing the corresponding 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 value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
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 data sets.
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.