Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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()
share|improve this question

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.

share|improve this answer
1  
Technically, the "mark as deleted" feature of dBase is not supported by shapefiles, so GDAL is generating corrupt shapefiles when it does this. – Vince Feb 28 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 Feb 28 at 17:25
    
Performing a 'save as' on the layer will remove the deleted features. – SpatialSuccess Feb 28 at 21:11
    
I don't have that big experience in QGIS and python. How do you invoke the SQL 'REPACK' ? – EvanH Feb 29 at 6:29

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.

share|improve this answer
    
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 Feb 29 at 6:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.