1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//! Wind-data types and sailing-search logic shared by `bywind-viz` (the
//! egui GUI), `bywind-cli` (the command-line frontend), and any other
//! headless consumer. No GUI dependencies.
//!
//! Module layout:
//!
//! - [`wind_map`] — `WindMap` / `TimedWindMap` / `BakedWindMap`, the time-varying
//! wind grid and its precomputed sampling structure.
//! - [`grib2`] — load a `TimedWindMap` from GRIB2 files.
//! - [`wind_av1`] — AV1 near-lossless wind-map codec for fast save/load.
//! - [`io`] — extension-dispatched loaders that pick between GRIB2 and
//! `wind_av1` automatically. The single-stop entry point used by both the
//! CLI and the GUI's file dialogs.
//! - [`fetch`] — pull GFS UGRD/VGRD-at-10m messages from NOAA's S3 bucket
//! into a concatenated GRIB2 stream the rest of the pipeline can ingest.
//! - [`fmt`] — human-readable formatters for durations / fuel / distances /
//! PSO-vs-benchmark deltas, shared by the GUI's stats panel and the CLI's
//! summary output.
//! - [`bounds`] — derive search and bake bounds from a wind map.
//! - [`route`] — `RouteEvolution` (type-erases the const-generic waypoint count)
//! plus the `waypoint_match!` / `route_evolution_match!` dispatch macros.
//! - [`search`] — pure, blocking entry points for the PSO and time-reopt loops.
//! - [`solution`] — persistence schema for a single search result.
//! - [`metrics`] — per-segment fuel / time / speed breakdown.
//! - [`landmass`] — Natural Earth landmass grid and A* sea-path finder.
//!
//! Most consumers can reach for the re-exports at this crate's root; specialised
//! types (e.g. error enums, low-level landmass primitives) are accessible via
//! `bywind::<module>::*`.
use ;
// Modules.
// Wind data: the core types most consumers reach for first.
// `BakeBounds` stays under `wind_map::` — it's a specialised parameter
// type only used to call `BakedWindMap::from_timed_map`.
pub use ;
// I/O: `Grib2Bbox` is a value type used to call the GRIB2 loader, so it
// gets a crate-root re-export. Named distinctly from the canonical
// `LonLatBbox` because its field order is lat-first (matching the GRIB2
// spec) rather than lon-first like the rest of the crate. Error enums
// stay scoped under their owning module (`grib2::LoadError`,
// `wind_av1::DecodeError`, `wind_av1::EncodeError`,
// `solution::LoadError`, `baked_codec::DecodeError`,
// `baked_codec::EncodeError`, `io::LoadError`,
// `config::ValidationError`) — the bare verb-level names read cleanly
// when fully qualified and avoid crate-root collisions between modules
// that all need to define `LoadError` / `DecodeError` etc.
pub use Grib2Bbox;
// Bounds and search: build a routing problem and solve it.
pub use ;
pub use MapBounds;
// Re-export the `swarmkit-sailing` types that appear in `bywind`'s public
// API surface (parameters / return types / public fields), so the surface
// reads as a single unified crate even though the sailing-PSO is its own
// publishable sibling. The two ship in lockstep — bywind pins a specific
// minor version of swarmkit-sailing and bumps along with it. Consumers
// who want to use the underlying sailing API directly can still depend
// on `swarmkit-sailing` themselves; the types are identical (`pub use`
// preserves type identity).
//
// - `Boat`, `SearchSettings` — passed to `run_search_blocking` / built
// from `BoatConfig::to_boat` / `SearchConfig::to_search_settings`.
// - `RouteBounds`, `LonLatBbox` — search domain types reached through
// `MapBounds`.
// - `Topology` — outer-PSO topology choice (field on `SearchConfig`).
// Marked `#[non_exhaustive]` upstream so adding variants is a patch
// change for both swarmkit-sailing and bywind.
pub use ;
// `DEFAULT_FRAME_STEP_SECONDS` is a niche default; consumers that need it
// reach for `config::DEFAULT_FRAME_STEP_SECONDS`.
pub use ;
pub use ;
// Search results: the type-erased evolution wrapper plus its fixed waypoint
// counts; metrics for displaying per-segment breakdowns; benchmark route from
// the A* + time-PSO baseline.
pub use ;
// `GbestView` / `GbestViewMut` stay under `route::` — they're borrowed
// views into a `RouteEvolution`, not types most consumers name directly.
pub use ;
// Persistence: serialisable schema for a single solution. The
// `LoadError` enum stays scoped at `solution::LoadError` — see the
// note above the `Grib2Bbox` re-export.
pub use SavedSolution;
// Landmass: A* sea-path support. `landmass_grid()` returns the
// `SDF_RESOLUTION_DEG = 0.5°` default grid; `landmass_grid_at_resolution`
// returns a grid at any caller-chosen cell size (cached per distinct
// resolution). Supporting types (`LandmassGrid`, `Polygon`,
// `raw_polygons`) live under `landmass::` for callers that need them.
pub use ;
/// A single wind measurement: speed plus the direction it's coming from.
///
/// `speed` is in knots (meteorological convention — same units the GRIB2
/// surface-wind path delivers; converted to m/s at bake time when the
/// sailing physics needs it). `direction` is in degrees compass
/// `0..=360`, *from*-bearing: `0` is wind blowing from the north, `90`
/// from the east, and so on. Wraparound at the `0`/`360` boundary is
/// handled by interpolating sin/cos components separately, so
/// [`WindMap::query`] returns continuous direction values across a
/// sample boundary that crosses true-north.
/// A single wind sample tagged with its `(lon, lat)` position.
///
/// Derives `Serialize` / `Deserialize` into the natural named-field
/// shape (`{"lon": …, "lat": …, "sample": {"speed": …, "direction": …}}`)
/// for any JSON / TOML / bincode consumer.
/// A [`WeatherRow`] tagged with a wall-clock time in seconds, used as the
/// row-level representation when serialising / deserialising a
/// [`TimedWindMap`] as a stream of samples.