Warning: This project is under active development and is not production-ready. It is being built in public as a learning and portfolio project. APIs, data models, and features may change without notice. Do not use for actual voyage planning or navigation.
A maritime route optimization platform for Medium Range (MR) Product Tankers. Minimizes fuel consumption through weather-aware A* routing, physics-based vessel modeling, and real-time sensor fusion.
Documentation: slmar.co/windmar/docs.html
- Holtrop-Mennen resistance prediction — calm water resistance with frictional, wave-making, and appendage components
- Two wave resistance methods — STAWAVE-1 (ISO 15016, default) and Kwon's method (speed-loss percentage, per TN001)
- SFOC curves at variable engine loads with calibration factor support
- Performance predictor — dual-mode inverse solver: find achievable speed at a given engine load, or find required power for a target calm-water speed in weather
- Hull fouling calibration from operational noon reports and engine log data
- Laden and ballast condition support with 20 configurable vessel parameters
- Vessel specifications persisted in PostgreSQL across restarts
- Engine log ingestion — upload CSV/Excel operational data with automatic column mapping
- Performance dashboard — 5 KPIs (avg speed, avg fuel, efficiency, distance, operating hours) + 6 interactive engine charts
- Analytics tab — fuel consumption distributions, speed-power scatter, voyage statistics
- Engine-log calibration bridge — calibrate vessel model directly from engine log data
- Batch management — upload, browse, filter, and delete engine log batches
- Dual-engine optimization: A* grid search + VISIR-style Dijkstra with time-expanded graph
- Both engines converge on ocean-crossing routes (tested: 901nm Portugal-Casquets, A* -2.6% fuel, VISIR -0.7% fuel)
- All 6 route variants computed per request (2 engines x 3 safety weights: fuel / balanced / safety)
- Sequential execution with progressive UI updates as each route completes
- A* grid at 0.2 deg (~12nm) resolution; VISIR at 0.25 deg (~15nm) — aligned with professional routing software (VISIR-2, StormGeo)
- Hard avoidance limits — Hs >= 6m and wind >= 70 kts are instant rejection (no motion calculation)
- Seakeeping safety constraints — graduated roll, pitch, acceleration limits with motion-based cost multipliers
- Distance-adaptive land mask sampling (~1 check per 2nm, auto-scaled per segment length)
- Per-edge land crossing checks on both engines using
global-land-mask(1km resolution) - Voluntary speed reduction (VSR) in heavy weather (VISIR engine)
- Variable speed optimization (10-18 knots per leg)
- Turn-angle path smoothing to eliminate grid staircase artifacts
- RTZ file import/export (IEC 61174 ECDIS standard)
- NOAA GFS (0.25 deg) for near-real-time wind fields via NOMADS GRIB filter
- 5-day wind forecast timeline (f000-f120, 3-hourly steps) with Windy-style animation
- Copernicus Marine Service (CMEMS) for wave and ocean current data
- ERA5 reanalysis as secondary wind fallback (~5-day lag)
- Climatology fallback for beyond-forecast-horizon voyages
- Unified provider that blends forecast and climatology with smooth transitions
- Pre-ingested weather database — grids compressed (zlib/float32) in PostgreSQL, served in milliseconds
- Redis shared cache across all API workers (replaces per-worker in-memory dict)
- User-triggered overlay model — no background loops; per-layer resync with viewport-aware CMEMS downloads
- Server-side grid subsampling (<=500 pts/axis) prevents browser OOM on large viewports
- Synthetic data generator for testing and demos
- Parametric Monte Carlo with temporally correlated perturbations
- Divides voyage into up to 100 time slices (~1 per 1.2 hours)
- Cholesky decomposition of exponential temporal correlation matrix
- Log-normal perturbation model: wind sigma=0.35, wave sigma=0.20 (70% correlated with wind), current sigma=0.15
- P10/P50/P90 confidence intervals for ETA, fuel consumption, and voyage time
- Pre-fetches multi-timestep wave forecast grids from database (0-120h)
- 100 simulations complete in <500ms
- IMO CII (Carbon Intensity Indicator) calculations with annual tightening
- Emission Control Areas (ECA/SECA) with fuel switching requirements
- High Risk Areas (HRA), Traffic Separation Schemes (TSS)
- Custom zone creation with penalty/exclusion/mandatory interactions
- GeoJSON export for frontend visualization
- SBG Electronics IMU sensor integration (roll, pitch, heave)
- FFT-based wave spectrum estimation from ship motion
- Multi-source sensor fusion engine
- Continuous model recalibration from live data
- ECDIS-style map-centric layout with full-width chart and header dropdowns
- Interactive Leaflet maps with weather overlays and route visualization
- Wind particle animation layer (leaflet-velocity)
- Windy-style wave crest rendering with click-to-inspect polar diagram popup
- Forecast timeline with play/pause, speed control, and 5-day scrubbing
- All 6 optimized routes displayed simultaneously with per-route color coding and toggleable visibility
- Unified comparison table with fuel, distance, time, and waypoint counts for every route variant
- Sequential optimization with progressive map updates (routes appear one by one)
- Navigation persistence — waypoints, route name, and optimization results survive page navigation via React Context
- Voyage calculation with per-leg fuel, speed, and ETA breakdown
- Consolidated vessel configuration, calibration, fuel analysis, and performance prediction page
- Engine log upload, entries browser, and analytics dashboard
- CII compliance tracking and projections
- Dark maritime theme, responsive design
windmar/
├── api/ # FastAPI backend
│ ├── main.py # API endpoints (~6500 lines), weather pipeline, vessel model
│ ├── auth.py # API key authentication (bcrypt)
│ ├── config.py # API configuration (pydantic-settings)
│ ├── middleware.py # Security headers, structured logging, metrics
│ ├── rate_limit.py # Token bucket rate limiter (Redis-backed)
│ ├── database.py # SQLAlchemy ORM setup
│ ├── models.py # Database models (weather, engine log, vessel specs)
│ ├── health.py # Health check logic
│ ├── state.py # Thread-safe application state (singleton)
│ ├── cache.py # Weather data caching (Redis shared cache)
│ ├── resilience.py # Circuit breakers
│ ├── cli.py # CLI utilities
│ └── live.py # Live sensor data API router
├── src/
│ ├── optimization/
│ │ ├── vessel_model.py # Holtrop-Mennen + Kwon resistance, SFOC, performance predictor
│ │ ├── base_optimizer.py # Abstract base class for route optimizers
│ │ ├── route_optimizer.py # A* grid search with weather costs (0.2 deg)
│ │ ├── visir_optimizer.py # VISIR-style Dijkstra time-expanded graph (0.25 deg)
│ │ ├── router.py # Engine dispatcher (A*/VISIR selection)
│ │ ├── voyage.py # Per-leg voyage calculator (LegWeather, VoyageResult)
│ │ ├── monte_carlo.py # Temporal MC simulation with Cholesky correlation
│ │ ├── grid_weather_provider.py # Bilinear interpolation from pre-fetched grids
│ │ ├── temporal_weather_provider.py # Trilinear interpolation (lat, lon, time)
│ │ ├── weather_assessment.py # Route weather assessment + DB provisioning
│ │ ├── vessel_calibration.py # Noon report + engine log calibration (scipy)
│ │ └── seakeeping.py # Ship motion safety assessment
│ ├── data/
│ │ ├── copernicus.py # GFS, ERA5, CMEMS providers + forecast prefetch
│ │ ├── db_weather_provider.py # DB-backed weather (compressed grids from PostgreSQL)
│ │ ├── weather_ingestion.py # Scheduled weather grid ingestion service
│ │ ├── regulatory_zones.py # Zone management and point-in-polygon
│ │ ├── eca_zones.py # ECA zone definitions
│ │ └── land_mask.py # Ocean/land detection
│ ├── sensors/
│ │ ├── sbg_nmea.py # SBG IMU NMEA parsing
│ │ ├── sbg_ellipse.py # SBG Ellipse sensor driver
│ │ └── wave_estimator.py # FFT wave spectrum from heave data
│ ├── fusion/
│ │ └── fusion_engine.py # Multi-source data fusion
│ ├── compliance/
│ │ └── cii.py # IMO CII rating calculations
│ ├── routes/
│ │ └── rtz_parser.py # RTZ XML route file parser
│ ├── validation.py # Input validation
│ ├── config.py # Application configuration
│ └── metrics.py # Performance metrics collection
├── frontend/ # Next.js 15 + TypeScript
│ ├── app/ # Pages (route planner, vessel config, CII, live dashboard)
│ ├── components/ # React components (maps, charts, weather layers, forecast timeline)
│ └── lib/ # API client, utilities
├── tests/
│ ├── unit/ # Vessel model, router, validation, ECA zones, Excel parser, CII, calibration, SBG NMEA, metrics
│ ├── integration/ # API endpoints, optimization flow
│ └── test_e2e_*.py # End-to-end sensor integration
├── examples/ # Demo scripts (simple, ARA-MED, calibration)
├── docker/ # init-db.sql, migrations/ (weather tables)
├── data/ # Runtime data (GRIB cache, calibration, climatology)
├── docker-compose.yml # Full stack (API + frontend + PostgreSQL + Redis)
├── Dockerfile # Multi-stage production build
└── pyproject.toml # Poetry project definition
| Layer | Technology |
|---|---|
| Backend | FastAPI, Uvicorn, Python 3.10+ |
| Frontend | Next.js 15, TypeScript, React, Tailwind CSS |
| Maps | React Leaflet |
| Charts | Recharts |
| Database | PostgreSQL 16, SQLAlchemy |
| Cache | Redis 7 |
| Scientific | NumPy, SciPy, Pandas |
| Auth | API keys, bcrypt |
| Containerization | Docker, Docker Compose |
git clone https://github.com/SL-Mar/Windmar.git
cd Windmar
cp .env.example .env # Edit with your settings
docker compose up -d --buildServices start on:
| Service | URL |
|---|---|
| Frontend | http://localhost:3003 |
| API | http://localhost:8003 |
| API Docs (Swagger) | http://localhost:8003/api/docs |
| PostgreSQL | localhost:5434 |
| Redis | localhost:6380 |
Important: The frontend requires the backend API to be running. Start the backend first, then the frontend in a separate terminal.
# Terminal 1 — Backend API (must be running for the frontend to work)
pip install -r requirements.txt
python api/main.py
# API starts on http://localhost:8000
# Terminal 2 — Frontend
cd frontend
cp .env.example .env.local # Sets API URL to http://localhost:8000
npm install --legacy-peer-deps
npm run dev
# Frontend starts on http://localhost:3000python examples/demo_simple.py # Synthetic weather demo
python examples/example_ara_med.py # Rotterdam to Augusta optimization
python examples/example_calibration.py # Noon report calibrationCopy .env.example to .env and configure:
| Variable | Description | Default |
|---|---|---|
ENVIRONMENT |
development / staging / production | development |
DATABASE_URL |
PostgreSQL connection string | postgresql://windmar:...@db:5432/windmar |
REDIS_URL |
Redis connection string | redis://:...@redis:6379/0 |
API_SECRET_KEY |
API key hashing secret | (generate with openssl rand -hex 32) |
CORS_ORIGINS |
Allowed frontend origins | http://localhost:3000 |
COPERNICUS_MOCK_MODE |
Use synthetic weather data | true |
AUTH_ENABLED |
Require API key authentication | true |
RATE_LIMIT_PER_MINUTE |
API rate limit | 60 |
Windmar uses a three-tier provider chain that automatically falls back when a source is unavailable:
| Data Type | Primary Source | Fallback | Credentials Required |
|---|---|---|---|
| Wind | NOAA GFS (0.25 deg, ~3.5h lag) | ERA5 reanalysis, Synthetic | None (GFS is free) |
| Waves | CMEMS global wave model | Synthetic | CMEMS account |
| Currents | CMEMS global physics model | Synthetic | CMEMS account |
| Forecast | GFS f000-f120 (5-day, 3h steps) | — | None |
Wind data works out of the box — GFS is fetched from NOAA NOMADS without authentication. For wave and current data, you need Copernicus Marine credentials.
CMEMS (waves and currents):
- Register at marine.copernicus.eu
- Set in
.env:COPERNICUSMARINE_SERVICE_USERNAME=your_username COPERNICUSMARINE_SERVICE_PASSWORD=your_password
CDS ERA5 (wind fallback):
- Register at cds.climate.copernicus.eu
- Copy your Personal Access Token from your profile page
- Set in
.env:CDSAPI_KEY=your_personal_access_token
Without these credentials, the system falls back to synthetic data automatically for waves and currents. Wind visualization always works via GFS.
See WEATHER_PIPELINE.md for full technical details on data acquisition, GRIB processing, and the forecast timeline.
GET /api/weather/health- Weather subsystem healthGET /api/weather/wind- Wind field grid (U/V components)GET /api/weather/wind/velocity- Wind in leaflet-velocity format (GFS)GET /api/weather/waves- Wave height field (CMEMS)GET /api/weather/swell- Swell fieldGET /api/weather/currents- Ocean current field (CMEMS)GET /api/weather/currents/velocity- Currents in leaflet-velocity formatGET /api/weather/sst- Sea surface temperatureGET /api/weather/visibility- Visibility fieldGET /api/weather/ice- Sea ice concentrationGET /api/weather/point- Weather at specific coordinatesGET /api/weather/freshness- Weather data age indicatorPOST /api/weather/{layer}/resync- Per-layer viewport-aware resync
GET /api/weather/forecast/status- GFS prefetch progress and run infoPOST /api/weather/forecast/prefetch- Trigger 5-day forecast download (f000-f120)GET /api/weather/forecast/frames- Bulk download all forecast frames
GET /api/weather/forecast/{layer}/status- Prefetch progressPOST /api/weather/forecast/{layer}/prefetch- Trigger forecast downloadGET /api/weather/forecast/{layer}/frames- Bulk download forecast frames
POST /api/routes/parse-rtz- Parse RTZ route filePOST /api/routes/from-waypoints- Create route from coordinates
POST /api/voyage/calculate- Full voyage calculation with weatherGET /api/voyage/weather-along-route- Weather conditions per waypointPOST /api/voyage/monte-carlo- Parametric MC simulation (P10/P50/P90)
POST /api/optimize/route- Weather-optimal route finding (A* or VISIR engine)GET /api/optimize/status- Optimizer configuration and available targets
GET /api/vessel/specs- Current vessel specificationsPOST /api/vessel/specs- Update vessel specifications (persisted to DB)GET /api/vessel/calibration- Current calibration factorsPOST /api/vessel/calibration/set- Manually set calibration factorsPOST /api/vessel/calibrate- Run calibration from noon reportsPOST /api/vessel/calibration/estimate-fouling- Estimate hull fouling factorGET /api/vessel/model-status- Full model parameters, calibration state, computed valuesGET /api/vessel/fuel-scenarios- Physics-based fuel scenarios (4 conditions)POST /api/vessel/predict- Performance predictor (engine load or target speed mode)GET /api/vessel/noon-reports- List uploaded noon reportsPOST /api/vessel/noon-reports- Add a single noon reportPOST /api/vessel/noon-reports/upload-csv- Upload operational data (CSV)POST /api/vessel/noon-reports/upload-excel- Upload operational data (Excel .xlsx/.xls)DELETE /api/vessel/noon-reports- Clear all noon reports
POST /api/engine-log/upload- Upload engine log CSV/ExcelGET /api/engine-log/entries- Browse entries with pagination and filtersGET /api/engine-log/summary- Aggregate statistics per batchPOST /api/engine-log/calibrate- Calibrate vessel model from engine log dataDELETE /api/engine-log/batch/{batch_id}- Delete a batch
GET /api/zones- All regulatory zones (GeoJSON)GET /api/zones/list- Zone summary listGET /api/zones/{zone_id}- Single zone detailsPOST /api/zones- Create custom zoneDELETE /api/zones/{zone_id}- Delete a custom zoneGET /api/zones/at-point- Zones at specific coordinatesGET /api/zones/check-path- Check zone intersections along a route
GET /api/cii/vessel-types- IMO vessel type categoriesGET /api/cii/fuel-types- Fuel types and CO2 emission factorsPOST /api/cii/calculate- Calculate CII ratingPOST /api/cii/project- Multi-year CII projectionPOST /api/cii/reduction- Required fuel reduction for target rating
GET /api/live/status- Sensor connection statusPOST /api/live/connect- Connect to SBG IMU sensorPOST /api/live/disconnect- Disconnect sensorGET /api/live/data- Current fused sensor dataGET /api/live/timeseries/{channel}- Time series for a specific channelGET /api/live/timeseries- All time series dataGET /api/live/motion/statistics- Motion statistics (roll, pitch, heave)GET /api/live/channels- Available data channelsPOST /api/live/export- Export recorded data
GET /api/health- Health checkGET /api/health/live- Liveness probeGET /api/health/ready- Readiness probeGET /api/status- Application status summaryGET /api/metrics- Prometheus metricsGET /api/metrics/json- Metrics in JSON formatGET /api/data-sources- Weather data source configuration
Full interactive documentation at /api/docs when the server is running.
pytest tests/ -v # All tests
pytest tests/unit/ -v # Unit tests only
pytest tests/integration/ -v # Integration tests
pytest tests/unit/test_vessel_model.py -v # Specific test fileThe system ships with a default MR Product Tanker configuration (all values configurable via API and persisted in DB):
| Parameter | Value |
|---|---|
| DWT | 49,000 MT |
| LOA / LPP | 183m / 176m |
| Beam | 32m |
| Draft (laden / ballast) | 11.8m / 6.5m |
| Displacement (laden / ballast) | 65,000 / 20,000 MT |
| Block coefficient (laden / ballast) | 0.82 / 0.75 |
| Wetted surface (laden / ballast) | 7,500 / 5,200 m2 |
| Main Engine MCR | 8,840 kW |
| SFOC at MCR | 171 g/kWh |
| Service Speed (laden / ballast) | 14.5 / 15.0 knots |
| Frontal area (laden / ballast) | 450 / 850 m2 |
| Lateral area (laden / ballast) | 2,100 / 2,800 m2 |
Engine log ingestion and analytics, physics model upgrade (SFOC fix, Kwon's wave resistance, performance predictor), weather pipeline refactoring, and dual-engine optimizer convergence with corrected cost formulas and MR safety limits.
Optimizer Fixes
- VISIR cost formula corrected — safety and zone multipliers now apply to fuel cost only, not the time penalty; previous formula
(fuel + lambda*hours) * safety * zoneinflated detour costs; fixed tofuel * safety * zone + lambda*hours - Hard avoidance limits — Hs >= 6m and wind >= 70 kts trigger instant rejection (
infcost) before computing vessel motions, matching MR Product Tanker operational limits (Beaufort 9+) - Wind speed plumbed to safety checks —
get_safety_cost_factor()now receives wind speed in both A* and VISIR engines - VISIR converges on 901nm route (Portugal to Casquets): 377 cells, 1.5s compute, -0.7% fuel savings
- A* converges on 901nm route: -2.6% fuel savings
Model Curves & Calibration
- Model curves endpoint —
GET /api/vessel/model-curvesreturns speed-indexed arrays for resistance, power, SFOC, and fuel consumption - Auto-load calibration — saved calibration factors restored on startup (survives container restarts)
- AnalysisPanel — calibration indicator and smart optimization route display
Layout Harmonization
- Standardized container layout (
container mx-auto px-6 pt-20 pb-12) across all dashboard pages - Vessel Model tab: 2x2 chart grid (was stacked), all charts at consistent height
- Engine Log: wider tab bar and upload section, consistent chart heights
- Analysis, CII, Live dashboard: consistent padding and offsets
Vessel Model Physics
- SFOC calibration factor fix —
sfoc_factorwas calibrated but never applied to the SFOC curve; now propagated throughVesselModel,state.py, and all model rebuild paths in the API - Kwon's wave resistance method — alternative to STAWAVE-1, selectable via
wave_methodparameter ('stawave1'|'kwon'); uses speed-loss percentage from Hs, Cb, Lpp, and directional factor (per TN001) - Performance predictor — bisection solver for the inverse problem: given engine load + weather, what speed is achievable? Returns STW, SOG, fuel/day, fuel/nm, resistance breakdown, weather speed loss
- Dual-mode prediction —
POST /api/vessel/predictaccepts eitherengine_load_pct(find speed at power) orcalm_speed_kts(find power for target speed); MCR capping with automatic fallback - Relative direction convention — all predictor directions are relative to bow (0 deg = ahead, 90 deg = beam, 180 deg = astern) instead of absolute compass headings
- Full model status endpoint —
GET /api/vessel/model-statusexposes all 20 VesselSpecs fields, calibration state, and computed optimal speeds - Physics-based fuel scenarios —
GET /api/vessel/fuel-scenariosreplaces hardcoded frontend scenarios with realVesselModel.calculate_fuel_consumption()results
Engine Log Analytics
- Engine log ingestion — upload CSV/Excel with automatic column mapping, parser handles multiple date formats and unit conversions
- Engine log DB model — batch + entries tables with indexes on timestamp, batch_id
- Entries browser — paginated entries with shared filters across Entries, Analytics, and Performance tabs
- Analytics dashboard — 5 KPIs (avg speed, avg fuel, efficiency, total distance, operating hours) + 6 interactive Recharts charts (speed-power scatter, fuel distribution, SFOC profile, voyage timeline)
- Performance tab — engine performance KPIs derived from operational data
- Engine-log calibration bridge —
POST /api/engine-log/calibrateruns vessel calibration against engine log entries - Vessel specs persistence — specs saved to PostgreSQL, restored on startup
Weather Pipeline
- User-triggered overlay model — removed all background ingestion loops, startup health gates, and ensure-all polling; weather data loads on demand when the user activates a layer
- Viewport-aware resync — per-layer
POST /api/weather/{layer}/resyncaccepts the frontend's current viewport bounds, so CMEMS data is downloaded for the region the user is viewing (not a hardcoded North Atlantic bbox) - CMEMS bbox cap — resync viewport capped at 40 deg lat x 60 deg lon to prevent API container OOM
- Overlay grid subsampling — all CMEMS overlay endpoints server-side subsampled to <=500 grid points per axis before JSON serialization
- Per-source isolation — resyncing one layer never touches another; supersede and orphan cleanup scoped by
sourcecolumn - Deferred supersede — new ingestion runs only replace old ones if they have >= forecast hours, preventing data loss when NOMADS/CMEMS is still publishing
- Wind DB fallback — when no GRIB file cache exists, wind frames are rebuilt from PostgreSQL
- Comprehensive pipeline documentation —
WEATHER_PIPELINE.mdrewritten with dataset sizes, memory estimates, subsampling rationale
Two-mode UI (Weather Viewer + Route Analysis), 7 weather overlay layers with forecast timeline, analysis panel with passage plan detail, route management, and production infrastructure.
Major UI overhaul to an ECDIS-style map-centric layout, enhanced weather visualization, and a formalized route optimization workflow with two speed strategies.
- ECDIS-style UI redesign — remove left sidebar, full-width map with header icon dropdowns for voyage parameters and regulation zones; consolidated vessel config, calibration, and fuel analysis into single
/vesselpage; ECDIS-style route indicator panel (bottom-left overlay) and right slide-out analysis panel - Wave crest rendering — Windy-style curved arc crest marks perpendicular to wave propagation direction, opacity scaled by wave height; click-to-inspect popup with SVG polar diagram showing wind, swell, and windwave components on compass rose
- Dual speed-strategy display — after A* path optimization, present two scenarios: Same Speed (constant speed, arrive earlier, moderate fuel savings) and Match ETA (slow-steam to match baseline arrival time, maximum fuel savings); strategy selector tabs in route comparison panel
- Voyage baseline gating — Optimize A* button disabled until a voyage calculation baseline is computed, ensuring meaningful fuel/time comparisons
- Dual-route visualization — display original (blue) and optimized (green dashed) routes simultaneously on map with comparison table (distance, fuel, time, waypoints) and Dismiss/Apply buttons
- GFS wind DB ingestion — add wind grids to the 6-hourly ingestion cycle (41 GFS forecast hours, 3h steps)
- Turn-angle path smoothing — post-filter removes waypoints with <15 deg course change to eliminate grid staircase artifacts from A* output
- A* optimizer tuning — increase time penalty to prevent long zigzag detours; scale smoothing tolerance to grid resolution
Pre-ingested weather grids in PostgreSQL, eliminating live download latency during route calculations.
- Weather ingestion service — background task downloads CMEMS wave/current and GFS wind grids every 6 hours, compresses with zlib (float32), stores in PostgreSQL
- DB weather provider — reads compressed grids, crops to route bounding box, returns
WeatherDataobjects compatible withGridWeatherProvider - Multi-tier fallback chain — Redis shared cache, DB pre-ingested, live CMEMS/GFS, synthetic
- Redis shared cache — replaces per-worker in-memory dict, all 4 Uvicorn workers share weather data
- Frontend freshness indicator — shows weather data age (green/yellow/red) in map overlay controls
- Performance: route optimization from ~90-180s to 2-5s; voyage calculation from minutes to sub-second
Component architecture refactor and Monte Carlo simulation engine.
- Frontend component split — monolithic
page.tsxrefactored into reusable components - Monte Carlo simulation — N=100 parametric simulation engine with P10/P50/P90 confidence intervals for ETA, fuel, and voyage time
- GridWeatherProvider — bilinear interpolation from pre-fetched weather grids, enabling 1000x faster A* routing
- Analysis tab — persistent storage of voyage results for comparison across routes
Live connectivity to Copernicus and NOAA weather services.
- CMEMS wave and current data — Copernicus Marine Service API integration with swell/wind-wave decomposition for accurate seakeeping
- GFS 5-day wind forecast timeline — f000-f120 (3-hourly steps) with Windy-style particle animation on the map
- ERA5 wind fallback — Climate Data Store reanalysis as secondary wind source (~5-day lag)
- Data sources documentation — credential setup guide, provider chain documentation
main- Stable release branchdemo- Demo deployment branch (isolated)
Full technical documentation, safety criteria, algorithm details, and changelog available at slmar.co/windmar/docs.html.
Licensed under the Apache License, Version 2.0.
SL Mar