Skip to content

Commit d9aeb21

Browse files
committed
added unwrap.js
1 parent 3380155 commit d9aeb21

File tree

6 files changed

+92
-2
lines changed

6 files changed

+92
-2
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Bounding boxes, or rectangular extents, are represented as an array of 4 numbers
2828
- [shift](#shift)
2929
- [split](#split)
3030
- [union](#union)
31+
- [unwrap](#unwrap)
3132
- [validate](#validate)
3233

3334
### bboxArea
@@ -342,6 +343,23 @@ union([wyoming, usa, iceland]);
342343
[[-125.10, 24.75, -66, 49.54], [-24.40, 63.29, -13.16, 66.73]]
343344
```
344345

346+
### unwrap
347+
Un-wrap an extent that overflows the edge of the earth.
348+
```js
349+
import unwrap from "bbox-fns/unwrap.js";
350+
351+
const earth = [-180, -90, 180, 90];
352+
const bbox = [-200, -21, -160, 87]; // extends over "left edge" of the earth
353+
354+
unwrap(bbox, earth);
355+
356+
// bounding box unwrapped and normalized within the bounds of the earth
357+
[
358+
[-180, -21, -160, 87],
359+
[160, -21, 180, 87]
360+
]
361+
```
362+
345363
### validate
346364
```js
347365
import validate from "bbox-fns/validate.js";

index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const split = require("./split.js");
2525
const validate = require("./validate.js");
2626
const preciseValidate = require("./precise/validate.js");
2727
const union = require("./union.js");
28+
const unwrap = require("./unwrap.js");
2829

2930
const bboxfns = {
3031
bboxArea,
@@ -51,7 +52,8 @@ const bboxfns = {
5152
split,
5253
validate,
5354
preciseValidate,
54-
union
55+
union,
56+
unwrap
5557
};
5658

5759
if (typeof define === "function" && define.amd) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"shift.js",
3232
"split.js",
3333
"union.js",
34+
"unwrap.js",
3435
"validate.js"
3536
],
3637
"scripts": {

split.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
function split(bbox, breakpoints) {
1414
const [xmin, ymin, xmax, ymax] = bbox;
15+
if (!breakpoints) throw new Error("[bbox-fns/split.js] missing breakpoints");
1516
const xbrks = breakpoints.x || [];
1617
const ybrks = breakpoints.y || [];
1718

test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ const {
4949
preciseDivide,
5050
validate,
5151
preciseValidate,
52-
union
52+
union,
53+
unwrap
5354
} = require("./index.js");
5455

5556
const globe = [-180, -90, 180, 90];
@@ -721,3 +722,24 @@ test("union", ({ eq }) => {
721722
eq(union([wyoming, usa, iceland]), [iceland, usa]);
722723
eq(union([wyoming, iceland]), [iceland, wyoming]);
723724
});
725+
726+
test("unwrap EPSG:4326", ({ eq }) => {
727+
const earth = [-180, -90, 180, 90];
728+
eq(unwrap([-180, -90, 180, 90], earth), [[-180, -90, 180, 90]]);
729+
eq(unwrap([-200, -90, -160, 90], earth), [
730+
[-180, -90, -160, 90],
731+
[160, -90, 180, 90]
732+
]);
733+
eq(unwrap([-200, -90, -180, 90], earth), [[160, -90, 180, 90]]);
734+
eq(unwrap([-200, -90, -185, 90], earth), [[160, -90, 175, 90]]);
735+
eq(unwrap([180, -90, 200, 90], earth), [[-180, -90, -160, 90]]);
736+
eq(unwrap([170, -90, 210, 90], earth), [
737+
[-180, -90, -150, 90],
738+
[170, -90, 180, 90]
739+
]);
740+
eq(unwrap([170, -90, 180, 90], earth), [[170, -90, 180, 90]]);
741+
eq(unwrap([-200, -21, -160, 87], earth), [
742+
[-180, -21, -160, 87],
743+
[160, -21, 180, 87]
744+
]);
745+
});

unwrap.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"use_strict";
2+
3+
const shift = require("./shift.js");
4+
const split = require("./split.js");
5+
const union = require("./union.js");
6+
7+
function unwrap(bbox, container) {
8+
const [global_xmin, global_ymin, global_xmax, global_ymax] = container;
9+
10+
const global_width = global_xmax - global_xmin;
11+
const global_height = global_ymax - global_ymin;
12+
13+
const breakpoints = {
14+
x: [
15+
global_xmin - global_width,
16+
global_xmin,
17+
global_xmax,
18+
global_xmax + global_width
19+
],
20+
y: [
21+
global_ymin - global_height,
22+
global_ymin,
23+
global_ymax,
24+
global_ymax + global_height
25+
]
26+
};
27+
28+
let bboxes = split(bbox, breakpoints);
29+
30+
// normalize bboxes to world boundaries
31+
bboxes = bboxes.map(b => {
32+
const [xmin, ymin, xmax, ymax] = b;
33+
return shift(b, {
34+
x: Math.ceil((global_xmin - xmin) / global_width) * global_width,
35+
y: Math.ceil((global_ymin - ymin) / global_height) * global_height
36+
});
37+
});
38+
39+
// combine bboxes if they overlap
40+
bboxes = union(bboxes);
41+
42+
return bboxes;
43+
}
44+
45+
module.exports = unwrap;
46+
module.exports.default = unwrap;

0 commit comments

Comments
 (0)