12

I have a bunch of latitude,longitude coordinates (mostly city/town centroids) in the United States for which I'd like to find the containing census tract.

For instance,

input => nn.nnn, -nn.nnn 
output => 010300

Is there a free or low-cost API out there that can help? (Essentially Yahoo Placefinder, with the additional response of census tract.)

(I understand that many cities include multiple census tracts and I'd expect that some small towns contain only parts of one or more census tracts. I'm comfortable ignoring that issue for now.)

1
  • Are you thinking about solution for a certain area or country agnostic solution?
    – radek
    Mar 10, 2012 at 1:04

5 Answers 5

11

The FCC census block conversion API is exactly what you're looking for.

2
  • Yup. Embarrassing, because I considered it for another part of the project, and had forgotten. Thanks. Mar 15, 2012 at 3:23
  • Note, in 2018 that link shows "This API has been replaced by the new Area and Census Block API, updated to reduce response time and support additional Area related data elements. As such, this legacy API is being decommissioned." and links to geo.fcc.gov/api/census. Commenting for posterity
    – arvi1000
    Jun 20, 2018 at 22:29
6

In PostGIS, if you have a table of points, and the census boundary information that @Sminbamangu refers to you could calculate this using the following approach:

SELECT 
       c.census_tract, 
       p.point_id
FROM
       census_boundary as c,
       table_of_points as p
WHERE
       ST_Contains(c.geom, p.geom);

You can see the description ST_Contains here. This would return a table of the points, and the census tract where they are located.

2
  • Tried that in Spatialite with 10 points and the California data and it does it in about 0.2 seconds ... +1.
    – Simbamangu
    Mar 11, 2012 at 6:33
  • Nice - I must explore Spatialite. I started using PostGIS 6 months ago and love it, but it's pretty heavy duty. Would be nice to have more self-contained datasets that are portable for times when there is no internet.
    – djq
    Mar 11, 2012 at 15:45
2

You could do it locally instead of an online API. One solution with R: Census boundary data for the USA is available through TIGER at census.gov; if you're thinking about the US then you could download the US states and use a function to get the tracts. For example, using California and a random (or random-ish) point:

library(maps)
library(maptools)


tractLookup <- function(x, y, state) {
  pt <- SpatialPoints(data.frame(x = x, y = y))
  overlay.pt <- overlay(pt, state) # what index number does pt fall inside?
  return(census$TRACT[overlay.pt]) # give the Tract number from the census layer
}

Try it out:

california <- readShapePoly("~/Downloads/US_2000_Census_Tracts/tr06_d00_shp/tr06_d00.shp")
tractLookup(-123.123, 40.789, california)

Gives 0004, which is correct.

# Look at the map
plot(census)
map('state', c('California'), lwd = 2, col = 'green', add = F) # optional
points(-123.123, 40.789, col = 'red', lwd = 2)

This works, but takes 5 seconds on my Mac, which would probably be too much if you're going to do a lot of this; I suspect someone will weigh in shortly with a PostGIS solution that will be a million times quicker ...

1

As mentioned by @Simbamangu, this could easily done locally by just about any desktop GIS software on the market.

For free & open source, take a look at a "join attributes by location" in QGIS.

If you plan to need to do this repeatedly over time, you could consider putting the datasets into PostGIS and creating a spatial join (see this example in the online help). You can then visualize the results in QGIS.

0
1

You can use Geocodio to convert latitude/longitude coordinates to FIPS codes.

We don't have a reverse geocooding to FIPS example in our docs, but it works the same way as the forward endpoint. You can see an example here (note: this DEMO API key has a limit per day, so you may need to create a free API key to see this. The first 2,500 lookups per day are free, no credit card required.)

https://api.geocod.io/v1.6/reverse?q=38.9002898,-76.9990361&&fields=census&api_key=DEMO

You can also see all of the data returned here: https://www.geocod.io/docs/?python#census-block-tract-fips-codes-amp-msa-csa-codes

Disclosure: I am one of the founders of Geocodio.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.