Skip to content

Dated reference imagery: true-colour composites, NDWI/MNDWI, and RGB layers in dft_map_interactive (+ HLS source) #79

Description

@NewGraphEnvironment

Problem

Checking a land-cover label or a detected change needs dated reference imagery for windows we choose: the same season in different years, or early vs late season within a year. The basemaps in dft_map_interactive() (Esri, Google, and Bing in #78) are high resolution but have no date, so they can say what a place is and not when it changed.

drift already fetches Sentinel-2 L2A cubes (dft_stac_cube(), with cloud masking, a months filter and median aggregation), but only as a single-index stack (ndvi, kndvi, ndmi). Three pieces are missing to use it as a reference-imagery source. floodplains#93 needs them for a stratified accuracy assessment of IO LULC in BC floodplains.

Scope

  1. True-colour (and false-colour) composites. Return a multi-band composite (e.g. B04/B03/B02, or B08/B04/B03 for vegetation) for a datetime window and months, through the same cloud mask, cache and tiling path as dft_stac_cube(). The new_graphiti post 2026-01-08-stac-ortho-mosaics did this outside drift with rstac + gdalcubes (June–July, eo:cloud_cover <= 20, median). That code is the starting point, and should not become a second copy.

  2. Water and wetness indices. Add NDWI (green/NIR) and MNDWI (green/SWIR16) to dft_index_table(). ndmi is there already. These are the direct indices for wetland drying and water extent.

  3. RGB layers in dft_map_interactive(). Today x is classified rasters coloured through class_table. Accept RGB composites as switchable overlays too, with labels such as "2017 Jun–Jul" and "2023 Aug–Sep", alongside the classified layers and transitions.

  4. HLS as a second cube source: split off to HLS (Harmonized Landsat Sentinel-2) as a cube source: Earthdata auth, CMR-STAC query, bit-mask Fmask #82. Harmonized Landsat Sentinel-2 through NASA Earthdata: 30 m, from 2013, 2–3 day revisit, for a pre-2017 baseline and seasonal density. A live spike (2026-09-28) established:

    • CMR-STAC rejects intersects (HTTP 500) and ignores the CQL2 cloud filter;
    • reading needs a real Earthdata Login account, because earthdatalogin's default credentials now return 401;
    • S30 and L30 differ in NIR/SWIR asset names;
    • Fmask is a bit mask, which gdalcubes::image_mask(bits=) can express.

    HLS (Harmonized Landsat Sentinel-2) as a cube source: Earthdata auth, CMR-STAC query, bit-mask Fmask #82 carries the rest.

Scale (added at the plan gate, 2026-09-28)

floodplains#93 reviews sample points across whole floodplains, not a reach, and the approach is built for that:

  • Per-point chips. Call dft_stac_composite() once per buffered sample point. Each chip is small and cached on its own, so adding a point fetches one chip. A single call over all the points would span the floodplain under one cache key.
  • Floodplain-wide browsing. Composites are cached as COGs, and dft_map_interactive(rgb =) accepts COG URLs served by titiler, as well as local rasters. The upload to object storage is the driver's job.
  • Composites are surface reflectance (float), not display bytes, so they can later serve as classifier covariates (floodplains#93, move 6).

Depends on #80: gdalcubes was archived on CRAN, so it now installs from GitHub. Pre-existing read-path defects surfaced here are #83.

Resolution (PR #86, v0.18.0, 2026-09-28)

All four acceptance items landed:

What differs from the text above:

  • Per-point chips work; floodplain-wide composites do not yet complete at BULK size.
    • 100 BULK chips took 84 min, median 40 s each.
    • A floodplain-wide read over BULK now gets every tile (3 h 16 min). That needed two read-path fixes that also apply to dft_stac_cube(): a convex-hull query past Planetary Computer's ~1 MiB search limit, and per-tile re-signing past its ~45-min token life.
    • Clipping the merged mosaic then fails. That is Floodplain-wide tiled composite: terra::mask cannot read the merged mosaic after a 3-hour read #88, so "floodplain-wide browsing via COG" above is not yet true at that scale.
  • The composite defaults to clip = FALSE, so reference imagery keeps its surroundings.
  • A window straddling Sentinel-2's 2022-01-25 offset change is refused.
  • A window cannot cross the new year.

Follow-ups:

Acceptance

  • A documented call returns a cloud-masked, median true-colour composite for an AOI, a year and a set of months. It is cached, and the cache key includes the bands and months.
  • dft_index_table() includes ndwi and mndwi, with tests against known band values.
  • dft_map_interactive() shows at least two dated RGB composites as switchable layers over the Esri/Google basemaps.
  • HLS is either delivered or filed as its own issue, with the auth path worked out (HLS (Harmonized Landsat Sentinel-2) as a cube source: Earthdata auth, CMR-STAC query, bit-mask Fmask #82; the end-to-end read awaits an Earthdata account).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions