Route is generated incorrectly when crossing time change line #120

Closed
opened 2026-09-22 10:52:31 +02:00 by kamilkrzywda · 1 comment
Owner
image.png
<img width="680" alt="image.png" src="attachments/819d6321-ec97-4be1-8da2-12e08a6f35ed">
Author
Owner

Fixed in v0.53.0 — PR #123, merged as 2a4b341 (CI run 163 green: build + unit 359/359 + full e2e).

What changed: greatCircleArc (lib/mapData.ts) now re-expresses each arc's samples in continuous longitudes via a module-private unwrapLons (first sample keeps its raw lon; later ones shifted ±360 vs the previous unwrapped value until |Δlon| ≤ 180), so all four line builders are fixed at once. queuedRoutesGeoJson gets one global re-unwrap pass after leg concatenation, since each leg unwraps relative to its own start airport and joints can jump ±360. Non-crossing routes are byte-identical (no-op). Out-of-range lons render on MapLibre's adjacent world copies (renderWorldCopies default-on) — one line stays one LineString, no splitting.

Tests: +4 unit (lib/mapData.test.ts, real dataset pairs NZAA/NFTF/NZCH: continuity across east/west crossings, endpoints exact mod 360, chord length ≈ haversine, non-crossing lons stay in [−180, 180], two-leg queue chain continuous across the joint) and +1 e2e (e2e/hover.spec.ts: hook-created Auckland → Fua'amotu package renders one continuous trace — no segment may contain a ±180 jump; expectHoverRoute endpoint check now mod-360 aware).

Known limitation (tracked as #124): plane markers still use the snapshot's wrapped lat/lon, so a plane mid-crossing teleports 360° on its marker at the instant it passes ±180 while its route line stays continuous. Fix needs airport coordinates inside planesGeoJson — deliberately out of scope here.

Deployed to https://flight.dev.kkhost.pl (verified /api/version = 0.53.0, root page 200).

Fixed in **v0.53.0** — PR #123, merged as `2a4b341` (CI run 163 green: build + unit 359/359 + full e2e). **What changed:** `greatCircleArc` (`lib/mapData.ts`) now re-expresses each arc's samples in continuous longitudes via a module-private `unwrapLons` (first sample keeps its raw lon; later ones shifted ±360 vs the previous *unwrapped* value until |Δlon| ≤ 180), so all four line builders are fixed at once. `queuedRoutesGeoJson` gets one global re-unwrap pass after leg concatenation, since each leg unwraps relative to its own start airport and joints can jump ±360. Non-crossing routes are byte-identical (no-op). Out-of-range lons render on MapLibre's adjacent world copies (`renderWorldCopies` default-on) — one line stays one LineString, no splitting. **Tests:** +4 unit (`lib/mapData.test.ts`, real dataset pairs NZAA/NFTF/NZCH: continuity across east/west crossings, endpoints exact mod 360, chord length ≈ haversine, non-crossing lons stay in [−180, 180], two-leg queue chain continuous across the joint) and +1 e2e (`e2e/hover.spec.ts`: hook-created Auckland → Fua'amotu package renders one continuous trace — no segment may contain a ±180 jump; `expectHoverRoute` endpoint check now mod-360 aware). **Known limitation (tracked as #124):** plane markers still use the snapshot's wrapped lat/lon, so a plane mid-crossing teleports 360° on its marker at the instant it passes ±180 while its route line stays continuous. Fix needs airport coordinates inside `planesGeoJson` — deliberately out of scope here. Deployed to https://flight.dev.kkhost.pl (verified `/api/version` = 0.53.0, root page 200).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OpenCode/Flight-Ops#120