Skip to content

Fix outlet ordering + extract reusable trace#152

Merged
NewGraphEnvironment merged 4 commits intomainfrom
147-sk-outlet-ordering
Apr 14, 2026
Merged

Fix outlet ordering + extract reusable trace#152
NewGraphEnvironment merged 4 commits intomainfrom
147-sk-outlet-ordering

Conversation

@NewGraphEnvironment
Copy link
Copy Markdown
Owner

Summary

  • Fix lake outlet ordering: use wscode_ltree + localcode_ltree (network topology) instead of downstream_route_measure (meaningless across BLKs) for multi-BLK waterbodies
  • Fix cumulative distance partitioning: partition by waterbody_key instead of blue_line_key so distance accumulates per lake trace, not per BLK
  • Extract .frs_trace_downstream() — reusable downstream trace with distance cap + gradient stop, takes any origins SQL
  • Rename .frs_connected_spawning() to .frs_connected_waterbody() — parameterized waterbody_poly table supports lakes and wetlands

BULK SK spawning: -22.6% → +0.1% vs bcfishpass.

Test plan

  • 696 tests pass
  • Code-check clean (2 rounds)
  • Verify BULK SK spawning matches bcfishpass within tolerance
  • Verify ADMS SK spawning unchanged (single-outlet lake unaffected)

Fixes #147
Relates to NewGraphEnvironment/sred-2025-2026#16

🤖 Generated with Claude Code

NewGraphEnvironment and others added 3 commits April 14, 2026 07:00
Relates to #147

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lake_outlets CTE now orders by wscode_ltree + localcode_ltree (network
topology) instead of downstream_route_measure (meaningless across BLKs).
All downstream CTEs partition by waterbody_key instead of blue_line_key
so cumulative distance and barrier detection work per-lake, not per-BLK.

Fixes waterbody_key 329064462 (BULK) picking wrong tributary: SK spawning
goes from -22.6% to +0.1% vs bcfishpass.

Fixes #147

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split .frs_connected_spawning into reusable pieces:
- .frs_trace_downstream() — generic downstream trace with distance cap
  and gradient stop. Takes any origins SQL, returns linear_feature_ids.
- .frs_connected_waterbody() — orchestrator for waterbody-connected
  spawning. Parameterized waterbody_poly table so the same function
  works for lakes (fwa_lakes_poly) or wetlands (fwa_wetlands_poly).

Caller detects waterbody_type from rearing rules generically (L, W)
instead of hardcoding lake detection.

Relates to #147

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NewGraphEnvironment
Copy link
Copy Markdown
Owner Author

Reservoir support needed in Phase 2

bcfishpass load_habitat_linear_sk.sql lines 217-240 checks BOTH lakes AND reservoirs in the upstream cluster proximity:

clusters_near_rearing as (
  select c.cid, bool_or(lk.waterbody_key IS NOT NULL) as wb
  from clusters c
  left outer join whse_basemapping.fwa_lakes_poly lk
    on st_dwithin(c.geom, lk.geom, 2)
  WHERE lk.area_ha >= t.rear_lake_ha_min
  group by c.cid
  union all
  select c.cid, bool_or(res.waterbody_key IS NOT NULL) as wb
  from clusters c
  left outer join whse_basemapping.fwa_manmade_waterbodies_poly res
    on st_dwithin(c.geom, res.geom, 2)
  WHERE res.area_ha >= t.rear_lake_ha_min
  group by c.cid
)

The current PR accepts a single waterbody_poly table. This misses reservoirs. Options:

  1. Accept a vector of waterbody tables: waterbody_poly = c("fwa_lakes_poly", "fwa_manmade_waterbodies_poly")
  2. Build the UNION inside .frs_connected_waterbody() when multiple tables provided
  3. Pre-union the polygons into a temp table before calling the function

Also: Phase 1 (downstream trace) identifies lake outlets from rearing segments. Rearing on reservoirs also needs outlets traced downstream. The lake_outlets CTE filters by hr.rearing IS TRUE which includes reservoir rearing, so Phase 1 should be OK. But Phase 2's ST_DWithin against a single poly table misses reservoir clusters.

waterbody_type L now resolves to both fwa_lakes_poly and
fwa_manmade_waterbodies_poly. The FWA splits these by digitization
origin (natural vs manmade), not ecology — a 200ha reservoir functions
identically to a 200ha lake for fish rearing.

Shared helper used by .frs_rule_to_sql (rearing classification via
UNION ALL) and .frs_connected_waterbody (upstream cluster proximity
via OR EXISTS). Matches bcfishpass load_habitat_linear_sk.sql behaviour.

Relates to #147

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NewGraphEnvironment NewGraphEnvironment merged commit 770db53 into main Apr 14, 2026
1 check passed
@NewGraphEnvironment NewGraphEnvironment deleted the 147-sk-outlet-ordering branch April 14, 2026 15:39
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.

SK spawning: implement bcfishpass downstream trace + upstream lake proximity

1 participant