8

In a standalone application, I have a layer to which I select some features. Then I need to do an iteration, and I need it to be done in the order of the value of a field/attribute (In my example order by Name of the Cities).

vLayer = QgsVectorLayer(cities_of_world_file, 'Cities of World', "ogr")
country = 'Spain'
filter = '"Country"=\'%s\' '%country
vLayer.selectByExpression(filter, QgsVectorLayer.SetSelection)
for feature in vLayer.selectedFeatures():
    print(feature['City'])

I think there are two ways:

  1. Open the layer ordered, and after that, you make a selection. In SQL when you select records you can say ORDER BY, is this order in a QgsVectorLayer?

  2. Select features and after that, you sort.

How can I do this?

4 Answers 4

12

You can also use addOrderBy method of QgsFeatureRequest in this way:

request = QgsFeatureRequest().addOrderBy("City")
for f in vLayer.getSelectedFeatures(request):
    print(f["City"])

For a large dataset, using selectedFeatures() may take a long time, Instead, you may consider using the way in this answer.

getSelectedFeatures() is more memory-friendly when handling large selections.

2
  • @Kadir Thank you for your information. Do you know it's possible open a QgsVectorLayer order by an attribute?. Or you need first open, and after that, make QgsFeatureRequest addOrderBy of all features?
    – RBenet
    Commented Jan 17, 2022 at 10:00
  • 1
    @Ben W I have followed your suggestion. Always we learn something very new and interesting
    – RBenet
    Commented Jan 17, 2022 at 10:04
10

Try the snippet below. You can store selected features and an associated attribute as key, value pairs into a dictionary, then sort by the field value. After that, you can access the feature object stored as the key.

vLayer = QgsVectorLayer(cities_of_world_file, 'Cities of World', "ogr")

country='Spain'
filter='"Country"=\'%s\' '%country
vLayer.selectByExpression(filter,QgsVectorLayer.SetSelection)

selected = {f: f['City'] for f in vLayer.selectedFeatures()}
sorted_by_val = {k: v for k, v in sorted(selected.items(), key=lambda item: item[1])}

for feat, val in sorted_by_val.items():
    print(val)
    # do something with feat

https://stackoverflow.com/questions/613183/how-do-i-sort-a-dictionary-by-value

9

This also works:

sorted_list = sorted(vLayer.selectedFeatures(), key=lambda el: el['City'])

for feature in sorted_list:
    print(feature['City'])
8

@Ben W, thank you so much, I have marked your answer as correct.

Even so I have found a solution to solve it in one operation. It is a combination of your answer and the instructions on this website to sort a list with a dictionary inside(QgsVectorLayer.selectedFeatures()):

https://www.w3schools.com/python/ref_list_sort.asp

vLayer= QgsVectorLayer(cities_of_world_file, 'Cities of World', "ogr")
country='Spain'
filter='"Country"=\'%s\' '%country
vLayer.selectByExpression(filter,QgsVectorLayer.SetSelection)

iter=vLayer.selectedFeatures() # Is a list with a like dictionary inside
iter.sort(key=lambda item: item['City'])

for feature in iter:
    print(feature['City'])

Do you Know if it's possible to do my first way:

1.- Open Layer ordered, and after that you make selection. In SQL when you select records you can say ORDER BY, exist this order in a QgsVectorLayer?

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.