Skip to content

Instantly share code, notes, and snippets.

@jimr
Created August 15, 2013 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimr/6241313 to your computer and use it in GitHub Desktop.
Save jimr/6241313 to your computer and use it in GitHub Desktop.
Merge zipped shapefiles containing identical (or very similar) attribute tables.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Requires pyshp: https://pypi.python.org/pypi/pyshp
#
import os
import shapefile
import shutil
import tempfile
import zipfile
ROOT = '/path/to/folder/containing/zips/'
# For example.
FIELDS = (
('Country', 'C', 50, 0),
('POINT_X', 'N', 19, 11),
('POINT_Y', 'N', 19, 11),
)
# grab a list of the input files
zips = []
for fname in os.listdir(ROOT):
if fname.endswith('.zip'):
zips.append(fname)
shape = shapefile.Writer(shapefile.POINT)
# Set up the structure of the attribute table. If they're all the same, you
# could set this on the first iteration of the below loop by reading from
# sf.fields
for field in FIELDS:
shape.field(*field)
for i, fname in enumerate(zips):
# extract the zip into a temporary folder
out = tempfile.mkdtemp()
zf = zipfile.ZipFile(os.path.join(ROOT, fname))
zf.extractall(out)
# Read the shapefile ready for copying
shp = filter(lambda x: x.endswith('.shp'), zf.namelist())[0]
sf = shapefile.Reader(os.path.join(out, shp))
try:
for r in sf.shapeRecords():
# If not all of the shapefiles we're merging have all of the field
# data available, we can create a blank row and fill in what we can
# from the available data.
row = [0 for f in FIELDS]
for j, val in enumerate(r.record):
row[j] = val
shape.record(*row)
shape._shapes.append(r.shape)
except Exception as ex:
print 'ERR: %s' % zf.fp.name
continue
# Bin the temporary folder
shutil.rmtree(out)
shape.save('merged')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment