← Back to all posts
GeoJSON GIS API

GeoJSON Traffic Events API with BBox and Radius Queries

May 7, 2026 · 5 min read

If you’re building a traffic map, the last thing you want is to parse a proprietary format and convert coordinates. Most state 511 systems publish their data in some flavor of XML, ESRI ArcGIS JSON, or a custom polyline encoding — and almost none of them speak GeoJSON natively. By the time you’ve normalized 30 different feeds into something you can hand to Leaflet, you’ve written more parser code than map code.

Road511 returns standard RFC 7946 FeatureCollections from every spatial endpoint. Same projection, same property naming, same geometry types — whether the source was Transnomis JSON, an ArcGIS FeatureServer, or a WZDx feed. Drop the response into L.geoJSON(), map.addSource(), or QGIS and you’re done.

The GeoJSON Endpoints

Every spatial list endpoint has a /geojson variant returning Content-Type: application/geo+json:

GET /api/v1/events/geojson
GET /api/v1/features/geojson?type=cameras
GET /api/v1/truck/corridor/geojson

Same query parameters as the JSON variants — you can filter by jurisdiction, severity, road, type, bbox, and radius. The only difference is what you get back: a FeatureCollection instead of a paginated list.

Bounding Box Query

Showing events for the current map viewport is a one-liner. Grab the bounds, format them as minLng,minLat,maxLng,maxLat, and pass them to the endpoint:

const bounds = map.getBounds();
const bbox = [
  bounds.getWest(), bounds.getSouth(),
  bounds.getEast(), bounds.getNorth()
].join(',');

const res = await fetch(
  `https://api.road511.com/api/v1/events/geojson?bbox=${bbox}&status=active`,
  { headers: { 'X-API-Key': key } }
);
const geojson = await res.json();
L.geoJSON(geojson).addTo(map);

Re-run the fetch on every moveend event and you have a live, viewport-aware traffic layer. PostGIS handles the spatial filter on our end with a GiST index, so the response stays fast even when the box covers half a continent.

Radius Search

For routing and dispatch use cases, a radius around a single point is usually what you want — e.g. “every active incident within 50 km of this driver’s location”:

curl "https://api.road511.com/api/v1/events/geojson?lat=34.05&lng=-118.24&radius_km=50&status=active" \
  -H "X-API-Key: your_key"

Distance is computed on a geography type with great-circle accuracy (no flat-earth approximation), so a 50 km radius near the equator and a 50 km radius in northern Alberta both behave correctly.

Layered Maps with Multiple Feature Types

Most production traffic dashboards layer several data types on the same map — cameras, message signs, weather stations, rest areas. The pattern is just one fetch per feature type:

const types = ['cameras', 'signs', 'weather_stations', 'rest_areas'];

for (const type of types) {
  const res = await fetch(
    `https://api.road511.com/api/v1/features/geojson?type=${type}&jurisdiction=CA`,
    { headers: { 'X-API-Key': key } }
  );
  const geojson = await res.json();
  L.geoJSON(geojson, {
    pointToLayer: (f, latlng) => L.marker(latlng, { icon: icons[type] })
  }).addTo(layerGroups[type]);
}

Each layer can be toggled independently with L.control.layers(). The properties.feature_type field on every feature lets you style or filter inside a single layer if you prefer that pattern instead.

LineString Geometry, Not Just Points

Construction events, truck routes, weight-restriction corridors, and traffic-flow segments aren’t points — they’re polylines. Road511 returns them as LineString features in the same response, so a single L.geoJSON() call renders the whole mix correctly:

{
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-87.63, 41.88], [-87.62, 41.89], [-87.60, 41.90]]
  },
  "properties": {
    "id": "fhwa-il-staa-001",
    "feature_type": "truck_routes",
    "name": "I-90 STAA National Network"
  }
}

The truck-corridor endpoint goes one step further: it draws a buffered geometry around your route and returns every truck-relevant feature that intersects it — bridges, weight restrictions, restricted corridors, the lot — all as one GeoJSON FeatureCollection you can layer onto a route preview.

Spatial Queries Under the Hood

Every spatial query in Road511 lands on PostGIS. bbox uses ST_Intersects with a 2D index, radius_km uses ST_DWithin on the geography type, and the truck-corridor endpoint computes ST_Buffer around a polyline route before intersecting it against the truck features. Every spatial column has a GiST index, so a continent-wide bbox returns in tens of milliseconds even with seven figures of features in scope.

What that means in practice: you can fire a fresh query on every moveend event without rate-limit anxiety, and the map stays responsive at any zoom level.

Who Uses This

Try It

Live traffic data, ready for any map library

Standard RFC 7946 GeoJSON across 50 US states and 13 Canadian provinces. Bounding box, radius, and corridor queries that drop directly into Leaflet, Mapbox, MapLibre, ArcGIS, and QGIS — with no XML wrangling. Free 14-day trial. No credit card.

Get Free API Key Explore the Map