Skip to content

Instantly share code, notes, and snippets.

@jlehtoma
Created January 14, 2015 14:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlehtoma/c7388e0baee60680862e to your computer and use it in GitHub Desktop.
Save jlehtoma/c7388e0baee60680862e to your computer and use it in GitHub Desktop.
Re-create missing .shx-file for ESRI shapefiles
# Based on solution given here: http://geospatialpython.com/2011/11/generating-shapefile-shx-files.html
# Depends on pyshp
# Build a new shx index file
import fnmatch
import os
import shapefile
# List all the shapefiles
def find(pattern, path):
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
shp_files = find('*.shp', '.')
for shp_file in shp_files:
# Explicitly name the shp and dbf file objects
# so pyshp ignores the missing/corrupt shx
shp = open(shp_file, "rb")
dbf = open(shp_file.replace("shp", "dbf"), "rb")
r = shapefile.Reader(shp=shp, shx=None, dbf=dbf)
w = shapefile.Writer(r.shapeType)
# Copy everything from reader object to writer object
w._shapes = r.shapes()
w.records = r.records()
w.fields = list(r.fields)
# saving will generate the shx
fixed_shp_file = os.path.join(os.path.dirname(shp_file),
"fixed_" + os.path.basename(shp_file))
w.save(fixed_shp_file)
@guziy
Copy link

guziy commented Apr 8, 2016

HI:

What would you do if neither shx or dbf exist?

Cheers

@AlyssonJalles
Copy link

For corrupted shapefile, I also used shapechecker. It reconstruct the dbf and shx when missing.

Download here: http://www.oocities.org/andrew_williamson/old_shapechk.zip
Page: https://allaroundgis.wordpress.com/2013/12/10/shapefile-shp-shape-checker-v3-2/

@thebat137
Copy link

@jlehtoma, what's the license on this script?

@pjrule
Copy link

pjrule commented Jun 27, 2018

^Same question :)

@t-wolfeadam
Copy link

Note: This script does not work anymore!
You have to specify the filename when creating the writer object:
fixed_shp_file = os.path.join(os.path.dirname(shp_file), "fixed_" + os.path.basename(shp_file))
w = shapefile.Writer(fixed_shp_file, shapeType=r.shapeType)
and then instead of using save, just close (it auto-saves)

The way you copy the fields + records + shapes has also changed. See Adding from an existing Shape object of https://github.com/GeospatialPython/pyshp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment