34#include <QRegularExpression>
37QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm(
const QString &name,
const QString &group,
const QString &groupId )
38 : mModelName( name.isEmpty() ? QObject::tr(
"model" ) : name )
39 , mModelGroup( group )
40 , mModelGroupId( groupId )
43void QgsProcessingModelAlgorithm::initAlgorithm(
const QVariantMap & )
47QString QgsProcessingModelAlgorithm::name()
const
52QString QgsProcessingModelAlgorithm::displayName()
const
57QString QgsProcessingModelAlgorithm::group()
const
62QString QgsProcessingModelAlgorithm::groupId()
const
67QIcon QgsProcessingModelAlgorithm::icon()
const
72QString QgsProcessingModelAlgorithm::svgIconPath()
const
77QString QgsProcessingModelAlgorithm::shortHelpString()
const
79 if ( mHelpContent.empty() )
85QString QgsProcessingModelAlgorithm::shortDescription()
const
87 return mHelpContent.value( QStringLiteral(
"SHORT_DESCRIPTION" ) ).toString();
90QString QgsProcessingModelAlgorithm::helpUrl()
const
92 return mHelpContent.value( QStringLiteral(
"HELP_URL" ) ).toString();
95QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm(
const QgsProcessingModelChildAlgorithm &child,
const QVariantMap &modelParameters,
const QVariantMap &results,
const QgsExpressionContext &expressionContext, QString &error,
const QgsProcessingContext *context )
const
100 const QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
102 QString expressionText;
103 QVariantList paramParts;
104 for (
const QgsProcessingModelChildParameterSource &source : paramSources )
106 switch ( source.source() )
109 paramParts << source.staticValue();
113 paramParts << modelParameters.value( source.parameterName() );
118 QVariantMap linkedChildResults = results.value( source.outputChildId() ).toMap();
119 paramParts << linkedChildResults.value( source.outputName() );
126 paramParts << exp.evaluate( &expressionContext );
127 if ( exp.hasEvalError() )
129 error = QObject::tr(
"Could not evaluate expression for parameter %1 for %2: %3" ).arg( def->name(), child.description(), exp.evalErrorString() );
144 if ( ! expressionText.isEmpty() )
146 return expressionText;
148 else if ( paramParts.count() == 1 )
149 return paramParts.at( 0 );
155 QVariantMap childParams;
156 const QList< const QgsProcessingParameterDefinition * > childParameterDefinitions = child.algorithm()->parameterDefinitions();
159 if ( !def->isDestination() )
161 if ( !child.parameterSources().contains( def->name() ) )
164 const QVariant value = evaluateSources( def );
165 childParams.insert( def->name(), value );
172 bool isFinalOutput =
false;
173 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
174 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
175 for ( ; outputIt != outputs.constEnd(); ++outputIt )
177 if ( outputIt->childOutputName() == destParam->
name() )
179 QString paramName = child.childId() +
':' + outputIt.key();
180 bool foundParam =
false;
184 if ( modelParameters.contains( paramName ) )
186 value = modelParameters.value( paramName );
195 if ( modelParameters.contains( modelParam->name() ) )
197 value = modelParameters.value( modelParam->name() );
205 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
210 value = QVariant::fromValue( fromVar );
213 childParams.insert( destParam->
name(), value );
215 isFinalOutput =
true;
220 bool hasExplicitDefinition =
false;
221 if ( !isFinalOutput && child.parameterSources().contains( def->name() ) )
224 const QVariant value = evaluateSources( def );
225 if ( value.isValid() )
227 childParams.insert( def->name(), value );
228 hasExplicitDefinition =
true;
232 if ( !isFinalOutput && !hasExplicitDefinition )
237 bool required =
true;
240 required = childOutputIsRequired( child.childId(), destParam->
name() );
252const QgsProcessingParameterDefinition *QgsProcessingModelAlgorithm::modelParameterFromChildIdAndOutputName(
const QString &childId,
const QString &childOutputName )
const
256 if ( !definition->isDestination() )
259 const QString modelChildId = definition->
metadata().value( QStringLiteral(
"_modelChildId" ) ).toString();
260 const QString modelOutputName = definition->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
262 if ( modelChildId == childId && modelOutputName == childOutputName )
268bool QgsProcessingModelAlgorithm::childOutputIsRequired(
const QString &childId,
const QString &outputName )
const
271 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
272 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
274 if ( childIt->childId() == childId || !childIt->isActive() )
278 QMap<QString, QgsProcessingModelChildParameterSources> candidateChildParams = childIt->parameterSources();
279 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator childParamIt = candidateChildParams.constBegin();
280 for ( ; childParamIt != candidateChildParams.constEnd(); ++childParamIt )
282 const auto constValue = childParamIt.value();
283 for (
const QgsProcessingModelChildParameterSource &source : constValue )
286 && source.outputChildId() == childId
287 && source.outputName() == outputName )
299 QSet< QString > toExecute;
300 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
301 QSet< QString > broken;
302 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
304 if ( childIt->isActive() )
306 if ( childIt->algorithm() )
307 toExecute.insert( childIt->childId() );
309 broken.insert( childIt->childId() );
313 if ( !broken.empty() )
314 throw QgsProcessingException( QCoreApplication::translate(
"QgsProcessingModelAlgorithm",
"Cannot run model, the following algorithms are not available on this system: %1" ).arg(
qgsSetJoin( broken, QLatin1String(
", " ) ) ) );
316 QElapsedTimer totalTime;
322 QVariantMap childResults;
323 QVariantMap childInputs;
325 QVariantMap finalResults;
326 QSet< QString > executed;
327 bool executedAlg =
true;
328 while ( executedAlg && executed.count() < toExecute.count() )
331 for (
const QString &childId : std::as_const( toExecute ) )
336 if ( executed.contains( childId ) )
339 bool canExecute =
true;
340 const QSet< QString > dependencies = dependsOnChildAlgorithms( childId );
341 for (
const QString &dependency : dependencies )
343 if ( !executed.contains( dependency ) )
355 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
356 std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
358 bool skipGenericLogging =
true;
363 skipGenericLogging =
true;
373 skipGenericLogging =
false;
377 if ( feedback && !skipGenericLogging )
378 feedback->
pushDebugInfo( QObject::tr(
"Prepare algorithm: %1" ).arg( childId ) );
382 << createExpressionContextScopeForChildAlgorithm( childId, context, parameters, childResults );
386 QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext, error, &context );
387 if ( !error.isEmpty() )
390 if ( feedback && !skipGenericLogging )
391 feedback->
setProgressText( QObject::tr(
"Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
395 for (
auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
397 params << QStringLiteral(
"%1: %2" ).arg( childParamIt.key(),
398 child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
401 if ( feedback && !skipGenericLogging )
403 feedback->
pushInfo( QObject::tr(
"Input Parameters:" ) );
404 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( params.join( QLatin1String(
", " ) ) ) );
407 QElapsedTimer childTime;
412 QThread *modelThread = QThread::currentThread();
414 auto prepareOnMainThread = [modelThread, &ok, &childAlg, &childParams, &context, &modelFeedback]
416 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->prepare() must be run on the main thread" );
417 ok = childAlg->prepare( childParams, context, &modelFeedback );
418 context.pushToThread( modelThread );
422 if ( modelThread == qApp->thread() )
423 ok = childAlg->prepare( childParams, context, &modelFeedback );
426 context.pushToThread( qApp->thread() );
427 QMetaObject::invokeMethod( qApp, prepareOnMainThread, Qt::BlockingQueuedConnection );
430 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
444 auto runOnMainThread = [modelThread, &context, &modelFeedback, &results, &childAlg, &childParams]
446 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->runPrepared() must be run on the main thread" );
447 results = childAlg->runPrepared( childParams, context, &modelFeedback );
448 context.pushToThread( modelThread );
451 if ( feedback && !skipGenericLogging && modelThread != qApp->thread() )
452 feedback->
pushWarning( QObject::tr(
"Algorithm “%1” cannot be run in a background thread, switching to main thread for this step" ).arg( childAlg->displayName() ) );
454 context.pushToThread( qApp->thread() );
455 QMetaObject::invokeMethod( qApp, runOnMainThread, Qt::BlockingQueuedConnection );
460 results = childAlg->runPrepared( childParams, context, &modelFeedback );
469 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
472 auto postProcessOnMainThread = [modelThread, &ppRes, &childAlg, &context, &modelFeedback]
474 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"childAlg->postProcess() must be run on the main thread" );
475 ppRes = childAlg->postProcess( context, &modelFeedback );
476 context.pushToThread( modelThread );
480 if ( modelThread == qApp->thread() )
481 ppRes = childAlg->postProcess( context, &modelFeedback );
484 context.pushToThread( qApp->thread() );
485 QMetaObject::invokeMethod( qApp, postProcessOnMainThread, Qt::BlockingQueuedConnection );
488 Q_ASSERT_X( QThread::currentThread() == context.thread(),
"QgsProcessingModelAlgorithm::processAlgorithm",
"context was not transferred back to model thread" );
490 if ( !ppRes.isEmpty() )
493 if ( feedback && !skipGenericLogging )
496 QStringList formattedOutputs;
497 for (
auto displayOutputIt = displayOutputs.constBegin(); displayOutputIt != displayOutputs.constEnd(); ++displayOutputIt )
499 formattedOutputs << QStringLiteral(
"%1: %2" ).arg( displayOutputIt.key(),
502 feedback->
pushInfo( QObject::tr(
"Results:" ) );
503 feedback->
pushCommandInfo( QStringLiteral(
"{ %1 }" ).arg( formattedOutputs.join( QLatin1String(
", " ) ) ) );
506 childResults.insert( childId, results );
510 const QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
511 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
513 const int outputSortKey = mOutputOrder.indexOf( QStringLiteral(
"%1:%2" ).arg( childId, outputIt->childOutputName() ) );
514 switch ( mInternalVersion )
516 case QgsProcessingModelAlgorithm::InternalVersion::Version1:
517 finalResults.insert( childId +
':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
519 case QgsProcessingModelAlgorithm::InternalVersion::Version2:
522 finalResults.insert( modelParam->name(), results.value( outputIt->childOutputName() ) );
527 if ( !results.value( outputIt->childOutputName() ).toString().isEmpty() )
531 if ( outputSortKey > 0 )
536 executed.insert( childId );
538 std::function< void(
const QString &,
const QString & )> pruneAlgorithmBranchRecursive;
539 pruneAlgorithmBranchRecursive = [&](
const QString & id,
const QString &branch = QString() )
541 const QSet<QString> toPrune = dependentChildAlgorithms(
id, branch );
542 for (
const QString &targetId : toPrune )
544 if ( executed.contains( targetId ) )
547 executed.insert( targetId );
548 pruneAlgorithmBranchRecursive( targetId, branch );
558 pruneAlgorithmBranchRecursive( childId, outputDef->name() );
566 for (
const QString &candidateId : std::as_const( toExecute ) )
568 if ( executed.contains( candidateId ) )
573 const QgsProcessingModelChildAlgorithm &candidate = mChildAlgorithms[ candidateId ];
574 const QMap<QString, QgsProcessingModelChildParameterSources> candidateParams = candidate.parameterSources();
575 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = candidateParams.constBegin();
577 for ( ; paramIt != candidateParams.constEnd(); ++paramIt )
579 for (
const QgsProcessingModelChildParameterSource &source : paramIt.value() )
584 if ( !results.contains( source.outputName() ) )
589 executed.insert( candidateId );
591 pruneAlgorithmBranchRecursive( candidateId, QString() );
602 childAlg.reset(
nullptr );
603 modelFeedback.setCurrentStep( executed.count() );
604 if ( feedback && !skipGenericLogging )
605 feedback->
pushInfo( QObject::tr(
"OK. Execution took %1 s (%n output(s)).",
nullptr, results.count() ).arg( childTime.elapsed() / 1000.0 ) );
612 feedback->
pushDebugInfo( QObject::tr(
"Model processed OK. Executed %n algorithm(s) total in %1 s.",
nullptr, executed.count() ).arg( totalTime.elapsed() / 1000.0 ) );
614 mResults = finalResults;
615 mResults.insert( QStringLiteral(
"CHILD_RESULTS" ), childResults );
616 mResults.insert( QStringLiteral(
"CHILD_INPUTS" ), childInputs );
620QString QgsProcessingModelAlgorithm::sourceFilePath()
const
625void QgsProcessingModelAlgorithm::setSourceFilePath(
const QString &sourceFile )
627 mSourceFile = sourceFile;
630bool QgsProcessingModelAlgorithm::modelNameMatchesFilePath()
const
632 if ( mSourceFile.isEmpty() )
635 const QFileInfo fi( mSourceFile );
636 return fi.completeBaseName().compare( mModelName, Qt::CaseInsensitive ) == 0;
641 QStringList fileDocString;
642 fileDocString << QStringLiteral(
"\"\"\"" );
643 fileDocString << QStringLiteral(
"Model exported as python." );
644 fileDocString << QStringLiteral(
"Name : %1" ).arg( displayName() );
645 fileDocString << QStringLiteral(
"Group : %1" ).arg( group() );
646 fileDocString << QStringLiteral(
"With QGIS : %1" ).arg(
Qgis::versionInt() );
647 fileDocString << QStringLiteral(
"\"\"\"" );
648 fileDocString << QString();
651 QString indent = QString(
' ' ).repeated( indentSize );
652 QString currentIndent;
654 QMap< QString, QString> friendlyChildNames;
655 QMap< QString, QString> friendlyOutputNames;
656 auto uniqueSafeName = [](
const QString & name,
bool capitalize,
const QMap< QString, QString > &friendlyNames )->QString
658 const QString base = safeName( name, capitalize );
659 QString candidate = base;
661 while ( friendlyNames.contains( candidate ) )
664 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
669 const QString algorithmClassName = safeName( name(),
true );
671 QSet< QString > toExecute;
672 for (
auto childIt = mChildAlgorithms.constBegin(); childIt != mChildAlgorithms.constEnd(); ++childIt )
674 if ( childIt->isActive() && childIt->algorithm() )
676 toExecute.insert( childIt->childId() );
677 friendlyChildNames.insert( childIt->childId(), uniqueSafeName( childIt->description().isEmpty() ? childIt->childId() : childIt->description(), !childIt->description().isEmpty(), friendlyChildNames ) );
680 const int totalSteps = toExecute.count();
682 QStringList importLines;
683 switch ( outputType )
688 const auto params = parameterDefinitions();
689 importLines.reserve( params.count() + 3 );
690 importLines << QStringLiteral(
"from qgis.core import QgsProcessing" );
691 importLines << QStringLiteral(
"from qgis.core import QgsProcessingAlgorithm" );
692 importLines << QStringLiteral(
"from qgis.core import QgsProcessingMultiStepFeedback" );
694 bool hasAdvancedParams =
false;
698 hasAdvancedParams =
true;
701 if ( !importString.isEmpty() && !importLines.contains( importString ) )
702 importLines << importString;
705 if ( hasAdvancedParams )
706 importLines << QStringLiteral(
"from qgis.core import QgsProcessingParameterDefinition" );
708 lines << QStringLiteral(
"import processing" );
709 lines << QString() << QString();
711 lines << QStringLiteral(
"class %1(QgsProcessingAlgorithm):" ).arg( algorithmClassName );
715 lines << indent + QStringLiteral(
"def initAlgorithm(self, config=None):" );
716 if ( params.empty() )
718 lines << indent + indent + QStringLiteral(
"pass" );
722 lines.reserve( lines.size() + params.size() );
725 std::unique_ptr< QgsProcessingParameterDefinition > defClone( def->clone() );
727 if ( defClone->isDestination() )
729 const QString uniqueChildName = defClone->metadata().value( QStringLiteral(
"_modelChildId" ) ).toString() +
':' + defClone->metadata().value( QStringLiteral(
"_modelChildOutputName" ) ).toString();
730 const QString friendlyName = !defClone->description().isEmpty() ? uniqueSafeName( defClone->description(),
true, friendlyOutputNames ) : defClone->name();
731 friendlyOutputNames.insert( uniqueChildName, friendlyName );
732 defClone->setName( friendlyName );
736 if ( !mParameterComponents.value( defClone->name() ).comment()->description().isEmpty() )
738 const QStringList parts = mParameterComponents.value( defClone->name() ).comment()->description().split( QStringLiteral(
"\n" ) );
739 for (
const QString &part : parts )
741 lines << indent + indent + QStringLiteral(
"# %1" ).arg( part );
748 lines << indent + indent + QStringLiteral(
"param = %1" ).arg( defClone->asPythonString() );
749 lines << indent + indent + QStringLiteral(
"param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)" );
750 lines << indent + indent + QStringLiteral(
"self.addParameter(param)" );
754 lines << indent + indent + QStringLiteral(
"self.addParameter(%1)" ).arg( defClone->asPythonString() );
760 lines << indent + QStringLiteral(
"def processAlgorithm(self, parameters, context, model_feedback):" );
761 currentIndent = indent + indent;
763 lines << currentIndent + QStringLiteral(
"# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the" );
764 lines << currentIndent + QStringLiteral(
"# overall progress through the model" );
765 lines << currentIndent + QStringLiteral(
"feedback = QgsProcessingMultiStepFeedback(%1, model_feedback)" ).arg( totalSteps );
773 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
774 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
776 QString name = paramIt.value().parameterName();
777 if ( parameterDefinition( name ) )
780 params.insert( name, parameterDefinition( name )->valueAsPythonString( parameterDefinition( name )->defaultValue(), context ) );
784 if ( !params.isEmpty() )
786 lines << QStringLiteral(
"parameters = {" );
787 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
789 lines << QStringLiteral(
" '%1':%2," ).arg( it.key(), it.value() );
791 lines << QStringLiteral(
"}" )
795 lines << QStringLiteral(
"context = QgsProcessingContext()" )
796 << QStringLiteral(
"context.setProject(QgsProject.instance())" )
797 << QStringLiteral(
"feedback = QgsProcessingFeedback()" )
806 lines << currentIndent + QStringLiteral(
"results = {}" );
807 lines << currentIndent + QStringLiteral(
"outputs = {}" );
810 QSet< QString > executed;
811 bool executedAlg =
true;
813 while ( executedAlg && executed.count() < toExecute.count() )
816 const auto constToExecute = toExecute;
817 for (
const QString &childId : constToExecute )
819 if ( executed.contains( childId ) )
822 bool canExecute =
true;
823 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms( childId );
824 for (
const QString &dependency : constDependsOnChildAlgorithms )
826 if ( !executed.contains( dependency ) )
838 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms[ childId ];
845 if ( def->isDestination() )
850 bool isFinalOutput =
false;
851 QMap<QString, QgsProcessingModelOutput> outputs = child.modelOutputs();
852 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
853 for ( ; outputIt != outputs.constEnd(); ++outputIt )
855 if ( outputIt->childOutputName() == destParam->
name() )
857 QString paramName = child.childId() +
':' + outputIt.key();
858 paramName = friendlyOutputNames.value( paramName, paramName );
859 childParams.insert( destParam->
name(), QStringLiteral(
"parameters['%1']" ).arg( paramName ) );
860 isFinalOutput =
true;
865 if ( !isFinalOutput )
870 bool required =
true;
873 required = childOutputIsRequired( child.childId(), destParam->
name() );
879 childParams.insert( destParam->
name(), QStringLiteral(
"QgsProcessing.TEMPORARY_OUTPUT" ) );
885 lines << child.asPythonCode( outputType, childParams, currentIndent.size(), indentSize, friendlyChildNames, friendlyOutputNames );
887 if ( currentStep < totalSteps )
890 lines << currentIndent + QStringLiteral(
"feedback.setCurrentStep(%1)" ).arg( currentStep );
891 lines << currentIndent + QStringLiteral(
"if feedback.isCanceled():" );
892 lines << currentIndent + indent + QStringLiteral(
"return {}" );
895 executed.insert( childId );
899 switch ( outputType )
902 lines << currentIndent + QStringLiteral(
"return results" );
906 lines << indent + QStringLiteral(
"def name(self):" );
907 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
909 lines << indent + QStringLiteral(
"def displayName(self):" );
910 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelName );
914 lines << indent + QStringLiteral(
"def group(self):" );
915 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroup );
917 lines << indent + QStringLiteral(
"def groupId(self):" );
918 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( mModelGroupId );
922 if ( !shortHelpString().isEmpty() )
924 lines << indent + QStringLiteral(
"def shortHelpString(self):" );
925 lines << indent + indent + QStringLiteral(
"return \"\"\"%1\"\"\"" ).arg( shortHelpString() );
928 if ( !helpUrl().isEmpty() )
930 lines << indent + QStringLiteral(
"def helpUrl(self):" );
931 lines << indent + indent + QStringLiteral(
"return '%1'" ).arg( helpUrl() );
936 lines << indent + QStringLiteral(
"def createInstance(self):" );
937 lines << indent + indent + QStringLiteral(
"return %1()" ).arg( algorithmClassName );
940 static QMap< QString, QString > sAdditionalImports
942 { QStringLiteral(
"QgsCoordinateReferenceSystem" ), QStringLiteral(
"from qgis.core import QgsCoordinateReferenceSystem" ) },
943 { QStringLiteral(
"QgsExpression" ), QStringLiteral(
"from qgis.core import QgsExpression" ) },
944 { QStringLiteral(
"QgsRectangle" ), QStringLiteral(
"from qgis.core import QgsRectangle" ) },
945 { QStringLiteral(
"QgsReferencedRectangle" ), QStringLiteral(
"from qgis.core import QgsReferencedRectangle" ) },
946 { QStringLiteral(
"QgsPoint" ), QStringLiteral(
"from qgis.core import QgsPoint" ) },
947 { QStringLiteral(
"QgsReferencedPoint" ), QStringLiteral(
"from qgis.core import QgsReferencedPoint" ) },
948 { QStringLiteral(
"QgsProperty" ), QStringLiteral(
"from qgis.core import QgsProperty" ) },
949 { QStringLiteral(
"QgsRasterLayer" ), QStringLiteral(
"from qgis.core import QgsRasterLayer" ) },
950 { QStringLiteral(
"QgsMeshLayer" ), QStringLiteral(
"from qgis.core import QgsMeshLayer" ) },
951 { QStringLiteral(
"QgsVectorLayer" ), QStringLiteral(
"from qgis.core import QgsVectorLayer" ) },
952 { QStringLiteral(
"QgsMapLayer" ), QStringLiteral(
"from qgis.core import QgsMapLayer" ) },
953 { QStringLiteral(
"QgsProcessingFeatureSourceDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingFeatureSourceDefinition" ) },
954 { QStringLiteral(
"QgsPointXY" ), QStringLiteral(
"from qgis.core import QgsPointXY" ) },
955 { QStringLiteral(
"QgsReferencedPointXY" ), QStringLiteral(
"from qgis.core import QgsReferencedPointXY" ) },
956 { QStringLiteral(
"QgsGeometry" ), QStringLiteral(
"from qgis.core import QgsGeometry" ) },
957 { QStringLiteral(
"QgsProcessingOutputLayerDefinition" ), QStringLiteral(
"from qgis.core import QgsProcessingOutputLayerDefinition" ) },
958 { QStringLiteral(
"QColor" ), QStringLiteral(
"from qgis.PyQt.QtGui import QColor" ) },
959 { QStringLiteral(
"QDateTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDateTime" ) },
960 { QStringLiteral(
"QDate" ), QStringLiteral(
"from qgis.PyQt.QtCore import QDate" ) },
961 { QStringLiteral(
"QTime" ), QStringLiteral(
"from qgis.PyQt.QtCore import QTime" ) },
964 for (
auto it = sAdditionalImports.constBegin(); it != sAdditionalImports.constEnd(); ++it )
966 if ( importLines.contains( it.value() ) )
973 for (
const QString &line : std::as_const( lines ) )
975 if ( line.contains( it.key() ) )
983 importLines << it.value();
987 lines = fileDocString + importLines + lines;
996QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingModelAlgorithm::variablesForChildAlgorithm(
const QString &childId,
QgsProcessingContext *context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
998 QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables;
1000 auto safeName = [](
const QString & name )->QString
1003 const thread_local QRegularExpression safeNameRe( QStringLiteral(
"[\\s'\"\\(\\):\\.]" ) );
1004 return s.replace( safeNameRe, QStringLiteral(
"_" ) );
1039 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1043 QString description;
1044 switch ( source.source() )
1048 name = source.parameterName();
1049 value = modelParameters.value( source.parameterName() );
1050 description = parameterDefinition( source.parameterName() )->description();
1055 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1056 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1057 source.outputChildId() : child.description(), source.outputName() );
1060 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1061 child.description() );
1063 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1073 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1077 sources = availableSourcesForChild( childId, QStringList()
1084 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1088 QString description;
1090 switch ( source.source() )
1094 name = source.parameterName();
1095 value = modelParameters.value( source.parameterName() );
1096 description = parameterDefinition( source.parameterName() )->description();
1101 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1102 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1103 source.outputChildId() : child.description(), source.outputName() );
1104 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1107 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1108 child.description() );
1121 if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1124 value = fromVar.
sink;
1125 if ( value.userType() == QMetaType::type(
"QgsProperty" ) && context )
1133 layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( value ) );
1138 variables.insert( safeName( name ), VariableDefinition( layer ? QVariant::fromValue(
QgsWeakMapLayerPointer( layer ) ) : QVariant(), source, description ) );
1139 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1140 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1141 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1142 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( layer ? layer->
extent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1145 sources = availableSourcesForChild( childId, QStringList()
1147 for (
const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) )
1151 QString description;
1153 switch ( source.source() )
1157 name = source.parameterName();
1158 value = modelParameters.value( source.parameterName() );
1159 description = parameterDefinition( source.parameterName() )->description();
1164 const QgsProcessingModelChildAlgorithm &child = mChildAlgorithms.value( source.outputChildId() );
1165 name = QStringLiteral(
"%1_%2" ).arg( child.description().isEmpty() ?
1166 source.outputChildId() : child.description(), source.outputName() );
1167 value = results.value( source.outputChildId() ).toMap().value( source.outputName() );
1170 description = QObject::tr(
"Output '%1' from algorithm '%2'" ).arg( alg->outputDefinition( source.outputName() )->description(),
1171 child.description() );
1185 if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1190 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1193 value = fromVar.
sink;
1194 if ( context && value.userType() == QMetaType::type(
"QgsProperty" ) )
1199 if (
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
1201 featureSource = layer;
1203 if ( context && !featureSource )
1209 variables.insert( safeName( name ), VariableDefinition( value, source, description ) );
1210 variables.insert( safeName( QStringLiteral(
"%1_minx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMinimum() : QVariant(), source, QObject::tr(
"Minimum X of %1" ).arg( description ) ) );
1211 variables.insert( safeName( QStringLiteral(
"%1_miny" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMinimum() : QVariant(), source, QObject::tr(
"Minimum Y of %1" ).arg( description ) ) );
1212 variables.insert( safeName( QStringLiteral(
"%1_maxx" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
xMaximum() : QVariant(), source, QObject::tr(
"Maximum X of %1" ).arg( description ) ) );
1213 variables.insert( safeName( QStringLiteral(
"%1_maxy" ).arg( name ) ), VariableDefinition( featureSource ? featureSource->
sourceExtent().
yMaximum() : QVariant(), source, QObject::tr(
"Maximum Y of %1" ).arg( description ) ) );
1219QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextScopeForChildAlgorithm(
const QString &childId,
QgsProcessingContext &context,
const QVariantMap &modelParameters,
const QVariantMap &results )
const
1221 std::unique_ptr< QgsExpressionContextScope > scope(
new QgsExpressionContextScope( QStringLiteral(
"algorithm_inputs" ) ) );
1222 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = variablesForChildAlgorithm( childId, &context, modelParameters, results );
1223 QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition>::const_iterator varIt = variables.constBegin();
1224 for ( ; varIt != variables.constEnd(); ++varIt )
1228 return scope.release();
1231QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild(
const QString &childId,
const QStringList ¶meterTypes,
const QStringList &outputTypes,
const QList<int> &dataTypes )
const
1233 QgsProcessingModelChildParameterSources sources;
1236 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1237 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1243 if ( parameterTypes.contains( def->
type() ) )
1245 if ( !dataTypes.isEmpty() )
1261 bool ok = sourceDef->
dataTypes().isEmpty();
1262 const auto constDataTypes = sourceDef->
dataTypes();
1263 for (
int type : constDataTypes )
1278 sources << QgsProcessingModelChildParameterSource::fromModelParameter( paramIt->parameterName() );
1282 QSet< QString > dependents;
1283 if ( !childId.isEmpty() )
1285 dependents = dependentChildAlgorithms( childId );
1286 dependents << childId;
1289 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1290 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1292 if ( dependents.contains( childIt->childId() ) )
1302 if ( outputTypes.contains( out->type() ) )
1304 if ( !dataTypes.isEmpty() )
1310 if ( !vectorOutputIsCompatibleType( dataTypes, vectorOut->
dataType() ) )
1317 sources << QgsProcessingModelChildParameterSource::fromChildOutput( childIt->childId(), out->name() );
1325QVariantMap QgsProcessingModelAlgorithm::helpContent()
const
1327 return mHelpContent;
1330void QgsProcessingModelAlgorithm::setHelpContent(
const QVariantMap &helpContent )
1332 mHelpContent = helpContent;
1335void QgsProcessingModelAlgorithm::setName(
const QString &name )
1340void QgsProcessingModelAlgorithm::setGroup(
const QString &group )
1342 mModelGroup = group;
1345bool QgsProcessingModelAlgorithm::validate( QStringList &issues )
const
1350 if ( mChildAlgorithms.empty() )
1353 issues << QObject::tr(
"Model does not contain any algorithms" );
1356 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1358 QStringList childIssues;
1359 res = validateChildAlgorithm( it->childId(), childIssues ) && res;
1361 for (
const QString &issue : std::as_const( childIssues ) )
1363 issues << QStringLiteral(
"<b>%1</b>: %2" ).arg( it->description(), issue );
1369QMap<QString, QgsProcessingModelChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms()
const
1371 return mChildAlgorithms;
1374void QgsProcessingModelAlgorithm::setParameterComponents(
const QMap<QString, QgsProcessingModelParameter> ¶meterComponents )
1376 mParameterComponents = parameterComponents;
1379void QgsProcessingModelAlgorithm::setParameterComponent(
const QgsProcessingModelParameter &component )
1381 mParameterComponents.insert( component.parameterName(), component );
1384QgsProcessingModelParameter &QgsProcessingModelAlgorithm::parameterComponent(
const QString &name )
1386 if ( !mParameterComponents.contains( name ) )
1388 QgsProcessingModelParameter &component = mParameterComponents[ name ];
1389 component.setParameterName( name );
1392 return mParameterComponents[ name ];
1395QList< QgsProcessingModelParameter > QgsProcessingModelAlgorithm::orderedParameters()
const
1397 QList< QgsProcessingModelParameter > res;
1398 QSet< QString > found;
1399 for (
const QString ¶meter : mParameterOrder )
1401 if ( mParameterComponents.contains( parameter ) )
1403 res << mParameterComponents.value( parameter );
1409 for (
auto it = mParameterComponents.constBegin(); it != mParameterComponents.constEnd(); ++it )
1411 if ( !found.contains( it.key() ) )
1419void QgsProcessingModelAlgorithm::setParameterOrder(
const QStringList &order )
1421 mParameterOrder = order;
1424QList<QgsProcessingModelOutput> QgsProcessingModelAlgorithm::orderedOutputs()
const
1426 QList< QgsProcessingModelOutput > res;
1427 QSet< QString > found;
1429 for (
const QString &output : mOutputOrder )
1431 bool foundOutput =
false;
1432 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1434 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1435 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1437 if ( output == QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) )
1439 res << outputIt.value();
1441 found.insert( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) );
1450 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
1452 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
1453 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
1455 if ( !found.contains( QStringLiteral(
"%1:%2" ).arg( outputIt->childId(), outputIt->childOutputName() ) ) )
1457 res << outputIt.value();
1465void QgsProcessingModelAlgorithm::setOutputOrder(
const QStringList &order )
1467 mOutputOrder = order;
1470QString QgsProcessingModelAlgorithm::outputGroup()
const
1472 return mOutputGroup;
1475void QgsProcessingModelAlgorithm::setOutputGroup(
const QString &group )
1477 mOutputGroup = group;
1480void QgsProcessingModelAlgorithm::updateDestinationParameters()
1483 QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
1484 while ( it.hasNext() )
1494 qDeleteAll( mOutputs );
1498 QSet< QString > usedFriendlyNames;
1499 auto uniqueSafeName = [&usedFriendlyNames ](
const QString & name )->QString
1501 const QString base = safeName( name,
false );
1502 QString candidate = base;
1504 while ( usedFriendlyNames.contains( candidate ) )
1507 candidate = QStringLiteral(
"%1_%2" ).arg( base ).arg( i );
1509 usedFriendlyNames.insert( candidate );
1513 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1514 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1516 QMap<QString, QgsProcessingModelOutput> outputs = childIt->modelOutputs();
1517 QMap<QString, QgsProcessingModelOutput>::const_iterator outputIt = outputs.constBegin();
1518 for ( ; outputIt != outputs.constEnd(); ++outputIt )
1520 if ( !childIt->isActive() || !childIt->algorithm() )
1528 std::unique_ptr< QgsProcessingParameterDefinition > param( source->
clone() );
1532 if ( outputIt->isMandatory() )
1534 if ( mInternalVersion != InternalVersion::Version1 && !outputIt->description().isEmpty() )
1536 QString friendlyName = uniqueSafeName( outputIt->description() );
1537 param->setName( friendlyName );
1541 param->setName( outputIt->childId() +
':' + outputIt->name() );
1544 param->metadata().insert( QStringLiteral(
"_modelChildId" ), outputIt->childId() );
1545 param->metadata().insert( QStringLiteral(
"_modelChildOutputName" ), outputIt->name() );
1546 param->metadata().insert( QStringLiteral(
"_modelChildProvider" ), childIt->algorithm()->provider() ? childIt->algorithm()->provider()->id() : QString() );
1548 param->setDescription( outputIt->description() );
1549 param->setDefaultValue( outputIt->defaultValue() );
1552 if ( addParameter( param.release() ) && newDestParam )
1559 newDestParam->mOriginalProvider = provider;
1566void QgsProcessingModelAlgorithm::addGroupBox(
const QgsProcessingModelGroupBox &groupBox )
1568 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1571QList<QgsProcessingModelGroupBox> QgsProcessingModelAlgorithm::groupBoxes()
const
1573 return mGroupBoxes.values();
1576void QgsProcessingModelAlgorithm::removeGroupBox(
const QString &uuid )
1578 mGroupBoxes.remove( uuid );
1581QVariant QgsProcessingModelAlgorithm::toVariant()
const
1584 map.insert( QStringLiteral(
"model_name" ), mModelName );
1585 map.insert( QStringLiteral(
"model_group" ), mModelGroup );
1586 map.insert( QStringLiteral(
"help" ), mHelpContent );
1587 map.insert( QStringLiteral(
"internal_version" ),
qgsEnumValueToKey( mInternalVersion ) );
1589 QVariantMap childMap;
1590 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1591 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1593 childMap.insert( childIt.key(), childIt.value().toVariant() );
1595 map.insert( QStringLiteral(
"children" ), childMap );
1597 QVariantMap paramMap;
1598 QMap< QString, QgsProcessingModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
1599 for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
1601 paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
1603 map.insert( QStringLiteral(
"parameters" ), paramMap );
1605 QVariantMap paramDefMap;
1610 map.insert( QStringLiteral(
"parameterDefinitions" ), paramDefMap );
1612 QVariantList groupBoxDefs;
1613 for (
auto it = mGroupBoxes.constBegin(); it != mGroupBoxes.constEnd(); ++it )
1615 groupBoxDefs.append( it.value().toVariant() );
1617 map.insert( QStringLiteral(
"groupBoxes" ), groupBoxDefs );
1619 map.insert( QStringLiteral(
"modelVariables" ), mVariables );
1621 map.insert( QStringLiteral(
"designerParameterValues" ), mDesignerParameterValues );
1623 map.insert( QStringLiteral(
"parameterOrder" ), mParameterOrder );
1624 map.insert( QStringLiteral(
"outputOrder" ), mOutputOrder );
1625 map.insert( QStringLiteral(
"outputGroup" ), mOutputGroup );
1630bool QgsProcessingModelAlgorithm::loadVariant(
const QVariant &model )
1632 QVariantMap map = model.toMap();
1634 mModelName = map.value( QStringLiteral(
"model_name" ) ).toString();
1635 mModelGroup = map.value( QStringLiteral(
"model_group" ) ).toString();
1636 mModelGroupId = map.value( QStringLiteral(
"model_group" ) ).toString();
1637 mHelpContent = map.value( QStringLiteral(
"help" ) ).toMap();
1639 mInternalVersion =
qgsEnumKeyToValue( map.value( QStringLiteral(
"internal_version" ) ).toString(), InternalVersion::Version1 );
1641 mVariables = map.value( QStringLiteral(
"modelVariables" ) ).toMap();
1642 mDesignerParameterValues = map.value( QStringLiteral(
"designerParameterValues" ) ).toMap();
1644 mParameterOrder = map.value( QStringLiteral(
"parameterOrder" ) ).toStringList();
1645 mOutputOrder = map.value( QStringLiteral(
"outputOrder" ) ).toStringList();
1646 mOutputGroup = map.value( QStringLiteral(
"outputGroup" ) ).toString();
1648 mChildAlgorithms.clear();
1649 QVariantMap childMap = map.value( QStringLiteral(
"children" ) ).toMap();
1650 QVariantMap::const_iterator childIt = childMap.constBegin();
1651 for ( ; childIt != childMap.constEnd(); ++childIt )
1653 QgsProcessingModelChildAlgorithm child;
1657 if ( !child.loadVariant( childIt.value() ) )
1660 mChildAlgorithms.insert( child.childId(), child );
1663 mParameterComponents.clear();
1664 QVariantMap paramMap = map.value( QStringLiteral(
"parameters" ) ).toMap();
1665 QVariantMap::const_iterator paramIt = paramMap.constBegin();
1666 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1668 QgsProcessingModelParameter param;
1669 if ( !param.loadVariant( paramIt.value().toMap() ) )
1672 mParameterComponents.insert( param.parameterName(), param );
1675 qDeleteAll( mParameters );
1676 mParameters.clear();
1677 QVariantMap paramDefMap = map.value( QStringLiteral(
"parameterDefinitions" ) ).toMap();
1679 auto addParam = [ = ](
const QVariant & value )
1687 if ( param->name() == QLatin1String(
"VERBOSE_LOG" ) )
1691 param->setHelp( mHelpContent.value( param->name() ).toString() );
1694 addParameter( param.release() );
1698 QVariantMap map = value.toMap();
1699 QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
1700 QString name = map.value( QStringLiteral(
"name" ) ).toString();
1702 QgsMessageLog::logMessage( QCoreApplication::translate(
"Processing",
"Could not load parameter %1 of type %2." ).arg( name, type ), QCoreApplication::translate(
"Processing",
"Processing" ) );
1706 QSet< QString > loadedParams;
1708 for (
const QString &name : std::as_const( mParameterOrder ) )
1710 if ( paramDefMap.contains( name ) )
1712 addParam( paramDefMap.value( name ) );
1713 loadedParams << name;
1717 QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
1718 for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
1720 if ( !loadedParams.contains( paramDefIt.key() ) )
1721 addParam( paramDefIt.value() );
1724 mGroupBoxes.clear();
1725 const QVariantList groupBoxList = map.value( QStringLiteral(
"groupBoxes" ) ).toList();
1726 for (
const QVariant &groupBoxDef : groupBoxList )
1728 QgsProcessingModelGroupBox groupBox;
1729 groupBox.loadVariant( groupBoxDef.toMap() );
1730 mGroupBoxes.insert( groupBox.uuid(), groupBox );
1733 updateDestinationParameters();
1738bool QgsProcessingModelAlgorithm::vectorOutputIsCompatibleType(
const QList<int> &acceptableDataTypes,
QgsProcessing::SourceType outputType )
1743 return ( acceptableDataTypes.empty()
1744 || acceptableDataTypes.contains( outputType )
1755void QgsProcessingModelAlgorithm::reattachAlgorithms()
const
1757 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1758 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1760 if ( !childIt->algorithm() )
1761 childIt->reattach();
1765bool QgsProcessingModelAlgorithm::toFile(
const QString &path )
const
1767 QDomDocument doc = QDomDocument( QStringLiteral(
"model" ) );
1769 doc.appendChild( elem );
1772 if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
1774 QTextStream stream( &file );
1775 doc.save( stream, 2 );
1782bool QgsProcessingModelAlgorithm::fromFile(
const QString &path )
1787 if ( file.open( QFile::ReadOnly ) )
1789 if ( !doc.setContent( &file ) )
1800 return loadVariant( props );
1803void QgsProcessingModelAlgorithm::setChildAlgorithms(
const QMap<QString, QgsProcessingModelChildAlgorithm> &childAlgorithms )
1805 mChildAlgorithms = childAlgorithms;
1806 updateDestinationParameters();
1809void QgsProcessingModelAlgorithm::setChildAlgorithm(
const QgsProcessingModelChildAlgorithm &
algorithm )
1812 updateDestinationParameters();
1815QString QgsProcessingModelAlgorithm::addChildAlgorithm( QgsProcessingModelChildAlgorithm &
algorithm )
1817 if (
algorithm.childId().isEmpty() || mChildAlgorithms.contains(
algorithm.childId() ) )
1821 updateDestinationParameters();
1825QgsProcessingModelChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm(
const QString &childId )
1827 return mChildAlgorithms[ childId ];
1830bool QgsProcessingModelAlgorithm::removeChildAlgorithm(
const QString &
id )
1832 if ( !dependentChildAlgorithms(
id ).isEmpty() )
1835 mChildAlgorithms.remove(
id );
1836 updateDestinationParameters();
1840void QgsProcessingModelAlgorithm::deactivateChildAlgorithm(
const QString &
id )
1842 const auto constDependentChildAlgorithms = dependentChildAlgorithms(
id );
1843 for (
const QString &child : constDependentChildAlgorithms )
1845 childAlgorithm( child ).setActive(
false );
1847 childAlgorithm(
id ).setActive(
false );
1848 updateDestinationParameters();
1851bool QgsProcessingModelAlgorithm::activateChildAlgorithm(
const QString &
id )
1853 const auto constDependsOnChildAlgorithms = dependsOnChildAlgorithms(
id );
1854 for (
const QString &child : constDependsOnChildAlgorithms )
1856 if ( !childAlgorithm( child ).isActive() )
1859 childAlgorithm(
id ).setActive(
true );
1860 updateDestinationParameters();
1866 if ( addParameter( definition ) )
1867 mParameterComponents.insert( definition->
name(), component );
1872 removeParameter( definition->
name() );
1873 addParameter( definition );
1876void QgsProcessingModelAlgorithm::removeModelParameter(
const QString &name )
1878 removeParameter( name );
1879 mParameterComponents.remove( name );
1882void QgsProcessingModelAlgorithm::changeParameterName(
const QString &oldName,
const QString &newName )
1887 auto replaceExpressionVariable = [oldName, newName, &expressionContext](
const QString & expressionString ) -> std::tuple< bool, QString >
1890 expression.prepare( &expressionContext );
1891 QSet<QString> variables = expression.referencedVariables();
1892 if ( variables.contains( oldName ) )
1894 QString newExpression = expressionString;
1895 newExpression.replace( QStringLiteral(
"@%1" ).arg( oldName ), QStringLiteral(
"@%2" ).arg( newName ) );
1896 return {
true, newExpression };
1898 return {
false, QString() };
1901 QMap< QString, QgsProcessingModelChildAlgorithm >::iterator childIt = mChildAlgorithms.begin();
1902 for ( ; childIt != mChildAlgorithms.end(); ++childIt )
1904 bool changed =
false;
1905 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1906 QMap<QString, QgsProcessingModelChildParameterSources>::iterator paramIt = childParams.begin();
1907 for ( ; paramIt != childParams.end(); ++paramIt )
1909 QList< QgsProcessingModelChildParameterSource > &value = paramIt.value();
1910 for (
auto valueIt = value.begin(); valueIt != value.end(); ++valueIt )
1912 switch ( valueIt->source() )
1916 if ( valueIt->parameterName() == oldName )
1918 valueIt->setParameterName( newName );
1926 bool updatedExpression =
false;
1927 QString newExpression;
1928 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( valueIt->expression() );
1929 if ( updatedExpression )
1931 valueIt->setExpression( newExpression );
1939 if ( valueIt->staticValue().userType() == QMetaType::type(
"QgsProperty" ) )
1944 bool updatedExpression =
false;
1945 QString newExpression;
1946 std::tie( updatedExpression, newExpression ) = replaceExpressionVariable( property.expressionString() );
1947 if ( updatedExpression )
1949 property.setExpressionString( newExpression );
1950 valueIt->setStaticValue( property );
1966 childIt->setParameterSources( childParams );
1970bool QgsProcessingModelAlgorithm::childAlgorithmsDependOnParameter(
const QString &name )
const
1972 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
1973 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
1976 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
1977 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
1978 for ( ; paramIt != childParams.constEnd(); ++paramIt )
1980 const auto constValue = paramIt.value();
1981 for (
const QgsProcessingModelChildParameterSource &source : constValue )
1984 && source.parameterName() == name )
1994bool QgsProcessingModelAlgorithm::otherParametersDependOnParameter(
const QString &name )
const
1996 const auto constMParameters = mParameters;
1999 if ( def->
name() == name )
2008QMap<QString, QgsProcessingModelParameter> QgsProcessingModelAlgorithm::parameterComponents()
const
2010 return mParameterComponents;
2013void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive(
const QString &childId, QSet<QString> &depends,
const QString &branch )
const
2015 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2016 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2018 if ( depends.contains( childIt->childId() ) )
2022 const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
2023 bool hasDependency =
false;
2024 for (
const QgsProcessingModelChildDependency &dep : constDependencies )
2026 if ( dep.childId == childId && ( branch.isEmpty() || dep.conditionalBranch == branch ) )
2028 hasDependency =
true;
2033 if ( hasDependency )
2035 depends.insert( childIt->childId() );
2036 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2041 QMap<QString, QgsProcessingModelChildParameterSources> childParams = childIt->parameterSources();
2042 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2043 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2045 const auto constValue = paramIt.value();
2046 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2049 && source.outputChildId() == childId )
2051 depends.insert( childIt->childId() );
2052 dependentChildAlgorithmsRecursive( childIt->childId(), depends, branch );
2060QSet<QString> QgsProcessingModelAlgorithm::dependentChildAlgorithms(
const QString &childId,
const QString &conditionalBranch )
const
2062 QSet< QString > algs;
2066 algs.insert( childId );
2068 dependentChildAlgorithmsRecursive( childId, algs, conditionalBranch );
2071 algs.remove( childId );
2077void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive(
const QString &childId, QSet< QString > &depends )
const
2079 const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );
2082 const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
2083 for (
const QgsProcessingModelChildDependency &val : constDependencies )
2085 if ( !depends.contains( val.childId ) )
2087 depends.insert( val.childId );
2088 dependsOnChildAlgorithmsRecursive( val.childId, depends );
2093 QMap<QString, QgsProcessingModelChildParameterSources> childParams = alg.parameterSources();
2094 QMap<QString, QgsProcessingModelChildParameterSources>::const_iterator paramIt = childParams.constBegin();
2095 for ( ; paramIt != childParams.constEnd(); ++paramIt )
2097 const auto constValue = paramIt.value();
2098 for (
const QgsProcessingModelChildParameterSource &source : constValue )
2100 switch ( source.source() )
2103 if ( !depends.contains( source.outputChildId() ) )
2105 depends.insert( source.outputChildId() );
2106 dependsOnChildAlgorithmsRecursive( source.outputChildId(), depends );
2113 const QSet<QString> vars = exp.referencedVariables();
2118 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> availableVariables = variablesForChildAlgorithm( childId );
2119 for (
auto childVarIt = availableVariables.constBegin(); childVarIt != availableVariables.constEnd(); ++childVarIt )
2125 if ( !vars.contains( childVarIt.key() ) || depends.contains( childVarIt->source.outputChildId() ) )
2129 depends.insert( childVarIt->source.outputChildId() );
2130 dependsOnChildAlgorithmsRecursive( childVarIt->source.outputChildId(), depends );
2145QSet< QString > QgsProcessingModelAlgorithm::dependsOnChildAlgorithms(
const QString &childId )
const
2147 QSet< QString > algs;
2151 algs.insert( childId );
2153 dependsOnChildAlgorithmsRecursive( childId, algs );
2156 algs.remove( childId );
2161QList<QgsProcessingModelChildDependency> QgsProcessingModelAlgorithm::availableDependenciesForChildAlgorithm(
const QString &childId )
const
2163 QSet< QString > dependent;
2164 if ( !childId.isEmpty() )
2166 dependent.unite( dependentChildAlgorithms( childId ) );
2167 dependent.insert( childId );
2170 QList<QgsProcessingModelChildDependency> res;
2171 for (
auto it = mChildAlgorithms.constBegin(); it != mChildAlgorithms.constEnd(); ++it )
2173 if ( !dependent.contains( it->childId() ) )
2176 bool hasBranches =
false;
2177 if ( it->algorithm() )
2185 QgsProcessingModelChildDependency alg;
2186 alg.childId = it->childId();
2187 alg.conditionalBranch = def->
name();
2195 QgsProcessingModelChildDependency alg;
2196 alg.childId = it->childId();
2204bool QgsProcessingModelAlgorithm::validateChildAlgorithm(
const QString &childId, QStringList &issues )
const
2207 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constFind( childId );
2208 if ( childIt != mChildAlgorithms.constEnd() )
2210 if ( !childIt->algorithm() )
2212 issues << QObject::tr(
"Algorithm is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2221 if ( childIt->parameterSources().contains( def->
name() ) )
2224 const QList< QgsProcessingModelChildParameterSource > sources = childIt->parameterSources().value( def->
name() );
2225 for (
const QgsProcessingModelChildParameterSource &source : sources )
2227 switch ( source.source() )
2233 issues << QObject::tr(
"Value for <i>%1</i> is not acceptable for this parameter" ).arg( def->
name() );
2238 if ( !parameterComponents().contains( source.parameterName() ) )
2241 issues << QObject::tr(
"Model input <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.parameterName(), def->
name() );
2246 if ( !childAlgorithms().contains( source.outputChildId() ) )
2249 issues << QObject::tr(
"Child algorithm <i>%1</i> used for parameter <i>%2</i> does not exist" ).arg( source.outputChildId(), def->
name() );
2271 issues << QObject::tr(
"Parameter <i>%1</i> is mandatory" ).arg( def->
name() );
2280 issues << QObject::tr(
"Invalid child ID: <i>%1</i>" ).arg( childId );
2285bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage )
const
2287 reattachAlgorithms();
2288 QMap< QString, QgsProcessingModelChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
2289 for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
2291 if ( !childIt->algorithm() )
2295 *errorMessage = QObject::tr(
"The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
2303QString QgsProcessingModelAlgorithm::asPythonCommand(
const QVariantMap ¶meters,
QgsProcessingContext &context )
const
2305 if ( mSourceFile.isEmpty() )
2320 QgsProcessingModelAlgorithm *alg =
new QgsProcessingModelAlgorithm();
2321 alg->loadVariant( toVariant() );
2322 alg->setProvider( provider() );
2323 alg->setSourceFilePath( sourceFilePath() );
2327QString QgsProcessingModelAlgorithm::safeName(
const QString &name,
bool capitalize )
2329 QString n = name.toLower().trimmed();
2330 const thread_local QRegularExpression rx( QStringLiteral(
"[^\\sa-z_A-Z0-9]" ) );
2331 n.replace( rx, QString() );
2332 const thread_local QRegularExpression rx2( QStringLiteral(
"^\\d*" ) );
2333 n.replace( rx2, QString() );
2335 n = n.replace(
' ',
'_' );
2339QVariantMap QgsProcessingModelAlgorithm::variables()
const
2344void QgsProcessingModelAlgorithm::setVariables(
const QVariantMap &variables )
2346 mVariables = variables;
2349QVariantMap QgsProcessingModelAlgorithm::designerParameterValues()
const
2351 return mDesignerParameterValues;
@ UpperCamelCase
Convert the string to upper camel case. Note that this method does not unaccent characters.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
@ 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.
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * processingModelAlgorithmScope(const QgsProcessingModelAlgorithm *model, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing model algorithm,...
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm,...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
An interface for objects which provide features via a getFeatures method.
virtual QgsRectangle sourceExtent() const
Returns the extent of all geometries from the source.
bool isCanceled() const
Tells whether the operation has been canceled already.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Abstract base class for processing algorithms.
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
@ FlagNoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
@ FlagCustomException
Algorithm raises custom exception notices, don't use the standard ones.
@ FlagSkipGenericModelLogging
When running as part of a model, the generic algorithm setup and results logging should be skipped.
@ FlagPruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
virtual QgsExpressionContext createExpressionContext(const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeatureSource *source=nullptr) const
Creates an expression context relating to the algorithm.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &name) const
Returns a matching parameter by name.
virtual QString asPythonCommand(const QVariantMap ¶meters, QgsProcessingContext &context) const
Returns a Python command string which can be executed to run the algorithm using the specified parame...
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
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.
@ Verbose
Verbose logging.
@ DefaultLevel
Default logging level.
@ ModelDebug
Model debug level logging. Includes verbose logging and other outputs useful for debugging models (si...
QgsExpressionContext & expressionContext()
Returns the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
LogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString generateTemporaryDestination(const QgsProcessingContext *context=nullptr) const
Generates a temporary destination value for this parameter.
void setSupportsNonFileBasedOutput(bool supportsNonFileBasedOutput)
Sets whether the destination parameter supports non filed-based outputs, such as memory layers or dir...
Custom exception class for processing related exceptions.
Encapsulates settings relating to a feature source input to a processing algorithm.
QgsProperty source
Source definition.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
Processing feedback object for multi-step operations.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
Base class for the definition of processing outputs.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
QgsProperty sink
Sink/layer definition.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
A vector layer output for processing algorithms.
static QString typeName()
Returns the type name for the output class.
QgsProcessing::SourceType dataType() const
Returns the layer type for the output layer.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Base class for the definition of processing parameters.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
QVariantMap metadata() const
Returns the parameter's freeform metadata.
virtual bool isDestination() const
Returns true if this parameter represents a file or layer destination, e.g.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
@ FlagOptional
Parameter is optional.
@ FlagHidden
Parameter is hidden and should not be shown to users.
virtual QgsProcessingParameterDefinition * clone() const =0
Creates a clone of the parameter definition.
virtual QString type() const =0
Unique parameter type name.
Flags flags() const
Returns any flags associated with the parameter.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QString name() const
Returns the name of the parameter.
virtual QStringList dependsOnOtherParameters() const
Returns a list of other parameter names on which this parameter is dependent (e.g.
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
A vector layer or feature source field parameter for processing algorithms.
static QString typeName()
Returns the type name for the parameter class.
DataType dataType() const
Returns the acceptable data type for the field.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Can be inherited by parameters which require limits to their acceptable data types.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
virtual QString pythonImportString() const
Returns a valid Python import string for importing the corresponding parameter type,...
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map.
Abstract base class for processing providers.
const QgsProcessingAlgorithm * algorithm(const QString &name) const
Returns the matching algorithm by name, or nullptr if no matching algorithm is contained by this prov...
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
static QString formatHelpMapAsHtml(const QVariantMap &map, const QgsProcessingAlgorithm *algorithm)
Returns a HTML formatted version of the help text encoded in a variant map for a specified algorithm.
@ Vector
Vector layer type.
static 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.
SourceType
Data source types enum.
@ TypeVectorLine
Vector line layers.
@ TypeMapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
@ TypeVectorPolygon
Vector polygon layers.
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ TypeVectorPoint
Vector point layers.
@ TypeVectorAnyGeometry
Any vector layer with geometry.
A store for object properties.
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
QVariant staticValue() const
Returns the current static value for the property.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
Represents a vector layer which manages a vector based data sets.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
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.