Skip to content

feat: add via option to force routes through named passages - #21

Merged
mayurrawte merged 1 commit into
mainfrom
feat/issue-8-via-passages
Jul 9, 2026
Merged

feat: add via option to force routes through named passages#21
mayurrawte merged 1 commit into
mainfrom
feat/issue-8-via-passages

Conversation

@mayurrawte

Copy link
Copy Markdown
Owner

What does this PR do?

Adds a via option to seaRoute — the inverse of restrictions. restrictions blocks a passage; via requires one, so users can force and compare explicit routings (e.g. "via Suez" vs "via Panama"):

seaRoute('CNSHA', 'NLRTM', { via: ['suez'] });   // through Suez (the default) — 19,753 km
seaRoute('CNSHA', 'NLRTM', { via: ['panama'] });  // across the Pacific + Panama — 25,315 km

Design (as suggested in the issue — reuse the multi-leg machinery):

  • Routes origin → passage₁ → … → passageₙ → destination, snapping each passage's PASSAGE_BBOXES centroid to the network as an intermediate waypoint via seaRouteMulti. No new routing logic. New passageCentroid() helper in restrictions.ts.
  • via accepts the same Passage names as restrictions and visits multiple passages in the order given.
  • A passage named in via is dropped from the effective per-leg restriction set, so a required passage is never blocked out from under the requirement — via: ['northeast'] reaches the Northeast Passage without also needing allowArctic.
  • Naming a passage in both via and restrictions (compared after alias canonicalisation, so via:['babalmandab'] + restrictions:['babelmandeb'] counts) is a contradiction and throws NoRouteError.
  • greatCircleLength/detourRatio stay measured against the direct origin→destination geodesic, matching plain seaRoute.

Acceptance criteria (from #8)

  • via accepts the same Passage names as restrictions.
  • ✅ Combining via and restrictions with a contradiction throws NoRouteError.
  • ✅ Test: Shanghai → Rotterdam via: ['panama'] routes across the Pacific + Panama, not Suez.

Checklist

  • npm run lint and npm test pass
  • New behavior is covered by a test
  • CHANGELOG.md updated (user-visible changes only)

Validation (all steps CI runs, from a clean tree)

  • npm ci
  • npm run lint
  • npm run format:check
  • npm run build
  • npm test ✅ (74 tests; 7 new covering via-Panama across the Pacific/not-Suez, via-Magellan rounding Cape Horn, via-Suez staying on the default route, via-Northeast without allowArctic, the origin→destination great-circle reference, and both contradiction cases including the alias)

Also verified end-to-end against the built dist (CJS): via:['panama'] = 25,315 km through Panama with no Suez, via:['suez'] = 19,753 km, and the contradiction case throws NoRouteError.

Closes #8


Generated by Claude Code

Adds a `via` option to seaRoute — the inverse of `restrictions`. Instead of
blocking a passage it requires one, routing origin → passage → destination
through each passage's PASSAGE_BBOXES centroid via the multi-leg machinery.

- `via` accepts the same Passage names as `restrictions` and visits multiple
  passages in order.
- A passage named in `via` is excluded from the effective per-leg restriction
  set, so a required passage is never blocked out from under the requirement
  (e.g. via: ['northeast'] needs no allowArctic).
- Naming a passage in both `via` and `restrictions` (after alias
  canonicalisation) throws NoRouteError.
- greatCircleLength/detourRatio remain measured against the direct
  origin→destination geodesic.

Adds passageCentroid() helper. Tests, README, DOCS and CHANGELOG updated.
@mayurrawte
mayurrawte force-pushed the feat/issue-8-via-passages branch from e4aa1e0 to cfe1830 Compare July 9, 2026 09:06
@mayurrawte
mayurrawte merged commit 8d01cbf into main Jul 9, 2026
4 checks passed
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.

Add via option to force routes through named passages (inverse of restrictions)

1 participant