2

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?

4

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))
  • I made the list conversion because the QgsFeatureIterator doesn't support indexing. – Chau Aug 17 '16 at 8:11
  • check the update – Matthias Kuhn Aug 17 '16 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 '16 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 – Matthias Kuhn Aug 17 '16 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 '16 at 12:20

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.