I have a piece of software (not Arc) that runs nightly on a non-production machine which updates shapefile features from an external database. Periodically I would like to delete all of the features in the shapefile (not the file itself, which must remain) and let the software "rebuild" the shapefile from scratch. I would like to automate this process.

I don't have any GIS software currently installed on that machine. I was hoping that I could script a routine in Python that would automatically delete the features, much like Arc's Delete Features geoprocessing tool.

Are there any Python modules that would allow me to do this? Preferrably open-source? I looked at Shapely and PyShp but didn't see anything that would allow me to delete the features in mass or that matched a WHERE clause. They can write features and analyze them, but haven't seen DELETE FEATURES functions anywhere.

I must certainly be missing something simple...

EDIT : I have 35 folders (different geographic extents, all in their own projection), with 35-65 shapefiles with makes around 1000 shapefiles to deal with.

4 Answers 4


You can use the GDAL/OGR python API, the code will be like that:

from osgeo import ogr

shapefile = ogr.Open( "shapfile.shp",1 )
for feature in range(count):
  • I get ERROR 1: The DeleteFeature() operation is not permitted on a read-only shapefile Nov 3, 2011 at 23:07
  • 4
    you have to open it for writing. Do it with: ogr.Open('shapefile.shp', 1)
    – capooti
    Nov 3, 2011 at 23:25

The command line ogr2ogr with a where clause guaranteed to create empty results is one quick and easy method:

ogr2ogr output.shp input.shp -where "FID < 0"

The overview page for python and OGR (and GDAL) is http://trac.osgeo.org/gdal/wiki/GdalOgrInPython

  • I like the idea. I would have to do some scripting around deleting the input file and renaming the output file back to the input name, but I could make it work if no other solutions are presented. Nov 3, 2011 at 22:40
  • 1
    here's a one line batch file for that: for %%a in (sample.shp) do (ogr2ogr %temp%\xxx.shp %%a -where "FID < 0" && copy %temp%\xxx.* %%~na.*). Pablo's answer is more extensible though. Nov 3, 2011 at 23:05

You can do this in pyshp. It's simple but not obvious because I never envisioned this use case. But it does make sense for automated update applications. I tested the following 6 lines of code and it worked great:

import shapefile
r = shapefile.Reader("myshape")
w = shapefile.Writer(r.shapeType)
# This line will give us the same dbf schema
w.fields = r.fields
# Use the original bounding box as a place holder in the header
w.bbox = lambda: r.bbox

You now have a shapefile written over the original that has correct headers and the original dbf fields. It will open safely in GIS software and shapefile libraries but has no features or dbf records.

The lambda function transfers the original bounding box over as a placeholder. You can put what ever float values you want in an array of [xmin, ymin, xmax, ymax]. Example:

w.bbox = lambda: [0.0, 0.0, 0.0, 0.0]

Changing dbf fields is simple too and documented in the pyshp docs.

Hope that helps.


Why not save a copy of the blank Shapefile and over-write your Shapefile of interest.

  • Ironically, IMHO this would be the most efficient solution as long as the schema does not change much... Nov 4, 2011 at 0:48
  • 1
    If it was for 1 or 2 files, I would agree. The main reason this wouldn't be as effecient is because I have 35 folders (different geographic extents, all in their own projection), with 35-65 shapefiles. The math says that would be 1000+ blank shapefiles to manage, which isn't practical either. Scripting a process to discover shapefiles & delete features is what I ultimately hope to end up with. Nov 4, 2011 at 14:26
  • @RyanDalton in the Q you said "the shapefile", which led us, well me anyway, to think of and devise a singular solution. I'm not complaining, just pointing out that more information about the use case up front might have led to answers more immediately applicable more quickly. Nov 6, 2011 at 4:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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