turf icon indicating copy to clipboard operation
turf copied to clipboard

bbox longitudes incorrect for geojson FeatureCollection spanning the anti-meridian

Open HughDevlin opened this issue 4 years ago • 7 comments

turf 6.3.0

Here is a link to geoJson from the US Census TIGER web that spans the antimeridian:

US Census TIGER Alaska outline

02 is the FIPS state code for Alaska.

This geoJson is a FeatureCollection with one Feature, a MultiPolygon with 50 components of coordinates.

turf.bbox(alaskaFeatureCollection) =>

[-179.23108599959195, 51.17509200018345, 179.85968100035376, 71.43978600002835]

The latitudes are correct but the longitudes are not.

For comparison:

d3.geoBounds(alaskaFeatureCollection) =>

[[172.34784599966287, 51.17509200018345], [-129.97416699982122, 71.43978600002835]]

Thank you for this project.

HughDevlin avatar Mar 31 '21 18:03 HughDevlin

The US Census TIGERweb is an ESRI arcGis server. The REST API delivers geoJson for a state in the United States as a FeatureCollection comprised of just one Feature. That one Feature is usually a Polygon, except it is a MultiPolygon for island states such as Alaska, Hawaii, Rhode Island, and Florida. There don't seem to be any "holes," at least not in Alaska; that is, all the rings in the Polygons or MultiPolygon are exterior, wound counter-clockwise, according to the "right-hand rule," in conformance with RFC 7946 August 2016 geoJson.

Alaska, the only state that spans the anti-meridian, is mostly in the Western hemisphere, except for the 10 western-most Aleutians which are in the Eastern hemisphere. All the component rings of the Alaska MultiPolygon are "split" on the anti-meridian as per the RFC; that is, no component spans hemispheres, each component is either all in the Eastern hemisphere or all in the Western hemisphere.

HughDevlin avatar Apr 03 '21 18:04 HughDevlin

Similar issue is seen for island Fiji. Turf returns the following bbox for it: [-180,-21.705859375,180,-12.476953125]

janvda avatar Dec 13 '22 14:12 janvda

Encountering this issue for all FeatureCollections crossing the meridian.

astukanov avatar Oct 03 '24 12:10 astukanov

When working with features that cross the antimeridian, I have code to "clean" the coordinates and then split the features before running bbox on it - https://github.com/seasketch/geoprocessing/blob/1337bac98043b3bc71e96635d7430a8a0959094d/packages/geoprocessing/src/toolbox/split.ts#L19. Give it a try?

This could make for good utility functions in turf for the user to preprocess their data as needed 🤔. I don't feel strongly that bbox and other turf functions affected by antimeridian crossing should do this work for the user automatically, but it could be documented if there is an expectation that features be pre-split by the user before using Turf functions.

More background information here - https://macwright.com/2016/09/26/the-180th-meridian

Notable section from GeoJSON spec:

In representing Features that cross the antimeridian, interoperability is improved by modifying their geometry. Any geometry that crosses the antimeridian SHOULD be represented by cutting it in two such that neither part’s representation crosses the antimeridian. - [GeoJSON Spec, 3.1.9](https://tools.ietf.org/html/rfc7946#section-3.1.9)

twelch avatar Oct 03 '24 23:10 twelch

Hi @astukanov. Do you have some example data you can share? The link from the original report no longer works.

smallsaucepan avatar Dec 15 '24 04:12 smallsaucepan

Here's an example of a rectangle that crosses the antimeridian, split in two parts.

import * as turf from "@turf/turf";

const multiPolygon = turf.multiPolygon([
  [
    [
      [170, 0],
      [170, 10],
      [180, 10],
      [180, 0],
      [170, 0],
    ],
  ],
  [
    [
      [-180, 0],
      [-180, 10],
      [-170, 10],
      [-170, 0],
      [-180, 0],
    ],
  ],
]);

const bbox = turf.bbox(multiPolygon);

console.log({ bbox });

Ideally you would like to get a result of [170, 0, -170, 10], but instead you get the whole world [-180, 0, 180, 10].

That's a problem if you use the result to modify the map bounds to zoom over the rectangle for example. That's a very common problem and there should be a way to address it easily in a specialized geometry library like turf (maybe an "antimeridian=true" option in bbox for example).

StellarCodeOrg avatar Jul 04 '25 13:07 StellarCodeOrg

  1. One way would be translate the feature in longitude until it doesn't cross the antimeridian anymore, calculate the bbox, and then translate the result backwards.

  2. Another (maybe better) way would be to express the longitude between 0° and 360°, make the calculation and then go back to -180, 180.

Is it something we can be expecting for the near future?

StellarCodeOrg avatar Jul 04 '25 13:07 StellarCodeOrg