34#include <QRegularExpression>
37QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
38 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
39 , mModelGroup( group )
40 , mModelGroupId( groupId )
43void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
47QString QgsProcessingModelAlgorithm::name()
const
52QString QgsProcessingModelAlgorithm::displayName()
const
57QString QgsProcessingModelAlgorithm::group()
const
62QString QgsProcessingModelAlgorithm::groupId()
const
67QIcon QgsProcessingModelAlgorithm::icon()
const
72QString QgsProcessingModelAlgorithm::svgIconPath()
const
77QString QgsProcessingModelAlgorithm::shortHelpString()
const
79 if ( mHelpContent.empty() )
85QString QgsProcessingModelAlgorithm::shortDescription()
const
87 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
90QString QgsProcessingModelAlgorithm::helpUrl()
const
92 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
95QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error )
const
100 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
102 QString expressionText;
103 QVariantList paramParts;
104 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
106 switch ( source.source() )
108 case QgsProcessingModelChildParameterSource::StaticValue:
109 paramParts << source.staticValue();
112 case QgsProcessingModelChildParameterSource::ModelParameter:
113 paramParts << modelParameters.value( source.parameterName() );
116 case QgsProcessingModelChildParameterSource::ChildOutput:
118 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
119 paramParts << linkedChildResults.value( source.outputName() );
123 case QgsProcessingModelChildParameterSource::Expression:
126 paramParts << exp.evaluate( &expressionContext );
127 if ( exp.hasEvalError() )
129 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
133 case QgsProcessingModelChildParameterSource::ExpressionText:
139 case QgsProcessingModelChildParameterSource::ModelOutput:
144 if ( ! expressionText.isEmpty() )
146 return expressionText;
148 else if ( paramParts.count() == 1 )
149 return paramParts.at( 0 );
155 QVariantMap childParams;
156 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
159 if ( !def->isDestination() )
161 if ( !child.parameterSources().contains( def->name() ) )
164 const QVariant value = evaluateSources( def );
165 childParams.insert( def->name(), value );
172 bool isFinalOutput =
false;
173 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
174 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
175 for ( ; outputIt != outputs.constEnd(); ++outputIt )
177 if ( outputIt->childOutputName() == destParam->
name() )
179 QString paramName = child.childId() +
':' + outputIt.key();
180 bool foundParam =
false;
184 if ( modelParameters.contains( paramName ) )
186 value = modelParameters.value( paramName );
195 if ( modelParameters.contains( modelParam->name() ) )
197 value = modelParameters.value( modelParam->name() );
205 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
210 value = QVariant::fromValue( fromVar );
213 childParams.insert( destParam->
name(), value );
215 isFinalOutput =
true;
220 bool hasExplicitDefinition =
false;
221 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
224 const QVariant value = evaluateSources( def );
225 if ( value.isValid() )
227 childParams.insert( def->name(), value );
228 hasExplicitDefinition =
true;
232 if ( !isFinalOutput && !hasExplicitDefinition )
237 bool required =
true;
240 required = childOutputIsRequired( child.childId(), destParam->
name() );
252const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
256 if ( !definition->isDestination() )
259 const QString modelChildId = definition->
metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
260 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
262 if ( modelChildId == childId && modelOutputName == childOutputName )
268bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
271 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
272 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
274 if ( childIt->childId() == childId || !childIt->isActive() )
278 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
279 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
280 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
282 const auto constValue = childParamIt.value();
283 for (
const QgsProcessingModelChildParameterSource &source : constValue )
285 if ( source.source() == QgsProcessingModelChildParameterSource::ChildOutput
286 && source.outputChildId() == childId
287 && source.outputName() == outputName )
299 QSet< QString > toExecute;
300 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
301 QSet< QString > broken;
302 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
304 if ( childIt->isActive() )
306 if ( childIt->algorithm() )
307 toExecute.insert( childIt->childId() );
309 broken.insert( childIt->childId() );
313 if ( !broken.empty() )
314 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg( broken.values().join( QLatin1String(
", " ) ) ) );
316 QElapsedTimer totalTime;
322 QVariantMap childResults;
323 QVariantMap childInputs;
327 QVariantMap finalResults;
328 QSet< QString > executed;
329 bool executedAlg =
true;
330 while ( executedAlg && executed.count() < toExecute.count() )
333 for (
const QString &childId : std::as_const( toExecute ) )
338 if ( executed.contains( childId ) )
341 bool canExecute =
true;
342 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
343 for (
const QString &dependency : dependencies )
345 if ( !executed.contains( dependency ) )
357 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
358 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
361 if ( feedback && !skipGenericLogging )
362 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
366 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
370 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error );
371 if ( !error.isEmpty() )
374 if ( feedback && !skipGenericLogging )
375 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
379 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
381 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
382 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
385 if ( feedback && !skipGenericLogging )
387 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
388 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
391 QElapsedTimer childTime;
396 QThread *modelThread = QThread::currentThread();
398 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
400 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
401 ok = childAlg->prepare( childParams, context, &modelFeedback );
402 context.pushToThread( modelThread );
406 if ( modelThread == qApp->thread() )
407 ok = childAlg->prepare( childParams, context, &modelFeedback );
410 context.pushToThread( qApp->thread() );
411 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
414 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
428 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
430 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
431 results = childAlg->runPrepared( childParams, context, &modelFeedback );
432 context.pushToThread( modelThread );
435 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
436 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
438 context.pushToThread( qApp->thread() );
439 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
444 results = childAlg->runPrepared( childParams, context, &modelFeedback );
453 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
456 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback]
458 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
459 ppRes = childAlg->postProcess( context, &modelFeedback );
460 context.pushToThread( modelThread );
464 if ( modelThread == qApp->thread() )
465 ppRes = childAlg->postProcess( context, &modelFeedback );
468 context.pushToThread( qApp->thread() );
469 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
472 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
474 if ( !ppRes.isEmpty() )
477 childResults.insert( childId, results );
481 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
482 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
483 for ( ; outputIt != outputs.constEnd(); ++outputIt )
485 switch ( mInternalVersion )
487 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
488 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
490 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
493 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
499 executed.insert( childId );
501 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
502 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
504 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
505 for (
const QString &targetId : toPrune )
507 if ( executed.contains( targetId ) )
510 executed.insert( targetId );
511 pruneAlgorithmBranchRecursive( targetId, branch );
521 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
529 for (
const QString &candidateId : std::as_const( toExecute ) )
531 if ( executed.contains( candidateId ) )
536 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
537 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
538 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
540 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
542 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
544 if ( source.source() == QgsProcessingModelChildParameterSource::ChildOutput && source.outputChildId() == childId )
547 if ( !results.contains( source.outputName() ) )
552 executed.insert( candidateId );
554 pruneAlgorithmBranchRecursive( candidateId, QString() );
565 childAlg.reset(
nullptr );
566 modelFeedback.setCurrentStep( executed.count() );
567 if ( feedback && !skipGenericLogging )
568 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
575 feedback->
pushDebugInfo( QObject::tr(
"Model processed OK. Executed %n algorithm(s) total in %1 s.",
nullptr, executed.count() ).arg( totalTime.elapsed() / 1000.0 ) );
577 mResults = finalResults;
578 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
579 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
583QString QgsProcessingModelAlgorithm::sourceFilePath()
const
588void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
590 mSourceFile = sourceFile;
593bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
595 if ( mSourceFile.isEmpty() )
598 const QFileInfo fi( mSourceFile );
599 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
604 QStringList fileDocString;
605 fileDocString << QStringLiteral(
"\"\"\"" );
606 fileDocString << QStringLiteral(
"Model exported as python." );
607 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
608 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
609 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
610 fileDocString << QStringLiteral(
"\"\"\"" );
611 fileDocString << QString();
614 QString indent = QString(
' ' ).repeated( indentSize );
615 QString currentIndent;
617 QMap< QString, QString> friendlyChildNames;
618 QMap< QString, QString> friendlyOutputNames;
619 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
621 const QString base = safeName( name, capitalize );
622 QString candidate = base;
624 while ( friendlyNames.contains( candidate ) )
627 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
632 const QString algorithmClassName = safeName( name(),
true );
634 QSet< QString > toExecute;
635 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
637 if ( childIt->isActive() && childIt->algorithm() )
639 toExecute.insert( childIt->childId() );
640 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
643 const int totalSteps = toExecute.count();
645 QStringList importLines;
646 switch ( outputType )
651 const auto params = parameterDefinitions();
652 importLines.reserve( params.count() + 3 );
653 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
654 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
655 importLines << QStringLiteral(
"from qgis.core import QgsProcessingMultiStepFeedback" );
657 bool hasAdvancedParams =
false;
661 hasAdvancedParams =
true;
664 if ( !importString.isEmpty() && !importLines.contains( importString ) )
665 importLines << importString;
668 if ( hasAdvancedParams )
669 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
671 lines << QStringLiteral(
"import processing" );
672 lines << QString() << QString();
674 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
678 lines << indent + QStringLiteral(
"def initAlgorithm(self, config=None):" );
679 if ( params.empty() )
681 lines << indent + indent + QStringLiteral(
"pass" );
685 lines.reserve( lines.size() + params.size() );
688 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
690 if ( defClone->isDestination() )
692 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
693 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
694 friendlyOutputNames.insert( uniqueChildName, friendlyName );
695 defClone->setName( friendlyName );
699 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
701 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
702 for (
const QString &part : parts )
704 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
711 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
712 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
713 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
717 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
723 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters, context, model_feedback):" );
724 currentIndent = indent + indent;
726 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
727 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
728 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
736 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
737 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
739 QString name = paramIt.value().parameterName();
740 if ( parameterDefinition( name ) )
743 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
747 if ( !params.isEmpty() )
749 lines << QStringLiteral(
"parameters = {" );
750 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
752 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
754 lines << QStringLiteral(
"}" )
758 lines << QStringLiteral(
"context = QgsProcessingContext()" )
759 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
760 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
769 lines << currentIndent + QStringLiteral(
"results = {}" );
770 lines << currentIndent + QStringLiteral(
"outputs = {}" );
773 QSet< QString > executed;
774 bool executedAlg =
true;
776 while ( executedAlg && executed.count() < toExecute.count() )
779 const auto constToExecute = toExecute;
780 for (
const QString &childId : constToExecute )
782 if ( executed.contains( childId ) )
785 bool canExecute =
true;
786 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
787 for (
const QString &dependency : constDependsOnChildAlgorithms )
789 if ( !executed.contains( dependency ) )
801 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
808 if ( def->isDestination() )
813 bool isFinalOutput =
false;
814 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
815 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
816 for ( ; outputIt != outputs.constEnd(); ++outputIt )
818 if ( outputIt->childOutputName() == destParam->
name() )
820 QString paramName = child.childId() +
':' + outputIt.key();
821 paramName = friendlyOutputNames.value( paramName, paramName );
822 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
823 isFinalOutput =
true;
828 if ( !isFinalOutput )
833 bool required =
true;
836 required = childOutputIsRequired( child.childId(), destParam->
name() );
842 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
848 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
850 if ( currentStep < totalSteps )
853 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
854 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
855 lines << currentIndent + indent + QStringLiteral(
"return {}" );
858 executed.insert( childId );
862 switch ( outputType )
865 lines << currentIndent + QStringLiteral(
"return results" );
869 lines << indent + QStringLiteral(
"def name(self):" );
870 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
872 lines << indent + QStringLiteral(
"def displayName(self):" );
873 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
877 lines << indent + QStringLiteral(
"def group(self):" );
878 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
880 lines << indent + QStringLiteral(
"def groupId(self):" );
881 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
885 if ( !shortHelpString().isEmpty() )
887 lines << indent + QStringLiteral(
"def shortHelpString(self):" );
888 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
891 if ( !helpUrl().isEmpty() )
893 lines << indent + QStringLiteral(
"def helpUrl(self):" );
894 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
899 lines << indent + QStringLiteral(
"def createInstance(self):" );
900 lines << indent + indent + QStringLiteral(
"return %1()" ).arg( algorithmClassName );
903 static QMap< QString, QString > sAdditionalImports
905 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
906 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
907 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
908 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
909 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
910 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
911 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
912 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
913 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
914 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
915 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
916 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
917 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
918 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
919 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
920 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
921 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
922 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
923 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
924 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
927 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
929 if ( importLines.contains( it.value() ) )
936 for (
const QString &line : std::as_const( lines ) )
938 if ( line.contains( it.key() ) )
946 importLines << it.value();
950 lines = fileDocString + importLines + lines;
959QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
961 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
963 auto safeName = [](
const QString & name )->QString
966 return s.replace( QRegularExpression( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) ), QStringLiteral(
"_" ) );
1000 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1004 QString description;
1005 switch ( source.source() )
1007 case QgsProcessingModelChildParameterSource::ModelParameter:
1009 name = source.parameterName();
1010 value = modelParameters.value( source.parameterName() );
1011 description = parameterDefinition( source.parameterName() )->description();
1014 case QgsProcessingModelChildParameterSource::ChildOutput:
1016 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1017 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1018 source.outputChildId() : child.description(), source.outputName() );
1021 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1022 child.description() );
1024 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1028 case QgsProcessingModelChildParameterSource::Expression:
1029 case QgsProcessingModelChildParameterSource::ExpressionText:
1030 case QgsProcessingModelChildParameterSource::StaticValue:
1031 case QgsProcessingModelChildParameterSource::ModelOutput:
1034 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1038 sources = availableSourcesForChild( childId, QStringList()
1045 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1049 QString description;
1051 switch ( source.source() )
1053 case QgsProcessingModelChildParameterSource::ModelParameter:
1055 name = source.parameterName();
1056 value = modelParameters.value( source.parameterName() );
1057 description = parameterDefinition( source.parameterName() )->description();
1060 case QgsProcessingModelChildParameterSource::ChildOutput:
1062 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1063 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1064 source.outputChildId() : child.description(), source.outputName() );
1065 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1068 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1069 child.description() );
1074 case QgsProcessingModelChildParameterSource::Expression:
1075 case QgsProcessingModelChildParameterSource::ExpressionText:
1076 case QgsProcessingModelChildParameterSource::StaticValue:
1077 case QgsProcessingModelChildParameterSource::ModelOutput:
1082 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1085 value = fromVar.
sink;
1086 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
1091 QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1095 variables.insert( safeName( name ), VariableDefinition( QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ), source, description ) );
1096 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1097 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1098 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1099 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1102 sources = availableSourcesForChild( childId, QStringList()
1104 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1108 QString description;
1110 switch ( source.source() )
1112 case QgsProcessingModelChildParameterSource::ModelParameter:
1114 name = source.parameterName();
1115 value = modelParameters.value( source.parameterName() );
1116 description = parameterDefinition( source.parameterName() )->description();
1119 case QgsProcessingModelChildParameterSource::ChildOutput:
1121 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1122 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1123 source.outputChildId() : child.description(), source.outputName() );
1124 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1127 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1128 child.description() );
1133 case QgsProcessingModelChildParameterSource::Expression:
1134 case QgsProcessingModelChildParameterSource::ExpressionText:
1135 case QgsProcessingModelChildParameterSource::StaticValue:
1136 case QgsProcessingModelChildParameterSource::ModelOutput:
1142 if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1147 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1150 value = fromVar.
sink;
1151 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
1156 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1158 featureSource = layer;
1160 if ( !featureSource )
1166 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1167 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1168 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1169 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1170 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1176QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1178 std::unique_ptr< QgsExpressionContextScope > scope(
new QgsExpressionContextScope( QStringLiteral(
"algorithm_inputs" ) ) );
1179 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, context, modelParameters, results );
1180 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1181 for ( ; varIt != variables.constEnd(); ++varIt )
1185 return scope.release();
1188QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1190 QgsProcessingModelChildParameterSources sources;
1193 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1194 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1200 if ( parameterTypes.contains( def->
type() ) )
1202 if ( !dataTypes.isEmpty() )
1218 bool ok = sourceDef->
dataTypes().isEmpty();
1219 const auto constDataTypes = sourceDef->
dataTypes();
1220 for (
int type : constDataTypes )
1235 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1239 QSet< QString > dependents;
1240 if ( !childId.isEmpty() )
1242 dependents = dependentChildAlgorithms( childId );
1243 dependents << childId;
1246 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1247 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1249 if ( dependents.contains( childIt->childId() ) )
1259 if ( outputTypes.contains( out->type() ) )
1261 if ( !dataTypes.isEmpty() )
1267 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1274 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1282QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1284 return mHelpContent;
1287void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1289 mHelpContent = helpContent;
1292void QgsProcessingModelAlgorithm::setName(
const QString &name )
1297void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1299 mModelGroup = group;
1302bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1307 if ( mChildAlgorithms.empty() )
1310 issues << QObject::tr(
"Model does not contain any algorithms" );
1313 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1315 QStringList childIssues;
1316 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1318 for (
const QString &issue : std::as_const( childIssues ) )
1320 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1326QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1328 return mChildAlgorithms;
1331void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1333 mParameterComponents = parameterComponents;
1336void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1338 mParameterComponents.insert( component.parameterName(), component );
1341QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1343 if ( !mParameterComponents.contains( name ) )
1345 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1346 component.setParameterName( name );
1349 return mParameterComponents[ name ];
1352QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1354 QList< QgsProcessingModelParameter > res;
1355 QSet< QString > found;
1356 for (
const QString ¶meter : mParameterOrder )
1358 if ( mParameterComponents.contains( parameter ) )
1360 res << mParameterComponents.value( parameter );
1366 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1368 if ( !found.contains( it.key() ) )
1376void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1378 mParameterOrder = order;
1381void QgsProcessingModelAlgorithm::updateDestinationParameters()
1384 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1385 while ( it.hasNext() )
1395 qDeleteAll( mOutputs );
1399 QSet< QString > usedFriendlyNames;
1400 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1402 const QString base = safeName( name,
false );
1403 QString candidate = base;
1405 while ( usedFriendlyNames.contains( candidate ) )
1408 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1410 usedFriendlyNames.insert( candidate );
1414 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1415 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1417 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1418 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1419 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1421 if ( !childIt->isActive() || !childIt->algorithm() )
1429 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1433 if ( outputIt->isMandatory() )
1435 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1437 QString friendlyName = uniqueSafeName( outputIt->description() );
1438 param->setName( friendlyName );
1442 param->setName( outputIt->childId() +
':' + outputIt->name() );
1445 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1446 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1447 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1449 param->setDescription( outputIt->description() );
1450 param->setDefaultValue( outputIt->defaultValue() );
1453 if ( addParameter( param.release() ) && newDestParam )
1460 newDestParam->mOriginalProvider = provider;
1467void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1469 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1472QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1474 return mGroupBoxes.values();
1477void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1479 mGroupBoxes.remove( uuid );
1482QVariant QgsProcessingModelAlgorithm::toVariant()
const
1485 map.insert( QStringLiteral(
"model_name" ), mModelName );
1486 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1487 map.insert( QStringLiteral(
"help" ), mHelpContent );
1488 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1490 QVariantMap childMap;
1491 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1492 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1494 childMap.insert( childIt.key(), childIt.value().toVariant() );
1496 map.insert( QStringLiteral(
"children" ), childMap );
1498 QVariantMap paramMap;
1499 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1500 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1502 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1504 map.insert( QStringLiteral(
"parameters" ), paramMap );
1506 QVariantMap paramDefMap;
1511 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1513 QVariantList groupBoxDefs;
1514 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1516 groupBoxDefs.append( it.value().toVariant() );
1518 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1520 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1522 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1524 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1529bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1531 QVariantMap map = model.toMap();
1533 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1534 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1535 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1536 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1538 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1540 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1541 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1543 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1545 mChildAlgorithms.clear();
1546 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1547 QVariantMap::const_iterator childIt = childMap.constBegin();
1548 for ( ; childIt != childMap.constEnd(); ++childIt )
1550 QgsProcessingModelChildAlgorithm child;
1554 if ( !child.loadVariant( childIt.value() ) )
1557 mChildAlgorithms.insert( child.childId(), child );
1560 mParameterComponents.clear();
1561 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1562 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1563 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1565 QgsProcessingModelParameter param;
1566 if ( !param.loadVariant( paramIt.value().toMap() ) )
1569 mParameterComponents.insert( param.parameterName(), param );
1572 qDeleteAll( mParameters );
1573 mParameters.clear();
1574 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1576 auto addParam = [ = ](
const QVariant & value )
1584 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1588 param->setHelp( mHelpContent.value( param->name() ).toString() );
1591 addParameter( param.release() );
1595 QVariantMap map = value.toMap();
1596 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1597 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1599 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1603 QSet< QString > loadedParams;
1605 for (
const QString &name : std::as_const( mParameterOrder ) )
1607 if ( paramDefMap.contains( name ) )
1609 addParam( paramDefMap.value( name ) );
1610 loadedParams << name;
1614 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1615 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1617 if ( !loadedParams.contains( paramDefIt.key() ) )
1618 addParam( paramDefIt.value() );
1621 mGroupBoxes.clear();
1622 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1623 for (
const QVariant &groupBoxDef : groupBoxList )
1625 QgsProcessingModelGroupBox groupBox;
1626 groupBox.loadVariant( groupBoxDef.toMap() );
1627 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1630 updateDestinationParameters();
1635bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
QgsProcessing::SourceType outputType )
1640 return ( acceptableDataTypes.empty()
1641 || acceptableDataTypes.contains( outputType )
1652void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1654 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1655 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1657 if ( !childIt->algorithm() )
1658 childIt->reattach();
1662bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1664 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1666 doc.appendChild( elem );
1669 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1671 QTextStream stream( &file );
1672 doc.save( stream, 2 );
1679bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1684 if ( file.open( QFile::ReadOnly ) )
1686 if ( !doc.setContent( &file ) )
1697 return loadVariant( props );
1700void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1702 mChildAlgorithms = childAlgorithms;
1703 updateDestinationParameters();
1706void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1709 updateDestinationParameters();
1712QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1714 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1718 updateDestinationParameters();
1722QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1724 return mChildAlgorithms[ childId ];
1727bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1729 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1732 mChildAlgorithms.remove(
id );
1733 updateDestinationParameters();
1737void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1739 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1740 for (
const QString &child : constDependentChildAlgorithms )
1742 childAlgorithm( child ).setActive(
false );
1744 childAlgorithm(
id ).setActive(
false );
1745 updateDestinationParameters();
1748bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1750 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1751 for (
const QString &child : constDependsOnChildAlgorithms )
1753 if ( !childAlgorithm( child ).isActive() )
1756 childAlgorithm(
id ).setActive(
true );
1757 updateDestinationParameters();
1763 if ( addParameter( definition ) )
1764 mParameterComponents.insert( definition->
name(), component );
1769 removeParameter( definition->
name() );
1770 addParameter( definition );
1773void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1775 removeParameter( name );
1776 mParameterComponents.remove( name );
1779void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1784 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1787 expression.prepare( &expressionContext );
1788 QSet<QString> variables = expression.referencedVariables();
1789 if ( variables.contains( oldName ) )
1791 QString newExpression = expressionString;
1792 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1793 return {
true, newExpression };
1795 return {
false, QString() };
1798 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1799 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1801 bool changed =
false;
1802 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1803 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
1804 for ( ; paramIt != childParams.end(); ++paramIt )
1806 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
1807 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
1809 switch ( valueIt->source() )
1811 case QgsProcessingModelChildParameterSource::ModelParameter:
1813 if ( valueIt->parameterName() == oldName )
1815 valueIt->setParameterName( newName );
1821 case QgsProcessingModelChildParameterSource::Expression:
1823 bool updatedExpression =
false;
1824 QString newExpression;
1825 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
1826 if ( updatedExpression )
1828 valueIt->setExpression( newExpression );
1834 case QgsProcessingModelChildParameterSource::StaticValue:
1836 if ( valueIt->staticValue().userType() == QMetaType::type(
"QgsProperty" ) )
1841 bool updatedExpression =
false;
1842 QString newExpression;
1843 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
1844 if ( updatedExpression )
1846 property.setExpressionString( newExpression );
1847 valueIt->setStaticValue( property );
1855 case QgsProcessingModelChildParameterSource::ChildOutput:
1856 case QgsProcessingModelChildParameterSource::ExpressionText:
1857 case QgsProcessingModelChildParameterSource::ModelOutput:
1863 childIt->setParameterSources( childParams );
1867bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
1869 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1870 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1873 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1874 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
1875 for ( ; paramIt != childParams.constEnd(); ++paramIt )
1877 const auto constValue = paramIt.value();
1878 for (
const QgsProcessingModelChildParameterSource &source : constValue )
1880 if ( source.source() == QgsProcessingModelChildParameterSource::ModelParameter
1881 && source.parameterName() == name )
1891bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
1893 const auto constMParameters = mParameters;
1896 if ( def->
name() == name )
1905QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
1907 return mParameterComponents;
1910void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
1912 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1913 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1915 if ( depends.contains( childIt->childId() ) )
1919 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
1920 bool hasDependency =
false;
1921 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
1923 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
1925 hasDependency =
true;
1930 if ( hasDependency )
1932 depends.insert( childIt->childId() );
1933 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
1938 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1939 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
1940 for ( ; paramIt != childParams.constEnd(); ++paramIt )
1942 const auto constValue = paramIt.value();
1943 for (
const QgsProcessingModelChildParameterSource &source : constValue )
1945 if ( source.source() == QgsProcessingModelChildParameterSource::ChildOutput
1946 && source.outputChildId() == childId )
1948 depends.insert( childIt->childId() );
1949 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
1957QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
1959 QSet< QString > algs;
1963 algs.insert( childId );
1965 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
1968 algs.remove( childId );
1974void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
1976 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
1979 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
1980 for (
const QgsProcessingModelChildDependency &val : constDependencies )
1982 if ( !depends.contains( val.childId ) )
1984 depends.insert( val.childId );
1985 dependsOnChildAlgorithmsRecursive( val.childId, depends );
1990 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
1991 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
1992 for ( ; paramIt != childParams.constEnd(); ++paramIt )
1994 const auto constValue = paramIt.value();
1995 for (
const QgsProcessingModelChildParameterSource &source : constValue )
1997 if ( source.source() == QgsProcessingModelChildParameterSource::ChildOutput && !depends.contains( source.outputChildId() ) )
1999 depends.insert( source.outputChildId() );
2000 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2006QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2008 QSet< QString > algs;
2012 algs.insert( childId );
2014 dependsOnChildAlgorithmsRecursive( childId, algs );
2017 algs.remove( childId );
2022QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2024 QSet< QString > dependent;
2025 if ( !childId.isEmpty() )
2027 dependent.unite( dependentChildAlgorithms( childId ) );
2028 dependent.insert( childId );
2031 QList<QgsProcessingModelChildDependency> res;
2032 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2034 if ( !dependent.contains( it->childId() ) )
2037 bool hasBranches =
false;
2038 if ( it->algorithm() )
2046 QgsProcessingModelChildDependency alg;
2047 alg.childId = it->childId();
2048 alg.conditionalBranch = def->
name();
2056 QgsProcessingModelChildDependency alg;
2057 alg.childId = it->childId();
2065bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2068 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2069 if ( childIt != mChildAlgorithms.constEnd() )
2071 if ( !childIt->algorithm() )
2073 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2082 if ( childIt->parameterSources().contains( def->
name() ) )
2085 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2086 for (
const QgsProcessingModelChildParameterSource &source : sources )
2088 switch ( source.source() )
2090 case QgsProcessingModelChildParameterSource::StaticValue:
2094 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2098 case QgsProcessingModelChildParameterSource::ModelParameter:
2099 if ( !parameterComponents().contains( source.parameterName() ) )
2102 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2106 case QgsProcessingModelChildParameterSource::ChildOutput:
2107 if ( !childAlgorithms().contains( source.outputChildId() ) )
2110 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2114 case QgsProcessingModelChildParameterSource::Expression:
2115 case QgsProcessingModelChildParameterSource::ExpressionText:
2116 case QgsProcessingModelChildParameterSource::ModelOutput:
2132 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2141 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2146bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2148 reattachAlgorithms();
2149 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2150 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2152 if ( !childIt->algorithm() )
2156 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2164QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2166 if ( mSourceFile.isEmpty() )
2181 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2182 alg->loadVariant( toVariant() );
2183 alg->setProvider( provider() );
2184 alg->setSourceFilePath( sourceFilePath() );
2188QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2190 QString n = name.toLower().trimmed();
2191 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2192 n.replace( rx, QString() );
2193 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2194 n.replace( rx2, QString() );
2196 n = n.replace(
' ',
'_' );
2200QVariantMap QgsProcessingModelAlgorithm::variables()
const
2205void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2207 mVariables = variables;
2210QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2212 return mDesignerParameterValues;
@ UpperCamelCase
Convert the string to upper camel case. Note that this method does not unaccent characters.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
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)
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.
@ FlagNoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
@ FlagCustomException
Algorithm raises custom exception notices, don't use the standard ones.
@ FlagSkipGenericModelLogging
When running as part of a model, the generic algorithm setup and results logging should be skipped.
@ FlagPruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
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.
Contains information about the context in which a processing algorithm is executed.
@ Verbose
Verbose logging.
QgsExpressionContext & expressionContext()
Returns the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
LogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString generateTemporaryDestination() 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 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.
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.
A vector layer output for processing algorithms.
static QString typeName()
Returns the type name for the output class.
QgsProcessing::SourceType dataType() const
Returns the layer type for the output layer.
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.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
@ FlagOptional
Parameter is optional.
@ FlagHidden
Parameter is hidden and should not be shown to users.
virtual QgsProcessingParameterDefinition * clone() const =0
Creates a clone of the parameter definition.
virtual QString type() const =0
Unique parameter type name.
Flags flags() const
Returns any flags associated with the parameter.
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.
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.
static QString typeName()
Returns the type name for the parameter class.
DataType 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.
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 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 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)
Interprets a string as a map layer within the supplied context.
PythonOutputType
Available Python output types.
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
SourceType
Data source types enum.
@ TypeVectorLine
Vector line layers.
@ TypeMapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
@ TypeVectorPolygon
Vector polygon layers.
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ TypeVectorPoint
Vector point layers.
@ TypeVectorAnyGeometry
Any vector layer with geometry.
A store for object properties.
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
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.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
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.
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.