Skip to main content
Every renderer-aware Footstep tool returns a render array on its response — a list of framework-agnostic GeoJSON layer descriptors. Drop them straight into deck.gl, MapLibre, Leaflet, Mapbox-GL-JS, or Cesium.
render is included by default. Pass compact: true to suppress it on calls from text-only clients — see response defaults & controls.

Layer descriptor shape

Every entry in render is a discriminated union on kind. Common fields: Layers do not carry an id or opacity — those belong to the renderer. Order in the array is z-precedence: earlier layers render under later ones.

Layer kinds

linestring — routes, traces, snapped paths

Emitted by get_directions, find_and_route, optimize_stops, compare_routes, search_along_route, snap_trace. style_hints.mode carries the travel mode (only on compare_routes); recommended_color is provided when one mode-styled layer needs to visually distinguish itself from another.

point — geocode results, destinations, ordered stops

Emitted by geocode, reverse_geocode, search_places, batch_geocode, plus the destination/stop layers attached to find_and_route, optimize_stops, search_along_route. Per-feature properties carries the row’s full record (label, confidence, place_type, etc.) so you can drive popups directly from the GeoJSON.

polygon — isochrone contours, areas

Emitted by get_isochrone (one layer per contour). style_hints.contour_value is the underlying numeric (minutes / kilometres) so renderers can colour by gradient.

h3-cells — predicted probability surfaces

Emitted by get_prediction. style_hints.value_range is required — clients use it to pick a colour scale without a second pass over the data. deck.gl’s H3HexagonLayer consumes data directly via getHexagon: d => d.hex.

trips, arcs, heatmap

Reserved for future spatial tools (animated trips for trajectory replay, arcs for matrix flows, heatmaps for density). Their schemas mirror the deck.gl layer of the same name; see @footstep-internal/render-envelope for the type definitions.

Framework integration

deck.gl

The kind taxonomy maps directly to deck.gl primitives: Translator example:

MapLibre / Mapbox-GL-JS

GeoJSON-typed kinds (linestring, point, polygon) drop straight in as sources:
For h3-cells, use h3-js to convert each hex to its boundary and emit a polygon FeatureCollection.

Leaflet

Leaflet’s fitBounds takes [[lat, lng], [lat, lng]] — flip from the RFC 7946 array.

Cesium

Use Cesium.GeoJsonDataSource.load(layer.data) for the GeoJSON-typed kinds. For h3-cells, convert via h3-js to polygons and add as a CZML / GeoJSON data source.

When the response has multiple layers

Several tools emit two or more layers in render:
  • find_and_route[linestring(route), point(destination)]
  • optimize_stops[linestring(route), point(ordered stops)]
  • compare_routes → one linestring per travel mode
  • get_isochrone → one polygon per contour
  • search_along_route[linestring(route), point(matched places)]
Iterate the array and add each layer. To fit the camera to the whole result, merge bounding boxes:

Suppressing the envelope

Text-only clients (Claude Desktop, terminal CLIs, summary bots) pass compact: true on every call to skip the envelope and only receive narrative-friendly summary fields. See response defaults & controls.