Created
September 6, 2013 00:58
-
-
Save om-henners/6458233 to your computer and use it in GitHub Desktop.
From a CSV which you can download from the [AEC](http://www.aec.gov.au/) generate a GeoJSON file containing locations of polling places in your electorate. See example output for the [Melbourne electoral division](http://www.aec.gov.au/profiles/vic/Melbourne.htm). Note, the script needs [Requests](http://docs.python-requests.org/en/latest/) to r…
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
""" | |
Where is my polling place? | |
========================== | |
Simple script to call the Google Geocoder service and get a map of polling | |
places. View the locations in Google Maps by converting the outout GeoJSON to | |
KML (Use ogr2ogr or `Jason Sanford's geojson-google-maps | |
<https://github.com/JasonSanford/geojson-google-maps>`_ utility) .Note that | |
the Google TOS require that the results of the geocode are used to be viewed | |
in google maps. | |
Built using `requests <http://docs.python-requests.org/en/latest/>`_ which you | |
should install if you want to use this. | |
""" | |
import csv | |
import argparse | |
import sys | |
import json | |
import requests | |
GEOCODER_URL = "http://maps.googleapis.com/maps/api/geocode/json" | |
def get_locn_candidates(path): | |
""" | |
.. function:: get_locn_candidates(path) | |
Generator for querying the Google Geocoding API and returning address candidate locations | |
:param path: Path to the CSV file from the AEC | |
""" | |
params = { | |
"region": "au", | |
"sensor": "false" | |
} | |
for row in csv.DictReader(open(path)): | |
params["address"] = "{Premises}, {Address}, {Suburb}, {State}".format(**row) | |
r = requests.get(GEOCODER_URL, params=params) | |
r.raise_for_status() | |
j = r.json() | |
if j["status"] == "OK": | |
yield j, row["Premises"] | |
elif j["status"] == "ZERO_RESULTS": | |
sys.stderr.write("Could not find a location for %s\r\n" % params["address"]) | |
else: | |
raise requests.exceptions.HTTPError, "Google Geocoder returned status of %s" % j["status"] | |
def build_geojson(csv_path, geojson_path=None): | |
""" | |
.. function:: build_geojson(csv_path[, geojson_path=None) | |
Builds a geojson object from addresses. | |
:param csv_path: Path to the CSV file from the AEC | |
:param geojson_path: Path to geojson output. Will be overwritten. | |
""" | |
if geojson_path: | |
gj_out = open(geojson_path, 'wb') | |
else: | |
gj_out = sys.stdout | |
feature_collection = { | |
"type":"FeatureCollection", | |
"features":[] | |
} | |
for response, premises in get_locn_candidates(csv_path): | |
for result in response["results"]: | |
feature = { | |
"type": "Feature", | |
"geometry": { | |
"type": "Point", | |
"coordinates": [ | |
result["geometry"]["location"]["lng"], | |
result["geometry"]["location"]["lat"] | |
] | |
}, | |
"properties": { | |
"premises": premises, | |
"google_address": result["formatted_address"], | |
"accuracy": result["geometry"]["location_type"] | |
} | |
} | |
feature_collection["features"].append(feature) | |
json.dump(feature_collection, gj_out, indent=2) | |
if __name__ == "__main__": | |
args = argparse.ArgumentParser(description=__doc__) | |
args.add_argument("csv_path", help="Path to the CSV of polling places downloaded from the AEC") | |
args.add_argument("-g", "--geojson", help="Path to a file to write the geojson file to. Will be overwritten") | |
a = args.parse_args() | |
build_geojson(a.csv_path, a.geojson) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment