Created
April 2, 2012 15:52
-
-
Save ianfieldhouse/2284557 to your computer and use it in GitHub Desktop.
Create PNG from Shapefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapefile | |
import pngcanvas | |
# Open shapefile with Python Shapefile Library | |
shapefile_name = 'REPLACE_WITH_SHAPEFILE_NAME' # e.g. england_oa_2001 | |
r = shapefile.Reader(shapefile_name) | |
# Determine bounding box x and y distances and then calculate an xyratio | |
# that can be used to determine the size of the generated PNG file. A xyratio | |
# of greater than one means that PNG is to be a landscape type image whereas | |
# an xyratio of less than one means the PNG is to be a portrait type image. | |
xdist = r.bbox[2] - r.bbox[0] | |
ydist = r.bbox[3] - r.bbox[1] | |
xyratio = xdist/ydist | |
image_max_dimension = 600 # Change this to desired max dimension of generated PNG | |
if (xyratio >= 1): | |
iwidth = image_max_dimension | |
iheight = int(image_max_dimension/xyratio) | |
else: | |
iwidth = int(image_max_dimension/xyratio) | |
iheight = image_max_dimension | |
# Iterate through all the shapes within the shapefile and draw polyline | |
# representations of them onto the PNGCanvas before saving the resultant canvas | |
# as a PNG file | |
xratio = iwidth/xdist | |
yratio = iheight/ydist | |
pixels = [] | |
c = pngcanvas.PNGCanvas(iwidth,iheight) | |
for shape in r.shapes(): | |
for x,y in shape.points: | |
px = int(iwidth - ((r.bbox[2] - x) * xratio)) | |
py = int((r.bbox[3] - y) * yratio) | |
pixels.append([px,py]) | |
c.polyline(pixels) | |
pixels = [] | |
f = file("%s.png" % shapefile_name,"wb") | |
f.write(c.dump()) | |
f.close() | |
# Create a world file | |
wld = file("%s.pgw" % shapefile_name, "w") | |
wld.write("%s\n" % (xdist/iwidth)) | |
wld.write("0.0\n") | |
wld.write("0.0\n") | |
wld.write("-%s\n" % (ydist/iheight)) | |
wld.write("%s\n" % r.bbox[0]) | |
wld.write("%s\n" % r.bbox[3]) | |
wld.close |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, 9 years later....
Line 20 should be multiplying by the xyratio.
Explanation:
If xyratio < 1, the width is smaller than the height. Dividing by a number < 1 will make the width larger, rather than smaller, as we intent.
Otherwise, thanks for this. Saved me a few hours and got me introduced to the meat of shapefiles.