5

Is there a way of establishing the order that a user selected features using QGIS and Python?

By example: we have a network of line features representing a road network, and the user defines a route from point A to point B. Currently, using layer.selectedFeatures() returns the correct features, but in the order they were drawn rather than the order they were selected.

I've tried a few things to do this manually:

  • QgsMapToolEmitPoint(canvas) obviously doesn't work - I want the feature not the point clicked. But I guess in worst case I could hack a spatial query to do a look up of the closest feature. Not ideal.
  • QgsMapToolSelect(canvas) doesn't seem to be available as part of the Python accessible GUI or CORE, although I can find mention of it existing elsewhere.

1 Answer 1

3

I see two possibilities:

  • Have a look at QgsSnapper (This is what you called the worst-case solution, although I don't think its bad at all. The internals would do the same)
  • Connect to the QgsVectorLayer.selectionChanged signal. In 1.9 you even get the delta of the selection.

from PyQt4.QtCore import pyqtSlot

@pyqtSlot('QgsFeatureIds', 'QgsFeatureIds', bool)
def onSelectionChanged(added, removed, cleared):
    print(added)

iface.activeLayer().selectionChanged.connect(onSelectionChanged)

The @pyqtSlot line is optional. (See here for an explanation why it's good practice.)

4
  • Thanks for the tips, Matthias. It looks like the connection on selectionChanged will do what I need. Could you provide an example of the connection though? I'm not familiar with the structure here and quite how to pass the feature ids into my custom function. Thanks in advance.
    – Dan
    Commented Aug 30, 2013 at 7:55
  • 1
    Answer edited... Commented Aug 30, 2013 at 8:45
  • Odd. I get the following error from your example: TypeError: onSelectionChanged() takes exactly 3 arguments (2 given). Perhaps an issue with it being a custom UI that uses self?
    – Dan
    Commented Aug 30, 2013 at 9:40
  • 1
    You will have to add self to onSelectionChanged if it's inside a class. def onSelectionChanged(self, added, removed, cleared) You also don't need the pyqtSlot stuff normally.
    – Nathan W
    Commented Aug 30, 2013 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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