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 : std::vector<std::pair<QMetaType::Type, QMetaType::Type>> {
84 { QMetaType::Type::Double, QMetaType::Type::UnknownType },
85 { QMetaType::Type::Int, QMetaType::Type::UnknownType },
86 { QMetaType::Type::QString, QMetaType::Type::UnknownType },
87 { QMetaType::Type::QDate, QMetaType::Type::UnknownType },
88 { QMetaType::Type::QTime, QMetaType::Type::UnknownType },
89 { QMetaType::Type::QDateTime, QMetaType::Type::UnknownType },
90 { QMetaType::Type::Bool, QMetaType::Type::UnknownType },
91 { QMetaType::Type::QByteArray, QMetaType::Type::UnknownType },
92 { QMetaType::Type::QStringList, QMetaType::Type::UnknownType },
93 { QMetaType::Type::QVariantList, QMetaType::Type::Int },
94 { QMetaType::Type::QVariantList, QMetaType::Type::Double }
101 auto fieldName = std::make_unique<QgsProcessingParameterString>( u
"FIELD_NAME"_s, QObject::tr(
"Field name" ), QVariant(),
false );
102 auto fieldType = std::make_unique<QgsProcessingParameterEnum>( u
"FIELD_TYPE"_s, QObject::tr(
"Result field type" ), fieldTypes,
false, 0 );
103 fieldType->setMetadata( { QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"icons"_s, icons } } ) } } ) } );
108 auto expression = std::make_unique<QgsProcessingParameterExpression>( u
"FORMULA"_s, QObject::tr(
"Formula" ), QVariant(), u
"INPUT"_s,
false );
110 expression->setMetadata( QVariantMap( { {
"inlineEditor",
true } } ) );
112 addParameter( fieldName.release() );
113 addParameter( fieldType.release() );
114 addParameter( fieldLength.release() );
115 addParameter( fieldPrecision.release() );
116 addParameter( expression.release() );
124QString QgsFieldCalculatorAlgorithm::shortHelpString()
const
127 "This algorithm computes a new vector layer with the same features of the input layer, "
128 "but either overwriting an existing attribute or adding an additional attribute. The values of this field "
129 "are computed from each feature using an expression, based on the properties and attributes of the feature. "
130 "Note that if \"Field name\" is an existing field in the layer then all the rest of the field settings are ignored."
134QString QgsFieldCalculatorAlgorithm::shortDescription()
const
137 "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."
142QgsFieldCalculatorAlgorithm *QgsFieldCalculatorAlgorithm::createInstance()
const
144 return new QgsFieldCalculatorAlgorithm();
150 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u
"INPUT"_s, context ) );
156 const int fieldTypeIdx = parameterAsInt( parameters, u
"FIELD_TYPE"_s, context );
157 const int fieldLength = parameterAsInt( parameters, u
"FIELD_LENGTH"_s, context );
158 const int fieldPrecision = parameterAsInt( parameters, u
"FIELD_PRECISION"_s, context );
159 const QString fieldName = parameterAsString( parameters, u
"FIELD_NAME"_s, context );
161 QMetaType::Type fieldType = QMetaType::Type::QString;
162 QMetaType::Type fieldSubType = QMetaType::Type::UnknownType;
163 switch ( fieldTypeIdx )
166 fieldType = QMetaType::Type::Double;
169 fieldType = QMetaType::Type::Int;
172 fieldType = QMetaType::Type::QString;
175 fieldType = QMetaType::Type::QDate;
178 fieldType = QMetaType::Type::QTime;
181 fieldType = QMetaType::Type::QDateTime;
184 fieldType = QMetaType::Type::Bool;
187 fieldType = QMetaType::Type::QByteArray;
190 fieldType = QMetaType::Type::QStringList;
191 fieldSubType = QMetaType::Type::QString;
194 fieldType = QMetaType::Type::QVariantList;
195 fieldSubType = QMetaType::Type::Int;
198 fieldType = QMetaType::Type::QVariantList;
199 fieldSubType = QMetaType::Type::Double;
203 if ( fieldName.isEmpty() )
206 const QgsField field( fieldName, fieldType, QString(), fieldLength, fieldPrecision, QString(), fieldSubType );
208 mFields = source->fields();
210 const int fieldIdx = mFields.indexFromName( field.name() );
214 mFields.append( field );
218 feedback->
pushWarning( QObject::tr(
"Field name %1 already exists and will be replaced" ).arg( field.name() ) );
221 mFieldIdx = mFields.lookupField( field.name() );
224 const QString expressionString = parameterAsString( parameters, u
"FORMULA"_s, context );
225 mExpressionContext = createExpressionContext( parameters, context, source.get() );
230 mExpression.setGeomCalculator( &mDa );
232 mExpression.setAreaUnits( context.
areaUnit() );
234 if ( mExpression.hasParserError() )
235 throw QgsProcessingException( QObject::tr(
"Parser error with formula expression \"%2\": %3" ).arg( expressionString, mExpression.parserErrorString() ) );
237 mExpression.prepare( &mExpressionContext );
245 const QStringList fieldNames = mFields.names();
246 for (
const QString &fieldName : fieldNames )
250 if ( attributeIndex >= 0 )
251 attributes[attributeIndex] = feature.
attribute( fieldName );
254 if ( mExpression.isValid() )
256 mExpressionContext.setFeature( feature );
257 mExpressionContext.lastScope()->setVariable( u
"row_number"_s, mRowNumber );
259 const QVariant value = mExpression.evaluate( &mExpressionContext );
261 if ( mExpression.hasEvalError() )
263 throw QgsProcessingException( QObject::tr(
"Evaluation error in expression \"%1\": %2" ).arg( mExpression.expression(), mExpression.evalErrorString() ) );
266 attributes[mFieldIdx] = value;
270 attributes[mFieldIdx] = QVariant();
279bool 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