Get started with closecity

closecity reads the Close API: travel times from every US census block to nearby places, on foot, by bike, and by public transit. This vignette is a short tour. The tutorials go further. The full list of query methods is on the CloseClient reference page, and the wider API is documented at docs.close.city.

Key terms

A few terms come up throughout:

Travel times

Times to nearby places are capped at 30 minutes for each mode, and recorded in whole minutes. A missing time means the place is not reachable within the cap, not that it is zero. Isochrones are the exception: they are available for any budget up to an hour.

Build a client

You make every request through a client object.

library(closecity)
close <- closecity::close_client(api_key = "ck_live_your_key")   # use your own key here

The catalog and lookup routes are free, so close_client() with no key also works for those.

close$modes()

Look things up instead of guessing

Two free calls save you from memorising codes. Both come back as data frames, so you filter and index them the usual way: read the numeric id for a category from the catalog, and turn a city name into a GEOID and a centre point.

amenity_types <- close$destination_types()
supermarket_type <- amenity_types[amenity_types$label == "grocery_stores", ]$dest_type_id

providence_ri <- close$places(q = "Providence")[1, ]
providence_ri[, c("name", "state", "geoid")]

The catalog’s name column is the readable label (“Grocery stores”); the underscored label is the internal key you match on. A place lookup carries a state, so you can tell Providence, RI from the one in Utah. When you have a point rather than a block, $point_summary(lat = , lon = ) reads the same travel times for a lat/lon starting point instead of a GEOID.

Make a call and map it

Routes with geometry return an sf object. close_map() draws it on an interactive basemap in one line: bright, hoverable points here, with the city boundary behind them and the view zoomed to fit.

supermarkets <- close$place_pois(geoid = providence_ri$geoid, type = supermarket_type)
city_boundary <- close$place_boundary(geoid = providence_ri$geoid)
closecity::close_map(
  x = supermarkets,
  color = "#e8590c",
  boundary = city_boundary,
  label = "name"
)

Choose an output

Every route returns tabular data by default: an sf object for inherently spatial data, a data frame otherwise. The output setting changes the shape: "tabular" never downloads boundaries, and "raw" gives the underlying reply with its metering and cursor fields. Set it on the client, or pass output = to one call.

A block summary, with the readable category names merged on and sorted by time:

walk_times <- close$block_summary(geoid = "440070008001068", mode = "walk")
walk_times <- merge(
  walk_times,
  amenity_types[, c("dest_type_id", "name")],
  by = "dest_type_id"
)
walk_times[order(walk_times$travel_time), c("name", "travel_time")]

…and the same call as the raw reply, whose results you can inspect yourself:

raw <- close$block_summary(geoid = "440070008001068", mode = "walk", output = "raw")
str(raw$results, max.level = 2, list.len = 3)

The client methods

Every data-getting method lives on the client. Follow any name to its arguments and return value on the CloseClient reference page.

Catalog and lookups (free, no key):

Travel times from a block or a point:

Points of interest:

Whole areas:

Handle errors

Failed requests raise a classed condition. Catch the base close_api_error, or a specific one.

tryCatch(
  close$block_summary(geoid = "000000000000000"),
  close_api_error = function(e) message(sprintf("%s (%d)", e$slug, e$status))
)