Skip to content

Instantly share code, notes, and snippets.

@ToddTurnbull
Last active September 5, 2019 22:41
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 ToddTurnbull/2e98566a270aab638293da8164f1c598 to your computer and use it in GitHub Desktop.
Save ToddTurnbull/2e98566a270aab638293da8164f1c598 to your computer and use it in GitHub Desktop.
Federal Electoral Districts in Waterloo Region
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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