-
-
Save sgillies/3642564 to your computer and use it in GitHub Desktop.
Putting it all together
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
from descartes import PolygonPatch | |
import fiona | |
from functools import partial, reduce | |
from math import sqrt | |
from itertools import imap | |
import pylab | |
from pyproj import Proj, transform | |
fiona.open = fiona.collection | |
BLUE = "#6699cc" | |
RED = "#cc6666" | |
# The one polygon rendering function we'll reuse throughout this module. | |
def add_record(fig, rec, fc=BLUE, ec=BLUE, alpha=1.0, zorder=2): | |
"""Makes a patch of the record's geometry, adds it to the default axes of | |
the given figure and returns the figure. The color and alpha parameters | |
can be constants or unary functions of the given record. | |
Note: not strictly functional because we're mutating the figure.""" | |
facecolor = callable(fc) and fc(rec) or fc | |
edgecolor = callable(ec) and ec(rec) or ec | |
alphaval = callable(alpha) and alpha(rec) or alpha | |
zorderval = callable(zorder) and zorder(rec) or zorder | |
fig.gca().add_patch( | |
PolygonPatch( | |
rec['geometry'], | |
fc=facecolor, | |
ec=edgecolor, | |
alpha=alphaval, | |
zorder=zorderval)) | |
return fig | |
add_feature_alpha = partial(add_record, alpha=0.5) | |
with fiona.open("docs/data/test_uk.shp") as features: | |
fig = reduce(add_feature_alpha, features, figure(figsize=(8, 8))) | |
fig.gca().autoscale(tight=False) | |
fig.savefig("test_uk.png") | |
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
# Add in map projection capabilities | |
def transform_coords(func, rec): | |
# Transform record geometry coordinates using the provided function. | |
# Returns a record or None. | |
try: | |
assert rec['geometry']['type'] == "Polygon" | |
record = rec.copy() | |
new_coords = list( | |
zip(*func(*zip(*ring)) | |
) for ring in rec['geometry']['coordinates']) | |
record['geometry']['coordinates'] = new_coords | |
return record | |
except Exception, e: | |
# Writing untransformed features to a different shapefile | |
# is another option. | |
logging.exception( | |
"Error transforming record %s:", rec) | |
return None | |
# The transform_coords() function calls another function for the actual | |
# transformation of coordinate values. We'll make one by "freezing" the | |
# input and output projections for pyproj.transform(). | |
epsg4326 = Proj(init="epsg:4326", no_defs=True) | |
robin = Proj( | |
proj="robin", | |
lon_0=0, | |
x_0=0, | |
y_0=0, | |
ellps="WGS84", | |
datum="WGS84", | |
units="m", | |
no_defs=True) | |
transform_robin = partial(transform, epsg4326, robin) | |
# Here's partial function that makes a Robinson projection of feature records. | |
# Usage: projected_features = map(robinson, features) | |
robinson = partial(transform_coords, transform_robin) | |
with fiona.open( | |
"/Users/seang/work/UVA-SL/world_borders/world_borders.shp" | |
) as features: | |
fig = reduce( | |
add_feature_alpha, imap(robinson, features), figure(figsize=(24, 12))) | |
fig.gca().autoscale(tight=False) | |
fig.savefig("world-robinson.png") |
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
# The rendering function allows image alpha to vary from feature to feature. | |
# We'll create a weighting function to control the alpha value, normalizing | |
# population density to 80 per square km. | |
def weight(rec): | |
props = rec['properties'] | |
dens = props['POP_CNTRY']/props['AREA'] | |
return min(sqrt(dens/80.0), 1.0) | |
# Here's our new rendering partial function. | |
add_feature_choropleth = partial(add_record, fc=RED, ec=RED, alpha=weight) | |
# And just for fun, we'll make a partial from reduce(). | |
choropleth = partial(reduce, add_feature_choropleth) | |
with fiona.open( | |
"/Users/seang/work/UVA-SL/world_borders/world_borders.shp" | |
) as features: | |
fig = choropleth(imap(robinson, features), figure(figsize=(24, 12))) | |
fig.gca().autoscale(tight=False) | |
fig.savefig("world-dens-robinson.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment