Skip to content

Add fl_dem_aoi() + Parsnip Watershed Group floodplain showcase vignette#37

Merged
NewGraphEnvironment merged 8 commits into
mainfrom
34-add-dem-source-helpers-file-stac-for-aoi
May 7, 2026
Merged

Add fl_dem_aoi() + Parsnip Watershed Group floodplain showcase vignette#37
NewGraphEnvironment merged 8 commits into
mainfrom
34-add-dem-source-helpers-file-stac-for-aoi

Conversation

@NewGraphEnvironment
Copy link
Copy Markdown
Owner

Summary

  • Adds fl_dem_aoi() — AOI-driven DEM fetch helper. Defaults to MRDEM-30 via /vsicurl/ (the rtj-doc-settled choice for watershed-scale BC work) but accepts any local path, /vsicurl/ HTTP COG, or /vsis3/ S3 URL. Buffered crop in source CRS, reprojection after crop. Replaces hand-rolled per-project DEM plumbing.
  • Ships vignettes/pars-floodplain.Rmd — watershed-scale showcase running fl_dem_aoi() + fl_valley_confine() end-to-end on the Parsnip River WSG (5,597 km²; 481.9 km² floodplain, 8.6% of WSG, at flood_factor = 4). Hero + south-east detail maps with parks, FN reserves, waterbodies, roads, railways, named streams.
  • Generic data-raw/wsg_vignette_data.R — change wsg <- "PARS" to any 4-letter BC WSG code; uses bcfishpass.streams_bt_vw for accessible bull-trout habitat. Cache: 14 MB across 3 files (multi-layer pars.gpkg + 2 GeoTIFFs). Direct GitHub raw download links surfaced in the vignette.
  • DESCRIPTION bumped 0.2.1 → 0.3.0; DBI, fresh, xciter added to Suggests with Remotes: for the org-only deps. R CMD check 0/0/0; tests 172/172 PASS; lintr clean on new files.

Related Issues

Test plan

  • devtools::test() — 172/172 PASS (includes a live MRDEM /vsicurl/ range read gated by skip_on_cran() + skip_if_offline())
  • lintr::lint_package() — 0 lints in new exported code (some indentation lints in the data-raw script are stylistic and Rbuildignored)
  • R CMD check — Status: OK (0 errors, 0 warnings, 0 notes)
  • pkgdown::build_site() — pars-floodplain vignette renders cleanly to HTML
  • Manual review of vignette output — hero + detail maps, methodology tables, summary stats all sensible

Notes

The vignette is designed to drop into a Peace report appendix — chunks read against the cached gpkg + GeoTIFFs, only the YAML output flavour is tied to the package vignette format. Bibliography regenerates via data-raw/bib_regenerate.R (rbbt → BBT, mirrors the cd repo pattern).

🤖 Generated with Claude Code

NewGraphEnvironment and others added 8 commits May 5, 2026 11:34
Approved phases scaffolded into planning/active/:
- Phase 1: implement fl_dem_aoi()
- Phase 2: PARS floodplain showcase vignette + data-raw cache
- Phase 3: polish + release prep

MRDEM-30 via /vsicurl/ as the primary path per rtj/docs/dem-sources.md;
LidarBC via STAC stays as example pattern, not a wrapper function.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single entry point that takes an sf AOI and returns a SpatRaster cropped
to a buffered extent. Source defaults to MRDEM-30 DTM via /vsicurl/ (the
settled choice in rtj/docs/dem-sources.md for watershed-scale BC work).
Local files, /vsicurl/ HTTP COGs, and /vsis3/ S3 COGs all work
identically — terra::rast handles dispatch.

Implementation lifts the access pattern from rtj/docs/dem-sources.md:50-65
verbatim with parameter wiring: buffer the AOI in its own CRS, transform
to the raster's CRS for the lazy crop, reproject after crop (never before
— the 84 GB MRDEM COG must not be reprojected as a whole). snap = 'out'
on the crop ensures the result fully covers the buffered AOI.

Buffer semantics: applies to whatever sf geometry is passed as aoi.
Polygon AOI → region-bounded crop. Streams sf → tight, memory-efficient
crop along the stream corridor (the wedzin production optimization,
now first-class).

Tests: 8 passing including a live MRDEM /vsicurl/ range read gated by
skip_on_cran + skip_if_offline. lintr clean. Full suite 172 PASS.

Phase 1 of #34 complete.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generic data-raw script — any WSG via 'wsg <- "PARS"' at the top, output
filenames namespaced (pars_aoi.gpkg, pars_streams.gpkg, etc.). Switching
the WSG re-runs the whole pipeline.

Pulls boundary from whse_basemapping.fwa_watershed_groups_poly and streams
from bcfishpass.streams_vw via fresh::frs_stream_fetch — streams_vw carries
channel_width / upstream_area_ha / map_upstream that fl_valley_confine()'s
flood model needs (the bare FWA stream networks table doesn't). Runs
fl_dem_aoi() against the MRDEM-30 default (streams-as-aoi for memory-
efficient crop) → fl_valley_confine() → fl_valley_poly().

Two XYZM bugs surfaced during the run. fwapg streams carry route measures
in M, and GEOS can't buffer XYZM:

1. fl_dem_aoi() fixed at source — wraps sf::st_zm() before the
   sf::st_buffer() call. Tests still PASS 18/18.
2. fl_valley_confine() also calls sf::st_buffer() internally for the
   channel_buffer feature; same crash. Worked around in the data-raw
   script with an explicit sf::st_zm(streams). Hardening fl_valley_confine
   the same way fl_dem_aoi was hardened is filed as a follow-up; out of
   scope for #34.

PARS cache totals 11 MB across 5 files (under the 15 MB target):
  pars_aoi.gpkg          0.31 MB   PARS WSG boundary (5597 km²)
  pars_streams.gpkg      2.7 MB    5,581 order-4+ segments from streams_vw
  pars_dem.tif           6.2 MB    INT2S MRDEM-30 clip, 4089x4862 cells
  pars_valleys.tif       88 KB     fl_valley_confine() binary output
  pars_floodplain.gpkg   1.2 MB    polygonized valleys

DEM stored as INT2S (Int16) — VCA at 30 m doesn't need sub-metre vertical
precision, and INT2S+DEFLATE+PREDICTOR=2 is ~5x smaller than FLT4S.

Phase 2a of #34 complete.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Demonstrates the fl_dem_aoi() + fl_valley_confine() workflow on the
Parsnip River watershed group (PARS, 5,597 km², FWCP Peace). Loads
cached outputs from inst/vignette-data/ — heavy compute lives in
data-raw/wsg_vignette_data.R, the vignette renders fast and offline
in CI.

Designed for portability to the Peace report appendix: the YAML output
is the only thing tied to the package vignette format, swap it for the
report's bookdown::pdf_book and the chunks work as-is.

Walks through:
- Why MRDEM-30 (links to rtj/docs/dem-sources.md rationale)
- AOI + streams loaded from cache
- The fl_dem_aoi(streams, buffer = 2000) call (eval=FALSE, shown as docs)
- The fl_valley_confine() pipeline
- Hillshade + floodplain hero map (terra::plot)
- Summary table: 449 km² floodplain on order 4+ streams (8% of PARS)
- One-paragraph 'adapt to another WSG' note pointing at the generic
  data-raw script

Renders cleanly to 604 KB HTML. Full test suite 172 PASS.

Phase 2b of #34 complete.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bump DESCRIPTION version 0.2.1 → 0.3.0 (new exported function = minor)
- NEWS entry under '# flooded 0.3.0' covering fl_dem_aoi(),
  vignettes/pars-floodplain.Rmd, and data-raw/wsg_vignette_data.R
- .Rbuildignore: add ^planning$ and ^\.claude$ (cleared the
  'top-level files' R CMD check NOTE)
- Delete stale vignettes/figure/ knitr leftover from previous vignette
  renders (cleared the 'vignettes' R CMD check NOTE)
- .gitignore: add *.Rcheck/ and *.tar.gz so local check artefacts
  don't pollute the working tree

R CMD check status now: 0 errors, 0 warnings, 0 notes (with
_R_CHECK_FORCE_SUGGESTS_=false to skip whitebox, which is unrelated to
this change). devtools::test() 172/172 PASS. lintr clean on new files.

Phase 3 of #34 complete.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Iterated heavily on the PARS showcase vignette in response to feedback:

Stream source switched to bcfishpass.streams_bt_vw — every row is
already classified accessible (access IN (1, 2)) by construction, so
filtering 'best accessible habitat order 3+' is a single SQL via
fresh::frs_db_query. Replaces an attempted wedzin-style frs_network +
frs_break_find pipeline that hit an upstream fresh bug (frs_break
forwarding points_table args into frs_break_find which doesn't accept
them). min_order lowered 4 → 3.

Waterbodies (lakes + wetlands) now picked up via waterbody_key linkage
on the order-3+ streams and passed to fl_valley_confine(waterbodies=...)
so the binary valley raster fills lake/wetland cells. flood_factor=4
(ff04 — functional floodplain). Resulting floodplain: 481.9 km²
(8.6% of PARS), 8,436 streams, 200 lakes + 464 wetlands.

Context layers added to the maps: railways, roads (filtered to FSR /
resource roads on the hero map; full network on the inset), First Nations
reserves (with black diamond markers + halo'd english_name labels),
parks / protected, and named streams (italic labels on the inset). gq
registry colours used for parks / reserves. All layers fresh::frs_clip'd
to the WSG and the DEM terra::mask'd to the WSG so nothing renders
outside the basin.

Vignette restructure:
- Methodology section moved to the top with ecological context paragraph
- fl_params() and fl_scenarios() rendered as knitr::kable tables with
  bookdown::html_vignette2 numbered captions
- Citation keys converted to inline citations via xciter (helper
  keys_to_pandoc() pre-formats bare semicolon-separated keys)
- bibliography: vignettes/references.bib regenerated by
  data-raw/bib_regenerate.R (rbbt → BBT, mirrors the cd repo pattern)
- ## References auto-populated by pandoc

Cache consolidation: 9 sf layers now live in a single multi-layer
GeoPackage (pars.gpkg). Rasters stay as standalone GeoTIFFs (gpkg's
raster spec is for tile pyramids, wrong format for analytical DEM /
binary valleys raster). Direct GitHub raw download links for all three
files surfaced in the vignette so non-R users can grab the bundle.

DESCRIPTION: DBI, fresh, xciter added to Suggests; Remotes points at
NewGraphEnvironment for fresh + xciter. Clears the 'unstated
dependencies in vignettes' R CMD check NOTE.

Final R CMD check: 0 errors, 0 warnings, 0 notes. Tests 172/172 pass.

Phase 4 of #34 complete.

Relates to #34

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Set echo = FALSE on map-floodplain, map-detail, params-stamp, and
scenarios-stamp. The maps and tables are the value of those chunks;
the rendering plumbing (terra::plot + halo'd text() + kable + xciter
key-formatting) was dominating the page without showcasing the package.

The eval = FALSE snippets that demonstrate fl_dem_aoi() and
fl_valley_confine() stay visible — those are what flooded actually
exposes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@NewGraphEnvironment NewGraphEnvironment merged commit 4ac367f into main May 7, 2026
1 check failed
@NewGraphEnvironment NewGraphEnvironment deleted the 34-add-dem-source-helpers-file-stac-for-aoi branch May 7, 2026 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add DEM source helpers (file, STAC) for AOI-driven workflows

1 participant