What is the Census Geocoder?
The Census Geocoder API is a remarkable tool. In a few simple lines of code, you transform addresses into a wealth of geospatial information, including location coordinates, census tract, voting district, etc.
The problem? The Geocoder misses a lot of addresses.
For example, the Philadelphia Art Museum is located at 2600 Benjamin Franklin Pkwy, Philadelphia, PA 19130. But, as of January 2023, if you put this address into the Geocoder API, it returns a blank. The address doesn’t match anything in its records.
Fortunately, you can send geographic coordinates to the API in addition to addresses. So, if you know the coordinates of the Philadelphia Art Museum, you still can get the information you need. There are several programs that specialize in this task of converting addresses into locations, such as Google Maps, Mapbox, etc.
At scale, this method of first converting your addresses into coordinates before sending to the Census Geocoder is more effective than sending addresses directly. You don’t have to worry about missing address records or correcting the spelling of addresses.
Enhancement Using the Mapbox API
Let’s see how this process works using the Mapbox API.
First, we’ll load the requests library. Since the Mapbox API requires a key, we’ll also load the os and dotenv libraries to retrieve the key as an environment variable.
import requests
from dotenv import load_dotenv
import os
load_dotenv()
MAPBOX_KEY = os.getenv('MAPBOX_TOKEN')
Now, we’ll convert the address of the Philadelphia Art Museum into coordinates using the Mapbox API.
# example address
address = "2600 Benjamin Franklin Pkwy, Philadelphia, PA 19130"
# make request to mapbox api using requests module to get longitude and latitude for address
url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + address + ".json?access_token=" + MAPBOX_KEY
response = requests.get(url).json()
# extract longitude and latitude from response
longitude = response["features"][0]["geometry"]["coordinates"][0]
latitude = response["features"][0]["geometry"]["coordinates"][1]
A fun twist
The world is round. Maps aren’t. To ease this tension, cartographers use different projections to flatten the world. The most common projection is the Mercator projection, which is used by Google Maps, Mapbox, and many other mapping services. But the Census Geocoder uses a different projection, known as NAD83, which better represents the United States.
Within the United States, the difference between the Mercator and NAD83 projections is small, a few feet at most. But, if you are worried about that level of detail, then you can convert your coordinates from the Mercator projection to the NAD83 projection. The pyproj library makes this easy.
from pyproj import Transformer
# Web Mercator = "EPSG:4326"
# NAD83 = "EPSG:4269"
transformer = Transformer.from_crs("EPSG:4326", "EPSG:4269")
latitude_nad83, longitude_nad83 = transformer.transform(latitude, longitude)
And finally, we’ll then send those coordinates to the Census Geocoder API. (Note that you can also change the benchmark and vintage parameters if you’re interested in, say, the legislative district an area used to be in.)
# make request to census geocoder api using requests module to get census tract for address
payload = {'x': longitude_nad83, 'y': latitude_nad83, 'benchmark': 4, 'vintage': 4, 'format': 'json'}
url = "https://geocoding.geo.census.gov/geocoder/geographies/coordinates"
response = requests.get(url, params=payload)
From this response, we can extract a huge amount of information!
response.json()