@turf/bbox and @turf/bbox-polygon - spec adherance at anitmeridian
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 10.5k
- Forks
- 1k
- Avg merge
- 1h 11m
- Merged PRs (30d)
- 4
Description
bbox and bboxPolygon both have some behavior that is not compliant with RFC 7946 and some other behavior that even though technically compliant is not expected behavior.
Most of this issue references the below feature, that (with inspiration from the bounding box section in RFC 7946 takes a rough outline of the Vanua Leva island in Fiji that crosses the antimeridian. This feature specifically handles the antimeridian in the specification recommended way by keeping all longitude values in [-180, 180] and using a MultiPolygon geometry.
Note that an alternate Polygon feature that has longitudes > 180 does not have any such issues, and renders totally find in mapbox,etc., just propagate longitudes outside [-180, 180].
const vanuaLeva = {
type: "Feature",
properties: {},
geometry: {
type: "MultiPolygon",
coordinates: [
[
[
[178.4596, -16.7634],
[178.4829, -16.8466],
[178.5892, -16.8379],
[178.7137, -17.0414],
[179.4633, -16.8354],
[179.9432, -16.7895],
[179.9341, -16.5075],
[179.8458, -16.2873],
[180, -16.23],
[180, -16.1],
[179.6086, -16.1577],
[178.5607, -16.5584],
[178.4596, -16.7634]
]
],
[
[
[-180, -16.23],
[-179.8639, -16.1731],
[-179.8250, -16.0496],
[-180, -16.1],
[-180, -16.23]
]
]
]
}
};
1. Whole Earth Band in turf.bbox()
turf.bbox(vanuaLeva)
// [ -180, -17.0414, 180, -16.0496 ]
This is a valid bounding box and produces a valid polygon with turf.bboxPolygon, but it represents a shape that completely wraps the Earth. And while the spec doesn't explicitly say that this is wrong, it doesn't represent the smallest box that contains the original geometry, and the spec does say that antimeridian wrapping bounding boxes should be of the form [ 178.4596, -17.0414, -179.8251, -16.0496 ] - note index 0 is not the smallest longitude per the spec.
Fix: turf.bbox needs to calculate an antimeridian and non-antimeridian spanning box and choose the one with the smallest longitude extent.
2. Invalid Polygon in turf.bboxPolygon() for Valid Bbox
If turf.bbox does produce the "correct" bbox for this geometry, i.e., [ 178.4596, -17.0414, -179.8251, -16.0496 ], then turf.bboxPolygon() produces an invalid polygon with incorrect winding order. The spec-compliant geometry for the bounding box should be a MultiPolygon with two outer rings - one for each side of the antimeridian (incidentally the same antimeridian behavior as noted in #3029).
Fix: turf.bboxPolygon needs to detect antimeridian crossing bounding boxes and produce multipolygon output.
3. Unsupported 3D Positions
Unrelated to antimeridian crossing, but still a spec compliance issue is that bbox ignores 3d positions (produces 2d bounding boxes from 3d geometries) and bboxPolygon throws for 3d positions. 3d positions are perfectly valid geojson and there is no reason why these two packages shouldn't support clearly valid geojson.
Fix: turf.bbox detects position dimensionality and acts appropriately, turf.bboxPolygon accepts 4 and 6 element bounding boxes, and produces a 2d or 3d output depending on the input. It no longer throws.
Will prepare a PR for this - let me know if any objections.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the @turf/bbox and @turf/bbox-polygon entry points, using the vanuaLeva example and RFC 7946 as the behavioral reference. Check the existing handling of antimeridian bounds and 3D positions; done means selecting the smallest compliant bbox, producing the required MultiPolygon, and supporting valid 3D GeoJSON without throwing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- data
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100