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