QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
23QString QgsAddIncrementalFieldAlgorithm::name() const
24{
25 return QStringLiteral( "addautoincrementalfield" );
26}
27
28QString QgsAddIncrementalFieldAlgorithm::displayName() const
29{
30 return QObject::tr( "Add autoincremental field" );
31}
32
33QString 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
46QStringList QgsAddIncrementalFieldAlgorithm::tags() const
47{
48 return QObject::tr( "add,create,serial,primary,key,unique,fields" ).split( ',' );
49}
50
51QString QgsAddIncrementalFieldAlgorithm::group() const
52{
53 return QObject::tr( "Vector table" );
54}
55
56QString QgsAddIncrementalFieldAlgorithm::groupId() const
57{
58 return QStringLiteral( "vectortable" );
59}
60
61QString QgsAddIncrementalFieldAlgorithm::outputName() const
62{
63 return QObject::tr( "Incremented" );
64}
65
66QList<int> QgsAddIncrementalFieldAlgorithm::inputLayerTypes() const
67{
68 return QList<int>() << static_cast< int >( Qgis::ProcessingSourceType::Vector );
69}
70
71QgsAddIncrementalFieldAlgorithm *QgsAddIncrementalFieldAlgorithm::createInstance() const
72{
73 return new QgsAddIncrementalFieldAlgorithm();
74}
75
76Qgis::ProcessingFeatureSourceFlags QgsAddIncrementalFieldAlgorithm::sourceFlags() const
77{
79}
80
81void 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 Qgis::ProcessingNumberParameterType::Integer, QVariant( 0 ), true ) );
88 addParameter( new QgsProcessingParameterField( QStringLiteral( "GROUP_FIELDS" ), QObject::tr( "Group values by" ), QVariant(),
89 QStringLiteral( "INPUT" ), Qgis::ProcessingFieldParameterDataType::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() | Qgis::ProcessingParameterFlag::Advanced );
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() | Qgis::ProcessingParameterFlag::Advanced );
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() | Qgis::ProcessingParameterFlag::Advanced );
100 addParameter( sortNullsFirst.release() );
101}
102
103QgsFields 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
111bool 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 = parameterAsStrings( 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
126QgsFeatureRequest 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
134QgsFeatureList 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
174bool QgsAddIncrementalFieldAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
175{
176 Q_UNUSED( layer )
177 return false;
178}
179
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition: qgis.h:3011
A vector of attributes.
Definition: qgsattributes.h:59
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Represents a list of OrderByClauses, with the most important first and the least important last.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setOrderBy(const OrderBy &orderBy)
Set a list of order by clauses.
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:160
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:335
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
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
Base class for all map layer types.
Definition: qgsmaplayer.h:75
Contains information about the context in which a processing algorithm is executed.
Base class for providing feedback from a processing algorithm.
A vector layer or feature source field parameter for processing algorithms.
A numeric parameter for processing algorithms.
A string parameter for processing algorithms.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917