Last active
September 5, 2019 22:41
-
-
Save ToddTurnbull/2e98566a270aab638293da8164f1c598 to your computer and use it in GitHub Desktop.
Federal Electoral Districts in Waterloo Region
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 functools import reduce | |
import json | |
import fiona | |
import pyproj | |
# https://open.canada.ca/data/en/dataset/737be5ea-27cf-48a3-91d6-e835f11834b0 | |
shp = "zip://federal_electoral_districts_boundaries_2015_shp_en.zip" | |
# fio info zip://federal_electoral_districts_boundaries_2015_shp_en.zip reports "EPSG:3347" | |
# "EPSG:4269" for geojson? | |
transformer = pyproj.Transformer.from_crs(crs_from="EPSG:3347", crs_to="EPSG:4269") | |
# https://www.elections.ca/content.aspx?section=res&dir=cir/list&document=index338&lang=e#list | |
waterloo_district_ids = (35016, 35045, 35046, 35047, 35112) | |
def reducer(value, function): | |
"""Use with reduce() to apply a sequence of functions to a value""" | |
return function(value) | |
def district_id(feature): | |
"""Get FEDNUM property for a district""" | |
return feature.get("properties", {}).get("FEDNUM", 0) | |
def coordinates(feature): | |
"""Get (Polygon) coordinates for a district""" | |
return feature.get("geometry", {}).get("coordinates", [[(0, 0)]]) | |
def transform(feature, transformer=transformer): | |
"""Transform each point in a Polygon""" | |
feature["geometry"]["coordinates"] = [ | |
[transformer.transform(x, y) for x, y in ring] | |
for ring in coordinates(feature) | |
] | |
return feature | |
def swap_xy(feature): | |
"""Swap x/y coordinates; use after transform()""" | |
feature["geometry"]["coordinates"] = [ | |
[(y, x, *z) for x, y, *z in ring] for ring in coordinates(feature) | |
] | |
return feature | |
def geojson(features): | |
"""Build a GeoJSON object""" | |
return json.dumps(dict(type="FeatureCollection", features=features)) | |
if __name__ == "__main__": | |
waterloo_districts = [] | |
with fiona.Env(): | |
with fiona.open(shp) as features: | |
for feature in features: | |
# filter for local districts | |
if district_id(feature) in waterloo_district_ids: | |
waterloo_feature = reduce(reducer, (transform, swap_xy), feature) | |
waterloo_districts.append(waterloo_feature) | |
# create a local copy | |
with open("waterloo_districts.geojson", "w") as f: | |
f.write(geojson(waterloo_districts)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment