Skip to content

Fix GeoJSON geometries that cross the 180th meridian (the antimeridian/the dateline) by splitting them into valid Multi-Geometries.

License

Notifications You must be signed in to change notification settings

krisaoe/antimeridian-ts

Repository files navigation

antimeridian-ts

Fix GeoJSON geometries that cross the 180th meridian (the antimeridian/the dateline) by splitting them into valid Multi-Geometries.

This is essential for web mapping (Mapbox, Leaflet, OpenLayers, etc) and geospatial analysis where geometries wrapping around the date line often render incorrectly or cause calculation errors.

CREDIT & ATTRIBUTION

Note: This library is a TypeScript port of the excellent Python antimeridian package created by gadomski.

The underlying logic, Great Circle splitting algorithms, and pole-wrapping logic are derived entirely from the original Python implementation. If you are working in a Python environment, please use the original package.

Features

  • GeoJSON Splitting: Automatically splits Polygons into MultiPolygons and LineStrings into MultiLineStrings at the 180th meridian.
  • Great Circle Support: Calculates split points using spherical geometry (Great Circle) by default, ensuring accurate cuts on the globe, with an option for flat Cartesian cuts.
  • Pole Wrapping: Correctly handles complex polygons that enclose the North or South Pole.
  • Winding Order: Enforces RFC 7946 winding order (Exterior Rings CCW, Interior Rings CW) via Turf.js.
  • GeoJSON Bounding Boxes: Calculates bounding boxes that correctly span the antimeridian (e.g., minX > maxX).

Important Note on bbox

If your input Feature already has a bbox property (e.g., [179, 0, -179, 1]), it will be copied over unchanged.

Since the geometry is being modified (split), the old bounding box is likely still valid (it covers the area), but if you want the bounding box to strictly match the new split geometry (or if you want to force it to follow the antimeridian-spanning standard), you should recalculate it using the library's bbox() function and update the field manually:

const fixed = fixGeoJson(input);
// Optional: Update the bbox to match the new geometry
fixed.bbox = bbox(fixed); 

Limitations & Differences from Python

While this package aims for algorithmic parity with the Python original, there are runtime differences:

  1. Input Validity: The Python version relies on shapely (GEOS) to automatically repair invalid geometries (e.g., self-intersections, bowties). This TypeScript version uses Turf.js, which assumes inputs are generally valid. Invalid input geometries may produce unexpected results.
  2. Strict Winding: This package is stricter about winding order than the Python version. Outputs will always be normalized to the Right-Hand Rule (CCW exteriors) to satisfy WebGL rendering requirements.
  3. Precision: Minor floating-point differences (~1e-9) may occur between the Python and TypeScript outputs due to the underlying math engines.
  4. Edge Containment: Hole detection relies on turf.booleanContains. Holes touching the exact edge of an exterior ring may be handled differently than in GEOS/Shapely.

Usage

import { fixGeoJson } from './antimeridian';

const crossingPolygon = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [[[179, 0], [179, 1], [-179, 1], [-179, 0], [179, 0]]]
  },
  properties: {}
};

const fixed = fixGeoJson(crossingPolygon);
console.log(fixed.geometry.type); // "MultiPolygon"

About

Fix GeoJSON geometries that cross the 180th meridian (the antimeridian/the dateline) by splitting them into valid Multi-Geometries.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published