Skip to content

Commit 2c52aae

Browse files
committed
refactor: Update the polybool library
This moves from the patched polybool library to the modern, maintained version. Closes #1404
1 parent 93bbe48 commit 2c52aae

File tree

5 files changed

+31
-36
lines changed

5 files changed

+31
-36
lines changed

package-lock.json

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"url": "https://github.com/OpenGeoscience/geojs"
1313
},
1414
"dependencies": {
15+
"@velipso/polybool": "^2.0.11",
1516
"canvas": "^3.0.0",
1617
"color-name": "^2.0.0",
1718
"docdash": "^2.0.1",
@@ -23,7 +24,6 @@
2324
"jquery": "^3.6.0",
2425
"kdbush": "^4.0.0",
2526
"mousetrap": "^1.6.5",
26-
"polybooljs": "git+https://github.com/manubb/polybooljs#eps-logic",
2727
"proj4": "^2.7.5"
2828
},
2929
"optionalDependencies": {

src/polygonFeature.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ var polygonFeature = function (arg) {
122122
if (!poly) {
123123
return undefined;
124124
}
125-
var outer, inner, range, coord, j, x, y, mapouter, mapinner, maprange;
125+
var outer, inner, range, coord, x, y, mapouter, mapinner, maprange;
126126

127127
coord = poly.outer || (Array.isArray(poly) ? poly : []);
128128
outer = new Array(coord.length);
129-
for (j = 0; j < coord.length; j += 1) {
129+
for (let j = 0; j < coord.length; j += 1) {
130130
outer[j] = posFunc.call(m_this, coord[j], j, d, i);
131131
x = outer[j].x;
132132
y = outer[j].y;
@@ -142,14 +142,14 @@ var polygonFeature = function (arg) {
142142
inner = (poly.inner || []).map(function (hole) {
143143
coord = hole || [];
144144
var trans = new Array(coord.length);
145-
for (j = 0; j < coord.length; j += 1) {
145+
for (let j = 0; j < coord.length; j += 1) {
146146
trans[j] = posFunc.call(m_this, coord[j], j, d, i);
147147
}
148148
return trans;
149149
});
150150
mapouter = transform.transformCoordinates(fcs, mapgcs, outer);
151151
mapinner = inner.map(part => transform.transformCoordinates(fcs, mapgcs, part));
152-
for (j = 0; j < mapouter.length; j += 1) {
152+
for (let j = 0; j < mapouter.length; j += 1) {
153153
x = mapouter[j].x;
154154
y = mapouter[j].y;
155155
if (!j) {

src/util/polyops.js

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
var PolyBool = require('polybooljs');
1+
const { PolyBool, GeometryEpsilon } = require('@velipso/polybool');
2+
const polybool = new PolyBool();
23
var geo_map = require('../map');
34
var util = require('../util/common');
45

@@ -106,7 +107,7 @@ function seglistToPolygonList(seglist) {
106107
const borders = []; // polygons in format needed for util.pointInPolygon
107108
const regions = []; // polygons in end result format
108109
const parents = []; // list of parents of each polygon
109-
seglist.forEach((s) => PolyBool.polygon(s).regions.forEach((r) => {
110+
seglist.forEach((s) => polybool.polygon(s).regions.forEach((r) => {
110111
const border = r.map((pt) => ({x: pt[0], y: pt[1]}));
111112
if (border.length < 3) {
112113
return;
@@ -162,36 +163,27 @@ function seglistToPolygonList(seglist) {
162163
*/
163164
function polygonOperationSeglist(op, epsilon, seglist) {
164165
op = 'select' + op.charAt(0).toUpperCase() + op.slice(1);
165-
PolyBool.epsilon(epsilon);
166+
const polyboolEps1 = new PolyBool(new GeometryEpsilon(epsilon));
166167

167168
while (seglist.length > 1) {
168169
const newlist = [];
169170
const half = Math.ceil(seglist.length / 2);
170171
for (let i = 0; i < half; i += 1) {
171172
let segments = seglist[i];
172173
if (i + half < seglist.length) {
173-
let nextseg = seglist[i + half];
174+
const nextseg = seglist[i + half];
174175
try {
175-
segments = PolyBool.combine(segments, nextseg);
176+
segments = polyboolEps1.combine(segments, nextseg);
176177
} catch (err) {
177-
segments = PolyBool.segments(PolyBool.polygon(segments));
178-
nextseg = PolyBool.segments(PolyBool.polygon(nextseg));
179178
for (let j = 20; j >= 6; j -= 1) {
180-
PolyBool.epsilon(Math.pow(0.1, j));
179+
const polyboolEps2 = new PolyBool(new GeometryEpsilon(Math.pow(0.1, j)));
181180
try {
182-
segments = PolyBool.combine(segments, nextseg);
181+
segments = polyboolEps2.combine(segments, nextseg);
183182
break;
184183
} catch (err) {}
185184
}
186-
PolyBool.epsilon(epsilon);
187185
}
188-
if (segments.combined) {
189-
segments.combined = segments.combined.filter(s => Math.abs(s.start[0] - s.end[0]) > epsilon || Math.abs(s.start[1] - s.end[1]) > epsilon);
190-
segments = PolyBool[op](segments);
191-
} else {
192-
console.warn('Failed in polygon functions.'); // eslint-disable-line no-console
193-
}
194-
segments.segments = segments.segments.filter(s => Math.abs(s.start[0] - s.end[0]) > epsilon || Math.abs(s.start[1] - s.end[1]) > epsilon);
186+
segments = polyboolEps1[op](segments);
195187
}
196188
newlist.push(segments);
197189
}
@@ -463,8 +455,8 @@ function generalOperationProcess(op, poly1, poly2, opts) {
463455
if (ingcs2 && gcs && ingcs2 !== gcs) {
464456
poly2 = poly2.map((p) => p.map((h) => transform.transformCoordinates(ingcs2, gcs, h)));
465457
}
466-
let seglist1 = poly1.map(p => PolyBool.segments({regions: p}));
467-
let seglist2 = poly2.map(p => PolyBool.segments({regions: p}));
458+
let seglist1 = poly1.map(p => polybool.segments({regions: p}));
459+
let seglist2 = poly2.map(p => polybool.segments({regions: p}));
468460
seglist1 = polygonOperationSeglist(opts.innerOperation || 'union', mode1.epsilon, seglist1);
469461
seglist2 = polygonOperationSeglist(opts.innerOperation || 'union', mode2.epsilon, seglist2);
470462
let seglist = seglist1;

tests/cases/polyops.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,16 @@ describe('geo.util.polyops', function () {
106106
a: [[0, 0], [10, 0], [10, 10], [0, 10]],
107107
b: [[4, 4], [6, 4], [6, 6], [4, 6]],
108108
union: {out: [[0, 10], [0, 0], [10, 0], [10, 10]], ca: [[0]], cb: [undefined]},
109-
difference: {out: [[[0, 10], [0, 0], [10, 0], [10, 10]], [[6, 6], [6, 4], [4, 4], [4, 6]]], ca: [[0]], cb: [[0]]},
109+
difference: {out: [[[0, 10], [0, 0], [10, 0], [10, 10]], [[4, 4], [6, 4], [6, 6], [4, 6]]], ca: [[0]], cb: [[0]]},
110110
intersect: {out: [[4, 6], [4, 4], [6, 4], [6, 6]], ca: [undefined], cb: [[0]]},
111-
xor: {out: [[[0, 10], [0, 0], [10, 0], [10, 10]], [[6, 6], [6, 4], [4, 4], [4, 6]]], ca: [[0]], cb: [[0]]}
111+
xor: {out: [[[0, 10], [0, 0], [10, 0], [10, 10]], [[4, 4], [6, 4], [6, 6], [4, 6]]], ca: [[0]], cb: [[0]]}
112112
}, {
113113
a: [[0, 0], [10, 0], [10, 10], [0, 10]],
114114
b: [[-2, -2], [12, -2], [12, 12], [-2, 12]],
115115
union: {out: [[-2, 12], [-2, -2], [12, -2], [12, 12]], ca: [undefined], cb: [[0]]},
116116
difference: {out: undefined, ca: [undefined], cb: [undefined]},
117117
intersect: {out: [[0, 10], [0, 0], [10, 0], [10, 10]], ca: [[0]], cb: [undefined]},
118-
xor: {out: [[[-2, 12], [-2, -2], [12, -2], [12, 12]], [[10, 10], [10, 0], [0, 0], [0, 10]]], ca: [[0]], cb: [[0]]}
118+
xor: {out: [[[-2, 12], [-2, -2], [12, -2], [12, 12]], [[0, 0], [10, 0], [10, 10], [0, 10]]], ca: [[0]], cb: [[0]]}
119119
}];
120120

121121
describe('general operations', function () {
@@ -129,6 +129,7 @@ describe('geo.util.polyops', function () {
129129
expect(opts.correspond.poly1).toEqual(test[op].ca);
130130
expect(opts.correspond.poly2).toEqual(test[op].cb);
131131

132+
opts.correspond = {};
132133
opts.poly1 = test.a;
133134
opts.poly2 = test.b;
134135
out = geo.util.polyops[op](opts);

0 commit comments

Comments
 (0)