In February 2025, USEPA removed its EJScreen website from public access, including an API for querying EJScreen indices/indicators and Census data. One of the main features of the API was geographically-based inquiries. It could be used to, for instance, return EJScreen and Census metrics weighted based on the Census Blocks within an 3 mile buffer around a selected point. The API facilitated the creation of community reports based on those kinds of queries.
Recreating that API would require extensive reverse engineering of the ArcGIS map server(s) that hosted the API functionality. Instead, our approach is to draw on EJAM, an R package that produces similar kinds of outputs. EJAM does not currently provide an API; this repo contains files necessary to create a Docker image of EJAM and its dependencies as well as an API model.
There are currently two endpoints for the API.
report
accepts GET requests with the following parameters:
lat
- the latitude of a given pointlon
- the longitude of that pointshape
- a GeoJSON object describing an area of interest, such as a polygon of neighborhood boundariesbuffer
- radius, in miles, around the center of a point or out from the edge of a polygon to extend the search. EJAM default = 3.fips
- A FIPS code for a specific US Census geography
report
expects either lat
/lon
OR shape
OR fips
. The default buffer is 3 miles but can be explicitly set to 0.
An HTML format of a report is returned.
Block Group in the Phoenix, AZ area with a 1 mile buffer: https://ejamapi-84652557241.us-central1.run.app/report?buffer=1&fips=040131109012
A point in the Phoenix area with a 4 mile buffer: https://ejamapi-84652557241.us-central1.run.app/report?lat=33&lon=-112&buffer=4
A rectangular area of interest in Phoenix, with no buffer: https://ejamapi-84652557241.us-central1.run.app/report?shape=%7B"type"%3A"FeatureCollection"%2C"features"%3A%5B%7B"type"%3A"Feature"%2C"properties"%3A%7B%7D%2C"geometry"%3A%7B"coordinates"%3A%5B%5B%5B-112.01991856401462%2C33.51124624304089%5D%2C%5B-112.01991856401462%2C33.47010908826502%5D%2C%5B-111.95488826248605%2C33.47010908826502%5D%2C%5B-111.95488826248605%2C33.51124624304089%5D%2C%5B-112.01991856401462%2C33.51124624304089%5D%5D%5D%2C"type"%3A"Polygon"%7D%7D%5D%7D&buffer=0
data
accepts POST requests with the following parameters:
sites
- a list of lat/lon pairs e.g.[{"lat":33, "lon":-112}, {"lat":34, "lon":-114}]
shape
- a GeoJSON object describing an area of interest, such as a polygon of neighborhood boundariesbuffer
- radius, in miles, around the center of a point or out from the edge of a polygon to extend the search. Default = 0fips
- A FIPS code for a specific US Census geographyscale
- For FIPS requests, the unit of analysis (state, county, blockgroup)geometries
- A boolean to indicate whether to return a geometry field for each analyzed unit. Default = FALSE
data
expects either sites
OR shape
OR fips
.
A JSON object of EJAM output is returned.
# Queries
import json
with open('houston_zips.json', 'r') as f:
houston_zips = json.load(f)
data = {"buffer":0,"shape":json.dumps(houston_zips)} # Using a previously loaded GeoJSON of zipcodes in Houston
data = {"buffer": 1, "shape": json.dumps(simple_shape), "geometries": True} # Using a previously loaded simple GeoJSON feature, and returning its geometry
data = {"buffer": 4, "sites": [{"lat":33, "lon":-112}]} # A single set of coordinates
data = {"buffer": 4, "sites": [{"lat":33, "lon":-112}, {"lat":34, "lon":-114}]} # Two or more sets of coordinates
data = {"buffer": 0, "fips": ["482012301001","482012302002", "482012302003"], "scale":"blockgroup"} # Four blockgroups
data = {"buffer": 0, "fips": "DE", "scale": "blockgroup"} # One state, returning results at the blockgroup level
data = {"buffer": 0, "fips": "DE", "scale": "county"} # One state with county level results
data = {"buffer": 0, "fips": ["DE", "RI"], "scale": "county"} # Two states, county level results
# Execute data query
import requests
url = "https://ejamapi-84652557241.us-central1.run.app/data"
response = requests.post(url, json=data)
# Load response as Pandas dataframe
df = pandas.DataFrame.from_dict(response.json())
df
- Work locally with EJAM by installing R/RStudio. Follow the instructions in the EJAM documentation.
- Test changes to the API (i.e. modify
rest_controller.r
) - Re-build and tag the Docker image
- Push to Docker Hub and/or Google Artifact Registry
- Re-deploy in Google Cloud Run
Copyright (C) Environmental Data and Governance Initiative (EDGI) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.0.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the LICENSE
file for details.