Problem
frs_point_snap() wraps fwa_indexpoint() which returns the nearest stream by proximity alone. This often snaps to small tributaries instead of the intended mainstem — e.g., snapping near the Neexdzii Kwa / Wedzin Kwa confluence hits a tiny unnamed stream (blk 360312275) instead of the Bulkley River (blk 360873822).
bcfishpass solves this with a multi-candidate scoring system (model/01_access/pscis/sql/02_pscis_streams_150m.sql):
- Fetch top N candidates within search radius using PostGIS KNN (
<->)
- Score by stream name match (+100), channel width vs stream order validation, tributary penalties
- Manual override lookup for known bad matches
ST_ClosestPoint + ST_LineLocatePoint for precise DRM calculation
Proposed Enhancements
Reusable patterns from bcfishpass that could improve fresh:
stream_order_min filter on snap candidates — prefer major streams when snapping confluence points
blue_line_key hint — snap to a specific stream when the target is known
- Multi-candidate return — return top N candidates ranked by distance so users can disambiguate
ST_ClosestPoint + ST_LineLocatePoint alternative — bypass fwa_indexpoint() entirely for more control over candidate selection and scoring
- Clustering/dedup —
ST_ClusterWithin pattern for batch snapping multiple points
The table and cols params already in place (v0.1.0) make these additions straightforward — custom views or tables with scoring columns can be swapped in.
Reference
bcfishpass/model/01_access/pscis/sql/02_pscis_streams_150m.sql — PSCIS snapping + scoring
bcfishpass/model/01_access/modelled_stream_crossings/sql/02_intersect_dra.sql — road crossing clustering
bcfishpass/model/01_access/pscis/README.md — full workflow docs
Relates to NewGraphEnvironment/sred-2025-2026#18