Files
GeoLibre/docs
Qiusheng Wu b01611255e feat(data): add ICESat-2 and GEDI spaceborne LiDAR footprints (#3079)
* feat(data): add ICESat-2 and GEDI spaceborne LiDAR footprints

Add Data -> ICESat-2 / GEDI reads a local HDF5 granule of ICESat-2
ATL06/ATL08 or GEDI L2A/L2B/L4A in the browser (h5wasm) and adds its
footprints as a GeoJSON point layer. The NetCDF reader skipped these
products because their per-footprint arrays are 1-D.

The reader picks a product description from the root short_name (or the
DAAC file name), lists beams and every 1-D field aligned with the
footprints, applies the product's quality flag and fill values, and adds
beam, beam type, UTC time and along-track distance to each feature. It
can limit the read to the current view and thins every beam evenly to a
point cap. The new layer is colored by the product's main field, so the
attribute table charts give an along-track profile.

Refs #3078

* Address review feedback

- Thin footprints with one stride over all beams' matches, so maxPoints
  caps the total; restarting the index per beam kept the first match of
  every beam and could exceed the cap (CodeRabbit).
- Null 64-bit integer fields that equal their _FillValue, compared as
  BigInt so the fill is not lost to float64 rounding (Claude).
- Fit a track that crosses the antimeridian with unwrapped bounds instead
  of zooming out to the whole world; pointBounds moves to lib/ so it can
  be unit-tested (Claude).

* Address review feedback

- Fall back to the default point cap when the Maximum footprints box is
  empty or invalid, instead of lifting the cap and building a
  million-feature layer from a full GEDI orbit (Claude).
- Compare a numeric 64-bit _FillValue only when it is a safe integer, as
  a BigInt, so a rounded fill cannot null a neighboring shot number; test
  added (CodeRabbit).

* Address Claude review feedback

- Drop an Add whose granule was closed during the pre-read yield (dialog
  closed or another file picked), instead of reading the closed file and
  reporting "No footprints matched" for the wrong granule.

* Address Claude review feedback

- Say what the quality filter does for each product under the checkbox,
  and relabel it "Apply the product's quality filter": ATL08 has no
  quality flag and only drops segments without a terrain height, so
  "pass the product's quality flag" overstated it.
- Drop the unreachable shift in pointBounds: the shifted range is only
  narrower when points straddle 180°, which keeps west360 in [0, 180].

* Address CodeRabbit review feedback

- Clear the busy state when another file is picked: a submit superseded
  during its pre-read yield returns early without clearing it, which left
  the Add button disabled for the newly opened granule.

* Address Claude review feedback

- Clamp a fractional maxPoints to at least 1, so 0.5 no longer floors
  to 0 and yields an infinite stride.
- Keep the first field with a name and rename only later duplicates to
  their path, so a product's default names (and the color-by primary
  field) stay stable when another dataset shares a name.

* feat(data): ICESat-2/GEDI sample granules, resizable dialog, Files section

- Add a Sample data dropdown with one granule per product (ATL06, ATL08,
  GEDI L2A/L2B/L4A) hosted on Source Cooperative, downloaded with a
  progress readout into a preallocated buffer and cancelled when the
  dialog closes or another file is picked.
- Stop the horizontal scrollbar: the dialog body is a grid whose column
  grew to the longest unbreakable HDF5 path (ATL06), so the form gets
  min-w-0 and field paths truncate.
- Widen the default dialog and add a corner resize grip, through a
  useDialogResize hook that follows the layer metadata dialog's grip.
- Move the menu entry from 3D layers to Files: the footprints render as
  flat points read from a granule file.

* Split the ICESat-2/GEDI dialog and handle encoded sample downloads

- check:untested-modules failed: the dialog reached 615 lines with no
  test loading it. Move the sample list, downloadWithProgress, fieldKey
  and baseName into lib/spaceborne-lidar-samples.ts (with tests), and the
  beam/field/filter controls into SpaceborneLidarOptions.tsx; the dialog
  is now 435 lines.
- Read a content-encoded response whole instead of preallocating from
  Content-Length, which is the compressed size there and would overflow
  the buffer (Claude review).
2026-10-09 21:33:24 -04:00
..
…
…
…