2727
2828from qgis .PyQt .QtCore import QVariant
2929from qgis .core import (QgsExpression ,
30+ QgsVectorLayer ,
3031 QgsProcessing ,
3132 QgsProcessingException ,
3233 QgsProcessingAlgorithm ,
@@ -43,6 +44,7 @@ class SelectByAttribute(QgisAlgorithm):
4344 FIELD = 'FIELD'
4445 OPERATOR = 'OPERATOR'
4546 VALUE = 'VALUE'
47+ METHOD = 'METHOD'
4648 OUTPUT = 'OUTPUT'
4749
4850 OPERATORS = ['=' ,
@@ -77,26 +79,38 @@ def flags(self):
7779 return super ().flags () | QgsProcessingAlgorithm .FlagNoThreading
7880
7981 def initAlgorithm (self , config = None ):
80- self .i18n_operators = ['=' ,
81- '!=' ,
82- '>' ,
83- '>=' ,
84- '<' ,
85- '<=' ,
86- self .tr ('begins with' ),
87- self .tr ('contains' ),
88- self .tr ('is null' ),
89- self .tr ('is not null' ),
90- self .tr ('does not contain' )
91- ]
92-
93- self .addParameter (QgsProcessingParameterVectorLayer (self .INPUT , self .tr ('Input layer' ), types = [QgsProcessing .TypeVector ]))
94-
82+ self .operators = ['=' ,
83+ '!=' ,
84+ '>' ,
85+ '>=' ,
86+ '<' ,
87+ '<=' ,
88+ self .tr ('begins with' ),
89+ self .tr ('contains' ),
90+ self .tr ('is null' ),
91+ self .tr ('is not null' ),
92+ self .tr ('does not contain' )
93+ ]
94+
95+ self .methods = [self .tr ('creating new selection' ),
96+ self .tr ('adding to current selection' ),
97+ self .tr ('removing from current selection' ),
98+ self .tr ('selecting within current selection' )]
99+
100+ self .addParameter (QgsProcessingParameterVectorLayer (self .INPUT ,
101+ self .tr ('Input layer' ),
102+ types = [QgsProcessing .TypeVector ]))
95103 self .addParameter (QgsProcessingParameterField (self .FIELD ,
96- self .tr ('Selection attribute' ), parentLayerParameterName = self .INPUT ))
104+ self .tr ('Selection attribute' ),
105+ parentLayerParameterName = self .INPUT ))
97106 self .addParameter (QgsProcessingParameterEnum (self .OPERATOR ,
98- self .tr ('Operator' ), self .i18n_operators ))
99- self .addParameter (QgsProcessingParameterString (self .VALUE , self .tr ('Value' )))
107+ self .tr ('Operator' ), self .operators ))
108+ self .addParameter (QgsProcessingParameterString (self .VALUE ,
109+ self .tr ('Value' )))
110+ self .addParameter (QgsProcessingParameterEnum (self .METHOD ,
111+ self .tr ('Modify current selection by' ),
112+ self .methods ,
113+ 0 ))
100114
101115 self .addOutput (QgsProcessingOutputVectorLayer (self .OUTPUT , self .tr ('Selected (attribute)' )))
102116
@@ -130,17 +144,28 @@ def processAlgorithm(self, parameters, context, feedback):
130144 elif operator == 'is not null' :
131145 expression_string = '{} IS NOT NULL' .format (field_ref )
132146 elif operator == 'begins with' :
133- expression_string = """%s LIKE '%s%%'""" % (field_ref , value )
147+ expression_string = "{} LIKE '{}%'" . format (field_ref , value )
134148 elif operator == 'contains' :
135- expression_string = """%s LIKE '%%%s%%'""" % (field_ref , value )
149+ expression_string = "{} LIKE '%{}%'" . format (field_ref , value )
136150 elif operator == 'does not contain' :
137- expression_string = """%s NOT LIKE '%%%s%%'""" % (field_ref , value )
151+ expression_string = "{} NOT LIKE '%{}%'" . format (field_ref , value )
138152 else :
139153 expression_string = '{} {} {}' .format (field_ref , operator , quoted_val )
140154
155+ method = self .parameterAsEnum (parameters , self .METHOD , context )
156+ if method == 0 :
157+ behavior = QgsVectorLayer .SetSelection
158+ elif method == 1 :
159+ behavior = QgsVectorLayer .AddToSelection
160+ elif method == 2 :
161+ behavior = QgsVectorLayer .RemoveFromSelection
162+ elif method == 3 :
163+ behavior = QgsVectorLayer .IntersectSelection
164+
141165 expression = QgsExpression (expression_string )
142166 if expression .hasParserError ():
143167 raise QgsProcessingException (expression .parserErrorString ())
144168
145- layer .selectByExpression (expression_string )
169+ layer .selectByExpression (expression_string , behavior )
170+
146171 return {self .OUTPUT : parameters [self .INPUT ]}
0 commit comments