8

I have a shapefile with only one field DN. I would like to delete all features which does not have specific value of the field. Let's say the DN can be 1,2 or 3.

So far I was able to find out how to select Features and how to delete feature, but I did not succeed to combine them. Let's say I want only features with DN = 3 to remain:

Selection of the Features found here, however, I do not know if it does what it is supposed to do since I did not find the way how to check what is inside.

select = layer.getFeatures(QgsFeatureRequest().setFilterExpression(u'"DN"!=3'))

delete features found here

res = Ilayer.dataProvider().deleteFeatures()

As far as I know, the deleteFeatures() requires IDs of the features, but I have no idea how to get them from from select which is QgsFeatureIterator.

18

You can loop over the iterator and get the .id() for every feature in it:

with edit(layer):
    # build a request to filter the features based on an attribute
    request = QgsFeatureRequest().setFilterExpression('"DN" != 3')

    # we don't need attributes or geometry, skip them to minimize overhead.
    # these lines are not strictly required but improve performance
    request.setSubsetOfAttributes([])
    request.setFlags(QgsFeatureRequest.NoGeometry)

    # loop over the features and delete
    for f in layer.getFeatures(request):
        layer.deleteFeature(f.id())

Or with QGIS < 2.12

request = QgsFeatureRequest().setFilterExpression('"DN" != 3')
request.setSubsetOfAttributes([])
request.setFlags(QgsFeatureRequest.NoGeometry)
ids = [f.id() for f in layer.getFeatures(request)]
layer.startEditing()
for fid in ids:
    layer.deleteFeature(fid)
layer.commitChanges()
  • Thank you, that was that! I just noticed that the FilterExpression was wrong (not u'"DN"=2||"DN"=1' but u'"DN"!=3' should be used). Please if you would edit your answer for this not to confuse other viewers. – MasterPJ Aug 29 '14 at 14:44
  • isn't it layer.dataProvider().deleteFeatures(ids)? – mbernasocchi Aug 13 '15 at 12:34
  • Using dataProvider() is possible but I prefer to work directly on the layer since this way the changes are communicated internally (to the map canvas, attribute table...) and other reasons. – Matthias Kuhn Aug 13 '15 at 21:34
  • 2
    layer.dataProvider().deleteFeatures(ids) has thrown crashes for me when layer.deleteFeature(fid) didnt... Bad crashes. The kind that cause a seg fault and kill qgis. The kind that take 6 hours to find... stick with the answer posted here. Bums me out because layer.dataProvider().deleteFeatures(ids) is all through my code and now I've got to fix it all. – Mr Purple Mar 9 '16 at 2:29

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.