26using namespace Qt::StringLiterals;
30QString QgsFieldCalculatorAlgorithm::name()
const
32 return u
"fieldcalculator"_s;
35QString QgsFieldCalculatorAlgorithm::displayName()
const
37 return QObject::tr(
"Field calculator" );
40QStringList QgsFieldCalculatorAlgorithm::tags()
const
42 return QObject::tr(
"field,calculator,vector" ).split(
',' );
45QString QgsFieldCalculatorAlgorithm::group()
const
47 return QObject::tr(
"Vector table" );
50QString QgsFieldCalculatorAlgorithm::groupId()
const
52 return u
"vectortable"_s;
55QString QgsFieldCalculatorAlgorithm::outputName()
const
57 return QObject::tr(
"Calculated" );
60QList<int> QgsFieldCalculatorAlgorithm::inputLayerTypes()
const
75void QgsFieldCalculatorAlgorithm::initParameters(
const QVariantMap &configuration )
77 Q_UNUSED( configuration )
79 QStringList fieldTypes;
81 fieldTypes.reserve( 11 );
83 for (
const auto &type :
84 std::vector<std::pair<QMetaType::Type, QMetaType::Type>> {
85 { QMetaType::Type::Double, QMetaType::Type::UnknownType },
86 { QMetaType::Type::Int, QMetaType::Type::UnknownType },
87 { QMetaType::Type::QString, QMetaType::Type::UnknownType },
88 { QMetaType::Type::QDate, QMetaType::Type::UnknownType },
89 { QMetaType::Type::QTime, QMetaType::Type::UnknownType },
90 { QMetaType::Type::QDateTime, QMetaType::Type::UnknownType },
91 { QMetaType::Type::Bool, QMetaType::Type::UnknownType },
92 { QMetaType::Type::QByteArray, QMetaType::Type::UnknownType },
93 { QMetaType::Type::QStringList, QMetaType::Type::UnknownType },
94 { QMetaType::Type::QVariantList, QMetaType::Type::Int },
95 { QMetaType::Type::QVariantList, QMetaType::Type::Double }
102 auto fieldName = std::make_unique<QgsProcessingParameterString>( u
"FIELD_NAME"_s, QObject::tr(
"Field name" ), QVariant(),
false );
103 auto fieldType = std::make_unique<QgsProcessingParameterEnum>( u
"FIELD_TYPE"_s, QObject::tr(
"Result field type" ), fieldTypes,
false, 0 );
104 fieldType->setMetadata(
105 { QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"icons"_s, icons } } ) } } )
111 auto expression = std::make_unique<QgsProcessingParameterExpression>( u
"FORMULA"_s, QObject::tr(
"Formula" ), QVariant(), u
"INPUT"_s,
false );
113 expression->setMetadata( QVariantMap( { {
"inlineEditor",
true } } ) );
115 addParameter( fieldName.release() );
116 addParameter( fieldType.release() );
117 addParameter( fieldLength.release() );
118 addParameter( fieldPrecision.release() );
119 addParameter( expression.release() );
127QString QgsFieldCalculatorAlgorithm::shortHelpString()
const
129 return QObject::tr(
"This algorithm computes a new vector layer with the same features of the input layer, "
130 "but either overwriting an existing attribute or adding an additional attribute. The values of this field "
131 "are computed from each feature using an expression, based on the properties and attributes of the feature. "
132 "Note that if \"Field name\" is an existing field in the layer then all the rest of the field settings are ignored." );
135QString QgsFieldCalculatorAlgorithm::shortDescription()
const
137 return QObject::tr(
"Computes a new vector layer with the same features of the input layer, "
138 "but either overwriting an existing attribute or adding an additional attribute." );
141QgsFieldCalculatorAlgorithm *QgsFieldCalculatorAlgorithm::createInstance()
const
143 return new QgsFieldCalculatorAlgorithm();
149 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u
"INPUT"_s, context ) );
155 const int fieldTypeIdx = parameterAsInt( parameters, u
"FIELD_TYPE"_s, context );
156 const int fieldLength = parameterAsInt( parameters, u
"FIELD_LENGTH"_s, context );
157 const int fieldPrecision = parameterAsInt( parameters, u
"FIELD_PRECISION"_s, context );
158 const QString fieldName = parameterAsString( parameters, u
"FIELD_NAME"_s, context );
160 QMetaType::Type fieldType = QMetaType::Type::QString;
161 QMetaType::Type fieldSubType = QMetaType::Type::UnknownType;
162 switch ( fieldTypeIdx )
165 fieldType = QMetaType::Type::Double;
168 fieldType = QMetaType::Type::Int;
171 fieldType = QMetaType::Type::QString;
174 fieldType = QMetaType::Type::QDate;
177 fieldType = QMetaType::Type::QTime;
180 fieldType = QMetaType::Type::QDateTime;
183 fieldType = QMetaType::Type::Bool;
186 fieldType = QMetaType::Type::QByteArray;
189 fieldType = QMetaType::Type::QStringList;
190 fieldSubType = QMetaType::Type::QString;
193 fieldType = QMetaType::Type::QVariantList;
194 fieldSubType = QMetaType::Type::Int;
197 fieldType = QMetaType::Type::QVariantList;
198 fieldSubType = QMetaType::Type::Double;
202 if ( fieldName.isEmpty() )
215 mFields = source->fields();
217 const int fieldIdx = mFields.indexFromName( field.name() );
221 mFields.append( field );
225 feedback->
pushWarning( QObject::tr(
"Field name %1 already exists and will be replaced" ).arg( field.name() ) );
228 mFieldIdx = mFields.lookupField( field.name() );
231 const QString expressionString = parameterAsString( parameters, u
"FORMULA"_s, context );
232 mExpressionContext = createExpressionContext( parameters, context, source.get() );
237 mExpression.setGeomCalculator( &mDa );
239 mExpression.setAreaUnits( context.
areaUnit() );
241 if ( mExpression.hasParserError() )
243 .arg( expressionString, mExpression.parserErrorString() ) );
245 mExpression.prepare( &mExpressionContext );
253 const QStringList fieldNames = mFields.names();
254 for (
const QString &fieldName : fieldNames )
258 if ( attributeIndex >= 0 )
259 attributes[attributeIndex] = feature.
attribute( fieldName );
262 if ( mExpression.isValid() )
264 mExpressionContext.setFeature( feature );
265 mExpressionContext.lastScope()->setVariable( u
"row_number"_s, mRowNumber );
267 const QVariant value = mExpression.evaluate( &mExpressionContext );
269 if ( mExpression.hasEvalError() )
272 .arg( mExpression.expression(), mExpression.evalErrorString() ) );
275 attributes[mFieldIdx] = value;
279 attributes[mFieldIdx] = QVariant();
288bool QgsFieldCalculatorAlgorithm::supportInPlaceEdit(
const QgsMapLayer *layer )
const
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ RespectsEllipsoid
Algorithm respects the context's ellipsoid settings, and uses ellipsoidal based measurements.
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Handles parsing and evaluation of expressions (formerly called "search strings").
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
static QIcon iconForFieldType(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType, const QString &typeString=QString())
Returns an icon corresponding to a field type.
Base class for all map layer types.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Qgis::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit to use for distance calculations.
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
QList< QgsFeature > QgsFeatureList