QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsalgorithmrefactorfields.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmrefactorfields.h
3 ---------------------------------
4 begin : June 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
20
22
23QString QgsRefactorFieldsAlgorithm::name() const
24{
25 return QStringLiteral( "refactorfields" );
26}
27
28QString QgsRefactorFieldsAlgorithm::displayName() const
29{
30 return QObject::tr( "Refactor fields" );
31}
32
33QString QgsRefactorFieldsAlgorithm::shortHelpString() const
34{
35 return QObject::tr( "This algorithm allows editing the structure of the attributes table of a vector layer. Fields can be modified "
36 "in their type and name, using a fields mapping.\n\n"
37 "The original layer is not modified. A new layer is generated, which contains a modified attribute table, according "
38 "to the provided fields mapping.\n\n"
39 "Rows in orange have constraints in the template layer from which these fields were loaded. Treat this information "
40 "as a hint during configuration. No constraints will be added on an output layer nor will they be checked or "
41 "enforced by the algorithm." );
42}
43
44QStringList QgsRefactorFieldsAlgorithm::tags() const
45{
46 return QObject::tr( "attributes,table" ).split( ',' );
47}
48
49QString QgsRefactorFieldsAlgorithm::group() const
50{
51 return QObject::tr( "Vector table" );
52}
53
54QString QgsRefactorFieldsAlgorithm::groupId() const
55{
56 return QStringLiteral( "vectortable" );
57}
58
59QString QgsRefactorFieldsAlgorithm::outputName() const
60{
61 return QObject::tr( "Refactored" );
62}
63
64QList<int> QgsRefactorFieldsAlgorithm::inputLayerTypes() const
65{
66 return QList<int>() << QgsProcessing::TypeVector;
67}
68
69QgsProcessingFeatureSource::Flag QgsRefactorFieldsAlgorithm::sourceFlags() const
70{
72}
73
74QgsRefactorFieldsAlgorithm *QgsRefactorFieldsAlgorithm::createInstance() const
75{
76 return new QgsRefactorFieldsAlgorithm();
77}
78
79void QgsRefactorFieldsAlgorithm::initParameters( const QVariantMap & )
80{
81 std::unique_ptr< QgsProcessingParameterFieldMapping > param = std::make_unique< QgsProcessingParameterFieldMapping> ( QStringLiteral( "FIELDS_MAPPING" ), QObject::tr( "Fields mapping" ), QStringLiteral( "INPUT" ) );
82 addParameter( param.release() );
83}
84
85QgsFields QgsRefactorFieldsAlgorithm::outputFields( const QgsFields & ) const
86{
87 return mFields;
88}
89
90bool QgsRefactorFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
91{
92 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
93 if ( !source )
94 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
95
96 mDa.setSourceCrs( source->sourceCrs(), context.transformContext() );
97 mDa.setEllipsoid( context.ellipsoid() );
98
99 mExpressionContext = createExpressionContext( parameters, context, source.get() );
100
101 const QVariantList mapping = parameters.value( QStringLiteral( "FIELDS_MAPPING" ) ).toList();
102 for ( const QVariant &map : mapping )
103 {
104 const QVariantMap fieldDef = map.toMap();
105 const QString name = fieldDef.value( QStringLiteral( "name" ) ).toString();
106 if ( name.isEmpty() )
107 throw QgsProcessingException( QObject::tr( "Field name cannot be empty" ) );
108
109 const QVariant::Type type = static_cast< QVariant::Type >( fieldDef.value( QStringLiteral( "type" ) ).toInt() );
110 const QString typeName = fieldDef.value( QStringLiteral( "sub_name" ) ).toString();
111 const QVariant::Type subType = static_cast< QVariant::Type >( fieldDef.value( QStringLiteral( "sub_type" ) ).toInt() );
112
113 const int length = fieldDef.value( QStringLiteral( "length" ), 0 ).toInt();
114 const int precision = fieldDef.value( QStringLiteral( "precision" ), 0 ).toInt();
115
116 mFields.append( QgsField( name, type, typeName, length, precision, QString(), subType ) );
117
118 const QString expressionString = fieldDef.value( QStringLiteral( "expression" ) ).toString();
119 if ( !expressionString.isEmpty() )
120 {
121 QgsExpression expression( expressionString );
122 expression.setGeomCalculator( &mDa );
123 expression.setDistanceUnits( context.distanceUnit() );
124 expression.setAreaUnits( context.areaUnit() );
125 if ( expression.hasParserError() )
126 {
127 throw QgsProcessingException( QObject::tr( "Parser error for field \"%1\" with expression \"%2\": %3" )
128 .arg(
129 name,
130 expressionString,
131 expression.parserErrorString() ) );
132 }
133 mExpressions.append( expression );
134 }
135 else
136 {
137 mExpressions.append( QgsExpression() );
138 }
139 }
140
141 return true;
142}
143
144QgsFeatureList QgsRefactorFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
145{
146 if ( !mExpressionsPrepared )
147 {
148 for ( auto it = mExpressions.begin(); it != mExpressions.end(); ++it )
149 {
150 if ( it->isValid() )
151 it->prepare( &mExpressionContext );
152 }
153 }
154
155 QgsAttributes attributes;
156 attributes.reserve( mExpressions.size() );
157 for ( auto it = mExpressions.begin(); it != mExpressions.end(); ++it )
158 {
159 if ( it->isValid() )
160 {
161 mExpressionContext.setFeature( feature );
162 mExpressionContext.lastScope()->setVariable( QStringLiteral( "row_number" ), mRowNumber );
163 const QVariant value = it->evaluate( &mExpressionContext );
164 if ( it->hasEvalError() )
165 {
166 throw QgsProcessingException( QObject::tr( "Evaluation error in expression \"%1\": %2" ).arg( it->expression(), it->evalErrorString() ) );
167 }
168 attributes.append( value );
169 }
170 else
171 {
172 attributes.append( QVariant() );
173 }
174 }
175
176 QgsFeature f = feature;
177 f.setAttributes( attributes );
178 mRowNumber++;
179 return QgsFeatureList() << f;
180}
181
182bool QgsRefactorFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
183{
184 Q_UNUSED( layer )
185 return false;
186}
187
A vector of attributes.
Definition: qgsattributes.h:59
Class for 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...
Definition: qgsfeature.h:56
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
Container of fields for a vector layer.
Definition: qgsfields.h:45
Base class for all map layer types.
Definition: qgsmaplayer.h:73
Contains information about the context in which a processing algorithm is executed.
QgsUnitTypes::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
QgsUnitTypes::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.
Definition: qgsexception.h:83
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Base class for providing feedback from a processing algorithm.
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:922
const QString & typeName
int precision