mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-20 00:06:36 -04:00
200 lines
6.5 KiB
Python
200 lines
6.5 KiB
Python
"""
|
|
***************************************************************************
|
|
SelectByAttribute.py
|
|
---------------------
|
|
Date : May 2010
|
|
Copyright : (C) 2010 by Michael Minn
|
|
Email : pyqgis at michaelminn dot com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************
|
|
"""
|
|
|
|
__author__ = "Michael Minn"
|
|
__date__ = "May 2010"
|
|
__copyright__ = "(C) 2010, Michael Minn"
|
|
|
|
from qgis.PyQt.QtCore import QMetaType
|
|
from qgis.core import (
|
|
QgsExpression,
|
|
QgsVectorLayer,
|
|
QgsProcessing,
|
|
QgsProcessingException,
|
|
QgsProcessingAlgorithm,
|
|
QgsProcessingParameterVectorLayer,
|
|
QgsProcessingParameterField,
|
|
QgsProcessingParameterEnum,
|
|
QgsProcessingParameterString,
|
|
QgsProcessingOutputVectorLayer,
|
|
)
|
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
|
|
|
|
|
class SelectByAttribute(QgisAlgorithm):
|
|
INPUT = "INPUT"
|
|
FIELD = "FIELD"
|
|
OPERATOR = "OPERATOR"
|
|
VALUE = "VALUE"
|
|
METHOD = "METHOD"
|
|
OUTPUT = "OUTPUT"
|
|
|
|
OPERATORS = [
|
|
"=",
|
|
"<>",
|
|
">",
|
|
">=",
|
|
"<",
|
|
"<=",
|
|
"begins with",
|
|
"contains",
|
|
"is null",
|
|
"is not null",
|
|
"does not contain",
|
|
]
|
|
STRING_OPERATORS = ["begins with", "contains", "does not contain"]
|
|
|
|
def tags(self):
|
|
return self.tr("select,attribute,value,contains,null,field").split(",")
|
|
|
|
def group(self):
|
|
return self.tr("Vector selection")
|
|
|
|
def groupId(self):
|
|
return "vectorselection"
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def flags(self):
|
|
return (
|
|
super().flags()
|
|
| QgsProcessingAlgorithm.Flag.FlagNoThreading
|
|
| QgsProcessingAlgorithm.Flag.FlagNotAvailableInStandaloneTool
|
|
)
|
|
|
|
def initAlgorithm(self, config=None):
|
|
self.operators = [
|
|
"=",
|
|
"≠",
|
|
">",
|
|
"≥",
|
|
"<",
|
|
"≤",
|
|
self.tr("begins with"),
|
|
self.tr("contains"),
|
|
self.tr("is null"),
|
|
self.tr("is not null"),
|
|
self.tr("does not contain"),
|
|
]
|
|
|
|
self.methods = [
|
|
self.tr("creating new selection"),
|
|
self.tr("adding to current selection"),
|
|
self.tr("removing from current selection"),
|
|
self.tr("selecting within current selection"),
|
|
]
|
|
|
|
self.addParameter(
|
|
QgsProcessingParameterVectorLayer(
|
|
self.INPUT,
|
|
self.tr("Input layer"),
|
|
types=[QgsProcessing.SourceType.TypeVector],
|
|
)
|
|
)
|
|
self.addParameter(
|
|
QgsProcessingParameterField(
|
|
self.FIELD,
|
|
self.tr("Selection attribute"),
|
|
parentLayerParameterName=self.INPUT,
|
|
)
|
|
)
|
|
self.addParameter(
|
|
QgsProcessingParameterEnum(
|
|
self.OPERATOR, self.tr("Operator"), self.operators, defaultValue=0
|
|
)
|
|
)
|
|
self.addParameter(
|
|
QgsProcessingParameterString(self.VALUE, self.tr("Value"), optional=True)
|
|
)
|
|
self.addParameter(
|
|
QgsProcessingParameterEnum(
|
|
self.METHOD,
|
|
self.tr("Modify current selection by"),
|
|
self.methods,
|
|
defaultValue=0,
|
|
)
|
|
)
|
|
|
|
self.addOutput(
|
|
QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Selected (attribute)"))
|
|
)
|
|
|
|
def name(self):
|
|
return "selectbyattribute"
|
|
|
|
def displayName(self):
|
|
return self.tr("Select by attribute")
|
|
|
|
def processAlgorithm(self, parameters, context, feedback):
|
|
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
|
|
|
fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
|
operator = self.OPERATORS[
|
|
self.parameterAsEnum(parameters, self.OPERATOR, context)
|
|
]
|
|
value = self.parameterAsString(parameters, self.VALUE, context)
|
|
|
|
fields = layer.fields()
|
|
|
|
idx = fields.lookupField(fieldName)
|
|
if idx < 0:
|
|
raise QgsProcessingException(
|
|
self.tr("Field '{}' was not found in layer").format(fieldName)
|
|
)
|
|
|
|
fieldType = fields[idx].type()
|
|
|
|
if fieldType != QMetaType.Type.QString and operator in self.STRING_OPERATORS:
|
|
op = "".join('"%s", ' % o for o in self.STRING_OPERATORS)
|
|
raise QgsProcessingException(
|
|
self.tr("Operators {0} can be used only with string fields.").format(op)
|
|
)
|
|
|
|
field_ref = QgsExpression.quotedColumnRef(fieldName)
|
|
quoted_val = QgsExpression.quotedValue(value)
|
|
if operator == "is null":
|
|
expression_string = f"{field_ref} IS NULL"
|
|
elif operator == "is not null":
|
|
expression_string = f"{field_ref} IS NOT NULL"
|
|
elif operator == "begins with":
|
|
expression_string = f"{field_ref} LIKE '{value}%'"
|
|
elif operator == "contains":
|
|
expression_string = f"{field_ref} LIKE '%{value}%'"
|
|
elif operator == "does not contain":
|
|
expression_string = f"{field_ref} NOT LIKE '%{value}%'"
|
|
else:
|
|
expression_string = f"{field_ref} {operator} {quoted_val}"
|
|
|
|
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
|
if method == 0:
|
|
behavior = QgsVectorLayer.SelectBehavior.SetSelection
|
|
elif method == 1:
|
|
behavior = QgsVectorLayer.SelectBehavior.AddToSelection
|
|
elif method == 2:
|
|
behavior = QgsVectorLayer.SelectBehavior.RemoveFromSelection
|
|
elif method == 3:
|
|
behavior = QgsVectorLayer.SelectBehavior.IntersectSelection
|
|
|
|
expression = QgsExpression(expression_string)
|
|
if expression.hasParserError():
|
|
raise QgsProcessingException(expression.parserErrorString())
|
|
|
|
layer.selectByExpression(expression_string, behavior)
|
|
|
|
return {self.OUTPUT: parameters[self.INPUT]}
|