Skip to content

Commit

Permalink
Use expression filter request for SelectByAttribute
Browse files Browse the repository at this point in the history
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 13, 2015
1 parent fd9f0b5 commit 7c8177e
Showing 1 changed file with 7 additions and 13 deletions.
20 changes: 7 additions & 13 deletions python/plugins/processing/algs/qgis/SelectByAttribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.