@dra2020/baseclient 1.0.101 → 1.0.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baseclient.js +124 -67
- package/dist/baseclient.js.map +1 -1
- package/dist/poly/all.d.ts +1 -0
- package/dist/poly/featurecleanholes.d.ts +1 -0
- package/dist/poly/topo.d.ts +10 -7
- package/lib/poly/all.ts +1 -0
- package/lib/poly/featurecleanholes.ts +89 -0
- package/lib/poly/poly.ts +19 -50
- package/lib/poly/topo.ts +27 -32
- package/package.json +1 -1
package/dist/baseclient.js
CHANGED
|
@@ -5938,6 +5938,7 @@ __exportStar(__webpack_require__(/*! ./selfintersect */ "./lib/poly/selfintersec
|
|
|
5938
5938
|
__exportStar(__webpack_require__(/*! ./shamos */ "./lib/poly/shamos.ts"), exports);
|
|
5939
5939
|
__exportStar(__webpack_require__(/*! ./pointinpoly */ "./lib/poly/pointinpoly.ts"), exports);
|
|
5940
5940
|
__exportStar(__webpack_require__(/*! ./mapto */ "./lib/poly/mapto.ts"), exports);
|
|
5941
|
+
__exportStar(__webpack_require__(/*! ./featurecleanholes */ "./lib/poly/featurecleanholes.ts"), exports);
|
|
5941
5942
|
|
|
5942
5943
|
|
|
5943
5944
|
/***/ }),
|
|
@@ -6241,6 +6242,91 @@ function polyDiameterFlat(poly) {
|
|
|
6241
6242
|
exports.polyDiameterFlat = polyDiameterFlat;
|
|
6242
6243
|
|
|
6243
6244
|
|
|
6245
|
+
/***/ }),
|
|
6246
|
+
|
|
6247
|
+
/***/ "./lib/poly/featurecleanholes.ts":
|
|
6248
|
+
/*!***************************************!*\
|
|
6249
|
+
!*** ./lib/poly/featurecleanholes.ts ***!
|
|
6250
|
+
\***************************************/
|
|
6251
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
6252
|
+
|
|
6253
|
+
|
|
6254
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6255
|
+
exports.featureCleanHoles = void 0;
|
|
6256
|
+
const union_1 = __webpack_require__(/*! ./union */ "./lib/poly/union.ts");
|
|
6257
|
+
const poly_1 = __webpack_require__(/*! ./poly */ "./lib/poly/poly.ts");
|
|
6258
|
+
function flattenMultiPoly(polys) {
|
|
6259
|
+
let c = [];
|
|
6260
|
+
polys.forEach((poly) => {
|
|
6261
|
+
poly.forEach((ring) => {
|
|
6262
|
+
c.push([ring]);
|
|
6263
|
+
});
|
|
6264
|
+
});
|
|
6265
|
+
return c;
|
|
6266
|
+
}
|
|
6267
|
+
// Handed a multipolygon that may not have been properly structured as outer rings and inner holes, fix it up.
|
|
6268
|
+
// This is relatively expensive since we compute intersection areas to test for holes.
|
|
6269
|
+
//
|
|
6270
|
+
function featureCleanHoles(f) {
|
|
6271
|
+
if (!f
|
|
6272
|
+
|| f.type !== 'Feature'
|
|
6273
|
+
|| !f.geometry
|
|
6274
|
+
|| f.geometry.type !== 'MultiPolygon'
|
|
6275
|
+
|| !Array.isArray(f.geometry.coordinates))
|
|
6276
|
+
return f;
|
|
6277
|
+
// Normalize to flattened polygon
|
|
6278
|
+
f.geometry.coordinates = flattenMultiPoly(f.geometry.coordinates);
|
|
6279
|
+
let polys = f.geometry.coordinates;
|
|
6280
|
+
let areas = polys.map(poly_1.polyArea);
|
|
6281
|
+
// Compute 'top triangle' of overlap grid, then reflect
|
|
6282
|
+
let overlaps = polys.map((p1, i) => {
|
|
6283
|
+
return polys.map((p2, j) => { return j <= i ? false : (0, union_1.polyIntersects)(p1, p2); });
|
|
6284
|
+
});
|
|
6285
|
+
// Now reflect
|
|
6286
|
+
let n = polys.length;
|
|
6287
|
+
for (let i = 0; i < n - 1; i++)
|
|
6288
|
+
for (let j = i + 1; j < n; j++)
|
|
6289
|
+
overlaps[j][i] = overlaps[i][j];
|
|
6290
|
+
// The outer polygon is one that
|
|
6291
|
+
// 1. Overlaps with this one
|
|
6292
|
+
// 2. Has a larger area than this one
|
|
6293
|
+
// 3. Has the smallest area of any that overlap
|
|
6294
|
+
// 4. There are an odd number of polygons that satisfy 1 and 2. (This allows nesting of polygons inside holes.)
|
|
6295
|
+
//
|
|
6296
|
+
function findOuter(i) {
|
|
6297
|
+
let jOuter = -1;
|
|
6298
|
+
let aOuter = 0;
|
|
6299
|
+
let nOverlap = 0;
|
|
6300
|
+
for (let j = 0; j < n; j++)
|
|
6301
|
+
if (overlaps[i][j] && areas[j] > areas[i]) {
|
|
6302
|
+
nOverlap++;
|
|
6303
|
+
if (jOuter < 0 || areas[j] < aOuter) {
|
|
6304
|
+
jOuter = j;
|
|
6305
|
+
aOuter = areas[j];
|
|
6306
|
+
}
|
|
6307
|
+
}
|
|
6308
|
+
return (nOverlap % 2) == 1 ? jOuter : -1;
|
|
6309
|
+
}
|
|
6310
|
+
// Walk through and match up holes with their containers
|
|
6311
|
+
for (let i = 0; i < n; i++) {
|
|
6312
|
+
let j = findOuter(i);
|
|
6313
|
+
if (j >= 0) {
|
|
6314
|
+
polys[j].push(polys[i][0]);
|
|
6315
|
+
polys[i] = [];
|
|
6316
|
+
}
|
|
6317
|
+
}
|
|
6318
|
+
// Delete outer shell of hole rings that were moved
|
|
6319
|
+
f.geometry.coordinates = polys.filter((p) => p.length > 0);
|
|
6320
|
+
// Degenerate multi-polygon
|
|
6321
|
+
if (f.geometry.coordinates.length == 1) {
|
|
6322
|
+
f.geometry.type = 'Polygon';
|
|
6323
|
+
f.geometry.coordinates = f.geometry.coordinates[0];
|
|
6324
|
+
}
|
|
6325
|
+
return f;
|
|
6326
|
+
}
|
|
6327
|
+
exports.featureCleanHoles = featureCleanHoles;
|
|
6328
|
+
|
|
6329
|
+
|
|
6244
6330
|
/***/ }),
|
|
6245
6331
|
|
|
6246
6332
|
/***/ "./lib/poly/graham-scan.ts":
|
|
@@ -7233,6 +7319,7 @@ exports.polyBadCoordinates = exports.polyRewindRings = exports.featureRewind = e
|
|
|
7233
7319
|
const Util = __importStar(__webpack_require__(/*! ../util/all */ "./lib/util/all.ts"));
|
|
7234
7320
|
const PP = __importStar(__webpack_require__(/*! ./polypack */ "./lib/poly/polypack.ts"));
|
|
7235
7321
|
const graham_scan_1 = __webpack_require__(/*! ./graham-scan */ "./lib/poly/graham-scan.ts");
|
|
7322
|
+
const featurecleanholes_1 = __webpack_require__(/*! ./featurecleanholes */ "./lib/poly/featurecleanholes.ts");
|
|
7236
7323
|
exports.DefaultTickOptions = { maxLeafCount: 256, maxDepth: 20, tickStep: 1 };
|
|
7237
7324
|
// Internal utilities
|
|
7238
7325
|
exports.EARTH_RADIUS = 6371000; // Radius of earth in meters
|
|
@@ -7749,7 +7836,7 @@ function closePoly(poly) {
|
|
|
7749
7836
|
poly.forEach(closeRing);
|
|
7750
7837
|
return poly;
|
|
7751
7838
|
}
|
|
7752
|
-
function
|
|
7839
|
+
function featureClose(f) {
|
|
7753
7840
|
let d = Util.depthof(f.geometry.coordinates);
|
|
7754
7841
|
if (d === 4)
|
|
7755
7842
|
closePoly(f.geometry.coordinates);
|
|
@@ -7793,6 +7880,15 @@ function polyRingWindings(poly) {
|
|
|
7793
7880
|
return windings;
|
|
7794
7881
|
}
|
|
7795
7882
|
exports.polyRingWindings = polyRingWindings;
|
|
7883
|
+
function flattenMultiPoly(polys) {
|
|
7884
|
+
let c = [];
|
|
7885
|
+
polys.forEach((poly) => {
|
|
7886
|
+
poly.forEach((ring) => {
|
|
7887
|
+
c.push([ring]);
|
|
7888
|
+
});
|
|
7889
|
+
});
|
|
7890
|
+
return c;
|
|
7891
|
+
}
|
|
7796
7892
|
// This mutates the passed in feature to ensure it is correctly wound
|
|
7797
7893
|
// For convenience, passed back the value provided.
|
|
7798
7894
|
//
|
|
@@ -7810,53 +7906,16 @@ function featureRewind(f, options) {
|
|
|
7810
7906
|
return canonicalPoint(f, options);
|
|
7811
7907
|
// Make sure polygon is closed (first === last)
|
|
7812
7908
|
if (options.validateClose)
|
|
7813
|
-
|
|
7909
|
+
featureClose(f);
|
|
7814
7910
|
// Check if multi-polygon is really polygon with holes
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
let windings = polyRingWindings(f);
|
|
7818
|
-
if (options.validateHoles && d === 5 && windings.length > 1) {
|
|
7819
|
-
// First winding needs to be correct so we have a poly to add holes to
|
|
7820
|
-
if (!misWound(windings[0])) {
|
|
7821
|
-
// Flatten everything out and then rebuild hole structure based on windings
|
|
7822
|
-
let nHoles = 0;
|
|
7823
|
-
windings.forEach(w => { nHoles += w.iRing ? 1 : 0; });
|
|
7824
|
-
if (nHoles) {
|
|
7825
|
-
let c = [];
|
|
7826
|
-
f.geometry.coordinates.forEach((poly) => {
|
|
7827
|
-
poly.forEach((ring) => {
|
|
7828
|
-
c.push([ring]);
|
|
7829
|
-
});
|
|
7830
|
-
});
|
|
7831
|
-
f.geometry.coordinates = c;
|
|
7832
|
-
windings = polyRingWindings(f);
|
|
7833
|
-
}
|
|
7834
|
-
let polys = f.geometry.coordinates;
|
|
7835
|
-
let iPoly = 0;
|
|
7836
|
-
for (let iWinding = 0; iWinding < windings.length; iWinding++) {
|
|
7837
|
-
let good = !misWound(windings[iWinding]);
|
|
7838
|
-
if (good)
|
|
7839
|
-
iPoly = iWinding;
|
|
7840
|
-
else {
|
|
7841
|
-
// If hole, add to previous poly
|
|
7842
|
-
polys[iPoly].push(polys[iWinding][0]);
|
|
7843
|
-
polys[iWinding] = null;
|
|
7844
|
-
}
|
|
7845
|
-
}
|
|
7846
|
-
f.geometry.coordinates = polys.filter((p) => p != null);
|
|
7847
|
-
}
|
|
7848
|
-
// Degenerate multi-polygon
|
|
7849
|
-
if (f.geometry.coordinates.length == 1) {
|
|
7850
|
-
f.geometry.type = 'Polygon';
|
|
7851
|
-
f.geometry.coordinates = f.geometry.coordinates[0];
|
|
7852
|
-
d = 4;
|
|
7853
|
-
}
|
|
7854
|
-
}
|
|
7911
|
+
if (options.validateHoles)
|
|
7912
|
+
(0, featurecleanholes_1.featureCleanHoles)(f);
|
|
7855
7913
|
// OK, now go through each ring
|
|
7856
7914
|
let polys = f.geometry.coordinates;
|
|
7915
|
+
let d = Util.depthof(f.geometry.coordinates);
|
|
7857
7916
|
if (d == 4)
|
|
7858
7917
|
polys = [polys];
|
|
7859
|
-
windings = polyRingWindings(f);
|
|
7918
|
+
let windings = polyRingWindings(f);
|
|
7860
7919
|
windings.forEach((w) => {
|
|
7861
7920
|
let good = !misWound(w);
|
|
7862
7921
|
if (!good) {
|
|
@@ -10035,18 +10094,16 @@ exports.topoMergeFeatures = topoMergeFeatures;
|
|
|
10035
10094
|
let UniqueState = FSM.FSM_CUSTOM1;
|
|
10036
10095
|
let FSM_COMPUTING = UniqueState++;
|
|
10037
10096
|
class FsmIncrementalUnion extends FSM.Fsm {
|
|
10038
|
-
constructor(env, options, key, map) {
|
|
10097
|
+
constructor(env, options, multi, key, map) {
|
|
10039
10098
|
super(env);
|
|
10040
10099
|
this.options = options;
|
|
10100
|
+
this.multi = multi;
|
|
10041
10101
|
this.key = key;
|
|
10042
10102
|
this.result = null;
|
|
10043
10103
|
this.map = null;
|
|
10044
10104
|
if (map)
|
|
10045
10105
|
this.recompute(map);
|
|
10046
10106
|
}
|
|
10047
|
-
matches(key) {
|
|
10048
|
-
return Util.shallowEqual(this.key, key);
|
|
10049
|
-
}
|
|
10050
10107
|
recompute(map) {
|
|
10051
10108
|
if (this.map != null && map != null && Util.shallowEqual(map, this.map)) {
|
|
10052
10109
|
this.work = { nUnion: 0, nDifference: 0, ms: 0 };
|
|
@@ -10060,7 +10117,7 @@ class FsmIncrementalUnion extends FSM.Fsm {
|
|
|
10060
10117
|
let values = Object.values(map);
|
|
10061
10118
|
this.work = { nUnion: values.length, nDifference: 0, ms: 0 };
|
|
10062
10119
|
let elapsed = new Util.Elapsed();
|
|
10063
|
-
this.result = topoMergeFeatures(this.
|
|
10120
|
+
this.result = topoMergeFeatures(this.multi.allTopo(), values);
|
|
10064
10121
|
this.work.ms = elapsed.ms();
|
|
10065
10122
|
this.map = map;
|
|
10066
10123
|
}
|
|
@@ -10086,41 +10143,36 @@ class FsmTopoUnion extends FSM.Fsm {
|
|
|
10086
10143
|
constructor(env, options) {
|
|
10087
10144
|
super(env);
|
|
10088
10145
|
this.options = Util.shallowAssignImmutable(P.DefaultTickOptions, options);
|
|
10089
|
-
this.unions =
|
|
10146
|
+
this.unions = {};
|
|
10090
10147
|
this.work = { nUnion: 0, nDifference: 0, ms: 0 };
|
|
10091
10148
|
}
|
|
10092
10149
|
get result() {
|
|
10093
|
-
if (this.unions
|
|
10094
|
-
return this.unions.map((i) => ({ key: i.key, poly: i.result, work: i.work }));
|
|
10150
|
+
if (Util.countKeys(this.unions) > 0 && this.state === FSM.FSM_DONE)
|
|
10151
|
+
return Object.values(this.unions).map((i) => ({ key: i.key, poly: i.result, work: i.work }));
|
|
10095
10152
|
else
|
|
10096
10153
|
return null;
|
|
10097
10154
|
}
|
|
10098
10155
|
cancel() {
|
|
10099
|
-
this.unions.forEach((i) => {
|
|
10156
|
+
Object.values(this.unions).forEach((i) => {
|
|
10100
10157
|
i.cancel();
|
|
10101
10158
|
});
|
|
10102
|
-
this.unions =
|
|
10159
|
+
this.unions = {};
|
|
10103
10160
|
this.setState(FSM.FSM_DONE);
|
|
10104
10161
|
}
|
|
10105
10162
|
cancelOne(key) {
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
u.cancel();
|
|
10110
|
-
return;
|
|
10111
|
-
}
|
|
10112
|
-
}
|
|
10163
|
+
let u = this.unions[key];
|
|
10164
|
+
if (u)
|
|
10165
|
+
u.cancel();
|
|
10113
10166
|
}
|
|
10114
|
-
recompute(key, map) {
|
|
10115
|
-
let fsm = this.unions
|
|
10116
|
-
if (fsm == null) {
|
|
10117
|
-
fsm = new FsmIncrementalUnion(this.env, this.options, key, map);
|
|
10118
|
-
this.unions
|
|
10167
|
+
recompute(multi, key, map) {
|
|
10168
|
+
let fsm = this.unions[key];
|
|
10169
|
+
if (fsm == null || fsm.multi !== multi) {
|
|
10170
|
+
fsm = new FsmIncrementalUnion(this.env, this.options, multi, key, map);
|
|
10171
|
+
this.unions[key] = fsm;
|
|
10119
10172
|
}
|
|
10120
10173
|
else
|
|
10121
10174
|
fsm.recompute(map);
|
|
10122
10175
|
this.work = { nUnion: 0, nDifference: 0, ms: 0 };
|
|
10123
|
-
this.unions.forEach((u) => { this.work.nUnion += u.work.nUnion; this.work.nDifference += u.work.nDifference; });
|
|
10124
10176
|
this.waitOn(fsm);
|
|
10125
10177
|
this.setState(FSM_COMPUTING);
|
|
10126
10178
|
}
|
|
@@ -10129,8 +10181,13 @@ class FsmTopoUnion extends FSM.Fsm {
|
|
|
10129
10181
|
switch (this.state) {
|
|
10130
10182
|
case FSM.FSM_STARTING:
|
|
10131
10183
|
case FSM_COMPUTING:
|
|
10184
|
+
this.work = { nUnion: 0, nDifference: 0, ms: 0 };
|
|
10132
10185
|
if (this.unions)
|
|
10133
|
-
this.unions.forEach((
|
|
10186
|
+
Object.values(this.unions).forEach((i) => {
|
|
10187
|
+
this.work.ms += i.work.ms;
|
|
10188
|
+
this.work.nUnion += i.work.nUnion;
|
|
10189
|
+
this.work.nDifference += i.work.nDifference;
|
|
10190
|
+
});
|
|
10134
10191
|
this.setState(FSM.FSM_DONE);
|
|
10135
10192
|
break;
|
|
10136
10193
|
}
|