Skip to content

Design a standard multi-resolution H3 hex representation (IUCN richness, iNat ranges) #548

Description

@cboettig

Some datasets are inherently multi-resolution: they contain features spanning many orders of magnitude in size, so no single native H3 resolution works.

  • Too fine for a global / continent-scale feature → astronomical cell counts and OOM (e.g. a globally-distributed species range at res 8).
  • Too coarse for a tiny feature → the feature collapses to a handful of cells or vanishes (e.g. a narrow-endemic range, a small wetland, at res 5).

Forcing one resolution is therefore either hopeless or lossy. We need a standard, documented way to represent and query multi-resolution hex across the catalog — today each such dataset invents its own custom handling.

Concrete cases

dataset today problem
IUCN richness (public-iucn) two homes: res-8 richness/hex and res-5 hex/ not a duplicate to reconcile — a genuine multi-res need with no standard representation or documented query path
iNat ranges (public-inat/range-maps/hex) single native res 4 coarse; under-serves small-range taxa
swap/nevada/mixres.py bespoke multi-resolution assembler prior art — literally hand-rolls what a standard should provide

Design questions to resolve

  1. Representation. One asset with a per-row/per-feature resolution marker? Separate assets per resolution with a documented join convention? A single "mixed-resolution" hex where each feature is stored at the finest resolution it can afford, carrying parents for roll-up joins?
  2. Query pattern. How does a consumer aggregate/join without knowing which resolution a given feature lives at? Must be reliable for LLM agents (the audience for these STAC descriptions).
  3. cng-datasets support. What would an adaptive/per-feature resolution mode look like in the standard build (likely an enhancement on boettiger-lab/datasets)? File the enhancement once the representation is chosen.
  4. STAC. h3:native_resolution is singular today; extend the convention to declare a resolution set / adaptive scheme on the asset.

Acceptance

  • A written standard for multi-resolution hex: representation + query pattern + STAC declaration.
  • Any required cng-datasets enhancement filed and linked.
  • IUCN richness re-expressed in the standard form (retires the ad-hoc two-location split and catalog/iucn/k8s/iucn-reencode-hex.yaml).

Blocks / unblocks

These derivation jobs stay on custom COPY … PARTITION_BY (h0) code until this design (and the reducers it implies) land in the standard routines — they do real derived work, so they can't just be deleted:

  • high-seas add-parents / gfw aggregate·rename·consolidate
  • plant-richness / rarity-weighted-endemic-plant-richness p80-percentile hex
  • gbif/2026-06/process_gbif_h3.py, overturemaps/.../derive-countries-hex.yaml
  • catalog/iucn/k8s/iucn-reencode-hex.yaml (held pending the IUCN re-expression)

Background — completed migration work (#332 follow-up, now done)

This issue began as the #332 follow-up ("which pipeline writes iNat / IUCN so fragmentation doesn't recur"). The answer: hex fragmentation came from custom COPY … TO '<dir>/' (PARTITION_BY (h0)) jobs (multi-thread → one file per thread per partition), not cng-datasets — the standard raster/vector/repartition routines already write one data_0.parquet per h0. All of that is resolved:

What is left is purely the multi-resolution design above — no live data defect.

Refs #332, #551.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions