0

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.

  • 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. – maxo Jul 31 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. – Son of a Beach Jul 31 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. – Vince Aug 1 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) – user2856 Aug 1 at 4:37
0

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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