Skip to content

feat: ECA/SECA distance + optional CO₂e emissions reporting - #22

Open
mayurrawte wants to merge 2 commits into
mainfrom
feat/issue-12-eca-emissions
Open

feat: ECA/SECA distance + optional CO₂e emissions reporting#22
mayurrawte wants to merge 2 commits into
mainfrom
feat/issue-12-eca-emissions

Conversation

@mayurrawte

Copy link
Copy Markdown
Owner

What does this PR do?

Adds opt-in emissions reporting to seaRoute/seaRouteMulti — the two things the commercial Searoutes API leads with, offered in open source. Turn it on with emissions: true:

import 'searoute-ts/eca';                 // load the ECA/SECA zones (enables ecaKm)
import { seaRoute } from 'searoute-ts';

const r = seaRoute('CNSHA', 'NLRTM', { emissions: true, vesselClass: 'panamax' });
r.properties.ecaKm;        // km inside emission-control zones
r.properties.ecaFraction;  // that ÷ length (0–1)
r.properties.co2eTonnes;   // rough CO₂e estimate

Phase 1 — ECA/SECA distance (ecaKm)

  • properties.ecaKm / ecaFraction report how much of the in-water route lies inside ECA/SECA emission-control areas. Computed by subdividing each route segment into ~5 km steps and testing midpoints against zone bboxes — the same bbox idea already used for passage detection, as the issue suggested.
  • Zones ship behind a new searoute-ts/eca subpath export (per the issue's "keep zone polygons behind a subpath to avoid bloating the core (Halve package size: load the network from a single shared asset instead of inlining it in both builds #10)"), mirroring the searoute-ts/ports pattern — importing it registers the defaults via registerEcaZones; without the import, ecaKm stays undefined and the core stays lean.
  • Coverage: Baltic Sea, North Sea (+ English Channel), Mediterranean (SECA in force 2025-05-01), North American (Pacific/Atlantic/Gulf) and US Caribbean ECAs.
  • Honesty: the bundled zones are bounding-box approximations of the IMO MARPOL Annex VI areas (the North American/Caribbean ECAs really follow a 200 nm baseline offset — here they're coarse coastal envelopes). Clearly documented as estimates, and fully replaceable with higher-fidelity polygons via registerEcaZones.

Phase 2 — CO₂e estimate (co2eTonnes, opt-in)

  • When a vesselClass (VESSEL_CLASSES) or explicit co2eFactorKgPerKm is given, properties.co2eTonnes = distanceKm × factor.
  • Factors are derived transparently (not magic numbers): fuelTonnesPerDay × 3.114 (IMO HFO CO₂ conversion) × 1000 / (24 × serviceSpeedKnots × 1.852) → kg CO₂e/km. Cited to the IMO Fourth GHG Study 2020.
  • glecInflation (e.g. 0.15) applies the GLEC ~15 % shortest-path distance uplift to the CO₂e estimate only.
  • Documented clearly as an order-of-magnitude estimate, not a certified figure, and the factor is configurable.

New exports — core: registerEcaZones, getEcaZones, hasEcaZones, ecaDistanceKm, EcaZone, EcaBbox, VESSEL_CLASSES, co2eFactorKgPerKm, CO2_PER_TONNE_FUEL, VesselClass, VesselClassSpec; subpath searoute-ts/eca: ECA_ZONES, registerEcaZones, EcaZone. No breaking changes; no version bump.

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 ✅ (emits the searoute-ts/eca subpath in CJS/ESM/types)
  • npm test ✅ (78 tests; 5 new core CO₂e tests covering factor scaling, co2eFactorKgPerKm override, glecInflation, and no-emission-props-without-the-flag; 6 new src/eca/index.spec.ts tests covering zone registration, a North Sea route ~100 % in-zone, an Indian-Ocean route ~0 % in-zone, ECA + CO₂e together, ecaDistanceKm on an explicit Mediterranean line, and registerEcaZones custom-zone override)

Also verified end-to-end against the built dist (CJS + ESM): Rotterdam→London = 392 km with ecaKm 392 / fraction 1.00 and co2eTonnes 88.2 (panamax); Singapore→Mumbai ecaKm 0.00; glecInflation: 0.15 scales CO₂e as expected.

Closes #12


Generated by Claude Code

mayurrawte and others added 2 commits July 9, 2026 14:55
Opt-in emissions reporting on route properties (rough estimates, not certified):

- properties.ecaKm / ecaFraction: kilometres of the in-water route inside
  ECA/SECA emission-control zones. The zones ship behind a new searoute-ts/eca
  subpath export (bounding-box approximations of the IMO MARPOL Annex VI areas:
  Baltic, North Sea, Mediterranean, North American, US Caribbean); importing it
  registers them, keeping the core lean. Computed by subdividing each segment
  and testing midpoints against zone bboxes, mirroring passage detection.
- properties.co2eTonnes: rough distance x vessel-class factor estimate, when a
  vesselClass or co2eFactorKgPerKm is given. Factors derive transparently from
  representative fuel burn and the IMO HFO CO2 conversion (VESSEL_CLASSES);
  glecInflation applies the GLEC ~15% distance uplift.

New exports: registerEcaZones, getEcaZones, hasEcaZones, ecaDistanceKm, EcaZone,
EcaBbox, VESSEL_CLASSES, co2eFactorKgPerKm, CO2_PER_TONNE_FUEL, VesselClass,
VesselClassSpec, and searoute-ts/eca (ECA_ZONES). Tests, README, DOCS, CHANGELOG
updated.
ecaDistanceKm interpolated segment midpoints linearly in wrapped lon/lat,
so the 37 network edges that jump the ±180° dateline swept their midpoints
the long way round the globe — straight through the Mediterranean, North
Atlantic and North Sea bboxes. A Yokohama → Honolulu route reported ~249 km
of ECA distance in the open Pacific.

Unwrap the path first (reusing unwrapCoords) so dateline-crossing segments
interpolate the short way, and wrap each midpoint back into ±180° for the
zone test. Adds a unit regression for a mid-Pacific dateline segment and an
end-to-end trans-Pacific route test; corrects the DOCS.md claim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mayurrawte
mayurrawte force-pushed the feat/issue-12-eca-emissions branch from 05627b3 to 0fa50bd Compare July 9, 2026 09:26
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.

Emissions & ECA/SECA reporting: distance in emission-control zones + optional CO₂e estimate

1 participant