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 & )
53 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
54 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
65QString QgsProcessingModelAlgorithm::name()
const
70QString QgsProcessingModelAlgorithm::displayName()
const
75QString QgsProcessingModelAlgorithm::group()
const
80QString QgsProcessingModelAlgorithm::groupId()
const
85QIcon QgsProcessingModelAlgorithm::icon()
const
90QString QgsProcessingModelAlgorithm::svgIconPath()
const
95QString QgsProcessingModelAlgorithm::shortHelpString()
const
97 if ( mHelpContent.empty() )
103QString QgsProcessingModelAlgorithm::shortDescription()
const
105 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
108QString QgsProcessingModelAlgorithm::helpUrl()
const
110 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
113QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
118 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
120 QString expressionText;
121 QVariantList paramParts;
122 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
124 switch ( source.source() )
127 paramParts << source.staticValue();
131 paramParts << modelParameters.value( source.parameterName() );
136 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
137 paramParts << linkedChildResults.value( source.outputName() );
144 paramParts << exp.evaluate( &expressionContext );
145 if ( exp.hasEvalError() )
147 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
162 if ( ! expressionText.isEmpty() )
164 return expressionText;
166 else if ( paramParts.count() == 1 )
167 return paramParts.at( 0 );
173 QVariantMap childParams;
174 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
177 if ( !def->isDestination() )
179 if ( !child.parameterSources().contains( def->name() ) )
182 const QVariant value = evaluateSources( def );
183 childParams.insert( def->name(), value );
190 bool isFinalOutput =
false;
191 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
192 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
193 for ( ; outputIt != outputs.constEnd(); ++outputIt )
195 if ( outputIt->childOutputName() == destParam->
name() )
197 QString paramName = child.childId() +
':' + outputIt.key();
198 bool foundParam =
false;
202 if ( modelParameters.contains( paramName ) )
204 value = modelParameters.value( paramName );
213 if ( modelParameters.contains( modelParam->name() ) )
215 value = modelParameters.value( modelParam->name() );
223 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
228 value = QVariant::fromValue( fromVar );
231 childParams.insert( destParam->
name(), value );
233 isFinalOutput =
true;
238 bool hasExplicitDefinition =
false;
239 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
242 const QVariant value = evaluateSources( def );
243 if ( value.isValid() )
245 childParams.insert( def->name(), value );
246 hasExplicitDefinition =
true;
250 if ( !isFinalOutput && !hasExplicitDefinition )
255 bool required =
true;
258 required = childOutputIsRequired( child.childId(), destParam->
name() );
270const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
274 if ( !definition->isDestination() )
277 const QString modelChildId = definition->
metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
278 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
280 if ( modelChildId == childId && modelOutputName == childOutputName )
286bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
289 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
290 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
292 if ( childIt->childId() == childId || !childIt->isActive() )
296 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
297 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
298 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
300 const auto constValue = childParamIt.value();
301 for (
const QgsProcessingModelChildParameterSource &source : constValue )
304 && source.outputChildId() == childId
305 && source.outputName() == outputName )
317 QSet< QString > toExecute;
318 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
319 QSet< QString > broken;
321 const bool useSubsetOfChildren = !childSubset.empty();
322 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
324 if ( childIt->isActive() && ( !useSubsetOfChildren || childSubset.contains( childIt->childId() ) ) )
326 if ( childIt->algorithm() )
327 toExecute.insert( childIt->childId() );
329 broken.insert( childIt->childId() );
333 if ( !broken.empty() )
334 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
336 QElapsedTimer totalTime;
350 childInputs = config->initialChildInputs();
351 childResults = config->initialChildOutputs();
352 executed = config->previouslyExecutedChildAlgorithms();
356 if ( useSubsetOfChildren )
358 executed.subtract( childSubset );
361 QVariantMap finalResults;
363 bool executedAlg =
true;
364 int previousHtmlLogLength = feedback->
htmlLog().length();
365 int countExecuted = 0;
366 while ( executedAlg && countExecuted < toExecute.count() )
369 for (
const QString &childId : std::as_const( toExecute ) )
374 if ( executed.contains( childId ) )
377 bool canExecute =
true;
378 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
379 for (
const QString &dependency : dependencies )
381 if ( !executed.contains( dependency ) )
393 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
394 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
396 bool skipGenericLogging =
true;
401 skipGenericLogging =
true;
411 skipGenericLogging =
false;
415 if ( feedback && !skipGenericLogging )
416 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
420 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
424 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
425 if ( !error.isEmpty() )
428 if ( feedback && !skipGenericLogging )
429 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
434 childInputs.insert( childId, thisChildParams );
435 childResult.
setInputs( thisChildParams );
438 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
440 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
441 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
444 if ( feedback && !skipGenericLogging )
446 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
447 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
450 QElapsedTimer childTime;
455 QThread *modelThread = QThread::currentThread();
457 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
459 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
460 ok = childAlg->prepare( childParams, context, &modelFeedback );
461 context.pushToThread( modelThread );
465 if ( modelThread == qApp->thread() )
466 ok = childAlg->prepare( childParams, context, &modelFeedback );
469 context.pushToThread( qApp->thread() );
471#ifndef __clang_analyzer__
472 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
476 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
486 bool runResult =
false;
492 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
494 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
495 results = childAlg->runPrepared( childParams, context, &modelFeedback );
496 context.pushToThread( modelThread );
499 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
500 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
502 context.pushToThread( qApp->thread() );
504#ifndef __clang_analyzer__
505 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
511 results = childAlg->runPrepared( childParams, context, &modelFeedback );
522 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
525 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback, runResult]
527 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
528 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
529 context.pushToThread( modelThread );
533 if ( modelThread == qApp->thread() )
534 ppRes = childAlg->postProcess( context, &modelFeedback, runResult );
537 context.pushToThread( qApp->thread() );
539#ifndef __clang_analyzer__
540 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
544 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
546 if ( !ppRes.isEmpty() )
549 childResults.insert( childId, results );
554 if ( feedback && !skipGenericLogging )
557 QStringList formattedOutputs;
558 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
560 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
563 feedback->
pushInfo( QObject::tr(
"Results:" ) );
564 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
569 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
570 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
572 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
573 switch ( mInternalVersion )
575 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
576 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
578 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
581 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
586 const QString outputLayer = results.value( outputIt->childOutputName() ).toString();
587 if ( !outputLayer.isEmpty() && context.willLoadLayerOnCompletion( outputLayer ) )
591 if ( outputSortKey > 0 )
596 executed.insert( childId );
598 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
599 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
601 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
602 for (
const QString &targetId : toPrune )
604 if ( executed.contains( targetId ) )
607 executed.insert( targetId );
608 pruneAlgorithmBranchRecursive( targetId, branch );
618 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
626 for (
const QString &candidateId : std::as_const( toExecute ) )
628 if ( executed.contains( candidateId ) )
633 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
634 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
635 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
637 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
639 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
644 if ( !results.contains( source.outputName() ) )
649 executed.insert( candidateId );
651 pruneAlgorithmBranchRecursive( candidateId, QString() );
662 childAlg.reset(
nullptr );
664 modelFeedback.setCurrentStep( countExecuted );
665 if ( feedback && !skipGenericLogging )
667 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
672 const QString thisAlgorithmHtmlLog = feedback->
htmlLog().mid( previousHtmlLogLength );
673 previousHtmlLogLength = feedback->
htmlLog().length();
677 const QString formattedException = QStringLiteral(
"<span style=\"color:red\">%1</span><br/>" ).arg( error.toHtmlEscaped() ).replace(
'\n', QLatin1String(
"<br>" ) );
678 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>" ) );
680 childResult.
setHtmlLog( thisAlgorithmHtmlLog + formattedException + formattedRunTime );
681 context.modelResult().childResults().insert( childId, childResult );
687 childResult.
setHtmlLog( thisAlgorithmHtmlLog );
688 context.modelResult().childResults().insert( childId, childResult );
696 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 ) );
698 mResults = finalResults;
699 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
700 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
704QString QgsProcessingModelAlgorithm::sourceFilePath()
const
709void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
711 mSourceFile = sourceFile;
714bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
716 if ( mSourceFile.isEmpty() )
719 const QFileInfo fi( mSourceFile );
720 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
725 QStringList fileDocString;
726 fileDocString << QStringLiteral(
"\"\"\"" );
727 fileDocString << QStringLiteral(
"Model exported as python." );
728 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
729 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
730 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
731 fileDocString << QStringLiteral(
"\"\"\"" );
732 fileDocString << QString();
735 QString indent = QString(
' ' ).repeated( indentSize );
736 QString currentIndent;
738 QMap< QString, QString> friendlyChildNames;
739 QMap< QString, QString> friendlyOutputNames;
740 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
742 const QString base = safeName( name, capitalize );
743 QString candidate = base;
745 while ( friendlyNames.contains( candidate ) )
748 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
753 const QString algorithmClassName = safeName( name(),
true );
755 QSet< QString > toExecute;
756 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
758 if ( childIt->isActive() && childIt->algorithm() )
760 toExecute.insert( childIt->childId() );
761 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
764 const int totalSteps = toExecute.count();
766 QStringList importLines;
767 switch ( outputType )
772 const auto params = parameterDefinitions();
773 importLines.reserve( params.count() + 3 );
774 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
775 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
776 importLines << QStringLiteral(
"from qgis.core import QgsProcessingMultiStepFeedback" );
778 bool hasAdvancedParams =
false;
782 hasAdvancedParams =
true;
785 if ( !importString.isEmpty() && !importLines.contains( importString ) )
786 importLines << importString;
789 if ( hasAdvancedParams )
790 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
792 lines << QStringLiteral(
"import processing" );
793 lines << QString() << QString();
795 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
799 lines << indent + QStringLiteral(
"def initAlgorithm(self, config=None):" );
800 if ( params.empty() )
802 lines << indent + indent + QStringLiteral(
"pass" );
806 lines.reserve( lines.size() + params.size() );
809 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
811 if ( defClone->isDestination() )
813 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
814 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
815 friendlyOutputNames.insert( uniqueChildName, friendlyName );
816 defClone->setName( friendlyName );
820 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
822 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
823 for (
const QString &part : parts )
825 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
832 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
833 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
834 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
838 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
844 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters, context, model_feedback):" );
845 currentIndent = indent + indent;
847 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
848 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
849 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
857 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
858 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
860 QString name = paramIt.value().parameterName();
861 if ( parameterDefinition( name ) )
864 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
868 if ( !params.isEmpty() )
870 lines << QStringLiteral(
"parameters = {" );
871 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
873 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
875 lines << QStringLiteral(
"}" )
879 lines << QStringLiteral(
"context = QgsProcessingContext()" )
880 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
881 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
890 lines << currentIndent + QStringLiteral(
"results = {}" );
891 lines << currentIndent + QStringLiteral(
"outputs = {}" );
894 QSet< QString > executed;
895 bool executedAlg =
true;
897 while ( executedAlg && executed.count() < toExecute.count() )
900 const auto constToExecute = toExecute;
901 for (
const QString &childId : constToExecute )
903 if ( executed.contains( childId ) )
906 bool canExecute =
true;
907 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
908 for (
const QString &dependency : constDependsOnChildAlgorithms )
910 if ( !executed.contains( dependency ) )
922 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
929 if ( def->isDestination() )
934 bool isFinalOutput =
false;
935 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
936 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
937 for ( ; outputIt != outputs.constEnd(); ++outputIt )
939 if ( outputIt->childOutputName() == destParam->
name() )
941 QString paramName = child.childId() +
':' + outputIt.key();
942 paramName = friendlyOutputNames.value( paramName, paramName );
943 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
944 isFinalOutput =
true;
949 if ( !isFinalOutput )
954 bool required =
true;
957 required = childOutputIsRequired( child.childId(), destParam->
name() );
963 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
969 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
971 if ( currentStep < totalSteps )
974 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
975 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
976 lines << currentIndent + indent + QStringLiteral(
"return {}" );
979 executed.insert( childId );
983 switch ( outputType )
986 lines << currentIndent + QStringLiteral(
"return results" );
990 lines << indent + QStringLiteral(
"def name(self):" );
991 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
993 lines << indent + QStringLiteral(
"def displayName(self):" );
994 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
998 lines << indent + QStringLiteral(
"def group(self):" );
999 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
1001 lines << indent + QStringLiteral(
"def groupId(self):" );
1002 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
1006 if ( !shortHelpString().isEmpty() )
1008 lines << indent + QStringLiteral(
"def shortHelpString(self):" );
1009 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
1012 if ( !helpUrl().isEmpty() )
1014 lines << indent + QStringLiteral(
"def helpUrl(self):" );
1015 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
1020 lines << indent + QStringLiteral(
"def createInstance(self):" );
1021 lines << indent + indent + QStringLiteral(
"return %1()" ).arg( algorithmClassName );
1024 static QMap< QString, QString > sAdditionalImports
1026 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
1027 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
1028 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
1029 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
1030 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
1031 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
1032 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
1033 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
1034 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
1035 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
1036 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
1037 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
1038 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
1039 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
1040 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
1041 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
1042 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
1043 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
1044 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
1045 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
1048 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
1050 if ( importLines.contains( it.value() ) )
1057 for (
const QString &line : std::as_const( lines ) )
1059 if ( line.contains( it.key() ) )
1067 importLines << it.value();
1071 lines = fileDocString + importLines + lines;
1080QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1082 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1084 auto safeName = [](
const QString & name )->QString
1087 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1088 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1125 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1129 QString description;
1130 switch ( source.source() )
1134 name = source.parameterName();
1135 value = modelParameters.value( source.parameterName() );
1136 description = parameterDefinition( source.parameterName() )->description();
1141 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1142 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1143 source.outputChildId() : child.description(), source.outputName() );
1146 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1147 child.description() );
1149 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1159 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1163 sources = availableSourcesForChild( childId, QStringList()
1170 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1174 QString description;
1176 switch ( source.source() )
1180 name = source.parameterName();
1181 value = modelParameters.value( source.parameterName() );
1182 description = parameterDefinition( source.parameterName() )->description();
1187 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1188 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1189 source.outputChildId() : child.description(), source.outputName() );
1190 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1193 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1194 child.description() );
1207 if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1210 value = fromVar.
sink;
1211 if ( value.userType() == qMetaTypeId<QgsProperty>() && context )
1219 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1224 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1225 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1226 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1227 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1228 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1231 sources = availableSourcesForChild( childId, QStringList()
1233 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1237 QString description;
1239 switch ( source.source() )
1243 name = source.parameterName();
1244 value = modelParameters.value( source.parameterName() );
1245 description = parameterDefinition( source.parameterName() )->description();
1250 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1251 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1252 source.outputChildId() : child.description(), source.outputName() );
1253 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1256 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1257 child.description() );
1271 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
1276 else if ( value.userType() == qMetaTypeId<QgsProcessingOutputLayerDefinition>() )
1279 value = fromVar.
sink;
1280 if ( context && value.userType() == qMetaTypeId<QgsProperty>() )
1285 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1287 featureSource = layer;
1289 if ( context && !featureSource )
1295 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1296 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1297 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1298 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1299 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1305QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1307 std::unique_ptr< QgsExpressionContextScope > scope(
new QgsExpressionContextScope( QStringLiteral(
"algorithm_inputs" ) ) );
1308 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1309 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1310 for ( ; varIt != variables.constEnd(); ++varIt )
1314 return scope.release();
1317QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1319 QgsProcessingModelChildParameterSources sources;
1322 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1323 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1329 if ( parameterTypes.contains( def->
type() ) )
1331 if ( !dataTypes.isEmpty() )
1347 bool ok = sourceDef->
dataTypes().isEmpty();
1348 const auto constDataTypes = sourceDef->
dataTypes();
1349 for (
int type : constDataTypes )
1364 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1368 QSet< QString > dependents;
1369 if ( !childId.isEmpty() )
1371 dependents = dependentChildAlgorithms( childId );
1372 dependents << childId;
1375 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1376 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1378 if ( dependents.contains( childIt->childId() ) )
1388 if ( outputTypes.contains( out->type() ) )
1390 if ( !dataTypes.isEmpty() )
1396 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1403 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1411QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1413 return mHelpContent;
1416void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1418 mHelpContent = helpContent;
1421void QgsProcessingModelAlgorithm::setName(
const QString &name )
1426void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1428 mModelGroup = group;
1431bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1436 if ( mChildAlgorithms.empty() )
1439 issues << QObject::tr(
"Model does not contain any algorithms" );
1442 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1444 QStringList childIssues;
1445 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1447 for (
const QString &issue : std::as_const( childIssues ) )
1449 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1455QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1457 return mChildAlgorithms;
1460void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1462 mParameterComponents = parameterComponents;
1465void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1467 mParameterComponents.insert( component.parameterName(), component );
1470QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1472 if ( !mParameterComponents.contains( name ) )
1474 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1475 component.setParameterName( name );
1478 return mParameterComponents[ name ];
1481QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1483 QList< QgsProcessingModelParameter > res;
1484 QSet< QString > found;
1485 for (
const QString ¶meter : mParameterOrder )
1487 if ( mParameterComponents.contains( parameter ) )
1489 res << mParameterComponents.value( parameter );
1495 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1497 if ( !found.contains( it.key() ) )
1505void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1507 mParameterOrder = order;
1510QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1512 QList< QgsProcessingModelOutput > res;
1513 QSet< QString > found;
1515 for (
const QString &output : mOutputOrder )
1517 bool foundOutput =
false;
1518 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1520 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1521 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1523 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1525 res << outputIt.value();
1527 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1536 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1538 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1539 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1541 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1543 res << outputIt.value();
1551void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1553 mOutputOrder = order;
1556QString QgsProcessingModelAlgorithm::outputGroup()
const
1558 return mOutputGroup;
1561void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1563 mOutputGroup = group;
1566void QgsProcessingModelAlgorithm::updateDestinationParameters()
1569 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1570 while ( it.hasNext() )
1580 qDeleteAll( mOutputs );
1584 QSet< QString > usedFriendlyNames;
1585 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1587 const QString base = safeName( name,
false );
1588 QString candidate = base;
1590 while ( usedFriendlyNames.contains( candidate ) )
1593 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1595 usedFriendlyNames.insert( candidate );
1599 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1600 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1602 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1603 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1604 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1606 if ( !childIt->isActive() || !childIt->algorithm() )
1614 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1618 if ( outputIt->isMandatory() )
1620 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1622 QString friendlyName = uniqueSafeName( outputIt->description() );
1623 param->setName( friendlyName );
1627 param->setName( outputIt->childId() +
':' + outputIt->name() );
1630 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1631 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1632 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1634 param->setDescription( outputIt->description() );
1635 param->setDefaultValue( outputIt->defaultValue() );
1638 if ( addParameter( param.release() ) && newDestParam )
1645 newDestParam->mOriginalProvider = provider;
1652void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1654 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1657QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1659 return mGroupBoxes.values();
1662void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1664 mGroupBoxes.remove( uuid );
1667QVariant QgsProcessingModelAlgorithm::toVariant()
const
1670 map.insert( QStringLiteral(
"model_name" ), mModelName );
1671 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1672 map.insert( QStringLiteral(
"help" ), mHelpContent );
1673 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1675 QVariantMap childMap;
1676 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1677 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1679 childMap.insert( childIt.key(), childIt.value().toVariant() );
1681 map.insert( QStringLiteral(
"children" ), childMap );
1683 QVariantMap paramMap;
1684 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1685 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1687 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1689 map.insert( QStringLiteral(
"parameters" ), paramMap );
1691 QVariantMap paramDefMap;
1696 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1698 QVariantList groupBoxDefs;
1699 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1701 groupBoxDefs.append( it.value().toVariant() );
1703 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1705 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1707 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1709 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1710 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1711 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1716bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1718 QVariantMap map = model.toMap();
1720 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1721 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1722 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1723 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1725 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1727 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1728 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1730 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1731 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1732 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1734 mChildAlgorithms.clear();
1735 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1736 QVariantMap::const_iterator childIt = childMap.constBegin();
1737 for ( ; childIt != childMap.constEnd(); ++childIt )
1739 QgsProcessingModelChildAlgorithm child;
1743 if ( !child.loadVariant( childIt.value() ) )
1746 mChildAlgorithms.insert( child.childId(), child );
1749 mParameterComponents.clear();
1750 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1751 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1752 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1754 QgsProcessingModelParameter param;
1755 if ( !param.loadVariant( paramIt.value().toMap() ) )
1758 mParameterComponents.insert( param.parameterName(), param );
1761 qDeleteAll( mParameters );
1762 mParameters.clear();
1763 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1765 auto addParam = [
this](
const QVariant & value )
1773 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1777 param->setHelp( mHelpContent.value( param->name() ).toString() );
1780 addParameter( param.release() );
1784 QVariantMap map = value.toMap();
1785 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1786 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1788 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1792 QSet< QString > loadedParams;
1794 for (
const QString &name : std::as_const( mParameterOrder ) )
1796 if ( paramDefMap.contains( name ) )
1798 addParam( paramDefMap.value( name ) );
1799 loadedParams << name;
1803 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1804 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1806 if ( !loadedParams.contains( paramDefIt.key() ) )
1807 addParam( paramDefIt.value() );
1810 mGroupBoxes.clear();
1811 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1812 for (
const QVariant &groupBoxDef : groupBoxList )
1814 QgsProcessingModelGroupBox groupBox;
1815 groupBox.loadVariant( groupBoxDef.toMap() );
1816 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1819 updateDestinationParameters();
1824bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
Qgis::ProcessingSourceType outputType )
1829 return ( acceptableDataTypes.empty()
1830 || acceptableDataTypes.contains(
static_cast< int >( outputType ) )
1841void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1843 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1844 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1846 if ( !childIt->algorithm() )
1847 childIt->reattach();
1851bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1853 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1855 doc.appendChild( elem );
1858 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1860 QTextStream stream( &file );
1861 doc.save( stream, 2 );
1868bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1873 if ( file.open( QFile::ReadOnly ) )
1875 if ( !doc.setContent( &file ) )
1886 return loadVariant( props );
1889void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1891 mChildAlgorithms = childAlgorithms;
1892 updateDestinationParameters();
1895void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1898 updateDestinationParameters();
1901QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1903 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1907 updateDestinationParameters();
1911QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1913 return mChildAlgorithms[ childId ];
1916bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1918 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1921 mChildAlgorithms.remove(
id );
1922 updateDestinationParameters();
1926void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1928 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1929 for (
const QString &child : constDependentChildAlgorithms )
1931 childAlgorithm( child ).setActive(
false );
1933 childAlgorithm(
id ).setActive(
false );
1934 updateDestinationParameters();
1937bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1939 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1940 for (
const QString &child : constDependsOnChildAlgorithms )
1942 if ( !childAlgorithm( child ).isActive() )
1945 childAlgorithm(
id ).setActive(
true );
1946 updateDestinationParameters();
1952 if ( addParameter( definition ) )
1953 mParameterComponents.insert( definition->
name(), component );
1958 removeParameter( definition->
name() );
1959 addParameter( definition );
1962void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1964 removeParameter( name );
1965 mParameterComponents.remove( name );
1968void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1973 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1976 expression.prepare( &expressionContext );
1977 QSet<QString> variables = expression.referencedVariables();
1978 if ( variables.contains( oldName ) )
1980 QString newExpression = expressionString;
1981 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1982 return {
true, newExpression };
1984 return {
false, QString() };
1987 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1988 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1990 bool changed =
false;
1991 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1992 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
1993 for ( ; paramIt != childParams.end(); ++paramIt )
1995 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
1996 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
1998 switch ( valueIt->source() )
2002 if ( valueIt->parameterName() == oldName )
2004 valueIt->setParameterName( newName );
2012 bool updatedExpression =
false;
2013 QString newExpression;
2014 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
2015 if ( updatedExpression )
2017 valueIt->setExpression( newExpression );
2025 if ( valueIt->staticValue().userType() == qMetaTypeId<QgsProperty>() )
2030 bool updatedExpression =
false;
2031 QString newExpression;
2032 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
2033 if ( updatedExpression )
2035 property.setExpressionString( newExpression );
2036 valueIt->setStaticValue( property );
2052 childIt->setParameterSources( childParams );
2056bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
2058 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2059 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2062 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2063 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2064 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2066 const auto constValue = paramIt.value();
2067 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2070 && source.parameterName() == name )
2080bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
2082 const auto constMParameters = mParameters;
2085 if ( def->
name() == name )
2094QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2096 return mParameterComponents;
2099void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2101 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2102 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2104 if ( depends.contains( childIt->childId() ) )
2108 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2109 bool hasDependency =
false;
2110 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2112 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2114 hasDependency =
true;
2119 if ( hasDependency )
2121 depends.insert( childIt->childId() );
2122 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2127 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2128 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2129 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2131 const auto constValue = paramIt.value();
2132 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2135 && source.outputChildId() == childId )
2137 depends.insert( childIt->childId() );
2138 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2146QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2148 QSet< QString > algs;
2152 algs.insert( childId );
2154 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2157 algs.remove( childId );
2163void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2165 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2168 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2169 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2171 if ( !depends.contains( val.childId ) )
2173 depends.insert( val.childId );
2174 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2179 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2180 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2181 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2183 const auto constValue = paramIt.value();
2184 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2186 switch ( source.source() )
2189 if ( !depends.contains( source.outputChildId() ) )
2191 depends.insert( source.outputChildId() );
2192 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2199 const QSet<QString> vars = exp.referencedVariables();
2204 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2205 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2211 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2215 depends.insert( childVarIt->source.outputChildId() );
2216 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2231QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2233 QSet< QString > algs;
2237 algs.insert( childId );
2239 dependsOnChildAlgorithmsRecursive( childId, algs );
2242 algs.remove( childId );
2247QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2249 QSet< QString > dependent;
2250 if ( !childId.isEmpty() )
2252 dependent.unite( dependentChildAlgorithms( childId ) );
2253 dependent.insert( childId );
2256 QList<QgsProcessingModelChildDependency> res;
2257 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2259 if ( !dependent.contains( it->childId() ) )
2262 bool hasBranches =
false;
2263 if ( it->algorithm() )
2271 QgsProcessingModelChildDependency alg;
2272 alg.childId = it->childId();
2273 alg.conditionalBranch = def->
name();
2281 QgsProcessingModelChildDependency alg;
2282 alg.childId = it->childId();
2290bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2293 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2294 if ( childIt != mChildAlgorithms.constEnd() )
2296 if ( !childIt->algorithm() )
2298 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2307 if ( childIt->parameterSources().contains( def->
name() ) )
2310 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2311 for (
const QgsProcessingModelChildParameterSource &source : sources )
2313 switch ( source.source() )
2319 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2324 if ( !parameterComponents().contains( source.parameterName() ) )
2327 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2332 if ( !childAlgorithms().contains( source.outputChildId() ) )
2335 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2357 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2366 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2371bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2373 reattachAlgorithms();
2374 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2375 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2377 if ( !childIt->algorithm() )
2381 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2389QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2391 if ( mSourceFile.isEmpty() )
2406 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2407 alg->loadVariant( toVariant() );
2408 alg->setProvider( provider() );
2409 alg->setSourceFilePath( sourceFilePath() );
2413QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2415 QString n = name.toLower().trimmed();
2416 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2417 n.replace( rx, QString() );
2418 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2419 n.replace( rx2, QString() );
2421 n = n.replace(
' ',
'_' );
2425QVariantMap QgsProcessingModelAlgorithm::variables()
const
2430void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2432 mVariables = variables;
2435QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2437 return mDesignerParameterValues;
ProcessingSourceType
Processing data source types.
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ MapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
@ VectorAnyGeometry
Any vector layer with geometry.
@ VectorPoint
Vector point layers.
@ VectorPolygon
Vector polygon layers.
@ VectorLine
Vector line layers.
@ Success
Child was successfully executed.
@ Failed
Child encountered an error while executing.
@ Expression
Expression based property.
@ UpperCamelCase
Convert the string to upper camel case. Note that this method does not unaccent characters.
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
@ ExpressionText
Parameter value is taken from a text with expressions, evaluated just before the algorithm runs.
@ ModelOutput
Parameter value is linked to an output parameter for the model.
@ ChildOutput
Parameter value is taken from an output generated by a child algorithm.
@ ModelParameter
Parameter value is taken from a parent model parameter.
@ StaticValue
Parameter value is a static value.
@ Expression
Parameter value is taken from an expression, evaluated just before the algorithm runs.
@ SkipGenericModelLogging
When running as part of a model, the generic algorithm setup and results logging should be skipped.
@ CustomException
Algorithm raises custom exception notices, don't use the standard ones.
@ NoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
@ SecurityRisk
The algorithm represents a potential security risk if executed with untrusted inputs.
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Optional
Parameter is optional.
@ DefaultLevel
Default logging level.
@ Verbose
Verbose logging.
@ ModelDebug
Model debug level logging. Includes verbose logging and other outputs useful for debugging models.
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * processingModelAlgorithmScope(const QgsProcessingModelAlgorithm *model, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing model algorithm,...
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm,...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
An interface for objects which provide features via a getFeatures method.
virtual QgsRectangle sourceExtent() const
Returns the extent of all geometries from the source.
bool isCanceled() const
Tells whether the operation has been canceled already.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Abstract base class for processing algorithms.
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
virtual Qgis::ProcessingAlgorithmFlags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
virtual QgsExpressionContext createExpressionContext(const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeatureSource *source=nullptr) const
Creates an expression context relating to the algorithm.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &name) const
Returns a matching parameter by name.
virtual QString asPythonCommand(const QVariantMap ¶meters, QgsProcessingContext &context) const
Returns a Python command string which can be executed to run the algorithm using the specified parame...
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
Details for layers to load into projects.
int layerSortKey
Optional sorting key for sorting output layers when loading them into a project.
QString groupName
Optional name for a layer tree group under which to place the layer when loading it into a project.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QgsProcessingModelResult modelResult() const
Returns the model results, populated when the context is used to run a model algorithm.
QgsProcessingModelInitialRunConfig * modelInitialRunConfig()
Returns a reference to the model initial run configuration, used to run a model algorithm.
Qgis::ProcessingLogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
void setModelInitialRunConfig(std::unique_ptr< QgsProcessingModelInitialRunConfig > config)
Sets the model initial run configuration, used to run a model algorithm.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString generateTemporaryDestination(const QgsProcessingContext *context=nullptr) const
Generates a temporary destination value for this parameter.
void setSupportsNonFileBasedOutput(bool supportsNonFileBasedOutput)
Sets whether the destination parameter supports non filed-based outputs, such as memory layers or dir...
Custom exception class for processing related exceptions.
Encapsulates settings relating to a feature source input to a processing algorithm.
QgsProperty source
Source definition.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
Encapsulates the results of running a child algorithm within a model.
void setOutputs(const QVariantMap &outputs)
Sets the outputs generated by child algorithm.
void setExecutionStatus(Qgis::ProcessingModelChildAlgorithmExecutionStatus status)
Sets the status of executing the child algorithm.
void setInputs(const QVariantMap &inputs)
Sets the inputs used for the child algorithm.
void setHtmlLog(const QString &log)
Sets the HTML formatted contents of logged messages which occurred while running the child.
Configuration settings which control how a Processing model is executed.
QSet< QString > childAlgorithmSubset() const
Returns the subset of child algorithms to run (by child ID).
QVariantMap & rawChildOutputs()
Returns a reference to the map of raw child algorithm outputs.
QVariantMap & rawChildInputs()
Returns a reference to the map of raw child algorithm inputs.
QSet< QString > & executedChildIds()
Returns a reference to the set of child algorithm IDs which were executed during the model execution.
Processing feedback object for multi-step operations.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
Base class for the definition of processing outputs.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
QgsProperty sink
Sink/layer definition.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
A vector layer output for processing algorithms.
Qgis::ProcessingSourceType dataType() const
Returns the layer type for the output layer.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Base class for the definition of processing parameters.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
QVariantMap metadata() const
Returns the parameter's freeform metadata.
virtual bool isDestination() const
Returns true if this parameter represents a file or layer destination, e.g.
virtual QgsProcessingParameterDefinition * clone() const =0
Creates a clone of the parameter definition.
virtual QString type() const =0
Unique parameter type name.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QString name() const
Returns the name of the parameter.
virtual QStringList dependsOnOtherParameters() const
Returns a list of other parameter names on which this parameter is dependent (e.g.
Qgis::ProcessingParameterFlags flags() const
Returns any flags associated with the parameter.
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
A vector layer or feature source field parameter for processing algorithms.
Qgis::ProcessingFieldParameterDataType dataType() const
Returns the acceptable data type for the field.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Can be inherited by parameters which require limits to their acceptable data types.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
virtual QString pythonImportString() const
Returns a valid Python import string for importing the corresponding parameter type,...
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map.
Abstract base class for processing providers.
const QgsProcessingAlgorithm * algorithm(const QString &name) const
Returns the matching algorithm by name, or nullptr if no matching algorithm is contained by this prov...
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
static QString formatHelpMapAsHtml(const QVariantMap &map, const QgsProcessingAlgorithm *algorithm)
Returns a HTML formatted version of the help text encoded in a variant map for a specified algorithm.
@ Vector
Vector layer type.
static QString variantToPythonLiteral(const QVariant &value)
Converts a variant to a Python literal.
static QVariantMap removePointerValuesFromMap(const QVariantMap &map)
Removes any raw pointer values from an input map, replacing them with appropriate string values where...
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers=true, QgsProcessingUtils::LayerHint typeHint=QgsProcessingUtils::LayerHint::UnknownType, QgsProcessing::LayerOptionsFlags flags=QgsProcessing::LayerOptionsFlags())
Interprets a string as a map layer within the supplied context.
PythonOutputType
Available Python output types.
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
A store for object properties.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
QVariant staticValue() const
Returns the current static value for the property.
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.