The trick is to create a function that access QGIS graphical interface, and that is piped to the query of the virtual layer.
- Open a function editor (from anywhere, including from field calculator) and create a new function that reads the canvas extent and returns it as a geometry.
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
@qgsfunction(args='auto', group='Custom')
def currentExtent(feature, parent):
return QgsGeometry.fromRect(iface.mapCanvas().extent())
- Create a new virtual layer and use the new function, selecting features that intersects the displayed area. To get features entirely within the displayed area, use
ST_Within()
instead.
SELECT *
FROM mylayer
WHERE st_intersects(mylayer.geometry, currentExtent());
Note that if you have the attribute table open, you would need to click the refresh icon after panning the map.