Problem
streams_breaks deduplicates breaks at shared positions — when a gradient barrier and a crossing land at the same measure, one label survives. Barrier identity is lost. This breaks:
barrier_overrides — can't match a gradient barrier that was merged with a crossing
- Access reporting — can't distinguish barrier types downstream of a segment
- Habitat reporting — can't report km behind falls vs gradient vs crossings separately
bcfishpass v0.5.0 keeps separate barrier tables that persist independently. Each segment knows which barriers of each type are downstream via separate columns (barriers_bt_dnstr, barriers_falls_dnstr, etc.).
Proposed Solution
Allow multiple labels per position in streams_breaks. Change the unique constraint from (blue_line_key, downstream_route_measure) to (blue_line_key, downstream_route_measure, label).
A position can be both a crossing AND a gradient_15 barrier:
blue_line_key | downstream_route_measure | label
356362743 | 196606 | potential (crossing)
356362743 | 196606 | gradient_15 (gradient barrier)
Segmentation still deduplicates for geometry splitting (one cut per position). But the breaks table retains all labels. The access model queries by label. Overrides match by label + position.
This enables per-segment barrier composition: "this segment is behind gradient_15 + falls + crossing_potential" — each independently queryable, overridable, reportable.
Impact on existing code
frs_network_segment: change dedup logic — deduplicate geometry cuts but not label entries
- Access SQL: no change — already filters by label
barrier_overrides: works as designed — matches label + position
- Clustering: no change — uses labels already
Versions
- fresh: 0.13.1
- bcfishpass: v0.5.0
- link: 0.1.0
Relates to NewGraphEnvironment/link#16
Relates to NewGraphEnvironment/link#25
Relates to #143
Problem
streams_breaksdeduplicates breaks at shared positions — when a gradient barrier and a crossing land at the same measure, one label survives. Barrier identity is lost. This breaks:barrier_overrides— can't match a gradient barrier that was merged with a crossingbcfishpass v0.5.0 keeps separate barrier tables that persist independently. Each segment knows which barriers of each type are downstream via separate columns (
barriers_bt_dnstr,barriers_falls_dnstr, etc.).Proposed Solution
Allow multiple labels per position in
streams_breaks. Change the unique constraint from(blue_line_key, downstream_route_measure)to(blue_line_key, downstream_route_measure, label).A position can be both a crossing AND a gradient_15 barrier:
Segmentation still deduplicates for geometry splitting (one cut per position). But the breaks table retains all labels. The access model queries by label. Overrides match by label + position.
This enables per-segment barrier composition: "this segment is behind gradient_15 + falls + crossing_potential" — each independently queryable, overridable, reportable.
Impact on existing code
frs_network_segment: change dedup logic — deduplicate geometry cuts but not label entriesbarrier_overrides: works as designed — matches label + positionVersions
Relates to NewGraphEnvironment/link#16
Relates to NewGraphEnvironment/link#25
Relates to #143