0

I need to be able to select one feature/record at a time within a polygon shapefile, regardless of how many shapes it contains, using open source python libraries (e.g., OGR, pyshp, fiona). Then I want to use each feature/record in a different function that requires a shapefile format. Below is what I'm attempting with pyshp:

shp = shapefile.Reader(file) ## open and read the shapefile
shp = shp.shapes() ## read the geometry information of each shape record
shpInPoly = [] ## empty array that will contain the features in the file
for i in shp:
 shpInPoly.append(i)

Then I'd assume I could grab the first feature in the array of appended features like this:

currentPolygon = shpInPoly[0]

And use the "currentPolygon" variable in my other function with the first record/feature in the original shapefile.

But it doesn't work. The error I get in my other function which requires shapefile inputs is "shapefile.ShapefileException: Shapefile Reader requires a shapefile or file-like object." The other alternative, per the question title (and what I'm thinking is likely best), would be to export that selected feature/record and all its content (geometry and fields) to a new shapefile, to achieve the same purpose of using that in another shapefile-requring function. The only posts I found that attempt something similar are Exporting Selected Feature to New Shapefile using ArcPy? and Splitting shapefile into many shapefiles with open source?, but I can't use ArcPy.

Any ideas?

asked Jan 10, 2017 at 1:48

1 Answer 1

3

If your other function expects a single shapefile input, then you need to split each polygon in the polygon shapefile into its own shapefile. Right now you are passing subsections of a shapefile and the other function is complaining. The code will look something like the following.

import shapefile
# path and name of the input shapefile
input_shp = "my_polys.shp"
# read the input shapefile
r = shapefile.Reader(input_shp)
# list of filenames for the split 
# polygon shapefiles
shp_files = []
# Loop through each polygon and dbf record,
# and create a new shapefile. We add an
# enumeration to give us a number for each
# new shapefile name.
for i, shapeRec in enumerate(r.iterShapeRecords()):
 # polygon
 shape = shapeRec.shape
 # dbf record
 rec = shapeRec.record
 # Create a new shapefile writer
 w = shapefile.Writer(shapefile.POLYGON)
 # Copy the dbf fields from the original shapefile
 w.fields = list(r.fields)
 # Add the polygon to the new shapefiles list of shapes
 w._shapes.append(shape)
 # Do the same for the dbf record
 w.records.append(rec)
 # Create a unique name for each shapefle
 # based on the enumeration index
 shp_name = "poly_{}.shp".format(i)
 # Save the shapefile and append the 
 # name to a list of names
 w.save(shp_name)
 shp_files.append(shp_name)
# Now you can loop through the list
# of shapefile names and pass them
# to the other function
for shp in shp_files:
 my_other_function(shp)
# Or if the other function expects
# a pyshp shapefile object:
for shp in shp_files:
 r = shapefile.Reader(shp)
 my_other_function(r)
answered Jan 10, 2017 at 2:45

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.