![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Super Light-weight JavaScript Bounding Box Utility Functions
Bounding boxes, or rectangular extents, are represented as an array of 4 numbers:
[xmin, ymin, xmax, ymax]
Calculate the area of a bounding box
import bboxArea from "bbox-fns/bbox-area.js";
bboxArea([2, 3, 8, 9])
36 // (8 - 2) * (9 - 3)
Calculate the bounding box of an array of points (aka "a polygon ring")
import bboxArray from "bbox-fns/bbox-array.js";
bboxArray([
[ -180, 86.06126914660831 ],
[ -180, 85.66739606126914 ],
[ -179, 84.87964989059081 ],
[ -179, 84.48577680525165 ]
]);
[-180, 84.48577680525165, -179, 86.06126914660831]
// throws because of the NaN value
bboxArray([ -180, 86.06 ], [NaN, NaN], [ -179, 84.48 ]);
// skip NaN values (don't throw)
bboxArray(points, { nan_strategy: "skip" })
[-180, 84.48, -179, 86.06]
Convert a single [x, y] point into a bounding box of zero width and height;
import bboxPoint from "bbox-fns/bbox-point.js";
bboxPoint([-180, 86.06126914660831]);
[-180, 86.06126914660831, -180, 86.06126914660831]
Calculate the width and height of a bounding box
import bboxSize from "bbox-fns/bbox-size.js";
bboxSize([-180, 84.48577680525165, -179, 86.06126914660831]);
[1, 1.5754923413566644]
Check if a bounding box contains another
import booleanContains from "bbox-fns/boolean-contains.js";
const western_hemisphere = [-180, -90, 0, 90];
const colorado = [-109.05378, 37.0057, -102.0665, 41.0443];
booleanContains(western_hemisphere, colorado);
true
// exclude bbox that extends to the exact edge
booleanContains(western_hemisphere, [-10, -20, 0, 20], { exclusive: true });
false
Check if a bounding box contains a point
import booleanContainsPoint from "bbox-fns/boolean-contains-point.js";
const western_hemisphere = [-180, -90, 0, 90];
const eastern_hemisphere = [0, -90, 180, 90];
const hawaii = [-155.844437, 19.741755];
booleanContainsPoint(western_hemisphere, hawaii);
true
// point on boundary
booleanContainsPoint(western_hemisphere, [0, 0]);
true
// ignoring points on the exact edge
booleanContainsPoint(western_hemisphere, [0, 0], { exclusive: true });
false
Checks if two bounding boxes have any intersection at all.
import booleanIntersects from "bbox-fns/boolean-intersects.js";
const western_hemisphere = [-180, -90, 0, 90];
const eastern_hemisphere = [0, -90, 180, 90];
booleanIntersects(western_hemisphere, eastern_hemisphere);
true
Checks if coordinates represent a rectangular bounding box
import booleanRectangle from "bbox-fns/boolean-rectangle.js";
// rectangle for the globe bbox [-180, -90, 180, 90]
const coords = [
[ -180, 90 ],
[ -180, -90 ],
[ 0, -90 ],
[ 0, 90 ],
[ -180, 90 ]
];
booleanRectangle(coords);
true
// extra points that don't affect shape
const denseCoords = [
[ -180, 90 ],
[ -180, 0 ],
[ -180, -90 ],
[ -90, -90 ],
[ 0, -90 ],
[ 0, 0 ],
[ 0, 90 ],
[ -90, 90 ],
[ -180, 90 ]
];
booleanRectangle(denseCoords);
true
import intersect from "bbox-fns/intersect.js";
const western_hemisphere = [-180, -90, 0, 90];
const eastern_hemisphere = [0, -90, 180, 90];
intersect(western_hemisphere, eastern_hemisphere);
[0, -90, 0, 90] // prime meridian
import merge from "bbox-fns/merge.js";
const western_hemisphere = [-180, -90, 0, 90];
const eastern_hemisphere = [0, -90, 180, 90];
const bboxes = [western_hemisphere, eastern_hemisphere];
merge(bboxes);
[-180, -90, 180, 90] // bbox for the whole globe
Create GeoJSON-Like Polygon from a Bounding Box
import polygon from "bbox-fns/polygon.js";
polygon([-180, -90, 180, 90]);
// polygon is in counter-clockwise order
[
[
[-180, 90], // top-left
[-180, -90], // bottom-left
[180, -90], // bottom-right
[180, 90], // top-right
[-180, 90] // top-left
]
]
Calculate the bounding box of a geometry in either GeoJSON or ArcGIS JSON.
import calc from "bbox-fns/calc.js";
calc({
type: "Polygon",
coordinates: [
[
[30, 10],
[40, 40],
[20, 40],
[10, 20],
[30, 10]
]
]
});
[10, 10, 40, 40]
Calculate an array of bounding boxes for all the input geometries. For example, a multipolygon will return multiple bounding boxes.
import calcAll from "bbox-fns/calc-all.js";
calcAll({
type: "MultiPolygon",
coordinates: [ ... ]
});
[bbox1, bbox2, ...]
A more advanced version of polygon. Create a polygon while adding points to each side of the rectangle.
import polygon from "bbox-fns/dense-polygon.js";
// add 100 points along each side
densePolygon(bbox, { density: 100 });
// add 100 points along the top and bottom edge (x-axis)
// and 400 points along the left and right edge (y-axis)
densePolygon(bbox, { density: [100, 400] });
Chop bounding box up into multiple smaller bounding boxes.
import grid from "bbox-fns/grid.js";
const globe = [-180, -90, 180, 90];
const number_of_columns = 2; // how many grid cells left to right
const number_of_rows = 2; // how many grid cells top to bottom
const quadrants = grid(globe, [number_of_columns, number_of_rows]);
[
[-180, -90, 0, 0], // south-western
[0, -90, 180, 0], // south-eastern
[-180, 0, 0, 90], // north-western
[0, 0, 180, 90] // north-eastern
]
Multiply x and y values by the given scale values
import scale from "bbox-fns/scale.js";
// shrink the grid by 50%
scale([0, 9, 50, 200], 0.5);
[0, 4.5, 25, 100];
// scale x and y values by different factors
// same as [0 * 2, 9 * 10, 50 * 2, 200 * 10]
scale([0, 9, 50, 200], [2, 10]);
[0, 90, 100, 2000]
Shift bounding box horizontally and/or vertically
// shift bounding box overlapping left "edge"
// to the right, so it overlaps the right "edge"
shift([-200, 40, -160, 90], { x: 360 })
[160,40,200,90];
// shift horizontally and vertically
shift([-185, 90, -180, 95], [360, -90])
[175, 0, 180, 5]
// same as above
shift([-185, 90, -180, 95], { x: 360, y: -90 });
Split bounding box that crosses given x or y boundaries. For example, split a bbox that crosses the antimeridian into two bounding boxes.
import split from "bbox-fns/split.js";
// split across the antimeridian
split([-200, -90, 160, 90], { x: [-180, 180] })
[
[-200, -90, -180, 90], // overflow, left of antimeridian
[-180, -90, 160, 90] // right of antimeridian
]
// split across the antimeridian and the poles
split([-200, -90, 160, 100], { x: [-180, 180], y: [-90, 90] })
[
[-200,-90,-180,90],
[-200,90,-180,100],
[-180,-90,160,90],
[-180,90,160,100]
]
Reproject a bounding box using the given reprojection function
import reproject from "bbox-fns/reproject.js";
import proj4 from "proj4-fully-loaded";
// convert a bounding box from 4326 to a UTM projection
const { forward } = proj4("EPSG:4326", "EPSG:32610");
reproject(bbox, forward);
// you can also pass in an async reprojection function
reproject(bbox, forwardAsync, { async: true })
// you can also control the point density of the intermediate polygon
reproject(bbox, forward, { density: 99 })
// skip (don't throw error) when forward returns a NaN value
reproject(bbox, forward, { nan_strategy: "skip" })
import sort from "bbox-fns/sort.js";
const bboxes = [
[175, -85, 180, 90],
[-180, -85, -175, 90]
];
sort(bboxes)
[[-180,-85,-175,90],[175,-85,180,90]]
Combine all bounding boxes that intersect. This is different from merge, which will combine bounding boxes even if they don't intersect.
import union from "bbox-fns/union.js";
const wyoming = [-110.99, 40.97, -104.08, 45.03];
const usa = [-125.10, 24.75, -66, 49.54];
const iceland = [-24.40, 63.29, -13.16, 66.73];
union([wyoming, usa, iceland]);
// only includes usa and iceland, because wyoming merged into usa
[[-125.10, 24.75, -66, 49.54], [-24.40, 63.29, -13.16, 66.73]]
Un-wrap an extent that overflows the edge of the earth, returning an array of one or more bounding boxes.
import unwrap from "bbox-fns/unwrap.js";
const earth = [-180, -90, 180, 90];
const bbox = [-200, -21, -160, 87]; // extends over "left edge" of the earth
unwrap(bbox, earth);
// bounding box unwrapped and normalized within the bounds of the earth
[
[-180, -21, -160, 87],
[160, -21, 180, 87]
]
import validate from "bbox-fns/validate.js";
validate([-180, 0, 180, 45])
true
// invalid length
validate([-180, 0, 0, 180, 45, 0])
false
// xmin greater than xmax
validate([-45, 10, -90, 20])
false
If you are looking for a library with greater projection support and a class-based approach, try geo-extent!
This library borrows the names of some similar Turf.js functions, but it does not borrow the internal code.
In order to avoid floating point arithmetic errors, you can use the precise version of these functions where numbers are represented as strings.
import preciseBboxArray from "bbox-fns/precise/bbox-array.js";
import preciseDensePolygon from "bbox-fns/precise/dense-polygon.js";
import preciseDivide from "bbox-fns/precise/divide.js";
import preciseReproject from "bbox-fns/precise/reproject.js";
preciseDensePolygon(bbox, { density: [359, 179] }); // add 359 points to top and bottom, and 179 points to the left and right
[
[ '-180', '80' ], [ '-180', '79' ], [ '-180', '78' ], [ '-180', '77' ], /* ... */, [ '-180', '80' ]
]
preciseDivide([0, 9, 50, 200], [3, 4], { ellipsis: true })
["0", "2.25", "16.666...", "50"]
FAQs
Light-weight JavaScript Bounding Box Utility Functions
The npm package bbox-fns receives a total of 2,320 weekly downloads. As such, bbox-fns popularity was classified as popular.
We found that bbox-fns demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.