@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.
@@ -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 closeFeature(f) {
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
- closeFeature(f);
7909
+ featureClose(f);
7814
7910
  // Check if multi-polygon is really polygon with holes
7815
- // Only applies to multi-polygons with no holes
7816
- let d = Util.depthof(f.geometry.coordinates);
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.key.multi.allTopo(), values);
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.length > 0 && this.state === FSM.FSM_DONE)
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
- for (let i = 0; i < this.unions.length; i++) {
10107
- let u = this.unions[i];
10108
- if (u.matches(key)) {
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.find((i) => i.matches(key));
10116
- if (fsm == null) {
10117
- fsm = new FsmIncrementalUnion(this.env, this.options, key, map);
10118
- this.unions.push(fsm);
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((u) => { this.work.ms += u.work.ms; });
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
  }