Yes, it is possible by using a QgsFeatureRequest with 'setFilterRect' method. The argument of this method is a QgsRectangle object obtained for visible part of Map Canvas with its 'extent' method (QgsMapCanvas class). I tried out my approach with this code:
layer = iface.activeLayer()
mapcanvas = iface.mapCanvas()
rect = mapcanvas.extent()
request = QgsFeatureRequest().setFilterRect(rect)
selected_feats = layer.getFeatures(request)
attr = [ feat.attributes() for feat in selected_feats ]
print attr
print len(attr)
and world_borders shapefile that has 3784 features. After running the code with the next image situation:
I got the display of only 77 visible features attributes (printed result at the Python Console of GIS).
You can create a temporary layer based on your Postgis layer.
You can either filter features of the layer wich intersect the canvas extent, or filter the features wich are completly within the canvas extent.
On the example below, I have a layer (red), a canvas extent (red line) zoomed on the green feature, features intersecting the extent (pink features) and features within the extent (purple features).
To create those 2 layers I used this code :
import tempfile
tf = tempfile.TemporaryDirectory()
# IMPORT YOUR LAYER
if self.ctrs_cibles.featureCount() > 0:
# Creation of the layer with the features wich intersect the extent
self.ctrs_cibles.selectByRect(extent)
writer = QgsVectorFileWriter.writeAsVectorFormat(self.ctrs_cibles, tf.name +'/'+'filtered_layer_intersect.shp', "utf-8", self.ctrs_cibles.crs(), "ESRI Shapefile", onlySelected=True)
iface.addVectorLayer( tf.name +'/'+'filtered_layer_intersect.shp', '', 'ogr')
# Creation of the layer with the features wich are within the extent
inside_extent_ids = []
for feature in self.ctrs_cibles.getSelectedFeatures():
if feature.geometry().within(QgsGeometry().fromRect(extent)):
inside_extent_ids.append(feature.id())
self.ctrs_cibles.selectByIds(inside_extent_ids)
writer = QgsVectorFileWriter.writeAsVectorFormat(self.ctrs_cibles, tf.name +'/'+'filtered_layer_within.shp', "utf-8", self.ctrs_cibles.crs(), "ESRI Shapefile", onlySelected=True)
iface.addVectorLayer( tf.name +'/'+'filtered_layer_within.shp', '', 'ogr')
Best Answer
I dont know what can be done in plugins and not, but in QGIS you can apply a filter: