Fire Grid
Fire Grid aggregates individual fire events (hotspots) onto an H3 hexagonal grid. Instead of returning every hotspot, the grid buckets them into hexagonal cells at a chosen resolution and returns one aggregated record per cell. This keeps responses small and stable across zoom levels while still conveying where, how recently, and how intensely fire is burning.
Two endpoints expose the same aggregation in different shapes:
| Endpoint | Response | Use it when… |
|---|---|---|
GET /v1/fires/h3/json/ | Plain JSON array of cell records (no geometry) | You render the cells yourself from the h3_cell index, or you only need the per-cell metrics (counts, FRP, recency) without geometry. |
GET /v1/fires/h3/geojson/ | GeoJSON FeatureCollection; each feature is a cell polygon | You want ready-to-draw hexagon polygons and prefer not to convert H3 indices to geometry yourself. |
Both endpoints accept the same query parameters, require the apikey header, and
share the same bounding box (xmin, ymin, xmax, ymax), time
(date, minutes), satellite/algorithm, confidence and epsg filters as
GET /v1/fires/. The two parameters specific to the grid are:
h3_resolution(0–15, default8): the size of the cells (see below).shape_mode(pointorshape, defaultpoint): whether a hotspot is assigned to the single cell containing its centroid (point), or to every cell its footprint overlaps once buffered by half its GSD (shape).
Using the right API
- Analysis / custom rendering:
/fires/h3/json/. The array form is the lightest payload. You get theh3_cellindex for every populated cell and can compute the boundary, centroid or neighbours locally with any H3 binding, or feed the metrics straight into a table or chart. - Map display:
/fires/h3/geojson/. Each feature already carries the cell polygon in the requestedepsg, so you can hand theFeatureCollectiondirectly to a GeoJSON layer. The properties of every feature are exactly the fields documented in the JSON schema below.
Both endpoints return the identical set of aggregated properties, so you can switch between them without changing how you interpret a cell.
Choosing the cell resolution from the map zoom
The API does not infer resolution from a map zoom, you pass
h3_resolution explicitly. Pick a resolution so that cells stay a comfortable
on-screen size: too coarse and the fire footprint is a single blob, too fine and
you request thousands of tiny cells.
A good default heuristic for a standard 256 px Web-Mercator tile pyramid is:
h3_resolution = clamp(zoom - 3, 0, 15)
which keeps cells roughly 20–60 px across. Reissue the request with the new resolution whenever the user zooms across a threshold. As a reference, the average H3 cell edge length per resolution:
| Map zoom | h3_resolution | Approx. cell edge | Typical view |
|---|---|---|---|
| 0–3 | 0–1 | 1300 km → 480 km | Whole globe / continents |
| 4 | 1 | 480 km | Sub-continental |
| 5 | 2 | 180 km | Large country |
| 6 | 3 | 69 km | Region |
| 7 | 4 | 26 km | Large metro area |
| 8 | 5 | 10 km | Metro area |
| 9 | 6 | 3.7 km | City |
| 10 | 7 | 1.4 km | District |
| 11 | 8 (default) | 530 m | Neighbourhood |
| 12 | 9 | 200 m | Blocks |
| 13 | 10 | 76 m | Individual hotspots |
| 14+ | 11–15 | ≤ 29 m | Sub-hotspot detail |
Interpreting a cell
Every cell (a JSON array element, or one GeoJSON feature's properties) has the same fields:
| Field | Meaning |
|---|---|
h3_cell | The H3 index (base-16 string) at the requested resolution. Convert it to a boundary, centroid or set of neighbours with any H3 library. |
latest_acquisition_time | The most recent satellite acquisition among the hotspots in the cell, i.e. how fresh the activity is. |
min_gsd | Smallest (best) ground sampling distance, in metres, among the hotspots in the cell. Lower = more spatially precise detection. |
scale_factor | Pre-computed rendering scale in [0.25, 0.95] derived from the GSD (see scaling below). |
max_frp | Highest fire radiative power, in MW, observed in the cell. |
satellites | Distinct satellites that contributed a hotspot to the cell. |
leo_hotspot_count | Hotspots detected by low-earth-orbit satellites (higher spatial resolution, infrequent revisit). |
geo_hotspot_count | Hotspots detected by geostationary satellites (coarser resolution, frequent revisit). |
cluster_ids | The distinct fire cluster IDs the cell's hotspots belong to. Use these to cross-reference GET /v1/clusters/{id}. |
A cell tells you: something was detected here (h3_cell), how recently
(latest_acquisition_time), how strong (max_frp), how trustworthy the
position is (min_gsd, scale_factor), and by what (satellites,
leo_hotspot_count, geo_hotspot_count).
Colouring a cell
Colour communicates the dimension that matters for your use case. Two common schemes:
- By recency (default for live monitoring). Compute the cell age from
latest_acquisition_time(now - latest_acquisition_time) and map it onto a ramp, e.g. bright red/orange for the last hour, fading toward a muted grey/brown for older activity. This makes the current fire front stand out against cooling areas. - By intensity. Map
max_frponto a sequential ramp (e.g. yellow → red → purple). FRP spans orders of magnitude, so apply a logarithmic scale and clamp to a sensible maximum before mapping.
Whatever the hue encodes, you can encode a second dimension in opacity. For
example intensity in hue and recency in opacity, or vice-versa. Because the
json and geojson endpoints expose identical fields, the same colour logic
works for both.
Scaling a cell by GSD (inverted GSD)
Rendering every cell as a full hexagon overstates the certainty of coarse
detections. To convey spatial precision, scale each cell polygon about its
centroid by scale_factor before drawing it. The scale is inversely related
to GSD: precise (small-GSD) detections are drawn close to the full hexagon,
while coarse (large-GSD) detections shrink toward the cell centre.
scale_factor is pre-computed server-side so both endpoints agree. It is
derived from the cell's effective minimum GSD:
- Per hotspot, the effective GSD is its
gsd, except hotspots flaggedlow_accuracy, which are penalised to2000 m. - The cell takes the minimum effective GSD across its hotspots.
- That minimum is mapped to a scale, clamped to
[0.25, 0.95]:
MIN_GSD = 150 # m → best resolution we distinguish
MAX_GSD = 2000 # m → coarsest / low-accuracy
MIN_SCALE = 0.25
MAX_SCALE = 0.95
if min_gsd <= MIN_GSD: scale = MAX_SCALE # 0.95, near full hexagon
elif min_gsd >= MAX_GSD: scale = MIN_SCALE # 0.25, small marker
else: scale = MAX_SCALE - (min_gsd - MIN_GSD)
/ (MAX_GSD - MIN_GSD) * (MAX_SCALE - MIN_SCALE)
To apply it when drawing, scale the polygon around its centroid c:
p' = c + scale_factor * (p - c) for each vertex p of the cell
The json endpoint returns scale_factor alongside the metrics; the geojson
endpoint returns it as a feature property. If you prefer to derive the scale
yourself (for example to re-tune the constants), apply the formula above to the
cell's min_gsd, but note that min_gsd is the raw minimum GSD and does not
carry the low_accuracy penalty, so it will differ from scale_factor for cells
that only contain low-accuracy detections. Prefer the pre-computed
scale_factor unless you have a reason not to.