QGIS API Documentation 4.1.0-Master (376402f9aeb)
Loading...
Searching...
No Matches
qgsalgorithmselectbyattribute.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmselectbyattribute.h
3 ---------------------
4 begin : April 2026
5 copyright : (C) 2026 by Alexander Bruy
6 email : alexander dot bruy 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 "qgsvectorlayer.h"
21
22#include <QString>
23
24using namespace Qt::StringLiterals;
25
27
28QString QgsSelectByAttributeAlgorithm::name() const
29{
30 return u"selectbyattribute"_s;
31}
32
33QString QgsSelectByAttributeAlgorithm::displayName() const
34{
35 return QObject::tr( "Select by attribute" );
36}
37
38QStringList QgsSelectByAttributeAlgorithm::tags() const
39{
40 return QObject::tr( "extract,filter,attribute,value,contains,null,field" ).split( ',' );
41}
42
43QString QgsSelectByAttributeAlgorithm::group() const
44{
45 return QObject::tr( "Vector selection" );
46}
47
48QString QgsSelectByAttributeAlgorithm::groupId() const
49{
50 return u"vectorselection"_s;
51}
52
53QString QgsSelectByAttributeAlgorithm::shortHelpString() const
54{
55 return QObject::tr(
56 "This algorithm creates a selection in a vector layer.\n\n"
57 "The criteria for selected features is defined based on the values of an attribute from the input layer."
58 );
59}
60
61QString QgsSelectByAttributeAlgorithm::shortDescription() const
62{
63 return QObject::tr( "Selects features from a vector layer based on an attribute from the layer." );
64}
65
66QgsSelectByAttributeAlgorithm *QgsSelectByAttributeAlgorithm::createInstance() const
67{
68 return new QgsSelectByAttributeAlgorithm();
69}
70
71void QgsSelectByAttributeAlgorithm::initAlgorithm( const QVariantMap & )
72{
73 addParameter( new QgsProcessingParameterVectorLayer( u"INPUT"_s, QObject::tr( "Input layer" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector ) ) );
74 addParameter( new QgsProcessingParameterField( u"FIELD"_s, QObject::tr( "Selection attribute" ), QVariant(), u"INPUT"_s ) );
75 addParameter( new QgsProcessingParameterEnum(
76 u"OPERATOR"_s,
77 QObject::tr( "Operator" ),
78 QStringList()
79 << QObject::tr( "=" )
80 << QObject::tr( "≠" )
81 << QObject::tr( ">" )
82 << QObject::tr( "≥" )
83 << QObject::tr( "<" )
84 << QObject::tr( "≤" )
85 << QObject::tr( "begins with" )
86 << QObject::tr( "contains" )
87 << QObject::tr( "is null" )
88 << QObject::tr( "is not null" )
89 << QObject::tr( "does not contain" ),
90 false,
91 0
92 ) );
93 addParameter( new QgsProcessingParameterString( u"VALUE"_s, QObject::tr( "Value" ), QVariant(), false, true ) );
94 addParameter( new QgsProcessingParameterEnum(
95 u"SELECTION_METHOD"_s,
96 QObject::tr( "Modify current selection by" ),
97 QStringList() << QObject::tr( "creating new selection" ) << QObject::tr( "adding to current selection" ) << QObject::tr( "selecting within current selection" ) << QObject::tr( "removing from current selection" ),
98 false,
99 0
100 ) );
101
102 // backwards compatibility parameters
103 // TODO QGIS 5: remove compatibility parameters and their logic
104 auto methodParam = std::make_unique<QgsProcessingParameterEnum>(
105 u"METHOD"_s,
106 QObject::tr( "Modify current selection by" ),
107 QStringList() << QObject::tr( "creating new selection" ) << QObject::tr( "adding to current selection" ) << QObject::tr( "removing from current selection" ) << QObject::tr( "selecting within current selection" ),
108 false,
109 0
110 );
111 methodParam->setFlags( methodParam->flags() | Qgis::ProcessingParameterFlag::Hidden );
112 addParameter( std::move( methodParam ) );
113
114 addOutput( new QgsProcessingOutputVectorLayer( u"OUTPUT"_s, QObject::tr( "Selected (attribute)" ) ) );
115}
116
117bool QgsSelectByAttributeAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
118{
119 QgsVectorLayer *layer = parameterAsVectorLayer( parameters, u"INPUT"_s, context );
120 if ( !layer )
121 {
122 throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
123 }
124
125 const QString fieldName = parameterAsString( parameters, u"FIELD"_s, context );
126 const Operation op = static_cast<Operation>( parameterAsEnum( parameters, u"OPERATOR"_s, context ) );
127 const QString value = parameterAsString( parameters, u"VALUE"_s, context );
128 Qgis::SelectBehavior method = static_cast<Qgis::SelectBehavior>( parameterAsEnum( parameters, u"SELECTION_METHOD"_s, context ) );
129
130 // handle backwards compatibility parameter
131 if ( parameters.value( u"METHOD"_s ).isValid() )
132 {
133 method = static_cast<Qgis::SelectBehavior>( parameterAsEnum( parameters, u"METHOD"_s, context ) );
135 {
137 }
139 {
141 }
142 }
143
144 mLayerId = layer->id();
145
146 const int idx = layer->fields().lookupField( fieldName );
147 if ( idx < 0 )
148 {
149 throw QgsProcessingException( QObject::tr( "Field '%1' was not found in INPUT layer." ).arg( fieldName ) );
150 }
151
152 const QMetaType::Type fieldType = layer->fields().at( idx ).type();
153 if ( fieldType != QMetaType::Type::QString && ( op == BeginsWith || op == Contains || op == DoesNotContain ) )
154 {
155 QString method;
156 switch ( op )
157 {
158 case BeginsWith:
159 method = QObject::tr( "begins with" );
160 break;
161 case Contains:
162 method = QObject::tr( "contains" );
163 break;
164 case DoesNotContain:
165 method = QObject::tr( "does not contain" );
166 break;
167
168 default:
169 break;
170 }
171
172 throw QgsProcessingException( QObject::tr( "Operator '%1' can be used only with string fields." ).arg( method ) );
173 }
174
175 const QString fieldRef = QgsExpression::quotedColumnRef( fieldName );
176 const QString quotedVal = QgsExpression::quotedValue( value );
177 QString expr;
178 switch ( op )
179 {
180 case Equals:
181 expr = u"%1 = %2"_s.arg( fieldRef, quotedVal );
182 break;
183 case NotEquals:
184 expr = u"%1 <> %2"_s.arg( fieldRef, quotedVal );
185 break;
186 case GreaterThan:
187 expr = u"%1 > %2"_s.arg( fieldRef, quotedVal );
188 break;
189 case GreaterThanEqualTo:
190 expr = u"%1 >= %2"_s.arg( fieldRef, quotedVal );
191 break;
192 case LessThan:
193 expr = u"%1 < %2"_s.arg( fieldRef, quotedVal );
194 break;
195 case LessThanEqualTo:
196 expr = u"%1 <= %2"_s.arg( fieldRef, quotedVal );
197 break;
198 case BeginsWith:
199 expr = u"%1 LIKE '%2%'"_s.arg( fieldRef, value );
200 break;
201 case Contains:
202 expr = u"%1 LIKE '%%2%'"_s.arg( fieldRef, value );
203 break;
204 case IsNull:
205 expr = u"%1 IS NULL"_s.arg( fieldRef );
206 break;
207 case IsNotNull:
208 expr = u"%1 IS NOT NULL"_s.arg( fieldRef );
209 break;
210 case DoesNotContain:
211 expr = u"%1 NOT LIKE '%%2%'"_s.arg( fieldRef, value );
212 break;
213 }
214
215 QgsExpression expression( expr );
216 if ( expression.hasParserError() )
217 {
218 throw QgsProcessingException( expression.parserErrorString() );
219 }
220
221 QgsExpressionContext expressionContext = createExpressionContext( parameters, context );
222 expressionContext.appendScope( layer->createExpressionContextScope() );
223
224 layer->selectByExpression( expression, method, &expressionContext );
225
226 return true;
227}
228
229QVariantMap QgsSelectByAttributeAlgorithm::processAlgorithm( const QVariantMap &, QgsProcessingContext &, QgsProcessingFeedback * )
230{
231 QVariantMap results;
232 results.insert( u"OUTPUT"_s, mLayerId );
233 return results;
234}
235
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3720
@ Hidden
Parameter is hidden and should not be shown to users.
Definition qgis.h:3948
SelectBehavior
Specifies how a selection should be applied.
Definition qgis.h:1891
@ IntersectSelection
Modify current selection to include only select features which match.
Definition qgis.h:1894
@ RemoveFromSelection
Remove from current selection.
Definition qgis.h:1895
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
QMetaType::Type type
Definition qgsfield.h:63
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QString id
Definition qgsmaplayer.h:86
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 output for processing algorithms.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A vector layer or feature source field parameter for processing algorithms.
A string parameter for processing algorithms.
A vector layer (with or without geometry) parameter for processing algorithms.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE void selectByExpression(const QString &expression, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context=nullptr)
Selects matching features using an expression.
QgsExpressionContextScope * createExpressionContextScope() const final
This method needs to be reimplemented in all classes which implement this interface and return an exp...