QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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
20#include "qgsfeaturerequest.h"
21
23
24QString QgsAddIncrementalFieldAlgorithm::name() const
25{
26 return QStringLiteral( "addautoincrementalfield" );
27}
28
29QString QgsAddIncrementalFieldAlgorithm::displayName() const
30{
31 return QObject::tr( "Add autoincremental field" );
32}
33
34QString QgsAddIncrementalFieldAlgorithm::shortHelpString() const
35{
36 return QObject::tr( "This algorithm adds a new integer field to a vector layer, with a sequential value for each feature.\n\n"
37 "This field can be used as a unique ID for features in the layer. The new attribute "
38 "is not added to the input layer but a new layer is generated instead.\n\n"
39 "The initial starting value for the incremental series can be specified.\n\n"
40 "Specifying an optional modulus value will restart the count to START whenever the field value reaches the modulus value.\n\n"
41 "Optionally, grouping fields can be specified. If group fields are present, then the field value will "
42 "be reset for each combination of these group field values.\n\n"
43 "The sort order for features may be specified, if so, then the incremental field will respect "
44 "this sort order." );
45}
46
47QString QgsAddIncrementalFieldAlgorithm::shortDescription() const
48{
49 return QObject::tr( "Adds a new integer field to a vector layer, with a sequential value for each feature, "
50 "usable as a unique ID for features in the layer." );
51}
52
53QStringList QgsAddIncrementalFieldAlgorithm::tags() const
54{
55 return QObject::tr( "add,create,serial,primary,key,unique,fields" ).split( ',' );
56}
57
58QString QgsAddIncrementalFieldAlgorithm::group() const
59{
60 return QObject::tr( "Vector table" );
61}
62
63QString QgsAddIncrementalFieldAlgorithm::groupId() const
64{
65 return QStringLiteral( "vectortable" );
66}
67
68QString QgsAddIncrementalFieldAlgorithm::outputName() const
69{
70 return QObject::tr( "Incremented" );
71}
72
73QList<int> QgsAddIncrementalFieldAlgorithm::inputLayerTypes() const
74{
75 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector );
76}
77
78QgsAddIncrementalFieldAlgorithm *QgsAddIncrementalFieldAlgorithm::createInstance() const
79{
80 return new QgsAddIncrementalFieldAlgorithm();
81}
82
83Qgis::ProcessingFeatureSourceFlags QgsAddIncrementalFieldAlgorithm::sourceFlags() const
84{
86}
87
88void QgsAddIncrementalFieldAlgorithm::initParameters( const QVariantMap & )
89{
90 addParameter( new QgsProcessingParameterString( QStringLiteral( "FIELD_NAME" ), QObject::tr( "Field name" ), QStringLiteral( "AUTO" ) ) );
91 addParameter( new QgsProcessingParameterNumber( QStringLiteral( "START" ), QObject::tr( "Start values at" ), Qgis::ProcessingNumberParameterType::Integer, 0, true ) );
92 addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MODULUS" ), QObject::tr( "Modulus value" ), Qgis::ProcessingNumberParameterType::Integer, QVariant( 0 ), true ) );
93 addParameter( new QgsProcessingParameterField( QStringLiteral( "GROUP_FIELDS" ), QObject::tr( "Group values by" ), QVariant(), QStringLiteral( "INPUT" ), Qgis::ProcessingFieldParameterDataType::Any, true, true ) );
94
95 // sort params
96 auto sortExp = std::make_unique<QgsProcessingParameterExpression>( QStringLiteral( "SORT_EXPRESSION" ), QObject::tr( "Sort expression" ), QVariant(), QStringLiteral( "INPUT" ), true );
97 sortExp->setFlags( sortExp->flags() | Qgis::ProcessingParameterFlag::Advanced );
98 addParameter( sortExp.release() );
99 auto sortAscending = std::make_unique<QgsProcessingParameterBoolean>( QStringLiteral( "SORT_ASCENDING" ), QObject::tr( "Sort ascending" ), true );
100 sortAscending->setFlags( sortAscending->flags() | Qgis::ProcessingParameterFlag::Advanced );
101 addParameter( sortAscending.release() );
102 auto sortNullsFirst = std::make_unique<QgsProcessingParameterBoolean>( QStringLiteral( "SORT_NULLS_FIRST" ), QObject::tr( "Sort nulls first" ), false );
103 sortNullsFirst->setFlags( sortNullsFirst->flags() | Qgis::ProcessingParameterFlag::Advanced );
104 addParameter( sortNullsFirst.release() );
105}
106
107QgsFields QgsAddIncrementalFieldAlgorithm::outputFields( const QgsFields &inputFields ) const
108{
109 QgsFields outFields = inputFields;
110 outFields.append( QgsField( mFieldName, QMetaType::Type::LongLong ) );
111 mFields = outFields;
112 return outFields;
113}
114
115bool QgsAddIncrementalFieldAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
116{
117 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
118 mStartValue = parameterAsInt( parameters, QStringLiteral( "START" ), context );
119 mValue = mStartValue;
120 mModulusValue = parameterAsInt( parameters, QStringLiteral( "MODULUS" ), context );
121 mFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
122 mGroupedFieldNames = parameterAsStrings( parameters, QStringLiteral( "GROUP_FIELDS" ), context );
123
124 mSortExpressionString = parameterAsExpression( parameters, QStringLiteral( "SORT_EXPRESSION" ), context );
125 mSortAscending = parameterAsBoolean( parameters, QStringLiteral( "SORT_ASCENDING" ), context );
126 mSortNullsFirst = parameterAsBoolean( parameters, QStringLiteral( "SORT_NULLS_FIRST" ), context );
127
128 if ( source->fields().lookupField( mFieldName ) >= 0 )
129 {
130 throw QgsProcessingException( QObject::tr( "A field with the same name (%1) already exists" ).arg( mFieldName ) );
131 }
132
133 return true;
134}
135
136QgsFeatureRequest QgsAddIncrementalFieldAlgorithm::request() const
137{
138 if ( mSortExpressionString.isEmpty() )
139 return QgsFeatureRequest();
140
141 return QgsFeatureRequest().setOrderBy( QgsFeatureRequest::OrderBy() << QgsFeatureRequest::OrderByClause( mSortExpressionString, mSortAscending, mSortNullsFirst ) );
142}
143
144QgsFeatureList QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
145{
146 if ( !mGroupedFieldNames.empty() && mGroupedFields.empty() )
147 {
148 for ( const QString &field : std::as_const( mGroupedFieldNames ) )
149 {
150 int idx = mFields.lookupField( field );
151 if ( idx >= 0 )
152 mGroupedFields << idx;
153 }
154 }
155
156 QgsFeature f = feature;
157 QgsAttributes attributes = f.attributes();
158 if ( mGroupedFields.empty() )
159 {
160 attributes.append( mValue );
161 mValue++;
162 if ( mModulusValue != 0 && ( mValue % mModulusValue ) == 0 )
163 mValue = mStartValue;
164 }
165 else
166 {
167 QgsAttributes groupAttributes;
168 groupAttributes.reserve( mGroupedFields.size() );
169 for ( int index : std::as_const( mGroupedFields ) )
170 {
171 groupAttributes << f.attribute( index );
172 }
173 long long value = mGroupedValues.value( groupAttributes, mStartValue );
174 attributes.append( value );
175 value++;
176 if ( mModulusValue != 0 && ( value % mModulusValue ) == 0 )
177 value = mStartValue;
178 mGroupedValues[groupAttributes] = value;
179 }
180 f.setAttributes( attributes );
181 return QgsFeatureList() << f;
182}
183
184bool QgsAddIncrementalFieldAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
185{
186 Q_UNUSED( layer )
187 return false;
188}
189
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3539
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3711
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition qgis.h:3763
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3722
A vector of attributes.
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.
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:58
QgsAttributes attributes
Definition qgsfeature.h:67
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:73
Base class for all map layer types.
Definition qgsmaplayer.h:80
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
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