Getting started¶
A short tour of the client. The tutorials go further.
Words you will see¶
A few terms come up throughout:
Census block. The smallest area the Census Bureau publishes. Each one has a 15-digit id, its GEOID.
Destination type. A category of place, such as grocery stores or libraries. Every type has a numeric id.
Mode. How someone travels: walk, bike, or transit.
Isochrone. The area reachable from a point within a time limit, as a polygon.
Catchment. The reverse: every block that can reach a given place.
Build a client¶
You make every request through a client.
from closecity import Client
close = Client("ck_live_your_key") # use your own key here
The catalog and lookup routes are free, so Client() with no key works for those.
They come back as data frames:
close.modes()
| mode_id | mode | description | |
|---|---|---|---|
| 0 | 1 | walk | Walking |
| 1 | 2 | bike | Biking |
| 2 | 3 | transit | Public transit |
Look things up instead of guessing¶
Read the numeric id for a category from the catalog, and turn a city name into a GEOID and a centre point. Both are plain data frames, so you filter and index them the usual way.
types = close.destination_types()
grocery = types.loc[types["label"] == "grocery_stores", "dest_type_id"].iloc[0]
matches = close.places("Providence")
providence = matches.iloc[0]
providence["geoid"]
'4459000'
Make a call and map it¶
Routes with geometry return a GeoDataFrame, so you can map the result straight away.
groceries = close.pois_search(lat = providence["lat"], lon = providence["lon"],
radius_m = 1500, type = grocery)
groceries.plot(color = "#202a5b")
<Axes: >
Choose an output¶
Every route returns tabular data by default. The output setting controls the
shape:
"spatial"(the default) returns a GeoDataFrame where geometry applies, and a plain DataFrame otherwise."tabular"returns a plain DataFrame for every route and never downloads block boundaries. Reach for it when you only want the numbers."raw"returns the underlying reply, with the parsed body on.dataand the token counts alongside.
Set it on the client, or pass output= to a single call.
close.output = "raw"
summary = close.block_summary("440070008001068", mode = "walk")
summary.results
[{'dest_type_id': 1, 'mode': 'walk', 'travel_time': 10.0},
{'dest_type_id': 5, 'mode': 'walk', 'travel_time': 26.0},
{'dest_type_id': 6, 'mode': 'walk', 'travel_time': 22.0},
{'dest_type_id': 7, 'mode': 'walk', 'travel_time': 10.0},
{'dest_type_id': 27, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 28, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 29, 'mode': 'walk', 'travel_time': 9.0},
{'dest_type_id': 30, 'mode': 'walk', 'travel_time': 6.0},
{'dest_type_id': 31, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 32, 'mode': 'walk', 'travel_time': 15.0},
{'dest_type_id': 33, 'mode': 'walk', 'travel_time': 18.0},
{'dest_type_id': 34, 'mode': 'walk', 'travel_time': 9.0},
{'dest_type_id': 35, 'mode': 'walk', 'travel_time': 13.0},
{'dest_type_id': 38, 'mode': 'walk', 'travel_time': 17.0},
{'dest_type_id': 40, 'mode': 'walk', 'travel_time': 8.0},
{'dest_type_id': 41, 'mode': 'walk', 'travel_time': 9.0},
{'dest_type_id': 43, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 60, 'mode': 'walk', 'travel_time': 2.0},
{'dest_type_id': 63, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 64, 'mode': 'walk', 'travel_time': 4.0},
{'dest_type_id': 65, 'mode': 'walk', 'travel_time': 7.0},
{'dest_type_id': 66, 'mode': 'walk', 'travel_time': 13.0},
{'dest_type_id': 67, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 126, 'mode': 'walk', 'travel_time': 10.0},
{'dest_type_id': 159, 'mode': 'walk', 'travel_time': 14.0},
{'dest_type_id': 160, 'mode': 'walk', 'travel_time': 24.0},
{'dest_type_id': 200, 'mode': 'walk', 'travel_time': 2.0},
{'dest_type_id': 204, 'mode': 'walk', 'travel_time': 2.0},
{'dest_type_id': 205, 'mode': 'walk', 'travel_time': 2.0},
{'dest_type_id': 206, 'mode': 'walk', 'travel_time': 4.0},
{'dest_type_id': 207, 'mode': 'walk', 'travel_time': 7.0},
{'dest_type_id': 208, 'mode': 'walk', 'travel_time': 3.0},
{'dest_type_id': 209, 'mode': 'walk', 'travel_time': 9.0}]
In the frame modes, the token counts and other reply metadata ride on df.attrs.
Errors¶
Problem responses become typed exceptions.
from closecity import CloseAPIError
try:
close.block_summary("000000000000000")
except CloseAPIError as err:
print(err.status, err.slug)
404 block-not-found