26using namespace Qt::StringLiterals;
30QgsProcessingModelChildAlgorithm::QgsProcessingModelChildAlgorithm(
const QString &algorithmId )
32 setAlgorithmId( algorithmId );
35QgsProcessingModelChildAlgorithm::QgsProcessingModelChildAlgorithm(
const QgsProcessingModelChildAlgorithm &other )
36 : QgsProcessingModelComponent( other )
38 , mConfiguration( other.mConfiguration )
39 , mParams( other.mParams )
40 , mModelOutputs( other.mModelOutputs )
41 , mActive( other.mActive )
42 , mDependencies( other.mDependencies )
43 , mComment( other.mComment )
45 setAlgorithmId( other.algorithmId() );
48QgsProcessingModelChildAlgorithm &QgsProcessingModelChildAlgorithm::operator=(
const QgsProcessingModelChildAlgorithm &other )
53 QgsProcessingModelComponent::operator =( other );
55 mConfiguration = other.mConfiguration;
56 setAlgorithmId( other.algorithmId() );
57 mParams = other.mParams;
58 mModelOutputs = other.mModelOutputs;
59 mActive = other.mActive;
60 mDependencies = other.mDependencies;
61 mComment = other.mComment;
65QgsProcessingModelChildAlgorithm *QgsProcessingModelChildAlgorithm::clone()
const
67 return new QgsProcessingModelChildAlgorithm( *
this );
70void QgsProcessingModelChildAlgorithm::copyNonDefinitionPropertiesFromModel( QgsProcessingModelAlgorithm *model )
72 const QgsProcessingModelChildAlgorithm existingChild = model->childAlgorithm( mId );
73 copyNonDefinitionProperties( existingChild );
76 for (
auto it = mModelOutputs.begin(); it != mModelOutputs.end(); ++it )
78 const QMap<QString, QgsProcessingModelOutput> existingChildModelOutputs = existingChild.modelOutputs();
79 auto existingOutputIt = existingChildModelOutputs.find( it.key() );
80 if ( existingOutputIt == existingChildModelOutputs.end() )
83 if ( !existingOutputIt->position().isNull() )
85 it.value().setPosition( existingOutputIt->position() );
86 it.value().setSize( existingOutputIt->size() );
89 it.value().setPosition( position() + QPointF( size().width(), ( i + 1.5 ) * size().height() ) );
91 if ( QgsProcessingModelComment *comment = it.value().comment() )
93 if (
const QgsProcessingModelComment *existingComment = existingOutputIt->comment() )
95 comment->setDescription( existingComment->description() );
96 comment->setSize( existingComment->size() );
97 comment->setPosition( existingComment->position() );
98 comment->setColor( existingComment->color() );
107 return mAlgorithm.get();
110void QgsProcessingModelChildAlgorithm::setModelOutputs(
const QMap<QString, QgsProcessingModelOutput> &modelOutputs )
112 mModelOutputs = modelOutputs;
114 QMap<QString, QgsProcessingModelOutput>::iterator outputIt = mModelOutputs.begin();
115 for ( ; outputIt != mModelOutputs.end(); ++outputIt )
118 outputIt->setName( outputIt.key() );
119 outputIt->setChildId( mId );
123bool QgsProcessingModelChildAlgorithm::removeModelOutput(
const QString &name )
125 mModelOutputs.remove( name );
129QVariant QgsProcessingModelChildAlgorithm::toVariant()
const
132 map.insert( u
"id"_s, mId );
133 map.insert( u
"alg_id"_s, mAlgorithmId );
134 map.insert( u
"alg_config"_s, mConfiguration );
135 map.insert( u
"active"_s, mActive );
137 QVariantList dependencies;
138 for (
const QgsProcessingModelChildDependency &dependency : mDependencies )
140 dependencies << dependency.toVariant();
142 map.insert( u
"dependencies"_s, dependencies );
144 saveCommonProperties( map );
146 QVariantMap paramMap;
147 QMap< QString, QgsProcessingModelChildParameterSources >::const_iterator paramIt = mParams.constBegin();
148 for ( ; paramIt != mParams.constEnd(); ++paramIt )
150 QVariantList sources;
151 const auto constValue = paramIt.value();
152 for (
const QgsProcessingModelChildParameterSource &source : constValue )
154 sources << source.toVariant();
156 paramMap.insert( paramIt.key(), sources );
158 map.insert( u
"params"_s, paramMap );
160 QVariantMap outputMap;
161 QMap< QString, QgsProcessingModelOutput >::const_iterator outputIt = mModelOutputs.constBegin();
162 for ( ; outputIt != mModelOutputs.constEnd(); ++outputIt )
164 outputMap.insert( outputIt.key(), outputIt.value().toVariant() );
166 map.insert( u
"outputs"_s, outputMap );
171bool QgsProcessingModelChildAlgorithm::loadVariant(
const QVariant &child )
173 QVariantMap map = child.toMap();
175 mId = map.value( u
"id"_s ).toString();
179 mConfiguration = map.value( u
"alg_config"_s ).toMap();
180 setAlgorithmId( map.value( u
"alg_id"_s ).toString() );
181 if ( algorithmId().isEmpty() )
183 mActive = map.value( u
"active"_s ).toBool();
185 mDependencies.clear();
186 if ( map.value( u
"dependencies"_s ).userType() == QMetaType::Type::QStringList )
188 const QStringList dependencies = map.value( u
"dependencies"_s ).toStringList();
189 mDependencies.reserve( dependencies.size() );
190 for (
const QString &dependency : dependencies )
192 QgsProcessingModelChildDependency dep;
193 dep.childId = dependency;
194 mDependencies << dep;
199 const QVariantList dependencies = map.value( u
"dependencies"_s ).toList();
200 mDependencies.reserve( dependencies.size() );
201 for (
const QVariant &dependency : dependencies )
203 QgsProcessingModelChildDependency dep;
204 dep.loadVariant( dependency.toMap() );
205 mDependencies << dep;
209 restoreCommonProperties( map );
212 QVariantMap paramMap = map.value( u
"params"_s ).toMap();
213 QVariantMap::const_iterator paramIt = paramMap.constBegin();
214 for ( ; paramIt != paramMap.constEnd(); ++paramIt )
216 QgsProcessingModelChildParameterSources sources;
217 const auto constToList = paramIt->toList();
218 sources.reserve( constToList.size() );
219 for (
const QVariant &sourceVar : constToList )
221 QgsProcessingModelChildParameterSource param;
222 if ( !param.loadVariant( sourceVar.toMap() ) )
226 mParams.insert( paramIt.key(), sources );
229 mModelOutputs.clear();
230 QVariantMap outputMap = map.value( u
"outputs"_s ).toMap();
231 QVariantMap::const_iterator outputIt = outputMap.constBegin();
232 for ( ; outputIt != outputMap.constEnd(); ++outputIt )
234 QgsProcessingModelOutput output;
235 if ( !output.loadVariant( outputIt.value().toMap() ) )
238 mModelOutputs.insert( outputIt.key(), output );
245 int currentIndent,
int indentSize,
const QMap<QString, QString> &friendlyChildNames,
const QMap<QString, QString> &friendlyOutputNames )
const
248 const QString baseIndent = QString(
' ' ).repeated( currentIndent );
249 const QString lineIndent = QString(
' ' ).repeated( indentSize );
252 return QStringList();
254 if ( !description().isEmpty() )
255 lines << baseIndent + u
"# %1"_s.arg( description() );
256 if ( !mComment.description().isEmpty() )
258 const QStringList parts = mComment.description().split( u
"\n"_s );
259 for (
const QString &part : parts )
261 lines << baseIndent + u
"# %1"_s.arg( part );
265 QStringList paramParts;
266 QStringList paramComments;
267 for (
auto paramIt = mParams.constBegin(); paramIt != mParams.constEnd(); ++paramIt )
269 QStringList sourceParts;
270 QStringList sourceComments;
272 const auto parts = paramIt.value();
273 sourceParts.reserve( parts.size() );
274 sourceComments.reserve( parts.size() );
275 for (
const QgsProcessingModelChildParameterSource &source : parts )
277 QString part = source.asPythonCode( outputType, def, friendlyChildNames );
278 if ( !part.isEmpty() )
281 sourceComments << source.asPythonComment( def );
284 if ( sourceParts.count() == 1 )
286 paramParts << u
"'%1': %2"_s.arg( paramIt.key(), sourceParts.at( 0 ) );
287 paramComments << sourceComments.at( 0 );
291 paramParts << u
"'%1': [%2]"_s.arg( paramIt.key(), sourceParts.join(
',' ) );
292 paramComments << QString();
296 lines << baseIndent + u
"alg_params = {"_s;
297 lines.reserve( lines.size() + paramParts.size() );
299 for (
const QString &p : std::as_const( paramParts ) )
301 QString line = baseIndent + lineIndent + p +
',';
302 if ( !paramComments.value( i ).isEmpty() )
304 line += u
" # %1"_s.arg( paramComments.value( i ) );
309 for (
auto it = extraParameters.constBegin(); it != extraParameters.constEnd(); ++it )
313 if ( lines.constLast().endsWith(
',' ) )
315 lines[ lines.count() - 1 ].truncate( lines.constLast().length() - 1 );
317 lines << baseIndent + u
"}"_s;
319 lines << baseIndent + u
"outputs['%1'] = processing.run('%2', alg_params, context=context, feedback=feedback, is_child_algorithm=True)"_s.arg( friendlyChildNames.value( mId, mId ), mAlgorithmId );
321 for (
auto outputIt = mModelOutputs.constBegin(); outputIt != mModelOutputs.constEnd(); ++outputIt )
323 QString outputName = u
"%1:%2"_s.arg( mId, outputIt.key() );
324 outputName = friendlyOutputNames.value( outputName, outputName );
325 lines << baseIndent + u
"results['%1'] = outputs['%2']['%3']"_s.arg( outputName, friendlyChildNames.value( mId, mId ), outputIt.value().childOutputName() );
331QVariantMap QgsProcessingModelChildAlgorithm::configuration()
const
333 return mConfiguration;
336void QgsProcessingModelChildAlgorithm::setConfiguration(
const QVariantMap &configuration )
338 mConfiguration = configuration;
342void QgsProcessingModelChildAlgorithm::generateChildId(
const QgsProcessingModelAlgorithm &model )
348 id = u
"%1_%2"_s.arg( mAlgorithmId ).arg( i );
349 if ( !model.childAlgorithms().contains(
id ) )
356bool QgsProcessingModelChildAlgorithm::setAlgorithmId(
const QString &algorithmId )
358 mAlgorithmId = algorithmId;
360 return static_cast< bool >( mAlgorithm.get() );
363bool QgsProcessingModelChildAlgorithm::reattach()
const
365 return const_cast< QgsProcessingModelChildAlgorithm *
>( this )->setAlgorithmId( mAlgorithmId );
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
Abstract base class for processing algorithms.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &name) const
Returns a matching parameter by name.
Base class for the definition of processing parameters.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
PythonOutputType
Available Python output types.
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
QMap< QString, QString > QgsStringMap