Skip to content

Commit 1e3661c

Browse files
committedJun 1, 2018
Added QgsSpatialIndex to the python provider
1 parent abcad01 commit 1e3661c

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed
 

‎tests/src/python/provider_python.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
QgsProviderRegistry,
4343
QgsProviderMetadata,
4444
QgsGeometryEngine,
45+
QgsSpatialIndex,
4546
)
4647

4748
from qgis.PyQt.QtCore import QVariant
@@ -65,6 +66,9 @@ def __init__(self, source, request):
6566
else:
6667
self._select_rect_engine = None
6768
self._select_rect_geom = None
69+
self._feature_id_list = None
70+
if self._filter_rect is not None and self._source._provider._spatialindex is not None:
71+
self._feature_id_list = self._source._provider._spatialindex.intersects(self._filter_rect)
6872

6973
def fetchFeature(self, f):
7074
"""fetch next feature, return true on success"""
@@ -77,6 +81,21 @@ def fetchFeature(self, f):
7781
while not found:
7882
_f = self._source._features[list(self._source._features.keys())[self._index]]
7983
self._index += 1
84+
85+
if self._feature_id_list is not None and f.id() not in self._feature_id_list:
86+
continue
87+
88+
if not self._filter_rect.isNull():
89+
if not _f.hasGeometry():
90+
continue
91+
if self._request.flags() & QgsFeatureRequest.ExactIntersect:
92+
# do exact check in case we're doing intersection
93+
if not self._select_rect_engine.intersects(_f.geometry().constGet()):
94+
continue
95+
else:
96+
if not _f.geometry().boundingBox().intersects(self._filter_rect):
97+
continue
98+
8099
self._source._expression_context.setFeature(_f)
81100
if self._request.filterType() == QgsFeatureRequest.FilterExpression:
82101
if not self._request.filterExpression().evaluate(self._source._expression_context):
@@ -90,16 +109,6 @@ def fetchFeature(self, f):
90109
elif self._request.filterType() == QgsFeatureRequest.FilterFid:
91110
if _f.id() != self._request.filterFid():
92111
continue
93-
if not self._filter_rect.isNull():
94-
if not _f.hasGeometry():
95-
continue
96-
if self._request.flags() & QgsFeatureRequest.ExactIntersect:
97-
# do exact check in case we're doing intersection
98-
if not self._select_rect_engine.intersects(_f.geometry().constGet()):
99-
continue
100-
else:
101-
if not _f.geometry().boundingBox().intersects(self._filter_rect):
102-
continue
103112
f.setGeometry(_f.geometry())
104113
self.geometryToDestinationCrs(f, self._transform)
105114
f.setFields(_f.fields())
@@ -198,6 +207,9 @@ def __init__(self, uri=''):
198207
self._extent.setMinimal()
199208
self._subset_string = ''
200209
self._crs = mlayer.crs()
210+
self._spatialindex = None
211+
if 'index=yes'in self._uri:
212+
self.createSpatialIndex()
201213

202214
def featureSource(self):
203215
return PyFeatureSource(self)
@@ -256,6 +268,9 @@ def addFeatures(self, flist, flags=None):
256268
added = True
257269
f_added.append(_f)
258270

271+
if self._spatialindex is not None:
272+
self._spatialindex.insertFeature(_f)
273+
259274
if len(f_added):
260275
self.updateExtents()
261276

@@ -267,6 +282,8 @@ def deleteFeatures(self, ids):
267282
removed = False
268283
for id in ids:
269284
if id in self._features:
285+
if self._spatialindex is not None:
286+
self._spatialindex.deleteFeature(self._features[id])
270287
del self._features[id]
271288
removed = True
272289
if removed:
@@ -349,6 +366,10 @@ def supportsSubsetString(self):
349366
return True
350367

351368
def createSpatialIndex(self):
369+
if self._spatialindex is None:
370+
self._spatialindex = QgsSpatialIndex()
371+
for f in self._features:
372+
self._spatialindex.insertFeature(f)
352373
return True
353374

354375
def capabilities(self):

0 commit comments

Comments
 (0)
Please sign in to comment.