fix: keep clamped traffic bounds monotonic across the antimeridian

The previous fix wrapped the span correctly but normalized the
returned west/east back into [-180, 180), which re-inverts the box
whenever it crosses the antimeridian (west > east again). Downstream
consumers (getBoundsCenter, boundsOverlap) assume west <= east and
silently misbehave on an inverted box: the fetch center lands on the
opposite side of the planet, and the overlap gate never skips a
re-fetch.

Drop the normalization and leave west/east unnormalized instead, so
the box stays monotonic. The only remaining edge case (coordinates
outside the conventional range reaching the Overpass query builder)
is a visible, separate problem rather than a silently wrong center.

Addresses review feedback on #392.
This commit is contained in:
Ashfaq committed 2026-09-16 20:02:26 +05:30
1 parent c22ad6af32
commit 830c372c12
2 files changed
+18 -25

No files matched your search

+8 -16
View File
@@ -129,17 +129,6 @@ function longitudeSpanDeg(west, east) {
return raw >= 0 ? raw : raw + 360;
}
/**
* Normalize a longitude into [-180, 180). Matches the wrap idiom already
* used by `destinationPoint()` above.
*
* @param {number} lon - Longitude in degrees.
* @returns {number} Longitude normalized to [-180, 180).
*/
function normalizeLonDeg(lon) {
return ((lon + 540) % 360) - 180;
}
/**
* Clamp a bounding box's spans to `maxSpanDeg` and recenter it on `center`.
*
@@ -147,9 +136,12 @@ function normalizeLonDeg(lon) {
* but centers the box on the derived look-at point instead of the view
* rectangle's midpoint. Idempotent when `center` is the box's own midpoint.
*
* Longitude is handled as a cyclic axis: the input span wraps correctly
* across the antimeridian, and the output west/east are normalized back into
* [-180, 180) instead of drifting outside the normal coordinate range.
* Longitude is handled as a cyclic axis for the span calculation, so the
* input span wraps correctly across the antimeridian. The output west/east
* are deliberately left unnormalized (may fall outside [-180, 180)) so that
* `west <= east` always holds — callers such as `getBoundsCenter` and
* `boundsOverlap` rely on that invariant and would silently misbehave on a
* normalized-but-inverted box (see #392 review).
*
* @param {{south:number, west:number, north:number, east:number}} bounds
* Source bounds (span donor).
@@ -163,7 +155,7 @@ export function clampBoundsAroundCenter(bounds, center, maxSpanDeg = 0.05) {
return {
south: center.lat - latSpan / 2,
north: center.lat + latSpan / 2,
west: normalizeLonDeg(center.lon - lonSpan / 2),
east: normalizeLonDeg(center.lon + lonSpan / 2),
west: center.lon - lonSpan / 2,
east: center.lon + lonSpan / 2,
};
}