25 QString QgsFieldCalculatorAlgorithm::name()
const
27 return QStringLiteral(
"fieldcalculator" );
30 QString QgsFieldCalculatorAlgorithm::displayName()
const
32 return QObject::tr(
"Field calculator" );
35 QStringList QgsFieldCalculatorAlgorithm::tags()
const
37 return QObject::tr(
"field,calculator,vector" ).split(
',' );
40 QString QgsFieldCalculatorAlgorithm::group()
const
42 return QObject::tr(
"Vector table" );
45 QString QgsFieldCalculatorAlgorithm::groupId()
const
47 return QStringLiteral(
"vectortable" );
50 QString QgsFieldCalculatorAlgorithm::outputName()
const
52 return QObject::tr(
"Calculated" );
55 QList<int> QgsFieldCalculatorAlgorithm::inputLayerTypes()
const
65 void QgsFieldCalculatorAlgorithm::initParameters(
const QVariantMap &configuration )
67 Q_UNUSED( configuration )
69 QStringList fieldTypes;
71 fieldTypes.reserve( 11 );
73 for (
const auto &type :
74 std::vector < std::pair< QVariant::Type, QVariant::Type > >
76 {QVariant::Double, QVariant::Invalid },
77 {QVariant::Int, QVariant::Invalid },
78 {QVariant::String, QVariant::Invalid },
79 {QVariant::Date, QVariant::Invalid },
80 {QVariant::Time, QVariant::Invalid },
81 {QVariant::DateTime, QVariant::Invalid },
82 {QVariant::Bool, QVariant::Invalid },
83 {QVariant::ByteArray, QVariant::Invalid },
84 {QVariant::StringList, QVariant::Invalid },
85 {QVariant::List, QVariant::Int },
86 {QVariant::List, QVariant::Double }
93 std::unique_ptr< QgsProcessingParameterString > fieldName = std::make_unique< QgsProcessingParameterString > ( QStringLiteral(
"FIELD_NAME" ), QObject::tr(
"Field name" ), QVariant(),
false );
94 std::unique_ptr< QgsProcessingParameterEnum > fieldType = std::make_unique< QgsProcessingParameterEnum > ( QStringLiteral(
"FIELD_TYPE" ), QObject::tr(
"Result field type" ), fieldTypes,
false, 0 );
95 fieldType->setMetadata(
98 QStringLiteral(
"widget_wrapper" ),
101 QStringLiteral(
"icons" ), icons
107 std::unique_ptr< QgsProcessingParameterNumber > fieldLength = std::make_unique< QgsProcessingParameterNumber > ( QStringLiteral(
"FIELD_LENGTH" ), QObject::tr(
"Result field length" ),
QgsProcessingParameterNumber::Integer, QVariant( 0 ),
false, 0 );
108 std::unique_ptr< QgsProcessingParameterNumber > fieldPrecision = std::make_unique< QgsProcessingParameterNumber > ( QStringLiteral(
"FIELD_PRECISION" ), QObject::tr(
"Result field precision" ),
QgsProcessingParameterNumber::Integer, QVariant( 0 ),
false, 0 );
109 std::unique_ptr< QgsProcessingParameterExpression > expression = std::make_unique< QgsProcessingParameterExpression> ( QStringLiteral(
"FORMULA" ), QObject::tr(
"Formula" ), QVariant(), QStringLiteral(
"INPUT" ),
false );
111 expression->setMetadata( QVariantMap( {{
"inlineEditor",
true}} ) );
113 addParameter( fieldName.release() );
114 addParameter( fieldType.release() );
115 addParameter( fieldLength.release() );
116 addParameter( fieldPrecision.release() );
117 addParameter( expression.release() );
125 QString QgsFieldCalculatorAlgorithm::shortHelpString()
const
127 return QObject::tr(
"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." );
133 QgsFieldCalculatorAlgorithm *QgsFieldCalculatorAlgorithm::createInstance()
const
135 return new QgsFieldCalculatorAlgorithm();
141 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
147 const int fieldTypeIdx = parameterAsInt( parameters, QStringLiteral(
"FIELD_TYPE" ), context );
148 const int fieldLength = parameterAsInt( parameters, QStringLiteral(
"FIELD_LENGTH" ), context );
149 const int fieldPrecision = parameterAsInt( parameters, QStringLiteral(
"FIELD_PRECISION" ), context );
150 const QString fieldName = parameterAsString( parameters, QStringLiteral(
"FIELD_NAME" ), context );
152 QVariant::Type fieldType = QVariant::Type::String;
153 QVariant::Type fieldSubType = QVariant::Type::Invalid;
154 switch ( fieldTypeIdx )
157 fieldType = QVariant::Double;
160 fieldType = QVariant::Int;
163 fieldType = QVariant::String;
166 fieldType = QVariant::Date;
169 fieldType = QVariant::Time;
172 fieldType = QVariant::DateTime;
175 fieldType = QVariant::Bool;
178 fieldType = QVariant::ByteArray;
181 fieldType = QVariant::StringList;
182 fieldSubType = QVariant::String;
185 fieldType = QVariant::List;
186 fieldSubType = QVariant::Int;
189 fieldType = QVariant::List;
190 fieldSubType = QVariant::Double;
194 if ( fieldName.isEmpty() )
207 mFields = source->fields();
209 const int fieldIdx = mFields.indexFromName(
field.
name() );
213 mFields.append(
field );
217 feedback->
pushWarning( QObject::tr(
"Field name %1 already exists and will be replaced" ).arg(
field.
name() ) );
220 mFieldIdx = mFields.lookupField(
field.
name() );
223 const QString expressionString = parameterAsString( parameters, QStringLiteral(
"FORMULA" ), context );
224 mExpressionContext = createExpressionContext( parameters, context, source.get() );
229 mExpression.setGeomCalculator( &mDa );
231 mExpression.setAreaUnits( context.
areaUnit() );
233 if ( mExpression.hasParserError() )
235 .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( QStringLiteral(
"row_number" ), mRowNumber );
259 const QVariant value = mExpression.evaluate( &mExpressionContext );
261 if ( mExpression.hasEvalError() )
264 .arg( mExpression.expression(), mExpression.evalErrorString() ) );
267 attributes[mFieldIdx] = value;
271 attributes[mFieldIdx] = QVariant();
280 bool QgsFieldCalculatorAlgorithm::supportInPlaceEdit(
const QgsMapLayer *layer )
const