2

EDIT: I've tried running the code linked in the duplicate flag, it's posted here for reference, and it doesn't run. I had already referred to that answer in my initial post.

My problem

Downloaded shapefile is missing .shx file and trying to use pyshp to build it on a mac.*

I've tried this code that I've picked up from the pyshp documentation. When checking the r.shapes and r.records, it looks like all of the info is there.

myshp = open("Stockton/Stockton.shp", "rb")
mydbf = open("Stockton/Stockton.dbf", "rb")
r = shapefile.Reader(shp=myshp, dbf=mydbf, shx=None)

In the documentation, it looks like each record and shape is being added one at a time. Is there a method I'm missing? Or could a list comprehension be used here to loop through everything?**

Data and References

I've downloaded the Microsoft Building Data for Stockton CA from here. I've tried to follow the code from the answer here

 # Build a new shx index file
 #Code by Joel Lawhead http://geospatialpython.com/2011/11/generating-shapefile-shx-files.html
 import shapefile
 # Explicitly name the shp and dbf file objects
 # so pyshp ignores the missing/corrupt shx
 myshp = open("Stockton/Stockton.shp", "rb")
 mydbf = open("Stockton/Stockton.dbf", "rb")
 r = shapefile.Reader(shp=myshp, shx=None, dbf=mydbf)
 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
 w.save("myshape")

but get this error:

TypeError Traceback (most recent call last)
<ipython-input-94-345df1656b96> in <module>
 7 mydbf = open("Stockton/Stockton.dbf", "rb")
 8 r = shapefile.Reader(shp=myshp, shx=None, dbf=mydbf)
----> 9 w = shapefile.Writer(r.shapeType)
 10 # Copy everything from reader object to writer object
 11 w._shapes = r.shapes()
...
TypeError: expected str, bytes or os.PathLike object, not int

*Because I'm using a Mac, none of the solutions here seem like they would work.

**Still fairly new to Python so please forgive wrong/confusing terminology.

Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Jul 31, 2019 at 22:19
5
  • I'm not quite sure how this is a duplicate as the question linked doesn't answer my question. I've run that code and posted the error it gives me. Commented Jul 31, 2019 at 22:52
  • 1
    The OGR options should still work on your Mac. OGR is part of GDAL, which can be installed and run on a Mac. There's a bit of a learning curve though. Commented Jul 31, 2019 at 23:01
  • There exist datasets for which the .shx cannot be recovered, like shapefiles with CAD objects in them. The CAD data live in a hole between the documented geometry data, and the size of the hole can only be determined by peeking at the next record start. Commented Aug 1, 2019 at 0:14
  • 1
    I agree, this isn't a dupe. You need to pass a filepath as the first arg, or use keyword args shapefile.Writer(target='path/to/shx', shapeType=r.shapeType) Commented Aug 1, 2019 at 4:37
  • gis.stackexchange.com/help/someone-answers Commented Dec 9, 2021 at 7:27

1 Answer 1

6

That example code you link to looks like it's out of date (for an old version of pyshp).

This works (based on bits and pieces from the docs):

shp = r"path/to/shp" # NOTE no .shp extension
from shapefile import (Reader, Writer)
try: # Py2 (I haven't actually tested on python 2...)
 from StringIO import StringIO as IO
except ImportError: # Py3
 from io import BytesIO as IO
with IO() as shpio, IO() as dbfio: # Don't overwrite existing .shp, .dbf
 with Reader(shp) as r, Writer(shp=shpio, dbf=dbfio, shx=shp+'.shx') as w:
 w.fields = r.fields[1:] # skip first deletion field
 for rec in r.iterShapeRecords():
 w.record(*rec.record)
 w.shape(rec.shape)
answered Aug 2, 2019 at 0:14
2
  • You just SAVED MY ASS. THANK YOU! Commented Sep 22, 2022 at 15:01
  • If you're using fiona or geopandas to read in shapefiles, you can also add the following at the start of your script: import gdal; gdal.SetConfigOption('SHAPE_RESTORE_SHX', 'YES') Commented Feb 27, 2023 at 8:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.