3

I am trying to make a virtual layer that is based on a map layer that only returns the features in the current map canvas extent. The purpose is to setup a Data Graph that shows statistical data of only the features in the current map extent. I cannot find any examples of this being done in qgis or using SQL. Is it possible?

6

The trick is to create a function that access QGIS graphical interface, and that is piped to the query of the virtual layer.

1) 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())

2) 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.

  • How will this handle features that are partially outside the map canvas? – csk Apr 26 at 18:16
  • 1
    @csk Since it uses st_intersects, features that are partially displayed will be returned. One can change the query and use ST_Within instead (or any other spatial predicate) – JGH Apr 26 at 18:19
  • 1
    @csk and since it return *, the original (complete) geometry will be returned – JGH Apr 26 at 18:21
  • Thank you for the explanation. That's what I suspected, but wanted to be sure. A large feature that only slightly extends into the map canvas could have an unexpected impact on the graph. – csk Apr 26 at 18:24
  • I didn't know custom expressions could be used in virtual layers ... that's cool ... i suppose they can have a big impact on queries execution times ... ? – snaileater Apr 26 at 18:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.