9

This tiny little script deletes all small features in all layers. This works fine but the size of .shp files are not reduced. Please tell me why...

canvas = iface.mapCanvas()
expr = QgsExpression("$length<100")
for l in canvas.layers():
    l.startEditing()
    it = l.getFeatures(QgsFeatureRequest(expr))
    for ft in it:
        l.deleteFeature(ft.id())
    l.commitChanges()

2 Answers 2

14

Because the fastest way to delete features from shapefiles is to mark records with a "deleted" flag in the .dbf part without rewriting all .shp, .shx, and .dbf parts. This is also documented in the GDAL shp driver page http://www.gdal.org/drv_shapefile.html

The OGR shapefile driver supports rewriting existing shapes in a shapefile as well as deleting shapes. Deleted shapes are marked for deletion in the .dbf file, and then ignored by OGR. To actually remove them permanently (resulting in renumbering of FIDs) invoke the SQL 'REPACK ' via the datasource ExecuteSQL() method.

4
  • 2
    Technically, the "mark as deleted" feature of dBase is not supported by shapefiles, so GDAL is generating corrupt shapefiles when it does this.
    – Vince
    Commented Feb 28, 2016 at 17:00
  • There is an old answer gis.stackexchange.com/questions/162615/… (this one being perhaps a duplicate) where I found that MapObjects by ESRI had similar delRecord(index) method that does not remove anything physically. Perhaps ESRI programs take better care of running "pack" before closing shapefiles but it feels like they also do have some support for "mark as deleted".
    – user30184
    Commented Feb 28, 2016 at 17:25
  • Performing a 'save as' on the layer will remove the deleted features. Commented Feb 28, 2016 at 21:11
  • I don't have that big experience in QGIS and python. How do you invoke the SQL 'REPACK' ?
    – EvanH
    Commented Feb 29, 2016 at 6:29
5

You should check the version of QGIS that you are seeing this in.

I know that this behaviour was tweaked in version 2.14, so that after calling deleteFeatures a shapefile will be repacked to remove any leftover orphan rows.

You should re-test with version 2.14 and see if there's any improvement.

1
  • Thank you very much for your answer. It sounds great that it was tweaked in version 2.14. I'm running version 2.12.2 and I know that 2.12.3 is ready for download but where can I find version 2.14 ?
    – EvanH
    Commented Feb 29, 2016 at 6:10

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.