QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsalgorithmaddincrementalfield.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmaddincrementalfield.cpp
3  -----------------------------------
4  begin : April 2017
5  copyright : (C) 2017 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 #include "qgsfeaturerequest.h"
20 
22 
23 QString QgsAddIncrementalFieldAlgorithm::name() const
24 {
25  return QStringLiteral( "addautoincrementalfield" );
26 }
27 
28 QString QgsAddIncrementalFieldAlgorithm::displayName() const
29 {
30  return QObject::tr( "Add autoincremental field" );
31 }
32 
33 QString QgsAddIncrementalFieldAlgorithm::shortHelpString() const
34 {
35  return QObject::tr( "This algorithm adds a new integer field to a vector layer, with a sequential value for each feature.\n\n"
36  "This field can be used as a unique ID for features in the layer. The new attribute "
37  "is not added to the input layer but a new layer is generated instead.\n\n"
38  "The initial starting value for the incremental series can be specified.\n\n"
39  "Specifying an optional modulus value will restart the count to START whenever the field value reaches the modulus value.\n\n"
40  "Optionally, grouping fields can be specified. If group fields are present, then the field value will "
41  "be reset for each combination of these group field values.\n\n"
42  "The sort order for features may be specified, if so, then the incremental field will respect "
43  "this sort order." );
44 }
45 
46 QStringList QgsAddIncrementalFieldAlgorithm::tags() const
47 {
48  return QObject::tr( "add,create,serial,primary,key,unique,fields" ).split( ',' );
49 }
50 
51 QString QgsAddIncrementalFieldAlgorithm::group() const
52 {
53  return QObject::tr( "Vector table" );
54 }
55 
56 QString QgsAddIncrementalFieldAlgorithm::groupId() const
57 {
58  return QStringLiteral( "vectortable" );
59 }
60 
61 QString QgsAddIncrementalFieldAlgorithm::outputName() const
62 {
63  return QObject::tr( "Incremented" );
64 }
65 
66 QList<int> QgsAddIncrementalFieldAlgorithm::inputLayerTypes() const
67 {
68  return QList<int>() << QgsProcessing::TypeVector;
69 }
70 
71 QgsAddIncrementalFieldAlgorithm *QgsAddIncrementalFieldAlgorithm::createInstance() const
72 {
73  return new QgsAddIncrementalFieldAlgorithm();
74 }
75 
76 QgsProcessingFeatureSource::Flag QgsAddIncrementalFieldAlgorithm::sourceFlags() const
77 {
79 }
80 
81 void QgsAddIncrementalFieldAlgorithm::initParameters( const QVariantMap & )
82 {
83  addParameter( new QgsProcessingParameterString( QStringLiteral( "FIELD_NAME" ), QObject::tr( "Field name" ), QStringLiteral( "AUTO" ) ) );
84  addParameter( new QgsProcessingParameterNumber( QStringLiteral( "START" ), QObject::tr( "Start values at" ),
86  addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MODULUS" ), QObject::tr( "Modulus value" ),
87  QgsProcessingParameterNumber::Integer, QVariant( 0 ), true ) );
88  addParameter( new QgsProcessingParameterField( QStringLiteral( "GROUP_FIELDS" ), QObject::tr( "Group values by" ), QVariant(),
89  QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true, true ) );
90 
91  // sort params
92  std::unique_ptr< QgsProcessingParameterExpression > sortExp = std::make_unique< QgsProcessingParameterExpression >( QStringLiteral( "SORT_EXPRESSION" ), QObject::tr( "Sort expression" ), QVariant(), QStringLiteral( "INPUT" ), true );
93  sortExp->setFlags( sortExp->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
94  addParameter( sortExp.release() );
95  std::unique_ptr< QgsProcessingParameterBoolean > sortAscending = std::make_unique< QgsProcessingParameterBoolean >( QStringLiteral( "SORT_ASCENDING" ), QObject::tr( "Sort ascending" ), true );
96  sortAscending->setFlags( sortAscending->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
97  addParameter( sortAscending.release() );
98  std::unique_ptr< QgsProcessingParameterBoolean > sortNullsFirst = std::make_unique< QgsProcessingParameterBoolean >( QStringLiteral( "SORT_NULLS_FIRST" ), QObject::tr( "Sort nulls first" ), false );
99  sortNullsFirst->setFlags( sortNullsFirst->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
100  addParameter( sortNullsFirst.release() );
101 }
102 
103 QgsFields QgsAddIncrementalFieldAlgorithm::outputFields( const QgsFields &inputFields ) const
104 {
105  QgsFields outFields = inputFields;
106  outFields.append( QgsField( mFieldName, QVariant::LongLong ) );
107  mFields = outFields;
108  return outFields;
109 }
110 
111 bool QgsAddIncrementalFieldAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
112 {
113  mStartValue = parameterAsInt( parameters, QStringLiteral( "START" ), context );
114  mValue = mStartValue;
115  mModulusValue = parameterAsInt( parameters, QStringLiteral( "MODULUS" ), context );
116  mFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
117  mGroupedFieldNames = parameterAsFields( parameters, QStringLiteral( "GROUP_FIELDS" ), context );
118 
119  mSortExpressionString = parameterAsExpression( parameters, QStringLiteral( "SORT_EXPRESSION" ), context );
120  mSortAscending = parameterAsBoolean( parameters, QStringLiteral( "SORT_ASCENDING" ), context );
121  mSortNullsFirst = parameterAsBoolean( parameters, QStringLiteral( "SORT_NULLS_FIRST" ), context );
122 
123  return true;
124 }
125 
126 QgsFeatureRequest QgsAddIncrementalFieldAlgorithm::request() const
127 {
128  if ( mSortExpressionString.isEmpty() )
129  return QgsFeatureRequest();
130 
131  return QgsFeatureRequest().setOrderBy( QgsFeatureRequest::OrderBy() << QgsFeatureRequest::OrderByClause( mSortExpressionString, mSortAscending, mSortNullsFirst ) );
132 }
133 
134 QgsFeatureList QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
135 {
136  if ( !mGroupedFieldNames.empty() && mGroupedFields.empty() )
137  {
138  for ( const QString &field : std::as_const( mGroupedFieldNames ) )
139  {
140  int idx = mFields.lookupField( field );
141  if ( idx >= 0 )
142  mGroupedFields << idx;
143  }
144  }
145 
146  QgsFeature f = feature;
147  QgsAttributes attributes = f.attributes();
148  if ( mGroupedFields.empty() )
149  {
150  attributes.append( mValue );
151  mValue++;
152  if ( mModulusValue != 0 && ( mValue % mModulusValue ) == 0 )
153  mValue = mStartValue;
154  }
155  else
156  {
157  QgsAttributes groupAttributes;
158  groupAttributes.reserve( mGroupedFields.size() );
159  for ( int index : std::as_const( mGroupedFields ) )
160  {
161  groupAttributes << f.attribute( index );
162  }
163  long long value = mGroupedValues.value( groupAttributes, mStartValue );
164  attributes.append( value );
165  value++;
166  if ( mModulusValue != 0 && ( value % mModulusValue ) == 0 )
167  value = mStartValue;
168  mGroupedValues[ groupAttributes ] = value;
169  }
170  f.setAttributes( attributes );
171  return QgsFeatureList() << f;
172 }
173 
174 bool QgsAddIncrementalFieldAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
175 {
176  Q_UNUSED( layer )
177  return false;
178 }
179 
QgsFeatureRequest::OrderByClause
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Definition: qgsfeaturerequest.h:152
qgsfeaturerequest.h
QgsProcessingParameterNumber
A numeric parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2179
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:37
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsProcessingParameterDefinition::FlagAdvanced
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition: qgsprocessingparameters.h:451
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:584
field
const QgsField & field
Definition: qgsfield.h:463
QgsFields::append
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
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsProcessing::TypeVector
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
QgsProcessingParameterString
A string parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2647
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
qgsalgorithmaddincrementalfield.h
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:327
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsProcessingParameterNumber::Integer
@ Integer
Integer values.
Definition: qgsprocessingparameters.h:2186
QgsProcessingFeatureSource::Flag
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
Definition: qgsprocessingutils.h:582
QgsFeatureRequest::OrderBy
Represents a list of OrderByClauses, with the most important first and the least important last.
Definition: qgsfeaturerequest.h:264
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsFeatureRequest::setOrderBy
QgsFeatureRequest & setOrderBy(const OrderBy &orderBy)
Set a list of order by clauses.
Definition: qgsfeaturerequest.cpp:210
QgsAttributes
A vector of attributes. Mostly equal to QVector<QVariant>.
Definition: qgsattributes.h:57
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
QgsProcessingParameterField::Any
@ Any
Accepts any field.
Definition: qgsprocessingparameters.h:2947
QgsProcessingParameterField
A vector layer or feature source field parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2940
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50