QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
19
21
23
24QString QgsRefactorFieldsAlgorithm::name() const
25{
26 return QStringLiteral( "refactorfields" );
27}
28
29QString QgsRefactorFieldsAlgorithm::displayName() const
30{
31 return QObject::tr( "Refactor fields" );
32}
33
34QString QgsRefactorFieldsAlgorithm::shortHelpString() const
35{
36 return QObject::tr( "This algorithm allows editing the structure of the attributes table of a vector layer. Fields can be modified "
37 "in their type and name, using a fields mapping.\n\n"
38 "The original layer is not modified. A new layer is generated, which contains a modified attribute table, according "
39 "to the provided fields mapping.\n\n"
40 "Rows in orange have constraints in the template layer from which these fields were loaded. Treat this information "
41 "as a hint during configuration. No constraints will be added on an output layer nor will they be checked or "
42 "enforced by the algorithm." );
43}
44
45QString QgsRefactorFieldsAlgorithm::shortDescription() const
46{
47 return QObject::tr( "Allows editing the structure of the attributes table of a vector layer, permitting field renaming, creation and deletion." );
48}
49
50QStringList QgsRefactorFieldsAlgorithm::tags() const
51{
52 return QObject::tr( "attributes,table" ).split( ',' );
53}
54
55QString QgsRefactorFieldsAlgorithm::group() const
56{
57 return QObject::tr( "Vector table" );
58}
59
60QString QgsRefactorFieldsAlgorithm::groupId() const
61{
62 return QStringLiteral( "vectortable" );
63}
64
65QString QgsRefactorFieldsAlgorithm::outputName() const
66{
67 return QObject::tr( "Refactored" );
68}
69
70QList<int> QgsRefactorFieldsAlgorithm::inputLayerTypes() const
71{
72 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector );
73}
74
75Qgis::ProcessingAlgorithmDocumentationFlags QgsRefactorFieldsAlgorithm::documentationFlags() const
76{
78}
79
80Qgis::ProcessingFeatureSourceFlags QgsRefactorFieldsAlgorithm::sourceFlags() const
81{
83}
84
85QgsRefactorFieldsAlgorithm *QgsRefactorFieldsAlgorithm::createInstance() const
86{
87 return new QgsRefactorFieldsAlgorithm();
88}
89
90void QgsRefactorFieldsAlgorithm::initParameters( const QVariantMap & )
91{
92 auto param = std::make_unique<QgsProcessingParameterFieldMapping>( QStringLiteral( "FIELDS_MAPPING" ), QObject::tr( "Fields mapping" ), QStringLiteral( "INPUT" ) );
93 addParameter( param.release() );
94}
95
96QgsFields QgsRefactorFieldsAlgorithm::outputFields( const QgsFields & ) const
97{
98 return mFields;
99}
100
101bool QgsRefactorFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
102{
103 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
104 if ( !source )
105 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
106
107 mDa.setSourceCrs( source->sourceCrs(), context.transformContext() );
108 mDa.setEllipsoid( context.ellipsoid() );
109
110 mExpressionContext = createExpressionContext( parameters, context, source.get() );
111
112 const QVariantList mapping = parameters.value( QStringLiteral( "FIELDS_MAPPING" ) ).toList();
113 for ( const QVariant &map : mapping )
114 {
115 const QVariantMap fieldDef = map.toMap();
116 const QString name = fieldDef.value( QStringLiteral( "name" ) ).toString();
117 if ( name.isEmpty() )
118 throw QgsProcessingException( QObject::tr( "Field name cannot be empty" ) );
119
120 const QMetaType::Type type = static_cast<QMetaType::Type>( fieldDef.value( QStringLiteral( "type" ) ).toInt() );
121 const QString typeName = fieldDef.value( QStringLiteral( "sub_name" ) ).toString();
122 const QMetaType::Type subType = static_cast<QMetaType::Type>( fieldDef.value( QStringLiteral( "sub_type" ) ).toInt() );
123
124 const int length = fieldDef.value( QStringLiteral( "length" ), 0 ).toInt();
125 const int precision = fieldDef.value( QStringLiteral( "precision" ), 0 ).toInt();
126
127 const QString alias = fieldDef.value( QStringLiteral( "alias" ) ).toString();
128 const QString comment = fieldDef.value( QStringLiteral( "comment" ) ).toString();
129
130 QgsField newField( name, type, typeName, length, precision, QString(), subType );
131 newField.setAlias( alias );
132 newField.setComment( comment );
133 mFields.append( newField );
134
135 const QString expressionString = fieldDef.value( QStringLiteral( "expression" ) ).toString();
136 if ( !expressionString.isEmpty() )
137 {
138 QgsExpression expression( expressionString );
139 expression.setGeomCalculator( &mDa );
140 expression.setDistanceUnits( context.distanceUnit() );
141 expression.setAreaUnits( context.areaUnit() );
142 if ( expression.hasParserError() )
143 {
144 throw QgsProcessingException( QObject::tr( "Parser error for field \"%1\" with expression \"%2\": %3" )
145 .arg(
146 name,
147 expressionString,
148 expression.parserErrorString()
149 ) );
150 }
151 mExpressions.append( expression );
152 }
153 else
154 {
155 mExpressions.append( QgsExpression() );
156 }
157 }
158
159 return true;
160}
161
162QgsFeatureList QgsRefactorFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
163{
164 if ( !mExpressionsPrepared )
165 {
166 for ( auto it = mExpressions.begin(); it != mExpressions.end(); ++it )
167 {
168 if ( it->isValid() )
169 it->prepare( &mExpressionContext );
170 }
171 }
172
173 QgsAttributes attributes;
174 attributes.reserve( mExpressions.size() );
175 for ( auto it = mExpressions.begin(); it != mExpressions.end(); ++it )
176 {
177 if ( it->isValid() )
178 {
179 mExpressionContext.setFeature( feature );
180 mExpressionContext.lastScope()->setVariable( QStringLiteral( "row_number" ), mRowNumber );
181 const QVariant value = it->evaluate( &mExpressionContext );
182 if ( it->hasEvalError() )
183 {
184 throw QgsProcessingException( QObject::tr( "Evaluation error in expression \"%1\": %2" ).arg( it->expression(), it->evalErrorString() ) );
185 }
186 attributes.append( value );
187 }
188 else
189 {
190 attributes.append( QVariant() );
191 }
192 }
193
194 QgsFeature f = feature;
195 f.setAttributes( attributes );
196 mRowNumber++;
197 return QgsFeatureList() << f;
198}
199
200bool QgsRefactorFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
201{
202 Q_UNUSED( layer )
203 return false;
204}
205
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3539
@ RespectsEllipsoid
Algorithm respects the context's ellipsoid settings, and uses ellipsoidal based measurements.
Definition qgis.h:3621
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
Definition qgis.h:3630
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3711
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3722
A vector of attributes.
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...
Definition qgsfeature.h:58
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
Container of fields for a vector layer.
Definition qgsfields.h:46
Base class for all map layer types.
Definition qgsmaplayer.h:80
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.
QList< QgsFeature > QgsFeatureList