One JSON file per river, rendered by python3 tools/build_river_guide.py <config>.
Output: output/river-guides/<slug>-guide.html + output/pdf/<slug>-river-guide.pdf
(PDF printed automatically via headless Chrome). A3 landscape; layout picks itself:
map-on-top for wide rivers, map-left for tall ones (bbox aspect > 0.6).
data/river-guides/<slug>-osm.json (Overpass:
river ways + highways + landuse + waterways in the river bbox) and a centreline —
either OSM way ids (centreline.type: "osm") or an FWA export with
centreline.coordinates (type: "fwa"). Obstacles (falls/cascades/rapids/dams,
FISS + FWA merged) come from data/river-guides/obstructions-kootenay.geojson
automatically by proximity (150 m) — refresh with tools/build_obstructions.py --refresh.skookumchuck-creek.json (wide) or goat-river.json (tall).
Fill points/zones/markers/labels/cards from the river's wiki page
(wiki/rivers-and-lakes/<slug>.md: standfirst, regs, access, flies) — cards carry
the fishing content; keep regs wording aligned with the wiki.LINT overlap: lines for
colliding labels/markers (estimated boxes). Fix config coordinates until
LINT: no label overlaps detected, then do ONE visual check of the PDF
(sips -s format png + zoom crops of dense clusters). Lint does not know about
icons, leader lines, map edges or the legend box — check those visually:
labels near the bbox edge, leaders crossing icons, and the bottom-right legend
overlay are the usual offenders.legend
text is per-config. Long marker labels in dense clusters: shorten the on-map text
and keep the full name in the stops card.Honesty rules (keep): falls/rapids positions are approximate and incomplete; road crossings are landmarks, not access rights; "not for navigation" note stays.