flooded 0.8.4
- The bundled stream data come from the tables
linkbuilds with itsdefaultconfiguration, with upstream area and precipitation from fwapg, instead of bcfishpass’s views (#87). This coversinst/testdata/streams.gpkgand thestreamslayer ofinst/vignette-data/pars.gpkg. The build scripts pin thelinkrun they read and stop when it has moved. The shipped columns change:-
segmented_stream_id(character) is replaced byid_segment(integer), which is unique only together with the newwatershed_group_codecolumn; -
spawningandrearingare logical, not integer codes, sofl_valley_join(cols = NULL)now picks them up on the bundled tile; -
linear_feature_idis added, and rows are ordered byblue_line_keyanddownstream_route_measure.
inst/NOTICE.mdcredits each column to its source. A bcfishpass credit remains for access and habitat, becauselink’sdefaultconfiguration applies bcfishpass’s override tables. -
- The Parsnip article is rewritten to open with its answer: 40,640 ha of floodplain at flood factor 4, 7.3 % of the watershed group (#92). Every number in it is computed from the article’s data, which its data script pins by digest, and a check fails when a quoted claim stops holding. A table gives the floodplain area at flood factors 2, 4, 6 and 7.
-
floodedis cited with its Zenodo concept DOI, 10.5281/zenodo.23302790, whichcitation("flooded")now prints.CITATION.cffnames the maintainer as the only author and New Graph Environment Ltd. as publisher.
flooded 0.8.3
-
fl_valley_join()’snearestnames the segment that owns each cell (seg, the row ofsegments), so a per-segment value that is not a logical flag, a 0-1 habitat grade or a length, joins to the floodplain cells through it (#89).
flooded 0.8.2
- The README now says what flooded maps and how: the Valley Confinement Algorithm and where it comes from, what a run needs and where those inputs come from, a Parsnip figure, and a runnable example (#81). The reference index is grouped by purpose,
inst/NOTICE.mdgives the licence of each bundled dataset, and New Graph Environment Ltd. is copyright holder and funder.
flooded 0.8.1
- gdalcubes (Suggests) now installs from
NewGraphEnvironment/gdalcubes@newgraph, in step with drift (NewGraphEnvironment/drift#104). That build is upstream 0.7.5 plus fixes proposed as appelmar/gdalcubes#113-115, and the pin reverts toappelmar/gdalcubeswhen those merge. Two packages naming different sources for gdalcubes make pak fail when they install together.
flooded 0.8.0
- New
fl_valley_join()joins per-segment logical attributes (habitat flags, say) to valley cells by position (#83). Each cell takes the nearest segment on each group that claims it infl_valley_attribute()’s output, and two answers come back:nearestgives every cell one owner, so per-reach areas add up to the floodplain, andanyisTRUEwhere any claiming group’s nearest segment is. Joining on the group key instead credits a group’s whole floodplain with any flag found anywhere on it: on the Bulkley’s whole-network floodplain, 16,705 ha of sockeye spawning by key against 572 ha by position.
flooded 0.7.2
-
fl_dem_aoi()now returnsNA, not the NoData rounded to Float32, where a reprojected integer DEM reaches past the area read (#76). A UInt32 source such as the bundleddem.tif(NoData- came back as 4294967296 m there whenever the crop was file-backed: a crop of the whole file, or a subset crop that terra keeps on disk. Integer sources are now read through a floating-point copy before
terra::project(). Float sources such as MRDEM-30 take exactly the old path, so their output is unchanged.
- The defect is terra’s:
terra::project()writesNaNonly where cells still match the NoData in Float32, and a NoData Float32 cannot hold exactly (UInt32 4294967295, Int32 2147483647, INT8U’s default) is stored rounded and survives as a value.gdalwarpfrom the same GDAL build does not do this. Seeresearch/dem_reprojection.md§4.
- came back as 4294967296 m there whenever the crop was file-backed: a crop of the whole file, or a subset crop that terra keeps on disk. Integer sources are now read through a floating-point copy before
flooded 0.7.1
-
fl_dem_aoi()now pins the AOI’s own transforms the way 0.7.0 pinned the warp (#78): the read window (the buffered AOI carried into the source CRS) and, for an AOI in a third CRS, the grid (carried intotarget_crs) use the projection-only pipeline between projected NAD83 CRSs, so the returned DEM no longer depends on which PROJ sf links. Measured on 60 sub-cell AOI positions, a ~1.3 m datum step changed 0.7.0’s DEM at 3 of them (47 to 91 edge cells, none inside the buffered AOI); the fix changes it at none.-
Output is unchanged where sf’s PROJ applies no shift for these pairs. Edge cells can change for callers whose sf takes a datum step, and for callers who pass a custom
pipelinewith the AOI intarget_crs: the read window now follows their string, inverted. A string that cannot be applied in reverse stops with a clear error. - Geographic, northing-first and non-NAD83 AOI pairs, and
pipeline = "", still follow sf’s PROJ; recordsf::sf_extSoftVersion()with a kept DEM in those cases.
-
Output is unchanged where sf’s PROJ applies no shift for these pairs. Edge cells can change for callers whose sf takes a datum step, and for callers who pass a custom
flooded 0.7.0
-
fl_dem_aoi()now reprojects onto a grid aligned to multiples of a newresargument (default: the source cell size, so MRDEM-30 gives exactly 30 m) instead of a grid GDAL chose (about 30.43-30.54 m). Between projected NAD83 CRSs with easting/northing axes it pins the datum step to a projection-only pipeline, so a DEM no longer moves when PROJ’s EPSG database changes; the newpipeline = ""restores PROJ’s choice, and a string is used as given (#67). The grid had been moving with PROJ’s NAD83(CSRS)-to-NAD83 operation (no shift in PROJ 9.5.1, about 1.3 m via WGS 84 in 9.8.1), not with the GDAL version.- Results change for every caller: the DEM grid moves once. A MORR coho floodplain moved +0.17%; the Parsnip vignette cache, rebuilt, moved -0.6% (41,142.9 to 40,888.2 ha).
-
API change: a geographic
target_crsnow requiresres; the error quotes the degree value at the AOI. - Requires terra (>= 1.9-25).
flooded 0.6.6
-
fl_patch_rm()andfl_patch_conn()now keepNAinput cellsNA(#65). Each used to turn them into 0 on one code path and keep them on the other:fl_patch_rm()zeroed them only when some patch was small enough to remove. A caller using either helper directly now getsNAback where it used to get 0, so passna.rm = TRUEwhen summing. - In
fl_valley_confine(),NAnow means only “no DEM”. Every cell with a DEM value is 0 or 1, including ground a gap cuts off from every stream and cells whose slope isNA; on the early path throughfl_patch_rm()some of those used to come outNA. The bundled tile gives the same result as 0.6.5 cell for cell, and on DEMs with gaps the result now always matches what 0.6.5 gave whenever cleanup removed a patch, which is almost every real run. The cachedstac-demand Parsnip results are unchanged.
flooded 0.6.5
-
fl_valley_attribute()now binds its per-group polygons in pairs instead of in onedo.call(rbind)(#72). On the Bulkley (BULK) stream order >= 2 network, 2,550 blue lines on a 38.3-million-cell grid, binding went from 52.8 s to 5.0 s and the whole attribution from 332.9 s to 238-240 s (CPU). Every group’s cells are unchanged on the bundled tile and on four watershed networks. The Performance section of?fl_valley_attributenow gives measured times for those four networks. The 5x per-group slowdown from the Morice (MORR) to BULK first reported for 0.6.0 was mostly the full-grid fallback fixed in 0.6.4 (#71).
flooded 0.6.4
-
fl_valley_attribute(complete = TRUE)no longer computes distance over the whole grid to place the valley cells no group reaches (#71). It finds the nearest burned stream cell for those cells only. That is the same rule as before, so assignments change only where two groups’ stream cells are exactly equally near. On the Morice (MORR) coho network, 340 blue lines on an 18.1-million-cell grid, attribution went from 855.8 s to 37.8 s. The step itself went from 805.6 s to 0.4 s, and all 14,170 cells it placed went to the same groups as before.
flooded 0.6.3
-
fl_valley_confine()now returnsNAwhere the DEM isNA, as its documentation already said (#63). It usually returned 0 or 1 there instead (NAsurvived only when no valley patch was small enough forfl_patch_rm()to remove), so a gap in coverage (patchy lidar, a DEM clipped to a watershed) read as measured hillslope or valley: a plot drew it as hillslope or valley, and any share taken over non-NAcells counted it as measured. The channel buffer and waterbodies are still added inside a gap, because neither depends on the DEM. A gap still feeds the slope, cost-distance and flood steps, so valid cells around it can differ from a run on a complete DEM. If you sum or average the output on a DEM with gaps, passna.rm = TRUE. - Results on the bundled tile do not change, because it has no
NAcells. Thestac-demlidar cache was rebuilt with the fix. Its uncovered cells, counted on the 10 m grids the lidar results are compared on (115,385 for the 5 m run, 11,020 for the 1 m site, outside the channel buffer), were all 0 and are nowNA. No valley cell moved, and none of the vignette’s areas or shares changed. Its lidar figures now draw the uncovered area in its own colour. The cached Parsnip result has no valley cells onNADEM, so its hectares hold. -
fl_patch_rm()andfl_patch_conn()can still turnNAinput cells into 0 (#65).
flooded 0.6.2
- The
stac-demvignette now runs live, and its figures are current (#51). It was pre-baked from a.Rmd.origand had drifted for several releases: its numbers predated the 0.5.0 units fix and did not reproduce even under the old units, its two figure images were never committed (both 404 on the site), and a figure cross-reference printed as literal@ref(...). The 10 m runs now execute when the page is built. The 5 m and 1 m lidar runs need the STAC endpoint, a ~1.3 GB tile download and ~20 minutes, sodata-raw/stac_dem_vignette_data.Rruns them once and caches the results ininst/vignette-data/(~13 KB). - The cache records the 10 m cell counts it was built against.
tests/testthat/test-vignette_data.Rfails, and the vignette shows a note, when the currentfl_valley_confine()no longer reproduces them, so the next drift is caught by the test suite rather than by a reader. It cannot see a change that only shows at 1-5 m. - At corrected depths the vignette’s resolution argument holds, but in a different shape. Over the test tile, 5 m lidar maps 4.67 km2 of valley bottom against 2.87 km2 from the resampled 25 m TRIM DEM (previously published as 6.26 vs 5.46). At the 1 m site, lidar maps 310.3 ha against 205.9 ha. The “pop-ups” (25 m floodplain that the 1 m run excludes) are 19.8 ha, 9.6% of the 25 m floodplain (previously 36.1 ha, 9.7%), while 124.3 ha are found only at 1 m. So the gap between resolutions is no longer described as mostly the anthropogenic footprint: the coarse DEM gets the floodplain’s shape wrong in both directions.
- The vignette said pop-ups sit above the flood surface. At this site 77% of them sit on 1 m ground steeper than the 9% slope threshold, against 24% across the whole 25 m floodplain. The lidar resolves embankment sides and banks that a 25 m pixel smooths to just under the threshold (median 5% on the 25 m DEM); the slope criterion, not flood depth, is what mostly removes them. The build script now records this share and the page states it, rather than describing the mechanism from the figure.
- The STAC collection
stac-dem-bcis nowstac-elevation-bc, with the DEM under assetdem(formerlyimage). The vignette and thefl_dem_aoi()lidar example are updated. A search against the old name returns no items rather than an error. -
gdalcubesremains in Suggests (with the 0.6.1Remotes:pin), but onlydata-raw/stac_dem_vignette_data.Ruses it now. The vignette no longer loads it.
flooded 0.6.1
-
gdalcubes(Suggests, for thestac-demvignette) is pinned toappelmar/gdalcubesviaRemotes:while it is archived on CRAN, which had broken the docs build. Drop the pin once it returns (#60). -
inst/notes/floodplain_interpretation.mdnow distinguishes the two shapes of proportional claim and which of them survive a change in mapped extent (#52).
flooded 0.6.0
Breaking, but no result changes. fl_valley_confine()’s field argument is renamed area_field and is now required. Nothing this package has produced was affected — every caller in the repo, both vignettes, every example and the floodplains driver passed field = "upstream_area_ha" explicitly.
fielddefaulted to"channel_width", and the flood model reads the rasterized values as the drainage-area term in hectares of the Hall bankfull regression (fl_flood_surface()). Channel width (4.1–31.3 on the bundled tile) and upstream area (1,928.8–110,337.4) are both plain positive numerics, so the wrong one was raised to the 0.280 power without complaint and returned a smaller floodplain with no error and no warning (#47). Same class as #41 and #49.-
Measured on the bundled 10 m tile at
flood_factor = 6, current code:area_fieldprecip cells ha upstream_area_hamap_upstream28,727 287.3 channel_widthmap_upstream17,206 172.1 upstream_area_hanone 19,838 198.4 channel_widthnone 14,789 147.9 The old default returned 59.9% of the floodplain with precipitation supplied. Every wrong-column run is a strict subset — 0 cells gained anywhere. The issue’s headline figure of 47% was measured before the 0.5.0 units fix and does not describe current code; the defect is the same size, its consequence is not.
The requirement is scoped to the
sfbranch. Passing an already-rasterizedSpatRasterasstreamsnever reachesfl_stream_rasterize(), soarea_fieldis not demanded there — that branch cannot inspect the values it is handed, and a raster burned from the wrong column carries the identical defect one call earlier. It can inspect the layer’s name, sincefl_stream_rasterize()names its output after the column it burned, sofl_valley_confine()now warns when handed a layer namedchannel_width— which is also that function’s default, and so the one composition the package’s defaults lead you into. Measured withchannel_buffer = FALSE: 14,149 cells against 19,383. The guard names the column literally rather than reading the rasterizer’s default: those coincide today, and keying to the default would invert the guard if it ever moved. A raster burned from any other wrong column is still undetectable, so the roxygen states the requirement rather than claiming to enforce it.One deprecation path is silent.
fl_valley_confine(dem, streams, "channel_width")passed positionally rebinds toarea_fieldwith no warning, because the shim can only see the named argument. There are no positional callers in this repo or infloodplains.fieldstill works for one release. Supplying it warns and forwards toarea_field, reproducing the same delineation exactly. Removal is tracked in #53 — move toarea_field.fl_stream_rasterize()is unchanged, including its"channel_width"default: it is deliberately generic and also rasterizes precipitation, stream order and internal seed indices. The hazard was always the composition, so both functions now cross-reference each other and state which column the flood model requires.
flooded 0.5.0
Results change. Every floodplain produced by 0.4.1 or earlier is over-mapped.
Fix the bankfull regression being fed the wrong units (#49).
fl_flood_surface()passed hectares (upstream_area_ha) and millimetres (map_upstream) into the verbatim Hall et al. (2007) coefficients, which that paper and Nagel et al. (2014) both specify as taking drainage area in km2 and mean annual precipitation in cm/yr. The conversion now happens inside the function, so callers keep passing the columns they already have.-
Bankfull width was 8.2224x too large and bankfull depth 3.5926x too large, everywhere, on every run this package has ever done. The shipped scenarios were therefore not what they claimed:
labelled actual multiple of bankfull depth ff027.19 ff0414.37 ff0621.56 Against Hall’s field-validated 3 for historical floodplain and Nagel’s 5-7 for valley bottom.
-
How much area this costs is dataset-dependent, and not a fixed ratio. The error only reaches the boundary where the flood mask is the binding criterion. Measured on both shipped datasets, and every corrected run is a strict subset of the as-coded one - 0 cells gained anywhere:
dataset scenario as-coded corrected retained bundled 10 m tile ff02320.8 ha 185.4 ha 57.8% bundled 10 m tile ff04476.8 ha 231.9 ha 48.6% bundled 10 m tile ff06536.4 ha 287.3 ha 53.6% Parsnip WSG, MRDEM-30 ff0448,603.1 ha 41,142.9 ha 84.7% At 10 m the flood mask binds and the fix roughly halves the extent. At 30 m the slope and cost-distance criteria bind first, so most of the inflated flood height was already being clipped and the loss is ~15%.
Scenario values are unchanged at 2 / 4 / 6. They were taken from the literature ladder (Rosgen 2, Hall 3, Nagel 5-7) in the first place; what changed is that they now behave as labelled. Raising
ffto recover the old extent is not supported by anything - on MRDEM-30, correctedff04throughff07span only 6.4% of area, so evenff07lands at 90% of the as-codedff04.precipnow defaults toNULL, which drops the precipitation term (multiplier exactly 1). The former default of1cannot express that once the input is read as millimetres: 1 mm is 0.1 cm/yr, scaling depth by 0.6089 - shallower than omitting the term.fl_flood_surface(),fl_flood_model()andfl_valley_confine()all move together. Passing a precipitation raster or a scalar in mm is unaffected.Shipped vignette artifacts regenerated:
inst/vignette-data/pars_valleys.tifand thefloodplainlayer ofpars.gpkg. The as-coded run reproduces the previous artifact exactly (521,028 cells, 0 difference), which is what establishes the corrected one as a like-for-like replacement. This supersedes the 0.4.1 note below saying the shipped artifacts were still current — that was true of the #41 cost-distance fix and is not true of this one.vignettes/stac-dem.Rmdcould not be regenerated: it is the baked half of the.Rmd.origpattern, and re-baking needs the STAC endpoint plus a 1 m lidar re-run. It carries an explicit caveat instead. Its printed figures do not reproduce even under the old units — 54,637 published against 53,635 as-coded today — so roughly a thousand cells of that gap predate this release.fl_flood_surface()gains a units test pinned to hard literals computed from the published equation. No test in this package pinned an absolute value before now, and_snaps/was empty, which is why a 3.59x error survived a green suite. Note that Nagel’s combined formh_bf = 0.054 * A^0.170 * P^0.215cannot serve as the oracle - it is an algebraic identity of the two-step form and so agrees in any units.Documentation corrected throughout:
inst/notes/methodology.mdstated the two channel-width formulas with no input units at all, which is the gap that let this survive. Historical measurements in that file taken under the defect are annotated rather than restated.
flooded 0.4.1
Fix
fl_cost_distance()seeding on every zero-friction cell rather than only stream cells (#41). Seeds are encoded by setting stream cells to0and callingterra::costDist(target = 0), which matches every zero cell — so any cell whose friction was already exactly zero acted as a free cost source. Friction exactly equal to0is now floored to1e-6before seeding. Flat ground stays cheap to cross (0.1 accumulated over a 100 km path at 10 m, against a defaultcost_thresholdof 2500); it simply stops being a source. Negative friction is deliberately not floored, soterra::costDist()’s own rejection of a negative cost surface is left intact.-
The fix strictly removes spurious reach from the cost mask; it never adds any. Measured on the two DEMs this package ships, and the answer differs by dataset — check your own rather than assuming:
DEM exact-zero slope cells cost-mask change delineation change bundled dem.tif/slope.tif, 10 m0 of 45,726 none none pars_dem.tif(MRDEM-30, 30 m, 20.9 Mcell)80 of 10.7 M -2,289 cells (214 ha), 0 added none So MRDEM-30 does contain exact zeros, the cost mask does move — and on both shipped datasets the delineation does not, because the slope, distance and flood criteria plus morphological cleanup absorb every affected cell.
fl_valley_confine()returns the same 53,635 cells on the bundled tile and the same 521,028 cells on the Parsnip Watershed Group, with zero cells differing in either direction. The shipped vignette artifacts are therefore still current. Do not read that as a general guarantee. Where cost is the binding criterion — flatter terrain, a laxer
slope_threshold, a largerflood_factor— results will move. Exposure is highest on integer-metre DEMs, hydro-flattened lake surfaces and void-filled plateaus. Check withsum(terra::values(slope) == 0, na.rm = TRUE).The effect is largest under
fl_valley_attribute(), where cost is what separates one watercourse’s floodplain from another’s: a flat patch inside a group’s corridor would have spread that group’s mask across ground its own streams never reach.Fix a stray one-space indent in
fl_valley_poly().
flooded 0.4.0
- New
fl_valley_attribute()— attribute a finishedfl_valley_confine()delineation to the stream groups that produced it, so a floodplain can be filtered and queried per watercourse or reach rather than only per network (#40). Returns onesfrow per group; rows overlap where ground is genuinely shared between watercourses, which near a confluence is most of it. The delineation is never recomputed, so changing the grouping key relabels the output without moving a boundary. - Per-group VCA runs were measured and rejected: they disagree with the whole-network run in both directions, which would make a river’s floodplain depend on what else was in the run. See the function’s Details and the vignette section “Whose floodplain is it?” for the mechanism and its limits.
- Fix
fl_valley_poly()on a delineation with no valley cells — it renamed ansfcolumn by position, which detached the geometry column and made every accessor error.
flooded 0.3.2
- Drop the internal
rtj/docs/dem-sources.mdreference fromfl_dem_aoi()documentation and NEWS — MRDEM-30 is described as the default DEM source without pointing readers at a private doc they can’t access.
flooded 0.3.1
- Fix Parsnip River Watershed Group vignette: corrected geography (the south-east inset is the headwaters around Arctic Lake on the continental divide, not the Williston-bound confluences) and switched all prose mentions from
PARSto “Parsnip River Watershed Group”.
flooded 0.3.0
- New
fl_dem_aoi()— AOI-driven DEM fetch helper. Defaults to MRDEM-30 via/vsicurl/(a sensible default for watershed-scale BC work) but accepts any local path,/vsicurl/URL, or/vsis3/S3 URL viasource =. Buffered crop happens in the source raster’s CRS, reprojection after crop. Replaces hand-rolled per-project DEM plumbing (#34). - New
vignettes/pars-floodplain.Rmd— watershed-scale showcase runningfl_dem_aoi()+fl_valley_confine()end-to-end on the Parsnip River WSG (5,597 km²). Designed to port to a bookdown report appendix (#34). - New
data-raw/wsg_vignette_data.R— generic, parameterised bywsg <- "PARS". Re-runs the full pipeline for any 4-letter BC watershed group, namespaces outputs by WSG code (#34). - bcfishpass model version + date are cached at data-raw time as
inst/vignette-data/<wsg>_meta.rdsso the vignette renders without a database connection (#34).
flooded 0.2.1
- Startup quote ritual:
library(flooded)prints a random fact-checked quote on attach. Italic quote, grey attribution, clickable bluesourcehyperlink (OSC 8). Suppress viaoptions(flooded.quote_show_source = FALSE). - 157 shipped entries across 45 voices — 25 hip-hop (Kanye West, Royce da 5’9”, Black Thought, Ab-Soul, ASAP Rocky, Danny Brown, The Weeknd, Kenny Beats, Freddie Gibbs, Madlib, Travis Scott, Flatbush Zombies trio, J. Cole, Bad Bunny, Don Toliver, Aaron Frazer, Post Malone, Mac Miller, Lil Yachty, Fre$) + 20 climate voices (Hayhoe, Mann, Hansen, Schmidt, Marvel, Cobb, Rockström, Hassol, Oreskes, Wilkinson, Oppenheimer, Otto, Kalmus, Francis, Santer, Alley, McKibben, Wallace-Wells, Kolbert, Johnson).
- Curated via the soul
/quotes-enableskill. 8 parallel research agents returned 157 candidates; 2 independent fact-check agents flagged 2 drops and several URL upgrades to primary sources (GQ, W Magazine, Rolling Stone, Vulture). -
cliadded to Imports for OSC 8 hyperlinks and styling.
flooded 0.2.0
- Add
waterbodiesandchannel_bufferparams tofl_valley_confine()— fill lake/wetland donut holes and correct sub-pixel stream channels (#21). - Handle NA
channel_widthgracefully in channel buffer (order 1 streams). - Update vignette with waterbody/channel buffer comparison, order 4+ filter rationale, and channel width model documentation.
- Regenerate test data via
fresh::frs_network()withfrs_clip(). - Add VCA parameter legend CSV (
inst/extdata/flood_params.csv) with units, defaults, and literature sources for all tuning parameters. - Add
fl_scenarios()andfl_params()for loading pre-defined flood factor scenarios and parameter metadata (#28). - Add flood scenario CSV (
inst/extdata/flood_scenarios.csv) with three scenarios: ff02 (active channel), ff04 (functional floodplain), ff06 (valley bottom). - Add flood factor comparison section to vignette with three-panel plot.
- Replace hardcoded summary table with
fl_params()output.
flooded 0.1.1
- Replace raw SQL in
data-raw/network_extract.Rwithfresh::frs_network()for stream network extraction via network subtraction. - Add STAC DEM vignette comparing 25 m TRIM (resampled to 10 m) with native 1 m lidar — includes site-level zoom and pop-up analysis quantifying anthropogenic barriers to floodplain connectivity.
- Add
bcdatareproducibility script (data-raw/testdata_bcdata.R). - Add resolution and restoration section to README.
- Pre-build STAC vignette for fast pkgdown rendering.
