first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
# stations
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Geospatial helpers that find tide-gauge stations near a query point on the WGS84-equivalent reference ellipsoid. Wraps `@suaveplan/geo`'s `greatCircleDistance` so that callers do not need to choose an ellipsoid or unit themselves. Used by every provider that ships its own catalogue (ADMIRALTY, custom TICON datasets) and by user-facing UI surfaces that need a "nearest station" picker without instantiating a full provider.
## Features
- `findNearestStation(lat, lon, stations)` returning the single closest entry plus the great-circle distance in kilometres.
- `findStationsInRadius(lat, lon, radiusKm, stations)` returning every station within a radius, pre-sorted ascending by distance.
- Distances rounded to two decimal places (10 m precision) for stable display.
- Strict `TideError` codes for pathological inputs: `NO_STATIONS` and `INVALID_RADIUS`.
- Pure functions — no allocation beyond the result array, no shared state.
## Usage: Basic Example
```ts
import { findNearestStation } from "@suaveplan/tides";
const result = findNearestStation(51.5074, -0.1278, [
{ id: "1", name: "London", latitude: 51.5074, longitude: -0.1278, provider: "ticon" },
{ id: "2", name: "Dover", latitude: 51.1278, longitude: 1.3134, provider: "ticon" },
]);
console.log(result.station.name, result.distanceKm);
```
## Usage: Advanced Example
```ts
import { findStationsInRadius, type TideStation } from "@suaveplan/tides";
const stations: TideStation[] = await loadCatalogue();
const within50km = findStationsInRadius(51.5074, -0.1278, 50, stations);
for (const { station, distanceKm } of within50km) {
console.log(`${station.name}: ${distanceKm} km`);
}
```
## API Reference
- `findNearestStation(latitude: number, longitude: number, stations: readonly TideStation[]): NearestStationResult` — throws `TideError("NO_STATIONS")` when `stations` is empty.
- `findStationsInRadius(latitude: number, longitude: number, radiusKm: number, stations: readonly TideStation[]): NearestStationResult[]` — throws `TideError("INVALID_RADIUS")` when `radiusKm <= 0`. Result is sorted ascending by distance.
- `NearestStationResult` — `{ station: TideStation; distanceKm: number }`.
## Implementation Notes
Internally uses a single ellipsoid built via `defineEllipsoid(6_371_000, 6_356_000)`, matching the values used elsewhere in the geo plugin family. This is a slight approximation versus the strict WGS84 spheroid (6_378_137 / 6_356_752) but is consistent with the rest of the package family and avoids importing the full WGS84 constants table. The radius search performs a linear scan rather than a spatial index — for catalogues of more than a few thousand stations, callers should consider pre-bucketing by tile or using an external R-tree library; tide-gauge networks rarely exceed that size in practice. Distances are reported in kilometres (`"kilometre"` unit on `greatCircleDistance`).