With the PyQGIS API, I have a QgsVectorLayer object that is sometimes a GeoPackage/SHP layer, sometimes a PostGIS layer. I have a working code to get all features within a given polygon "frame" when the layer is from a GeoPackage, but when it is from PostGIS so spatial filtering is server-side (the layer has a spatial index), QgsFeatureRequest
functions setFilterRect
or setDistanceWithin
don't work anymore.
My code:
request = QgsFeatureRequest().setFilterRect(frame.boundingBox())
for feature in vectorLayer.getFeatures(request):
if feature.geometry().intersects(frame):
# feature stuff here
id = str(feature.attribute(idFieldId))
For PostGIS case, I tried to use an spatial filter in setFilterExpression
function but this doesn't get any feature:
spatialFilter = f"ST_Within({layer.dataProvider().uri().geometryColumn()}, ST_GeomFromText('{frame.asWkt()}', {frameSrid}))"
request.setFilterExpression(spatialFilter)
So, how to make a working and efficient spatial request with QgsFeatureRequest
with a PostGIS layer?
Anyway, I can switch code depending on layer source provider with layer.dataProvider().name()
which is ogr
or postgres
.
if feature.geometry().intersects(frame):
- this is not a necessary check, the request already checks which features will intersect with bbox.