3

I have a vector layer with say 100.000 features. I would like to get the N'th feature from the layer when sorted by an attribute field name:

Feature 1
Feature 2
    :
Feature N   <--
    :
Feature 99.999
Feature 100.000

Using a QgsFeatureRequest with layer.getFeatures(...) I can sort the features:

request = QgsFeatureRequest()
request.addOrderBy(field_name)

feature_iterator = layer.getFeatures(request)

Then I can extract the N'th feature by:

feature = list(feature_iterator)[N - 1]

It takes some time to make a list of 100.000 features. I can limit the number of features since I don't need to request the features coming after N:

request.setLimit(N)

But if I need feature N=99.999 I still need to request almost all of the features.

Question:
Can I get the N'th feature more efficiently?

1 Answer 1

7

Short answer: No, features are loaded from the provider as they are requested.

Long answer: It's likely possible to write a feature request that gives you exactly the one feature which you are looking for. If it's not possible to do with an expression (which needs to be simple enough that it can be translated to SQL), you can create a view that does the heavy lifting for you (assuming you are working with a database).

Sidenote:

The command you wrote will have a high memory consumption and loop through all features even if N is the second feature of 100'000.

feature = list(feature_iterator)[N - 1]

better directly access the feature from the iterator. This is almost as good as setting the limit (and of course can be combined with it). Providers typically load features in batches (blocks of something like 2000).

feature = next(itertools.islice(feature_iteartor, N-1, N))
6
  • I made the list conversion because the QgsFeatureIterator doesn't support indexing.
    – Chau
    Aug 17, 2016 at 8:11
  • check the update Aug 17, 2016 at 8:32
  • Even though I wished for a Yes to my question, I appreciate your answer - and thanks for the sidenote too :)
    – Chau
    Aug 17, 2016 at 10:09
  • Not that it would be impossible to implement a QgsFeatureIterator.skip(number) method in QGIS core in case it's important enough for someone to get his hands dirty Aug 17, 2016 at 10:42
  • I would like to get my hands dirty, but I haven't had the time to build or debug QGIS my self. I am getting closer though. Would a .skip(...) method be faster or just a more pretty solution?
    – Chau
    Aug 17, 2016 at 12:20

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.