Skip to content
Permalink
Browse files

Use expression filter request for SelectByAttribute

Makes SelectByAttribute orders of magnitude faster for providers which
support compiled expressions (eg Postgres), also allows algorithm
to take advantage of database indexes created on attribute.

For a 4 million point PostGIS layer (with an index on attribute)
BEFORE: cancelled after 20 mins
AFTER: ~2 seconds
  • Loading branch information
nyalldawson committed Nov 12, 2015
1 parent fd9f0b5 commit 7c8177e01a45fa3178991f5b3b033f3ae6faea78
Showing with 7 additions and 13 deletions.
  1. +7 −13 python/plugins/processing/algs/qgis/SelectByAttribute.py
@@ -26,7 +26,7 @@
__revision__ = '$Format:%H$'

from PyQt4.QtCore import QVariant
from qgis.core import QgsExpression
from qgis.core import QgsExpression, QgsFeatureRequest
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector
@@ -115,18 +115,12 @@ def processAlgorithm(self, progress):
raise GeoAlgorithmExecutionException(
self.tr('Unsupported field type "%s"' % fields[idx].typeName()))

expression = QgsExpression(expr)
expression.prepare(fields)

features = vector.features(layer)

selected = []
count = len(features)
total = 100.0 / float(count)
for count, f in enumerate(features):
if expression.evaluate(f, fields):
selected.append(f.id())
progress.setPercentage(int(count * total))
qExp = QgsExpression(expr)
if not qExp.hasParserError():
qReq = QgsFeatureRequest(qExp)
else:
raise GeoAlgorithmExecutionException(qExp.parserErrorString())
selected = [f.id() for f in layer.getFeatures(qReq)]

layer.setSelectedFeatures(selected)
self.setOutputValue(self.OUTPUT, fileName)

0 comments on commit 7c8177e

Please sign in to comment.
You can’t perform that action at this time.