QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsalgorithmdropfields.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmdropfields.cpp
3  ---------------------------------
4  begin : November 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 
18 #include "qgsalgorithmdropfields.h"
19 
21 
22 QgsProcessingAlgorithm::Flags QgsDropTableFieldsAlgorithm::flags() const
23 {
24  return QgsProcessingFeatureBasedAlgorithm::flags() & ~QgsProcessingAlgorithm::FlagSupportsInPlaceEdits;
25 }
26 
27 QString QgsDropTableFieldsAlgorithm::name() const
28 {
29  return QStringLiteral( "deletecolumn" );
30 }
31 
32 QString QgsDropTableFieldsAlgorithm::displayName() const
33 {
34  return QObject::tr( "Drop field(s)" );
35 }
36 
37 QString QgsDropTableFieldsAlgorithm::shortHelpString() const
38 {
39  return QObject::tr( "This algorithm takes a vector layer and generates a new one that has the exact same content but without the selected columns." );
40 }
41 
42 QString QgsDropTableFieldsAlgorithm::shortDescription() const
43 {
44  return QObject::tr( "Deletes fields from a vector layer." );
45 }
46 
47 QStringList QgsDropTableFieldsAlgorithm::tags() const
48 {
49  return QObject::tr( "drop,delete,remove,fields,columns,attributes" ).split( ',' );
50 }
51 
52 QString QgsDropTableFieldsAlgorithm::group() const
53 {
54  return QObject::tr( "Vector table" );
55 }
56 
57 QString QgsDropTableFieldsAlgorithm::groupId() const
58 {
59  return QStringLiteral( "vectortable" );
60 }
61 
62 QString QgsDropTableFieldsAlgorithm::outputName() const
63 {
64  return QObject::tr( "Remaining fields" );
65 }
66 
67 QList<int> QgsDropTableFieldsAlgorithm::inputLayerTypes() const
68 {
69  return QList<int>() << QgsProcessing::TypeVector;
70 }
71 
72 QgsProcessingFeatureSource::Flag QgsDropTableFieldsAlgorithm::sourceFlags() const
73 {
75 }
76 
77 QgsDropTableFieldsAlgorithm *QgsDropTableFieldsAlgorithm::createInstance() const
78 {
79  return new QgsDropTableFieldsAlgorithm();
80 }
81 
82 void QgsDropTableFieldsAlgorithm::initParameters( const QVariantMap & )
83 {
84  addParameter( new QgsProcessingParameterField( QStringLiteral( "COLUMN" ), QObject::tr( "Fields to drop" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true ) );
85 }
86 
87 QgsFields QgsDropTableFieldsAlgorithm::outputFields( const QgsFields &inputFields ) const
88 {
89  QgsFields outFields = inputFields;
90  // loop through twice - first we need to build up a list of original attribute indices
91  for ( const QString &field : mFieldsToDelete )
92  {
93  const int index = inputFields.lookupField( field );
94  if ( index >= 0 )
95  mFieldIndices.append( index );
96  }
97 
98  // important - make sure we remove from the end so we aren't changing used indices as we go
99  std::sort( mFieldIndices.begin(), mFieldIndices.end(), std::greater< int >() );
100 
101  // this second time we make a cleaned version of the fields
102  for ( const int index : std::as_const( mFieldIndices ) )
103  {
104  outFields.remove( index );
105  }
106  return outFields;
107 }
108 
109 bool QgsDropTableFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
110 {
111  mFieldsToDelete = parameterAsFields( parameters, QStringLiteral( "COLUMN" ), context );
112 
113  if ( feedback )
114  {
115  std::unique_ptr< QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
116  if ( source )
117  {
118  for ( const QString &field : std::as_const( mFieldsToDelete ) )
119  {
120  const int index = source->fields().lookupField( field );
121  if ( index < 0 )
122  {
123  feedback->pushInfo( QObject::tr( "Field “%1” does not exist in input layer " ).arg( field ) );
124  }
125  }
126  }
127  }
128 
129  return true;
130 }
131 
132 QgsFeatureList QgsDropTableFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
133 {
134  QgsFeature f = feature;
135  QgsAttributes attributes = f.attributes();
136  for ( const int index : mFieldIndices )
137  {
138  attributes.remove( index );
139  }
140  f.setAttributes( attributes );
141  return QgsFeatureList() << f;
142 }
143 
144 bool QgsDropTableFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
145 {
146  Q_UNUSED( layer )
147  return false;
148 }
149 
150 
151 
152 //
153 // QgsRetainTableFieldsAlgorithm
154 //
155 
156 QgsProcessingAlgorithm::Flags QgsRetainTableFieldsAlgorithm::flags() const
157 {
158  return QgsProcessingFeatureBasedAlgorithm::flags() & ~QgsProcessingAlgorithm::FlagSupportsInPlaceEdits;
159 }
160 
161 QString QgsRetainTableFieldsAlgorithm::name() const
162 {
163  return QStringLiteral( "retainfields" );
164 }
165 
166 QString QgsRetainTableFieldsAlgorithm::displayName() const
167 {
168  return QObject::tr( "Retain fields" );
169 }
170 
171 QString QgsRetainTableFieldsAlgorithm::shortHelpString() const
172 {
173  return QObject::tr( "This algorithm takes a vector layer and generates a new one that retains only the selected fields. All other fields will be dropped." );
174 }
175 
176 QString QgsRetainTableFieldsAlgorithm::shortDescription() const
177 {
178  return QObject::tr( "Retains selected fields from a vector layer." );
179 }
180 
181 QStringList QgsRetainTableFieldsAlgorithm::tags() const
182 {
183  return QObject::tr( "drop,delete,remove,retain,keep,other,fields,columns,attributes" ).split( ',' );
184 }
185 
186 QString QgsRetainTableFieldsAlgorithm::group() const
187 {
188  return QObject::tr( "Vector table" );
189 }
190 
191 QString QgsRetainTableFieldsAlgorithm::groupId() const
192 {
193  return QStringLiteral( "vectortable" );
194 }
195 
196 QString QgsRetainTableFieldsAlgorithm::outputName() const
197 {
198  return QObject::tr( "Retained fields" );
199 }
200 
201 QList<int> QgsRetainTableFieldsAlgorithm::inputLayerTypes() const
202 {
203  return QList<int>() << QgsProcessing::TypeVector;
204 }
205 
206 QgsProcessingFeatureSource::Flag QgsRetainTableFieldsAlgorithm::sourceFlags() const
207 {
209 }
210 
211 QgsRetainTableFieldsAlgorithm *QgsRetainTableFieldsAlgorithm::createInstance() const
212 {
213  return new QgsRetainTableFieldsAlgorithm();
214 }
215 
216 void QgsRetainTableFieldsAlgorithm::initParameters( const QVariantMap & )
217 {
218  addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELDS" ), QObject::tr( "Fields to retain" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true ) );
219 }
220 
221 QgsFields QgsRetainTableFieldsAlgorithm::outputFields( const QgsFields &inputFields ) const
222 {
223  // loop through twice - first we need to build up a list of original attribute indices
224  for ( const QString &field : mFieldsToRetain )
225  {
226  const int index = inputFields.lookupField( field );
227  if ( index >= 0 )
228  mFieldIndices.append( index );
229  }
230 
231  std::sort( mFieldIndices.begin(), mFieldIndices.end() );
232 
233  // this second time we make a cleaned version of the fields
234  QgsFields outFields;
235  for ( const int index : std::as_const( mFieldIndices ) )
236  {
237  outFields.append( inputFields.at( index ) );
238  }
239  return outFields;
240 }
241 
242 bool QgsRetainTableFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
243 {
244  mFieldsToRetain = parameterAsFields( parameters, QStringLiteral( "FIELDS" ), context );
245 
246  if ( feedback )
247  {
248  std::unique_ptr< QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
249  if ( source )
250  {
251  for ( const QString &field : std::as_const( mFieldsToRetain ) )
252  {
253  const int index = source->fields().lookupField( field );
254  if ( index < 0 )
255  {
256  feedback->pushInfo( QObject::tr( "Field “%1” does not exist in input layer " ).arg( field ) );
257  }
258  }
259  }
260  }
261 
262  return true;
263 }
264 
265 QgsFeatureList QgsRetainTableFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
266 {
267  QgsFeature f = feature;
268  const QgsAttributes inputAttributes = f.attributes();
269  QgsAttributes outputAttributes;
270  outputAttributes.reserve( mFieldIndices.count() );
271  for ( const int index : mFieldIndices )
272  {
273  outputAttributes.append( inputAttributes.at( index ) );
274  }
275  f.setAttributes( outputAttributes );
276  return QgsFeatureList() << f;
277 }
278 
279 bool QgsRetainTableFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
280 {
281  Q_UNUSED( layer )
282  return false;
283 }
284 
A vector of attributes.
Definition: qgsattributes.h:58
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:135
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
void remove(int fieldIdx)
Removes the field with the given index.
Definition: qgsfields.cpp:101
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
Base class for all map layer types.
Definition: qgsmaplayer.h:70
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
QgsProcessingAlgorithm::Flags flags() const override
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
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.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
A vector layer or feature source field parameter for processing algorithms.
@ 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:736
const QgsField & field
Definition: qgsfield.h:463