Looking for a home¶
Say you are moving to a new city and want to live somewhere walkable. Here you find the blocks that are within a 10-minute walk of a grocery store, a 5-minute walk of a restaurant, and a 20-minute walk of a frequent-transit stop. Then you narrow those blocks to the overlap of two commutes. The example city is Somerville, Massachusetts.
Running this tutorial uses about 2,900 tokens.
Set up¶
Build a client, then read the pieces you need from the free catalog.
from closecity import Client
import geopandas as gpd
close = Client("ck_live_your_key") # use your own key here
types = close.destination_types()
ids = dict(zip(types["label"], types["dest_type_id"]))
grocery = ids["grocery_stores"]
restaurant = ids["restaurants"]
transit = ids["frequent_transit"]
city = close.places("Somerville").iloc[0]
See what is around¶
Each search returns points, so plot the three amenities as three layers.
groceries = close.pois_search(lat = city["lat"], lon = city["lon"],
radius_m = 3000, type = grocery)
restaurants = close.pois_search(lat = city["lat"], lon = city["lon"],
radius_m = 3000, type = restaurant)
stops = close.pois_search(lat = city["lat"], lon = city["lon"],
radius_m = 3000, type = transit)
ax = restaurants.plot(color = "#c6cbe0", markersize = 6)
groceries.plot(ax = ax, color = "#058040")
stops.plot(ax = ax, color = "#f36e21", marker = "^")
<Axes: >
Find the blocks that qualify¶
Somerville is a census place, so one call by place GEOID pulls the per-block walk
times for every block in the city. The result is a GeoDataFrame with one row per
(block, category); the boundaries come from pygris, downloaded once. To search an
arbitrary area instead, use blocks_query with a centre and radius or a polygon.
blocks = close.place_blocks(city["geoid"], mode = "walk",
type = [grocery, restaurant, transit])
Take the blocks that pass each rule, then keep the blocks that pass all three.
near_grocery = set(blocks.loc[(blocks.dest_type_id == grocery) &
(blocks.travel_time <= 10), "geoid"])
near_restaurant = set(blocks.loc[(blocks.dest_type_id == restaurant) &
(blocks.travel_time <= 5), "geoid"])
near_transit = set(blocks.loc[(blocks.dest_type_id == transit) &
(blocks.travel_time <= 20), "geoid"])
candidates = near_grocery & near_restaurant & near_transit
winners = blocks[blocks.geoid.isin(candidates)]
ax = blocks.plot(color = "#eef0f7", edgecolor = "white")
winners.plot(ax = ax, color = "#f36e21")
<Axes: >