[GIS] How to get vector feature by mouse location

pyqgisqgisqgis-plugins

I'm writing a photo grouping plugin. My current problem can be broken up into "end goal" and "baby steps", because I think that's what I want. But if there's a way to get to the end by a different means, that's what I really need.

End goal: given 2 different QGIS layers, 'nodes' and 'sections', and given a bunch of groups of photos, mouse over a 'node' > click to assign photos to node. mouse over a 'section' > click to assign. Repeat indefinitely, not necessarily in order. Without toggling active layer back and forth and making selection(s) first.

Baby Step #1: find out what feature(s) on which vector layer(s) is under the mouse position.

I found the "Value Tool" plugin last night, read through the code, and it reports values from multiple raster layers based on the mouse position. I was super excited! Unfortunately, it seems that QgsVectorDataProvider doesn't have anything analogous to the QgsRasterDataProvider's identify(position) method, which is how that plugin works.

So I've been playing around with QgsVectorDataProvider.select(), but can't get it working. Probably doing something stupid. This post:
https://gis.stackexchange.com/a/22919/6690
makes it sound like it's possible.

Can anyone tell me what I'm doing wrong?

Steps (in Python console for now):

  1. load vector layer in QGIS
  2. iface = qgis.utils.iface; canvas = iface.mapCanvas(); layer = canvas.layer(0)
  3. layer.dataProvider().attributeIndexes() >> [0,1,2,3,4,5]
  4. A = layer.dataProvider.select((0,1,2,3,4,5),canvas.extent())
  5. checks: A >> nothing; type(A) >> 'type 'NoneType''

Once I can get a selection by position, I think I can get the list of layers I want to check, iterate through them with position, check & flag on overlaps, and we're off…

Best Answer

If you look at the API documentation for QgsVectorDataProvider you'll see that the select method returns void (see http://qgis.org/api/1.8/classQgsVectorDataProvider.html). This is why A is of NoneType in Python.

To access the features you need to iterate over the selection set after your select statement. Here is an example using a shapefile of cities, zoomed to a small area:

iface = qgis.utils.iface
canvas = iface.mapCanvas()
layer = canvas.layer(0)
provider = layer.dataProvider()
provider.select(provider.attributeIndexes(), canvas.extent())
feature = QgsFeature()
while provider.nextFeature(feature):
    attributes = feature.attributeMap()
    print attributes[0].toString()

This results in:

... 
Seward
Anchorage
>>> 

See Iterating over Vector Layer in the PyQGIS Cookbook: http://www.qgis.org/pyqgis-cookbook/vector.html

Related Question