Skip to content

Instantly share code, notes, and snippets.

@b5
Created January 22, 2019 16:38
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 b5/7fc378b6ee504e929ab390bca8f038f6 to your computer and use it in GitHub Desktop.
Save b5/7fc378b6ee504e929ab390bca8f038f6 to your computer and use it in GitHub Desktop.
Starlark Geospatial sample
# this is a Qri starlark transform script, use it with qri: https://qri.io
load("http.star", "http")
load("geo.star", "geo")
def download(ctx):
# Download list of 311 complaints, currently capped to 10000 responses for testing purposes
complaints = http.get("https://data.cityofnewyork.us/resource/fhrw-4uyv.json?$offset=0&$limit=10000")
# Download the New York Borough Boundaries
boros = http.get("http://data.beta.nyc//dataset/68c0332f-c3bb-4a78-a0c1-32af515892d6/resource/7c164faa-4458-4ff2-9ef0-09db00b509ef/download/42c737fd496f4d6683bba25fb0e86e1dnycboroughboundaries.geojson")
return {
"complaints" : complaints.json(),
# send boros over as a JSON string, parseGeoJSON will do the decoding
"boros": boros.text(),
}
def transform(ds, ctx):
complaints = ctx.download["complaints"]
boundaries, properties = geo.parseGeoJSON(ctx.download["boros"])
# bouroughs data specifies a number of polygons for each borough,
# combine them all into MultiPolygons, one for each borough
boro_names = [ boro['borough'] for boro in properties]
geoms = reduce(append_polygon, zip(boro_names, boundaries), {})
geoms = [geo.MultiPolygon(geoms[x]) for x in geoms]
boro_names = list(set(boro_names))
# dict of complaint-counts, keyed by borough name
boro_counts = dict(zip(boro_names, [0]*len(boro_names)))
for complaint in complaints:
# only use complaints that have lat & lng values
if 'latitude' in complaint and 'longitude' in complaint:
point = geo.Point(float(complaint['longitude']), float(complaint['latitude']))
for boro_name, geom in zip(boro_names, geoms):
if geo.within(point, geom):
boro_counts[boro_name] += 1
ds.set_body(boro_counts)
def append_polygon(acc, prop):
polys = acc.get(prop[0], [])
polys.append(prop[1])
acc[prop[0]] = polys
return acc
def reduce(fn, l, v):
for _, el in enumerate(l):
v = fn(v, el)
return v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment