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