Problems with multipart shapes using PyShp when creating a new Shapefile

1.2k Views Asked by At

I have a shapefile (blockgroups.shp) that I downloaded from: https://github.com/GeospatialPython/pyshp/tree/master/shapefiles

I want to create a new Shapefile with only four attributes (bkg_key, pop1990, white and black) using PyShp.

I've tried with this code:

import shapefile
file= "blockgroups.shp"
outFile = "newblockgroup3000"
sf = shapefile.Reader(file)
shapeRec= sf.shapeRecords()
w = shapefile.Writer(shapefile.POLYGON)
w.field('BKG_KEY', 'C', 40)
w.field('POP1990', 'N', 40)
w.field('NWHITES', 'N', 40)
w.field('NBLACKS', 'N', 40)
for row in shapeRec:
    bkg_key = row.record[1]
    pop1990 = row.record[2]
    white = row.record[7]
    black = row.record[8]
    points = row.shape.points
    parts = row.shape.parts
    w.parts = parts
    w.poly([points])
    w.record(bkg_key,pop1990,white,black)
    w.save(outFile)

It works for all the shapes except for one.

There is a record that has more than one part. The record which has more than one part is 'BKG_KEY = 060750601001' and 'POP = 4531'. In the new shapefile, this record has a strange shape because pyShp automatically connects the first and the last vertexs which come from different parts of the feature.

If I only select the records that 'POP1990 <4531' and the records that 'POP1990>4531'(excluding the mentioned record) it works so the problem only happens when there are records with multiple parts.

Is there any way to keep the number of parts of the original shapefile when I create the new one? How can I handle this problem.

I would appreciate some help. Thanks

1

There are 1 best solutions below

2
On

I found this question whilst looking for a solution to save multiple shapes in one shapefile using pyshp. Your code helped me solve my problem and so i'll provide a solution for this.

import shapefile

file= "blockgroups.shp"
outFile = "newblockgroup3000"
sf = shapefile.Reader(file)
shapeRec= sf.shapeRecords()
w = shapefile.Writer(shapefile.POLYGON)
w.field('BKG_KEY', 'C', 40)
w.field('POP1990', 'N', 40)
w.field('NWHITES', 'N', 40)
w.field('NBLACKS', 'N', 40)

for row in shapeRec:
    bkg_key = row.record[1]
    pop1990 = row.record[2]
    white = row.record[7]
    black = row.record[8]
    points = row.shape.points
    parts = row.shape.parts
    geom = []

    # handle parts here
    for i in range(len(parts)):
        xy = []
        pt = None
        if i < len(parts) - 1:
            pt = points[parts[i]:parts[i + 1]]
        else:
            pt = points[parts[i]:]
        for x, y in pt:
            xy.append([x, y])
        geom.append(xy)

    w.poly(geom)
    w.record(bkg_key,pop1990,white,black)
w.save()

Result before edit: enter image description here

Result after edit: enter image description here