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;
304 const bool useSubsetOfChildren = !childSubset.empty();
305 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
307 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
309 if ( childIt->algorithm() )
310 toExecute.insert( childIt->childId() );
312 broken.insert( childIt->childId() );
316 if ( !broken.empty() )
317 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
319 QElapsedTimer totalTime;
333 childInputs = config->initialChildInputs();
334 childResults = config->initialChildOutputs();
335 executed = config->previouslyExecutedChildAlgorithms();
339 if ( useSubsetOfChildren )
341 executed.subtract( childSubset );
344 QVariantMap finalResults;
346 bool executedAlg =
true;
347 int previousHtmlLogLength = feedback->
htmlLog().length();
348 int countExecuted = 0;
349 while ( executedAlg && countExecuted < toExecute.count() )
352 for (
const QString &childId : std::as_const( toExecute ) )
357 if ( executed.contains( childId ) )
360 bool canExecute =
true;
361 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
362 for (
const QString &dependency : dependencies )
364 if ( !executed.contains( dependency ) )
376 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
377 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
379 bool skipGenericLogging =
true;
384 skipGenericLogging =
true;
394 skipGenericLogging =
false;
398 if ( feedback && !skipGenericLogging )
399 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
403 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
407 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
408 if ( !error.isEmpty() )
411 if ( feedback && !skipGenericLogging )
412 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
417 childInputs.insert( childId, thisChildParams );
418 childResult.
setInputs( thisChildParams );
421 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
423 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
424 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
427 if ( feedback && !skipGenericLogging )
429 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
430 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
433 QElapsedTimer childTime;
438 QThread *modelThread = QThread::currentThread();
440 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
442 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
443 ok = childAlg->prepare( childParams, context, &modelFeedback );
444 context.pushToThread( modelThread );
448 if ( modelThread == qApp->thread() )
449 ok = childAlg->prepare( childParams, context, &modelFeedback );
452 context.pushToThread( qApp->thread() );
454#ifndef __clang_analyzer__
455 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
459 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
469 bool runResult =
false;
475 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
477 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
478 results = childAlg->runPrepared( childParams, context, &modelFeedback );
479 context.pushToThread( modelThread );
482 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
483 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
485 context.pushToThread( qApp->thread() );
487#ifndef __clang_analyzer__
488 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
494 results = childAlg->runPrepared( childParams, context, &modelFeedback );
505 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
508 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult]
510 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
511 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
512 context.pushToThread( modelThread );
516 if ( modelThread == qApp->thread() )
517 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
520 context.pushToThread( qApp->thread() );
522#ifndef __clang_analyzer__
523 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
527 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
529 if ( !ppRes.isEmpty() )
532 childResults.insert( childId, results );
537 if ( feedback && !skipGenericLogging )
540 QStringList formattedOutputs;
541 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
543 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
546 feedback->
pushInfo( QObject::tr(
"Results:" ) );
547 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
552 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
553 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
555 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
556 switch ( mInternalVersion )
558 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
559 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
561 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
564 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
569 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
570 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
574 if ( outputSortKey > 0 )
579 executed.insert( childId );
581 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
582 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
584 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
585 for (
const QString &targetId : toPrune )
587 if ( executed.contains( targetId ) )
590 executed.insert( targetId );
591 pruneAlgorithmBranchRecursive( targetId, branch );
601 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
609 for (
const QString &candidateId : std::as_const( toExecute ) )
611 if ( executed.contains( candidateId ) )
616 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
617 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
618 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
620 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
622 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
627 if ( !results.contains( source.outputName() ) )
632 executed.insert( candidateId );
634 pruneAlgorithmBranchRecursive( candidateId, QString() );
645 childAlg.reset(
nullptr );
647 modelFeedback.setCurrentStep( countExecuted );
648 if ( feedback && !skipGenericLogging )
650 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
655 const QString thisAlgorithmHtmlLog = feedback->
htmlLog().mid( previousHtmlLogLength );
656 previousHtmlLogLength = feedback->
htmlLog().length();
660 const QString formattedException = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( error.toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
661 const QString formattedRunTime = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( QObject::tr(
"Failed after %1 s." ).arg( childTime.elapsed() / 1000.0 ).toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
663 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
664 context.modelResult().childResults().insert( childId, childResult );
670 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
671 context.modelResult().childResults().insert( childId, childResult );
679 feedback->
pushDebugInfo( QObject::tr(
"Model processed OK. Executed %n algorithm(s) total in %1 s.",
nullptr, countExecuted ).arg(
static_cast< double >( totalTime.elapsed() ) / 1000.0 ) );
681 mResults = finalResults;
682 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
683 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
687QString QgsProcessingModelAlgorithm::sourceFilePath()
const
692void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
694 mSourceFile = sourceFile;
697bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
699 if ( mSourceFile.isEmpty() )
702 const QFileInfo fi( mSourceFile );
703 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
708 QStringList fileDocString;
709 fileDocString << QStringLiteral(
"\"\"\"" );
710 fileDocString << QStringLiteral(
"Model exported as python." );
711 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
712 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
713 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
714 fileDocString << QStringLiteral(
"\"\"\"" );
715 fileDocString << QString();
718 QString indent = QString(
' ' ).repeated( indentSize );
719 QString currentIndent;
721 QMap< QString, QString> friendlyChildNames;
722 QMap< QString, QString> friendlyOutputNames;
723 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
725 const QString base = safeName( name, capitalize );
726 QString candidate = base;
728 while ( friendlyNames.contains( candidate ) )
731 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
736 const QString algorithmClassName = safeName( name(),
true );
738 QSet< QString > toExecute;
739 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
741 if ( childIt->isActive() && childIt->algorithm() )
743 toExecute.insert( childIt->childId() );
744 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
747 const int totalSteps = toExecute.count();
749 QStringList importLines;
750 switch ( outputType )
755 const auto params = parameterDefinitions();
756 importLines.reserve( params.count() + 3 );
757 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
758 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
759 importLines << QStringLiteral(
"from qgis.core import QgsProcessingMultiStepFeedback" );
761 bool hasAdvancedParams =
false;
765 hasAdvancedParams =
true;
768 if ( !importString.isEmpty() && !importLines.contains( importString ) )
769 importLines << importString;
772 if ( hasAdvancedParams )
773 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
775 lines << QStringLiteral(
"import processing" );
776 lines << QString() << QString();
778 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
782 lines << indent + QStringLiteral(
"def initAlgorithm(self, config=None):" );
783 if ( params.empty() )
785 lines << indent + indent + QStringLiteral(
"pass" );
789 lines.reserve( lines.size() + params.size() );
792 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
794 if ( defClone->isDestination() )
796 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
797 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
798 friendlyOutputNames.insert( uniqueChildName, friendlyName );
799 defClone->setName( friendlyName );
803 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
805 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
806 for (
const QString &part : parts )
808 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
815 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
816 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
817 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
821 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
827 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters, context, model_feedback):" );
828 currentIndent = indent + indent;
830 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
831 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
832 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
840 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
841 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
843 QString name = paramIt.value().parameterName();
844 if ( parameterDefinition( name ) )
847 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
851 if ( !params.isEmpty() )
853 lines << QStringLiteral(
"parameters = {" );
854 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
856 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
858 lines << QStringLiteral(
"}" )
862 lines << QStringLiteral(
"context = QgsProcessingContext()" )
863 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
864 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
873 lines << currentIndent + QStringLiteral(
"results = {}" );
874 lines << currentIndent + QStringLiteral(
"outputs = {}" );
877 QSet< QString > executed;
878 bool executedAlg =
true;
880 while ( executedAlg && executed.count() < toExecute.count() )
883 const auto constToExecute = toExecute;
884 for (
const QString &childId : constToExecute )
886 if ( executed.contains( childId ) )
889 bool canExecute =
true;
890 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
891 for (
const QString &dependency : constDependsOnChildAlgorithms )
893 if ( !executed.contains( dependency ) )
905 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
912 if ( def->isDestination() )
917 bool isFinalOutput =
false;
918 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
919 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
920 for ( ; outputIt != outputs.constEnd(); ++outputIt )
922 if ( outputIt->childOutputName() == destParam->
name() )
924 QString paramName = child.childId() +
':' + outputIt.key();
925 paramName = friendlyOutputNames.value( paramName, paramName );
926 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
927 isFinalOutput =
true;
932 if ( !isFinalOutput )
937 bool required =
true;
940 required = childOutputIsRequired( child.childId(), destParam->
name() );
946 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
952 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
954 if ( currentStep < totalSteps )
957 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
958 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
959 lines << currentIndent + indent + QStringLiteral(
"return {}" );
962 executed.insert( childId );
966 switch ( outputType )
969 lines << currentIndent + QStringLiteral(
"return results" );
973 lines << indent + QStringLiteral(
"def name(self):" );
974 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
976 lines << indent + QStringLiteral(
"def displayName(self):" );
977 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
981 lines << indent + QStringLiteral(
"def group(self):" );
982 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
984 lines << indent + QStringLiteral(
"def groupId(self):" );
985 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
989 if ( !shortHelpString().isEmpty() )
991 lines << indent + QStringLiteral(
"def shortHelpString(self):" );
992 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
995 if ( !helpUrl().isEmpty() )
997 lines << indent + QStringLiteral(
"def helpUrl(self):" );
998 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
1003 lines << indent + QStringLiteral(
"def createInstance(self):" );
1004 lines << indent + indent + QStringLiteral(
"return %1()" ).arg( algorithmClassName );
1007 static QMap< QString, QString > sAdditionalImports
1009 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
1010 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
1011 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
1012 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
1013 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
1014 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
1015 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
1016 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
1017 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
1018 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
1019 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
1020 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
1021 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
1022 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
1023 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
1024 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
1025 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
1026 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
1027 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
1028 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
1031 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1033 if ( importLines.contains( it.value() ) )
1040 for (
const QString &line : std::as_const( lines ) )
1042 if ( line.contains( it.key() ) )
1050 importLines << it.value();
1054 lines = fileDocString + importLines + lines;
1063QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1065 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1067 auto safeName = [](
const QString & name )->QString
1070 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1071 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1106 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1110 QString description;
1111 switch ( source.source() )
1115 name = source.parameterName();
1116 value = modelParameters.value( source.parameterName() );
1117 description = parameterDefinition( source.parameterName() )->description();
1122 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1123 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1124 source.outputChildId() : child.description(), source.outputName() );
1127 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1128 child.description() );
1130 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1140 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1144 sources = availableSourcesForChild( childId, QStringList()
1151 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1155 QString description;
1157 switch ( source.source() )
1161 name = source.parameterName();
1162 value = modelParameters.value( source.parameterName() );
1163 description = parameterDefinition( source.parameterName() )->description();
1168 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1169 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1170 source.outputChildId() : child.description(), source.outputName() );
1171 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1174 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1175 child.description() );
1188 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1191 value = fromVar.
sink;
1192 if ( value.userType() == QMetaType::type(
"QgsProperty" ) && context )
1200 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1205 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1206 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1207 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1208 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1209 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1212 sources = availableSourcesForChild( childId, QStringList()
1214 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1218 QString description;
1220 switch ( source.source() )
1224 name = source.parameterName();
1225 value = modelParameters.value( source.parameterName() );
1226 description = parameterDefinition( source.parameterName() )->description();
1231 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1232 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1233 source.outputChildId() : child.description(), source.outputName() );
1234 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1237 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1238 child.description() );
1252 if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1257 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1260 value = fromVar.
sink;
1261 if ( context && value.userType() == QMetaType::type(
"QgsProperty" ) )
1266 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1268 featureSource = layer;
1270 if ( context && !featureSource )
1276 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1277 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1278 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1279 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1280 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1286QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1288 std::unique_ptr< QgsExpressionContextScope > scope(
new QgsExpressionContextScope( QStringLiteral(
"algorithm_inputs" ) ) );
1289 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1290 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1291 for ( ; varIt != variables.constEnd(); ++varIt )
1295 return scope.release();
1298QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1300 QgsProcessingModelChildParameterSources sources;
1303 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1304 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1310 if ( parameterTypes.contains( def->
type() ) )
1312 if ( !dataTypes.isEmpty() )
1328 bool ok = sourceDef->
dataTypes().isEmpty();
1329 const auto constDataTypes = sourceDef->
dataTypes();
1330 for (
int type : constDataTypes )
1345 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1349 QSet< QString > dependents;
1350 if ( !childId.isEmpty() )
1352 dependents = dependentChildAlgorithms( childId );
1353 dependents << childId;
1356 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1357 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1359 if ( dependents.contains( childIt->childId() ) )
1369 if ( outputTypes.contains( out->type() ) )
1371 if ( !dataTypes.isEmpty() )
1377 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1384 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1392QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1394 return mHelpContent;
1397void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1399 mHelpContent = helpContent;
1402void QgsProcessingModelAlgorithm::setName(
const QString &name )
1407void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1409 mModelGroup = group;
1412bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1417 if ( mChildAlgorithms.empty() )
1420 issues << QObject::tr(
"Model does not contain any algorithms" );
1423 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1425 QStringList childIssues;
1426 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1428 for (
const QString &issue : std::as_const( childIssues ) )
1430 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1436QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1438 return mChildAlgorithms;
1441void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1443 mParameterComponents = parameterComponents;
1446void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1448 mParameterComponents.insert( component.parameterName(), component );
1451QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1453 if ( !mParameterComponents.contains( name ) )
1455 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1456 component.setParameterName( name );
1459 return mParameterComponents[ name ];
1462QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1464 QList< QgsProcessingModelParameter > res;
1465 QSet< QString > found;
1466 for (
const QString ¶meter : mParameterOrder )
1468 if ( mParameterComponents.contains( parameter ) )
1470 res << mParameterComponents.value( parameter );
1476 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1478 if ( !found.contains( it.key() ) )
1486void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1488 mParameterOrder = order;
1491QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1493 QList< QgsProcessingModelOutput > res;
1494 QSet< QString > found;
1496 for (
const QString &output : mOutputOrder )
1498 bool foundOutput =
false;
1499 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1501 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1502 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1504 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1506 res << outputIt.value();
1508 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1517 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1519 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1520 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1522 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1524 res << outputIt.value();
1532void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1534 mOutputOrder = order;
1537QString QgsProcessingModelAlgorithm::outputGroup()
const
1539 return mOutputGroup;
1542void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1544 mOutputGroup = group;
1547void QgsProcessingModelAlgorithm::updateDestinationParameters()
1550 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1551 while ( it.hasNext() )
1561 qDeleteAll( mOutputs );
1565 QSet< QString > usedFriendlyNames;
1566 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1568 const QString base = safeName( name,
false );
1569 QString candidate = base;
1571 while ( usedFriendlyNames.contains( candidate ) )
1574 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1576 usedFriendlyNames.insert( candidate );
1580 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1581 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1583 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1584 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1585 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1587 if ( !childIt->isActive() || !childIt->algorithm() )
1595 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1599 if ( outputIt->isMandatory() )
1601 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1603 QString friendlyName = uniqueSafeName( outputIt->description() );
1604 param->setName( friendlyName );
1608 param->setName( outputIt->childId() +
':' + outputIt->name() );
1611 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1612 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1613 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1615 param->setDescription( outputIt->description() );
1616 param->setDefaultValue( outputIt->defaultValue() );
1619 if ( addParameter( param.release() ) && newDestParam )
1626 newDestParam->mOriginalProvider = provider;
1633void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1635 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1638QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1640 return mGroupBoxes.values();
1643void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1645 mGroupBoxes.remove( uuid );
1648QVariant QgsProcessingModelAlgorithm::toVariant()
const
1651 map.insert( QStringLiteral(
"model_name" ), mModelName );
1652 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1653 map.insert( QStringLiteral(
"help" ), mHelpContent );
1654 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1656 QVariantMap childMap;
1657 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1658 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1660 childMap.insert( childIt.key(), childIt.value().toVariant() );
1662 map.insert( QStringLiteral(
"children" ), childMap );
1664 QVariantMap paramMap;
1665 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1666 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1668 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1670 map.insert( QStringLiteral(
"parameters" ), paramMap );
1672 QVariantMap paramDefMap;
1677 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1679 QVariantList groupBoxDefs;
1680 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1682 groupBoxDefs.append( it.value().toVariant() );
1684 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1686 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1688 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1690 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1691 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1692 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1697bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1699 QVariantMap map = model.toMap();
1701 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1702 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1703 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1704 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1706 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1708 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1709 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1711 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1712 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1713 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1715 mChildAlgorithms.clear();
1716 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1717 QVariantMap::const_iterator childIt = childMap.constBegin();
1718 for ( ; childIt != childMap.constEnd(); ++childIt )
1720 QgsProcessingModelChildAlgorithm child;
1724 if ( !child.loadVariant( childIt.value() ) )
1727 mChildAlgorithms.insert( child.childId(), child );
1730 mParameterComponents.clear();
1731 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1732 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1733 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1735 QgsProcessingModelParameter param;
1736 if ( !param.loadVariant( paramIt.value().toMap() ) )
1739 mParameterComponents.insert( param.parameterName(), param );
1742 qDeleteAll( mParameters );
1743 mParameters.clear();
1744 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1746 auto addParam = [
this](
const QVariant & value )
1754 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1758 param->setHelp( mHelpContent.value( param->name() ).toString() );
1761 addParameter( param.release() );
1765 QVariantMap map = value.toMap();
1766 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1767 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1769 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1773 QSet< QString > loadedParams;
1775 for (
const QString &name : std::as_const( mParameterOrder ) )
1777 if ( paramDefMap.contains( name ) )
1779 addParam( paramDefMap.value( name ) );
1780 loadedParams << name;
1784 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1785 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1787 if ( !loadedParams.contains( paramDefIt.key() ) )
1788 addParam( paramDefIt.value() );
1791 mGroupBoxes.clear();
1792 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1793 for (
const QVariant &groupBoxDef : groupBoxList )
1795 QgsProcessingModelGroupBox groupBox;
1796 groupBox.loadVariant( groupBoxDef.toMap() );
1797 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1800 updateDestinationParameters();
1805bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1810 return ( acceptableDataTypes.empty()
1811 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1822void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1824 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1825 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1827 if ( !childIt->algorithm() )
1828 childIt->reattach();
1832bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1834 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1836 doc.appendChild( elem );
1839 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1841 QTextStream stream( &file );
1842 doc.save( stream, 2 );
1849bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1854 if ( file.open( QFile::ReadOnly ) )
1856 if ( !doc.setContent( &file ) )
1867 return loadVariant( props );
1870void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1872 mChildAlgorithms = childAlgorithms;
1873 updateDestinationParameters();
1876void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1879 updateDestinationParameters();
1882QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1884 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1888 updateDestinationParameters();
1892QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1894 return mChildAlgorithms[ childId ];
1897bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1899 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1902 mChildAlgorithms.remove(
id );
1903 updateDestinationParameters();
1907void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1909 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1910 for (
const QString &child : constDependentChildAlgorithms )
1912 childAlgorithm( child ).setActive(
false );
1914 childAlgorithm(
id ).setActive(
false );
1915 updateDestinationParameters();
1918bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1920 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1921 for (
const QString &child : constDependsOnChildAlgorithms )
1923 if ( !childAlgorithm( child ).isActive() )
1926 childAlgorithm(
id ).setActive(
true );
1927 updateDestinationParameters();
1933 if ( addParameter( definition ) )
1934 mParameterComponents.insert( definition->
name(), component );
1939 removeParameter( definition->
name() );
1940 addParameter( definition );
1943void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1945 removeParameter( name );
1946 mParameterComponents.remove( name );
1949void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1954 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1957 expression.prepare( &expressionContext );
1958 QSet<QString> variables = expression.referencedVariables();
1959 if ( variables.contains( oldName ) )
1961 QString newExpression = expressionString;
1962 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1963 return {
true, newExpression };
1965 return {
false, QString() };
1968 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1969 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1971 bool changed =
false;
1972 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1973 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
1974 for ( ; paramIt != childParams.end(); ++paramIt )
1976 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
1977 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
1979 switch ( valueIt->source() )
1983 if ( valueIt->parameterName() == oldName )
1985 valueIt->setParameterName( newName );
1993 bool updatedExpression =
false;
1994 QString newExpression;
1995 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
1996 if ( updatedExpression )
1998 valueIt->setExpression( newExpression );
2006 if ( valueIt->staticValue().userType() == QMetaType::type(
"QgsProperty" ) )
2011 bool updatedExpression =
false;
2012 QString newExpression;
2013 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2014 if ( updatedExpression )
2016 property.setExpressionString( newExpression );
2017 valueIt->setStaticValue( property );
2033 childIt->setParameterSources( childParams );
2037bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2039 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2040 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2043 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2044 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2045 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2047 const auto constValue = paramIt.value();
2048 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2051 && source.parameterName() == name )
2061bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2063 const auto constMParameters = mParameters;
2066 if ( def->
name() == name )
2075QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2077 return mParameterComponents;
2080void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2082 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2083 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2085 if ( depends.contains( childIt->childId() ) )
2089 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2090 bool hasDependency =
false;
2091 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2093 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2095 hasDependency =
true;
2100 if ( hasDependency )
2102 depends.insert( childIt->childId() );
2103 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2108 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2109 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2110 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2112 const auto constValue = paramIt.value();
2113 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2116 && source.outputChildId() == childId )
2118 depends.insert( childIt->childId() );
2119 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2127QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2129 QSet< QString > algs;
2133 algs.insert( childId );
2135 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2138 algs.remove( childId );
2144void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2146 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2149 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2150 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2152 if ( !depends.contains( val.childId ) )
2154 depends.insert( val.childId );
2155 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2160 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2161 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2162 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2164 const auto constValue = paramIt.value();
2165 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2167 switch ( source.source() )
2170 if ( !depends.contains( source.outputChildId() ) )
2172 depends.insert( source.outputChildId() );
2173 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2180 const QSet<QString> vars = exp.referencedVariables();
2185 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2186 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2192 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2196 depends.insert( childVarIt->source.outputChildId() );
2197 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2212QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2214 QSet< QString > algs;
2218 algs.insert( childId );
2220 dependsOnChildAlgorithmsRecursive( childId, algs );
2223 algs.remove( childId );
2228QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2230 QSet< QString > dependent;
2231 if ( !childId.isEmpty() )
2233 dependent.unite( dependentChildAlgorithms( childId ) );
2234 dependent.insert( childId );
2237 QList<QgsProcessingModelChildDependency> res;
2238 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2240 if ( !dependent.contains( it->childId() ) )
2243 bool hasBranches =
false;
2244 if ( it->algorithm() )
2252 QgsProcessingModelChildDependency alg;
2253 alg.childId = it->childId();
2254 alg.conditionalBranch = def->
name();
2262 QgsProcessingModelChildDependency alg;
2263 alg.childId = it->childId();
2271bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2274 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2275 if ( childIt != mChildAlgorithms.constEnd() )
2277 if ( !childIt->algorithm() )
2279 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2288 if ( childIt->parameterSources().contains( def->
name() ) )
2291 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2292 for (
const QgsProcessingModelChildParameterSource &source : sources )
2294 switch ( source.source() )
2300 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2305 if ( !parameterComponents().contains( source.parameterName() ) )
2308 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2313 if ( !childAlgorithms().contains( source.outputChildId() ) )
2316 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2338 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2347 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2352bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2354 reattachAlgorithms();
2355 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2356 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2358 if ( !childIt->algorithm() )
2362 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2370QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2372 if ( mSourceFile.isEmpty() )
2387 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2388 alg->loadVariant( toVariant() );
2389 alg->setProvider( provider() );
2390 alg->setSourceFilePath( sourceFilePath() );
2394QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2396 QString n = name.toLower().trimmed();
2397 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2398 n.replace( rx, QString() );
2399 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2400 n.replace( rx2, QString() );
2402 n = n.replace(
' ',
'_' );
2406QVariantMap QgsProcessingModelAlgorithm::variables()
const
2411void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2413 mVariables = variables;
2416QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2418 return mDesignerParameterValues;
ProcessingSourceType
Processing data source types.
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ MapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
@ VectorAnyGeometry
Any vector layer with geometry.
@ VectorPoint
Vector point layers.
@ VectorPolygon
Vector polygon layers.
@ VectorLine
Vector line layers.
@ Success
Child was successfully executed.
@ Failed
Child encountered an error while executing.
@ Expression
Expression based property.
@ UpperCamelCase
Convert the string to upper camel case. Note that this method does not unaccent characters.
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.
QgsProcessingModelResult modelResult() const
Returns the model results, populated when the context is used to run a model algorithm.
QgsProcessingModelInitialRunConfig * modelInitialRunConfig()
Returns a reference to the model initial run configuration, used to run a model algorithm.
Qgis::ProcessingLogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
void setModelInitialRunConfig(std::unique_ptr< QgsProcessingModelInitialRunConfig > config)
Sets the model initial run configuration, used to run a model algorithm.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString generateTemporaryDestination(const QgsProcessingContext *context=nullptr) const
Generates a temporary destination value for this parameter.
void setSupportsNonFileBasedOutput(bool supportsNonFileBasedOutput)
Sets whether the destination parameter supports non filed-based outputs, such as memory layers or dir...
Custom exception class for processing related exceptions.
Encapsulates settings relating to a feature source input to a processing algorithm.
QgsProperty source
Source definition.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
Encapsulates the results of running a child algorithm within a model.
void setOutputs(const QVariantMap &outputs)
Sets the outputs generated by child algorithm.
void setExecutionStatus(Qgis::ProcessingModelChildAlgorithmExecutionStatus status)
Sets the status of executing the child algorithm.
void setInputs(const QVariantMap &inputs)
Sets the inputs used for the child algorithm.
void setHtmlLog(const QString &log)
Sets the HTML formatted contents of logged messages which occurred while running the child.
Configuration settings which control how a Processing model is executed.
QSet< QString > childAlgorithmSubset() const
Returns the subset of child algorithms to run (by child ID).
QVariantMap & rawChildOutputs()
Returns a reference to the map of raw child algorithm outputs.
QVariantMap & rawChildInputs()
Returns a reference to the map of raw child algorithm inputs.
QSet< QString > & executedChildIds()
Returns a reference to the set of child algorithm IDs which were executed during the model execution.
Processing feedback object for multi-step operations.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
Base class for the definition of processing outputs.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
QgsProperty sink
Sink/layer definition.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
A vector layer output for processing algorithms.
Qgis::ProcessingSourceType dataType() const
Returns the layer type for the output layer.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
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.