CHAPTER 16
The antimeridian — the bug that breaks every map
Why lines and polygons that cross the ±180° longitude line break naive code, the splitting algorithm that fixes it, and GeoJSON specifics.
The antimeridian is the line at 180° / −180° longitude — the opposite side of the globe from the prime meridian. It runs through the Pacific Ocean and is where the International Date Line roughly follows.
Every developer who draws routes, polygons, or heatmaps eventually ships a bug where a line from Japan to Alaska shoots across the entire world map instead of crossing the Pacific. This chapter explains why and how to fix it.
The naive bug
Consider two points:
- Tokyo:
(35.68, 139.69) - Anchorage:
(61.22, -149.90)
A naive renderer connects them with a straight line in longitude space: from 139.69° E to -149.90° W — a difference of 289.59° going westward across Eurasia. The correct path crosses the antimeridian going eastward: a difference of only 70.41° across the Pacific.
The root cause: longitude wraps around at ±180°, but a simple subtraction doesn't know that. The number line treats -149.90 as "less than" 139.69 and draws the line in the wrong direction. The correct interpretation is that 210.10° E and -149.90° W are the same meridian.
Tokyo → Anchorage
❌ Naive: draws a straight line across the whole map (289° the wrong way)
Detecting an antimeridian crossing
The antimeridian is at longitude 180° / −180°. These are the same meridian — the number line wraps. The International Date Line roughly follows it but deviates for political reasons. For pure geographic math, treat 180° = −180°.
A segment crosses the antimeridian when the absolute difference in longitude is greater than 180°:
function crossesAntimeridian(lon1, lon2) {
return Math.abs(lon1 - lon2) > 180;
}
The fix: split the segment
When a crossing is detected, split the segment into two parts at ±180°:
function splitAtAntimeridian(lat1, lon1, lat2, lon2) {
if (!crossesAntimeridian(lon1, lon2)) {
return [[lat1, lon1, lat2, lon2]]; // no split needed
}
// Fraction along the segment where it crosses the antimeridian
const adjust = lon1 > 0 ? 360 : -360;
const lon2a = lon2 + adjust;
const t = (180 - lon1) / (lon2a - lon1); // t ∈ (0,1)
const latX = lat1 + t * (lat2 - lat1); // interpolated lat at crossing
return [
[lat1, lon1, latX, lon1 > 0 ? 180 : -180],
[latX, lon2 > 0 ? -180 : 180, lat2, lon2],
];
}
The adjust step "unwraps" the second longitude by adding or subtracting 360°, placing both longitudes on the same continuous number line so the interpolation t is valid.
Continue reading "The antimeridian — the bug that breaks every map"
You've reached the end of the free preview. Unlock all 22 paid chapters, including distance math, bearings, polygons, spatial indexing, and 3D map rendering — plus a downloadable PDF and the companion code repo.
- All 22 paid chapters with worked examples
- Downloadable PDF for offline reading
- Companion GitHub repo (JavaScript + Python)
- Free updates for life
Multiple payment options including Wise, PayPal, and bank transfer.
Related chapters
- Polygons — area, centroid, and containment — polygons are the most-affected shape
- GeoJSON — the universal format — GeoJSON's specific rules for antimeridian crossings
- Bounding boxes and spatial queries — bboxes that cross ±180° also break