Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# lane-progress
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Projects a vessel position onto a shipping lane and reports how much of
the lane has been traversed, how much remains, and which waypoint is
nearest. Used by `estimateETA` to derive the remaining-distance figure
that feeds the ETA computation, and exposed publicly so downstream UIs
can render lane-progress bars without re-implementing the geometry.
## Features
- Finds the nearest waypoint by great-circle distance.
- Estimates fractional progress within the nearest waypoint's adjacent
segment (prev or next, whichever is closer).
- Returns `{ progress, remainingDistanceNm, distanceTravelledNm,
nearestWaypointIndex }` with `progress` clamped to `[0, 1]` and
rounded to four decimals; distances clamped to `>= 0` and rounded to
two decimals.
- Throws `PortsInsufficientWaypointsError` for lanes with fewer than
two waypoints.
- Handles degenerate zero-length lanes (every waypoint identical) by
returning zero progress.
## Usage: Basic
```ts
import { findPositionOnLane, getShippingLaneStrict } from "@suaveplan/ports";
const lane = getShippingLaneStrict("asia-europe-suez");
const progress = findPositionOnLane(
{ latitude: 12.5, longitude: 43.3 },
lane
);
```
## Usage: Advanced
```ts
import { findPositionOnLane, type ShippingLane } from "@suaveplan/ports";
function eta(
coord: { latitude: number; longitude: number },
lane: ShippingLane,
knots: number,
departure: Date
): Date {
const { remainingDistanceNm } = findPositionOnLane(coord, lane);
const hours = remainingDistanceNm / knots;
return new Date(departure.getTime() + hours * 3_600_000);
}
```
## API Reference
- `findPositionOnLane(coord, lane): LaneProgress`.
## Implementation Notes
The "nearest waypoint" pass is a linear scan. The adjacent-segment
projection uses a 1D ratio (distance-to-nearest / segment-length)
clamped to `[0, 1]`; this is an approximation that works well when the
coord is reasonably close to the lane and degrades gracefully when the
coord is far off-lane (the ETA `confidence` band downgrades to
`medium`/`low`). The function never throws on out-of-lane coords —
callers receive a clamped progress fraction and a non-negative
remaining distance regardless of how far off-lane the vessel is.