Census Reporter API Exploration

We’re trying out a new site idea for the online digital sociology program. Once again, Matt came up with an idea that really got me excited and I started wandering around trying to figure out how to make it work. At some point I found CensusReporter.org. This is a pretty amazing site that is a Knight1 News Challenge-funded project.

What we want to do is figure out roughly where the viewer/visitor is geographically and give them a glimpse of that area through some data. Nothing too deep, just a taste of the interesting ways technology, data, and visualization can blend together to do interesting things. We don’t want the exact address for a few reasons. One, we don’t want to be too creepy. Two, getting a rough location through the IP address doesn’t trigger the browser approval request that more exact location data requires. My goal is not to subvert the approving/denying of location data but I worry too many people will miss that approval prompt and we’re not keeping this data.

Get Location

To get local data I have to figure out where the person is. To do that, I’m just grabbing the IP address and getting a location bounced back. There are a few ways to do this. I went with freegeoip.net and the following function would give a chunk of useful json location data.

The request (jquery style).

$.getJSON("//freegeoip.net/json/?callback=?", function(data) {
  var location = data;
  var lat = location.latitude;
  var long = location.longitude;
  var city = location.city;
  var state = location.region_code;
});

The data returned.

{
"ip": "128.172.35.18",
"country_code": "US",
"country_name": "United States",
"region_code": "VA",
"region_name": "Virginia",
"city": "Richmond",
"zip_code": "23284",
"time_zone": "America/New_York",
"latitude": 37.5538,
"longitude": -77.4603,
"metro_code": 556
}

Census Reporter

iframe Chart

In one of my semi-lucid searches I found this profile chart embed page. The iframe looked like this. I saw the geoID= and I was all excited. It looks like I can build these dynamically!2

<iframe id="cr-embed-16000US5367000-demographics-age-distribution_by_decade-total" class="census-reporter-embed" src="https://s3.amazonaws.com/embed.censusreporter.org/1.0/iframe.html?geoID=16000US5367000&chartDataID=demographics-age-distribution_by_decade-total&dataYear=2016&releaseID=ACS_2016_1-year&chartType=histogram&chartHeight=200&chartQualifier=&chartTitle=Population+by+age+range&initialSort=&statType=scaled-percentage" frameborder="0" width="100%" height="300" style="margin: 1em; max-width: 960px;"></iframe>

So I thought I’d be set to pull data using the city/state or the latitude/longitude but to use the census reporter I need the geoID. I went off on a few false trails but eventually found the API call to look up geoIDs via the census reporter itself.

Attempt One

https://api.censusreporter.org/1.0/geo/search?q=richmond
The trimmed down response to that query is below. The full_geoid is what I want but I’m hoping to ask without having to run a second loop through to match the full_name data.

{
"results": [
{
"full_geoid": "16000US5167000",
"full_name": "Richmond, VA",
"sumlevel": "160"
},
{
"full_geoid": "16000US0660620",
"full_name": "Richmond, CA",
"sumlevel": "160"
},
{
"full_geoid": "16000US1864260",
"full_name": "Richmond, IN",
"sumlevel": "160"
},
{
"full_geoid": "16000US1260230",
"full_name": "Richmond West, FL",
"sumlevel": "160"
},
{
"full_geoid": "05000US36085",
"full_name": "Richmond County, NY",
"sumlevel": "050"
},
{
"full_geoid": "05000US51760",
"full_name": "Richmond city, VA",
"sumlevel": "050"
},
{
"full_geoid": "05000US13245",
"full_name": "Richmond County, GA",
"sumlevel": "050"
}
]
}

Attempts #2a, #2b etc.

This fails with no results.
https://api.censusreporter.org/1.0/geo/search?q=richmond,va

My next try was to URL encode the query. I used this because I never remember how to encode commas.
https://api.censusreporter.org/1.0/geo/search?q=richmond%2C%20va

It gave me two responses but strangely neither one matches the geoID I want. I have no idea why.

{
"results": [
{
"full_geoid": "31000US40060",
"full_name": "Richmond, VA Metro Area",
"sumlevel": "310"
},
{
"full_geoid": "40000US74746",
"full_name": "Richmond, VA Urbanized Area",
"sumlevel": "400"
}
]
}

Attempt #3

You can also look up via lat/long. I know that because the API told me when I asked for something it wouldn’t respond to. It didn’t tell me exactly how to ask it though. There are several times were I tried longitude, long, and lng instead of lon but I’ll save you seeing that. This is what worked.
https://api.censusreporter.org/1.0/geo/search?lat=37.6211&lon=-77.6515
Sadly, this gives me a number of items back but not the Richmond one I expected.

Paying Attention

I continued to play some games and started getting some blank charts. I went back to the documentation page and with considerable less excitement I read.

Can I automate these embeds?
Unfortunately, no. The data for embedded charts is stored in tiny, static files to keep bandwidth low and performance high. This also lets us lock the data for a chart according to the ACS release in use when you embedded it, so your numbers don’t change just because we add new data to Census Reporter.

The data files for a chart are created the first time someone clicks “Embed” next to that chart on Census Reporter, and then stored for any future use. If you copy some embed code and change, say, the geoID variable to reflect another geography, odds are that new data file won’t have been created yet, and you’ll get a broken chart.

Ah well, it was a useful exploration and I’ll be using the site to do other stuff.