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 );
244QStringList QgsProcessingModelChildAlgorithm::asPythonCode(
249 const QMap<QString, QString> &friendlyChildNames,
250 const QMap<QString, QString> &friendlyOutputNames
254 const QString baseIndent = QString(
' ' ).repeated( currentIndent );
255 const QString lineIndent = QString(
' ' ).repeated( indentSize );
258 return QStringList();
260 if ( !description().isEmpty() )
261 lines << baseIndent + u
"# %1"_s.arg( description() );
262 if ( !mComment.description().isEmpty() )
264 const QStringList parts = mComment.description().split( u
"\n"_s );
265 for (
const QString &part : parts )
267 lines << baseIndent + u
"# %1"_s.arg( part );
271 QStringList paramParts;
272 QStringList paramComments;
273 for (
auto paramIt = mParams.constBegin(); paramIt != mParams.constEnd(); ++paramIt )
275 QStringList sourceParts;
276 QStringList sourceComments;
278 const auto parts = paramIt.value();
279 sourceParts.reserve( parts.size() );
280 sourceComments.reserve( parts.size() );
281 for (
const QgsProcessingModelChildParameterSource &source : parts )
283 QString part = source.asPythonCode( outputType, def, friendlyChildNames );
284 if ( !part.isEmpty() )
287 sourceComments << source.asPythonComment( def );
290 if ( sourceParts.count() == 1 )
292 paramParts << u
"'%1': %2"_s.arg( paramIt.key(), sourceParts.at( 0 ) );
293 paramComments << sourceComments.at( 0 );
297 paramParts << u
"'%1': [%2]"_s.arg( paramIt.key(), sourceParts.join(
',' ) );
298 paramComments << QString();
302 lines << baseIndent + u
"alg_params = {"_s;
303 lines.reserve( lines.size() + paramParts.size() );
305 for (
const QString &p : std::as_const( paramParts ) )
307 QString line = baseIndent + lineIndent + p +
',';
308 if ( !paramComments.value( i ).isEmpty() )
310 line += u
" # %1"_s.arg( paramComments.value( i ) );
315 for (
auto it = extraParameters.constBegin(); it != extraParameters.constEnd(); ++it )
319 if ( lines.constLast().endsWith(
',' ) )
321 lines[lines.count() - 1].truncate( lines.constLast().length() - 1 );
323 lines << baseIndent + u
"}"_s;
325 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 );
327 for (
auto outputIt = mModelOutputs.constBegin(); outputIt != mModelOutputs.constEnd(); ++outputIt )
329 QString outputName = u
"%1:%2"_s.arg( mId, outputIt.key() );
330 outputName = friendlyOutputNames.value( outputName, outputName );
331 lines << baseIndent + u
"results['%1'] = outputs['%2']['%3']"_s.arg( outputName, friendlyChildNames.value( mId, mId ), outputIt.value().childOutputName() );
337QVariantMap QgsProcessingModelChildAlgorithm::configuration()
const
339 return mConfiguration;
342void QgsProcessingModelChildAlgorithm::setConfiguration(
const QVariantMap &configuration )
344 mConfiguration = configuration;
348void QgsProcessingModelChildAlgorithm::generateChildId(
const QgsProcessingModelAlgorithm &model )
354 id = u
"%1_%2"_s.arg( mAlgorithmId ).arg( i );
355 if ( !model.childAlgorithms().contains(
id ) )
362bool QgsProcessingModelChildAlgorithm::setAlgorithmId(
const QString &algorithmId )
364 mAlgorithmId = algorithmId;
366 return static_cast< bool >( mAlgorithm.get() );
369bool QgsProcessingModelChildAlgorithm::reattach()
const
371 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