35#include <QRegularExpression>
38QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
39 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
40 , mModelGroup( group )
41 , mModelGroupId( groupId )
44void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
48QString QgsProcessingModelAlgorithm::name()
const
53QString QgsProcessingModelAlgorithm::displayName()
const
58QString QgsProcessingModelAlgorithm::group()
const
63QString QgsProcessingModelAlgorithm::groupId()
const
68QIcon QgsProcessingModelAlgorithm::icon()
const
73QString QgsProcessingModelAlgorithm::svgIconPath()
const
78QString QgsProcessingModelAlgorithm::shortHelpString()
const
80 if ( mHelpContent.empty() )
86QString QgsProcessingModelAlgorithm::shortDescription()
const
88 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
91QString QgsProcessingModelAlgorithm::helpUrl()
const
93 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
96QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
101 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
103 QString expressionText;
104 QVariantList paramParts;
105 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
107 switch ( source.source() )
110 paramParts << source.staticValue();
114 paramParts << modelParameters.value( source.parameterName() );
119 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
120 paramParts << linkedChildResults.value( source.outputName() );
127 paramParts << exp.evaluate( &expressionContext );
128 if ( exp.hasEvalError() )
130 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
145 if ( ! expressionText.isEmpty() )
147 return expressionText;
149 else if ( paramParts.count() == 1 )
150 return paramParts.at( 0 );
156 QVariantMap childParams;
157 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
160 if ( !def->isDestination() )
162 if ( !child.parameterSources().contains( def->name() ) )
165 const QVariant value = evaluateSources( def );
166 childParams.insert( def->name(), value );
173 bool isFinalOutput =
false;
174 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
175 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
176 for ( ; outputIt != outputs.constEnd(); ++outputIt )
178 if ( outputIt->childOutputName() == destParam->
name() )
180 QString paramName = child.childId() +
':' + outputIt.key();
181 bool foundParam =
false;
185 if ( modelParameters.contains( paramName ) )
187 value = modelParameters.value( paramName );
196 if ( modelParameters.contains( modelParam->name() ) )
198 value = modelParameters.value( modelParam->name() );
206 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
211 value = QVariant::fromValue( fromVar );
214 childParams.insert( destParam->
name(), value );
216 isFinalOutput =
true;
221 bool hasExplicitDefinition =
false;
222 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
225 const QVariant value = evaluateSources( def );
226 if ( value.isValid() )
228 childParams.insert( def->name(), value );
229 hasExplicitDefinition =
true;
233 if ( !isFinalOutput && !hasExplicitDefinition )
238 bool required =
true;
241 required = childOutputIsRequired( child.childId(), destParam->
name() );
253const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
257 if ( !definition->isDestination() )
260 const QString modelChildId = definition->
metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
261 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
263 if ( modelChildId == childId && modelOutputName == childOutputName )
269bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
272 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
273 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
275 if ( childIt->childId() == childId || !childIt->isActive() )
279 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
280 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
281 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
283 const auto constValue = childParamIt.value();
284 for (
const QgsProcessingModelChildParameterSource &source : constValue )
287 && source.outputChildId() == childId
288 && source.outputName() == outputName )
300 QSet< QString > toExecute;
301 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
302 QSet< QString > broken;
303 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
305 if ( childIt->isActive() )
307 if ( childIt->algorithm() )
308 toExecute.insert( childIt->childId() );
310 broken.insert( childIt->childId() );
314 if ( !broken.empty() )
315 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
317 QElapsedTimer totalTime;
323 QVariantMap childResults;
324 QVariantMap childInputs;
326 QVariantMap finalResults;
327 QSet< QString > executed;
328 bool executedAlg =
true;
329 while ( executedAlg && executed.count() < toExecute.count() )
332 for (
const QString &childId : std::as_const( toExecute ) )
337 if ( executed.contains( childId ) )
340 bool canExecute =
true;
341 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
342 for (
const QString &dependency : dependencies )
344 if ( !executed.contains( dependency ) )
356 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
357 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
359 bool skipGenericLogging =
true;
364 skipGenericLogging =
true;
374 skipGenericLogging =
false;
378 if ( feedback && !skipGenericLogging )
379 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
383 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
387 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
388 if ( !error.isEmpty() )
391 if ( feedback && !skipGenericLogging )
392 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
396 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
398 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
399 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
402 if ( feedback && !skipGenericLogging )
404 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
405 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
408 QElapsedTimer childTime;
413 QThread *modelThread = QThread::currentThread();
415 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
417 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
418 ok = childAlg->prepare( childParams, context, &modelFeedback );
419 context.pushToThread( modelThread );
423 if ( modelThread == qApp->thread() )
424 ok = childAlg->prepare( childParams, context, &modelFeedback );
427 context.pushToThread( qApp->thread() );
428 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
431 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
445 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
447 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
448 results = childAlg->runPrepared( childParams, context, &modelFeedback );
449 context.pushToThread( modelThread );
452 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
453 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
455 context.pushToThread( qApp->thread() );
456 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
461 results = childAlg->runPrepared( childParams, context, &modelFeedback );
470 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
473 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback]
475 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
476 ppRes = childAlg->postProcess( context, &modelFeedback );
477 context.pushToThread( modelThread );
481 if ( modelThread == qApp->thread() )
482 ppRes = childAlg->postProcess( context, &modelFeedback );
485 context.pushToThread( qApp->thread() );
486 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
489 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
491 if ( !ppRes.isEmpty() )
494 if ( feedback && !skipGenericLogging )
497 QStringList formattedOutputs;
498 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
500 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
503 feedback->
pushInfo( QObject::tr(
"Results:" ) );
504 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
507 childResults.insert( childId, results );
511 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
512 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
514 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
515 switch ( mInternalVersion )
517 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
518 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
520 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
523 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
528 if ( !results.value( outputIt->childOutputName() ).toString().isEmpty() )
532 if ( outputSortKey > 0 )
537 executed.insert( childId );
539 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
540 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
542 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
543 for (
const QString &targetId : toPrune )
545 if ( executed.contains( targetId ) )
548 executed.insert( targetId );
549 pruneAlgorithmBranchRecursive( targetId, branch );
559 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
567 for (
const QString &candidateId : std::as_const( toExecute ) )
569 if ( executed.contains( candidateId ) )
574 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
575 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
576 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
578 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
580 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
585 if ( !results.contains( source.outputName() ) )
590 executed.insert( candidateId );
592 pruneAlgorithmBranchRecursive( candidateId, QString() );
603 childAlg.reset(
nullptr );
604 modelFeedback.setCurrentStep( executed.count() );
605 if ( feedback && !skipGenericLogging )
606 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
613 feedback->
pushDebugInfo( QObject::tr(
"Model processed OK. Executed %n algorithm(s) total in %1 s.",
nullptr, executed.count() ).arg( totalTime.elapsed() / 1000.0 ) );
615 mResults = finalResults;
616 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
617 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
621QString QgsProcessingModelAlgorithm::sourceFilePath()
const
626void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
628 mSourceFile = sourceFile;
631bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
633 if ( mSourceFile.isEmpty() )
636 const QFileInfo fi( mSourceFile );
637 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
642 QStringList fileDocString;
643 fileDocString << QStringLiteral(
"\"\"\"" );
644 fileDocString << QStringLiteral(
"Model exported as python." );
645 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
646 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
647 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
648 fileDocString << QStringLiteral(
"\"\"\"" );
649 fileDocString << QString();
652 QString indent = QString(
' ' ).repeated( indentSize );
653 QString currentIndent;
655 QMap< QString, QString> friendlyChildNames;
656 QMap< QString, QString> friendlyOutputNames;
657 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
659 const QString base = safeName( name, capitalize );
660 QString candidate = base;
662 while ( friendlyNames.contains( candidate ) )
665 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
670 const QString algorithmClassName = safeName( name(),
true );
672 QSet< QString > toExecute;
673 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
675 if ( childIt->isActive() && childIt->algorithm() )
677 toExecute.insert( childIt->childId() );
678 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
681 const int totalSteps = toExecute.count();
683 QStringList importLines;
684 switch ( outputType )
689 const auto params = parameterDefinitions();
690 importLines.reserve( params.count() + 3 );
691 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
692 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
693 importLines << QStringLiteral(
"from qgis.core import QgsProcessingMultiStepFeedback" );
695 bool hasAdvancedParams =
false;
699 hasAdvancedParams =
true;
702 if ( !importString.isEmpty() && !importLines.contains( importString ) )
703 importLines << importString;
706 if ( hasAdvancedParams )
707 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
709 lines << QStringLiteral(
"import processing" );
710 lines << QString() << QString();
712 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
716 lines << indent + QStringLiteral(
"def initAlgorithm(self, config=None):" );
717 if ( params.empty() )
719 lines << indent + indent + QStringLiteral(
"pass" );
723 lines.reserve( lines.size() + params.size() );
726 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
728 if ( defClone->isDestination() )
730 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
731 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
732 friendlyOutputNames.insert( uniqueChildName, friendlyName );
733 defClone->setName( friendlyName );
737 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
739 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
740 for (
const QString &part : parts )
742 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
749 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
750 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
751 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
755 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
761 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters, context, model_feedback):" );
762 currentIndent = indent + indent;
764 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
765 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
766 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
774 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
775 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
777 QString name = paramIt.value().parameterName();
778 if ( parameterDefinition( name ) )
781 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
785 if ( !params.isEmpty() )
787 lines << QStringLiteral(
"parameters = {" );
788 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
790 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
792 lines << QStringLiteral(
"}" )
796 lines << QStringLiteral(
"context = QgsProcessingContext()" )
797 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
798 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
807 lines << currentIndent + QStringLiteral(
"results = {}" );
808 lines << currentIndent + QStringLiteral(
"outputs = {}" );
811 QSet< QString > executed;
812 bool executedAlg =
true;
814 while ( executedAlg && executed.count() < toExecute.count() )
817 const auto constToExecute = toExecute;
818 for (
const QString &childId : constToExecute )
820 if ( executed.contains( childId ) )
823 bool canExecute =
true;
824 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
825 for (
const QString &dependency : constDependsOnChildAlgorithms )
827 if ( !executed.contains( dependency ) )
839 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
846 if ( def->isDestination() )
851 bool isFinalOutput =
false;
852 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
853 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
854 for ( ; outputIt != outputs.constEnd(); ++outputIt )
856 if ( outputIt->childOutputName() == destParam->
name() )
858 QString paramName = child.childId() +
':' + outputIt.key();
859 paramName = friendlyOutputNames.value( paramName, paramName );
860 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
861 isFinalOutput =
true;
866 if ( !isFinalOutput )
871 bool required =
true;
874 required = childOutputIsRequired( child.childId(), destParam->
name() );
880 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
886 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
888 if ( currentStep < totalSteps )
891 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
892 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
893 lines << currentIndent + indent + QStringLiteral(
"return {}" );
896 executed.insert( childId );
900 switch ( outputType )
903 lines << currentIndent + QStringLiteral(
"return results" );
907 lines << indent + QStringLiteral(
"def name(self):" );
908 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
910 lines << indent + QStringLiteral(
"def displayName(self):" );
911 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
915 lines << indent + QStringLiteral(
"def group(self):" );
916 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
918 lines << indent + QStringLiteral(
"def groupId(self):" );
919 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
923 if ( !shortHelpString().isEmpty() )
925 lines << indent + QStringLiteral(
"def shortHelpString(self):" );
926 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
929 if ( !helpUrl().isEmpty() )
931 lines << indent + QStringLiteral(
"def helpUrl(self):" );
932 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
937 lines << indent + QStringLiteral(
"def createInstance(self):" );
938 lines << indent + indent + QStringLiteral(
"return %1()" ).arg( algorithmClassName );
941 static QMap< QString, QString > sAdditionalImports
943 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
944 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
945 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
946 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
947 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
948 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
949 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
950 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
951 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
952 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
953 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
954 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
955 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
956 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
957 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
958 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
959 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
960 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
961 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
962 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
965 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
967 if ( importLines.contains( it.value() ) )
974 for (
const QString &line : std::as_const( lines ) )
976 if ( line.contains( it.key() ) )
984 importLines << it.value();
988 lines = fileDocString + importLines + lines;
997QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
999 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1001 auto safeName = [](
const QString & name )->QString
1004 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1005 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1040 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1044 QString description;
1045 switch ( source.source() )
1049 name = source.parameterName();
1050 value = modelParameters.value( source.parameterName() );
1051 description = parameterDefinition( source.parameterName() )->description();
1056 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1057 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1058 source.outputChildId() : child.description(), source.outputName() );
1061 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1062 child.description() );
1064 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1074 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1078 sources = availableSourcesForChild( childId, QStringList()
1085 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1089 QString description;
1091 switch ( source.source() )
1095 name = source.parameterName();
1096 value = modelParameters.value( source.parameterName() );
1097 description = parameterDefinition( source.parameterName() )->description();
1102 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1103 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1104 source.outputChildId() : child.description(), source.outputName() );
1105 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1108 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1109 child.description() );
1122 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1125 value = fromVar.
sink;
1126 if ( value.userType() == QMetaType::type(
"QgsProperty" ) && context )
1134 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1139 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1140 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1141 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1142 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1143 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1146 sources = availableSourcesForChild( childId, QStringList()
1148 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1152 QString description;
1154 switch ( source.source() )
1158 name = source.parameterName();
1159 value = modelParameters.value( source.parameterName() );
1160 description = parameterDefinition( source.parameterName() )->description();
1165 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1166 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1167 source.outputChildId() : child.description(), source.outputName() );
1168 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1171 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1172 child.description() );
1186 if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1191 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1194 value = fromVar.
sink;
1195 if ( context && value.userType() == QMetaType::type(
"QgsProperty" ) )
1200 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1202 featureSource = layer;
1204 if ( context && !featureSource )
1210 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1211 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1212 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1213 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1214 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1220QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1222 std::unique_ptr< QgsExpressionContextScope > scope(
new QgsExpressionContextScope( QStringLiteral(
"algorithm_inputs" ) ) );
1223 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1224 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1225 for ( ; varIt != variables.constEnd(); ++varIt )
1229 return scope.release();
1232QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1234 QgsProcessingModelChildParameterSources sources;
1237 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1238 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1244 if ( parameterTypes.contains( def->
type() ) )
1246 if ( !dataTypes.isEmpty() )
1262 bool ok = sourceDef->
dataTypes().isEmpty();
1263 const auto constDataTypes = sourceDef->
dataTypes();
1264 for (
int type : constDataTypes )
1279 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1283 QSet< QString > dependents;
1284 if ( !childId.isEmpty() )
1286 dependents = dependentChildAlgorithms( childId );
1287 dependents << childId;
1290 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1291 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1293 if ( dependents.contains( childIt->childId() ) )
1303 if ( outputTypes.contains( out->type() ) )
1305 if ( !dataTypes.isEmpty() )
1311 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1318 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1326QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1328 return mHelpContent;
1331void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1333 mHelpContent = helpContent;
1336void QgsProcessingModelAlgorithm::setName(
const QString &name )
1341void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1343 mModelGroup = group;
1346bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1351 if ( mChildAlgorithms.empty() )
1354 issues << QObject::tr(
"Model does not contain any algorithms" );
1357 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1359 QStringList childIssues;
1360 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1362 for (
const QString &issue : std::as_const( childIssues ) )
1364 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1370QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1372 return mChildAlgorithms;
1375void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1377 mParameterComponents = parameterComponents;
1380void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1382 mParameterComponents.insert( component.parameterName(), component );
1385QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1387 if ( !mParameterComponents.contains( name ) )
1389 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1390 component.setParameterName( name );
1393 return mParameterComponents[ name ];
1396QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1398 QList< QgsProcessingModelParameter > res;
1399 QSet< QString > found;
1400 for (
const QString ¶meter : mParameterOrder )
1402 if ( mParameterComponents.contains( parameter ) )
1404 res << mParameterComponents.value( parameter );
1410 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1412 if ( !found.contains( it.key() ) )
1420void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1422 mParameterOrder = order;
1425QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1427 QList< QgsProcessingModelOutput > res;
1428 QSet< QString > found;
1430 for (
const QString &output : mOutputOrder )
1432 bool foundOutput =
false;
1433 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1435 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1436 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1438 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1440 res << outputIt.value();
1442 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1451 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1453 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1454 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1456 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1458 res << outputIt.value();
1466void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1468 mOutputOrder = order;
1471QString QgsProcessingModelAlgorithm::outputGroup()
const
1473 return mOutputGroup;
1476void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1478 mOutputGroup = group;
1481void QgsProcessingModelAlgorithm::updateDestinationParameters()
1484 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1485 while ( it.hasNext() )
1495 qDeleteAll( mOutputs );
1499 QSet< QString > usedFriendlyNames;
1500 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1502 const QString base = safeName( name,
false );
1503 QString candidate = base;
1505 while ( usedFriendlyNames.contains( candidate ) )
1508 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1510 usedFriendlyNames.insert( candidate );
1514 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1515 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1517 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1518 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1519 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1521 if ( !childIt->isActive() || !childIt->algorithm() )
1529 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1533 if ( outputIt->isMandatory() )
1535 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1537 QString friendlyName = uniqueSafeName( outputIt->description() );
1538 param->setName( friendlyName );
1542 param->setName( outputIt->childId() +
':' + outputIt->name() );
1545 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1546 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1547 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1549 param->setDescription( outputIt->description() );
1550 param->setDefaultValue( outputIt->defaultValue() );
1553 if ( addParameter( param.release() ) && newDestParam )
1560 newDestParam->mOriginalProvider = provider;
1567void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1569 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1572QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1574 return mGroupBoxes.values();
1577void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1579 mGroupBoxes.remove( uuid );
1582QVariant QgsProcessingModelAlgorithm::toVariant()
const
1585 map.insert( QStringLiteral(
"model_name" ), mModelName );
1586 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1587 map.insert( QStringLiteral(
"help" ), mHelpContent );
1588 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1590 QVariantMap childMap;
1591 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1592 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1594 childMap.insert( childIt.key(), childIt.value().toVariant() );
1596 map.insert( QStringLiteral(
"children" ), childMap );
1598 QVariantMap paramMap;
1599 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1600 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1602 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1604 map.insert( QStringLiteral(
"parameters" ), paramMap );
1606 QVariantMap paramDefMap;
1611 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1613 QVariantList groupBoxDefs;
1614 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1616 groupBoxDefs.append( it.value().toVariant() );
1618 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1620 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1622 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1624 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1625 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1626 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1631bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1633 QVariantMap map = model.toMap();
1635 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1636 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1637 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1638 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1640 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1642 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1643 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1645 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1646 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1647 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1649 mChildAlgorithms.clear();
1650 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1651 QVariantMap::const_iterator childIt = childMap.constBegin();
1652 for ( ; childIt != childMap.constEnd(); ++childIt )
1654 QgsProcessingModelChildAlgorithm child;
1658 if ( !child.loadVariant( childIt.value() ) )
1661 mChildAlgorithms.insert( child.childId(), child );
1664 mParameterComponents.clear();
1665 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1666 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1667 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1669 QgsProcessingModelParameter param;
1670 if ( !param.loadVariant( paramIt.value().toMap() ) )
1673 mParameterComponents.insert( param.parameterName(), param );
1676 qDeleteAll( mParameters );
1677 mParameters.clear();
1678 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1680 auto addParam = [
this](
const QVariant & value )
1688 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1692 param->setHelp( mHelpContent.value( param->name() ).toString() );
1695 addParameter( param.release() );
1699 QVariantMap map = value.toMap();
1700 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1701 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1703 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1707 QSet< QString > loadedParams;
1709 for (
const QString &name : std::as_const( mParameterOrder ) )
1711 if ( paramDefMap.contains( name ) )
1713 addParam( paramDefMap.value( name ) );
1714 loadedParams << name;
1718 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1719 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1721 if ( !loadedParams.contains( paramDefIt.key() ) )
1722 addParam( paramDefIt.value() );
1725 mGroupBoxes.clear();
1726 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1727 for (
const QVariant &groupBoxDef : groupBoxList )
1729 QgsProcessingModelGroupBox groupBox;
1730 groupBox.loadVariant( groupBoxDef.toMap() );
1731 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1734 updateDestinationParameters();
1739bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1744 return ( acceptableDataTypes.empty()
1745 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1756void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1758 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1759 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1761 if ( !childIt->algorithm() )
1762 childIt->reattach();
1766bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1768 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1770 doc.appendChild( elem );
1773 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1775 QTextStream stream( &file );
1776 doc.save( stream, 2 );
1783bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1788 if ( file.open( QFile::ReadOnly ) )
1790 if ( !doc.setContent( &file ) )
1801 return loadVariant( props );
1804void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1806 mChildAlgorithms = childAlgorithms;
1807 updateDestinationParameters();
1810void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1813 updateDestinationParameters();
1816QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1818 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1822 updateDestinationParameters();
1826QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1828 return mChildAlgorithms[ childId ];
1831bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1833 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1836 mChildAlgorithms.remove(
id );
1837 updateDestinationParameters();
1841void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1843 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1844 for (
const QString &child : constDependentChildAlgorithms )
1846 childAlgorithm( child ).setActive(
false );
1848 childAlgorithm(
id ).setActive(
false );
1849 updateDestinationParameters();
1852bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1854 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1855 for (
const QString &child : constDependsOnChildAlgorithms )
1857 if ( !childAlgorithm( child ).isActive() )
1860 childAlgorithm(
id ).setActive(
true );
1861 updateDestinationParameters();
1867 if ( addParameter( definition ) )
1868 mParameterComponents.insert( definition->
name(), component );
1873 removeParameter( definition->
name() );
1874 addParameter( definition );
1877void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1879 removeParameter( name );
1880 mParameterComponents.remove( name );
1883void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1888 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1891 expression.prepare( &expressionContext );
1892 QSet<QString> variables = expression.referencedVariables();
1893 if ( variables.contains( oldName ) )
1895 QString newExpression = expressionString;
1896 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1897 return {
true, newExpression };
1899 return {
false, QString() };
1902 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1903 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1905 bool changed =
false;
1906 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1907 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
1908 for ( ; paramIt != childParams.end(); ++paramIt )
1910 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
1911 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
1913 switch ( valueIt->source() )
1917 if ( valueIt->parameterName() == oldName )
1919 valueIt->setParameterName( newName );
1927 bool updatedExpression =
false;
1928 QString newExpression;
1929 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
1930 if ( updatedExpression )
1932 valueIt->setExpression( newExpression );
1940 if ( valueIt->staticValue().userType() == QMetaType::type(
"QgsProperty" ) )
1945 bool updatedExpression =
false;
1946 QString newExpression;
1947 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
1948 if ( updatedExpression )
1950 property.setExpressionString( newExpression );
1951 valueIt->setStaticValue( property );
1967 childIt->setParameterSources( childParams );
1971bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
1973 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1974 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1977 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1978 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
1979 for ( ; paramIt != childParams.constEnd(); ++paramIt )
1981 const auto constValue = paramIt.value();
1982 for (
const QgsProcessingModelChildParameterSource &source : constValue )
1985 && source.parameterName() == name )
1995bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
1997 const auto constMParameters = mParameters;
2000 if ( def->
name() == name )
2009QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2011 return mParameterComponents;
2014void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2016 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2017 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2019 if ( depends.contains( childIt->childId() ) )
2023 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2024 bool hasDependency =
false;
2025 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2027 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2029 hasDependency =
true;
2034 if ( hasDependency )
2036 depends.insert( childIt->childId() );
2037 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2042 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2043 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2044 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2046 const auto constValue = paramIt.value();
2047 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2050 && source.outputChildId() == childId )
2052 depends.insert( childIt->childId() );
2053 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2061QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2063 QSet< QString > algs;
2067 algs.insert( childId );
2069 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2072 algs.remove( childId );
2078void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2080 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2083 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2084 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2086 if ( !depends.contains( val.childId ) )
2088 depends.insert( val.childId );
2089 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2094 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2095 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2096 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2098 const auto constValue = paramIt.value();
2099 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2101 switch ( source.source() )
2104 if ( !depends.contains( source.outputChildId() ) )
2106 depends.insert( source.outputChildId() );
2107 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2114 const QSet<QString> vars = exp.referencedVariables();
2119 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2120 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2126 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2130 depends.insert( childVarIt->source.outputChildId() );
2131 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2146QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2148 QSet< QString > algs;
2152 algs.insert( childId );
2154 dependsOnChildAlgorithmsRecursive( childId, algs );
2157 algs.remove( childId );
2162QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2164 QSet< QString > dependent;
2165 if ( !childId.isEmpty() )
2167 dependent.unite( dependentChildAlgorithms( childId ) );
2168 dependent.insert( childId );
2171 QList<QgsProcessingModelChildDependency> res;
2172 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2174 if ( !dependent.contains( it->childId() ) )
2177 bool hasBranches =
false;
2178 if ( it->algorithm() )
2186 QgsProcessingModelChildDependency alg;
2187 alg.childId = it->childId();
2188 alg.conditionalBranch = def->
name();
2196 QgsProcessingModelChildDependency alg;
2197 alg.childId = it->childId();
2205bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2208 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2209 if ( childIt != mChildAlgorithms.constEnd() )
2211 if ( !childIt->algorithm() )
2213 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2222 if ( childIt->parameterSources().contains( def->
name() ) )
2225 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2226 for (
const QgsProcessingModelChildParameterSource &source : sources )
2228 switch ( source.source() )
2234 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2239 if ( !parameterComponents().contains( source.parameterName() ) )
2242 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2247 if ( !childAlgorithms().contains( source.outputChildId() ) )
2250 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2272 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2281 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2286bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2288 reattachAlgorithms();
2289 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2290 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2292 if ( !childIt->algorithm() )
2296 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2304QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2306 if ( mSourceFile.isEmpty() )
2321 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2322 alg->loadVariant( toVariant() );
2323 alg->setProvider( provider() );
2324 alg->setSourceFilePath( sourceFilePath() );
2328QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2330 QString n = name.toLower().trimmed();
2331 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2332 n.replace( rx, QString() );
2333 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2334 n.replace( rx2, QString() );
2336 n = n.replace(
' ',
'_' );
2340QVariantMap QgsProcessingModelAlgorithm::variables()
const
2345void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2347 mVariables = variables;
2350QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2352 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.
@ Expression
Expression based property.
@ 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.
@ 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...
@ 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 (si...
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.
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.
Qgis::ProcessingLogLevel 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 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 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.
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.
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 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.
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.
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.