@dra2020/baseclient 1.0.12 → 1.0.13

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.
Files changed (120) hide show
  1. package/package.json +16 -15
  2. package/LICENSE +0 -21
  3. package/README.md +0 -26
  4. package/dist/all/all.d.ts +0 -20
  5. package/dist/baseclient.js +0 -10113
  6. package/dist/baseclient.js.map +0 -1
  7. package/dist/context/all.d.ts +0 -1
  8. package/dist/context/context.d.ts +0 -13
  9. package/dist/filterexpr/all.d.ts +0 -1
  10. package/dist/filterexpr/filterexpr.d.ts +0 -67
  11. package/dist/fsm/all.d.ts +0 -1
  12. package/dist/fsm/fsm.d.ts +0 -119
  13. package/dist/geo/all.d.ts +0 -2
  14. package/dist/geo/geo.d.ts +0 -67
  15. package/dist/geo/vfeature.d.ts +0 -4
  16. package/dist/logabstract/all.d.ts +0 -1
  17. package/dist/logabstract/log.d.ts +0 -26
  18. package/dist/logclient/all.d.ts +0 -1
  19. package/dist/logclient/log.d.ts +0 -6
  20. package/dist/ot-editutil/all.d.ts +0 -2
  21. package/dist/ot-editutil/oteditutil.d.ts +0 -14
  22. package/dist/ot-editutil/otmaputil.d.ts +0 -21
  23. package/dist/ot-js/all.d.ts +0 -9
  24. package/dist/ot-js/otarray.d.ts +0 -111
  25. package/dist/ot-js/otclientengine.d.ts +0 -38
  26. package/dist/ot-js/otcomposite.d.ts +0 -37
  27. package/dist/ot-js/otcounter.d.ts +0 -17
  28. package/dist/ot-js/otengine.d.ts +0 -22
  29. package/dist/ot-js/otmap.d.ts +0 -19
  30. package/dist/ot-js/otserverengine.d.ts +0 -38
  31. package/dist/ot-js/otsession.d.ts +0 -114
  32. package/dist/ot-js/ottypes.d.ts +0 -29
  33. package/dist/poly/all.d.ts +0 -15
  34. package/dist/poly/blend.d.ts +0 -1
  35. package/dist/poly/boundbox.d.ts +0 -16
  36. package/dist/poly/cartesian.d.ts +0 -5
  37. package/dist/poly/graham-scan.d.ts +0 -8
  38. package/dist/poly/hash.d.ts +0 -1
  39. package/dist/poly/matrix.d.ts +0 -24
  40. package/dist/poly/minbound.d.ts +0 -1
  41. package/dist/poly/poly.d.ts +0 -52
  42. package/dist/poly/polybin.d.ts +0 -5
  43. package/dist/poly/polylabel.d.ts +0 -7
  44. package/dist/poly/polypack.d.ts +0 -30
  45. package/dist/poly/polyround.d.ts +0 -1
  46. package/dist/poly/polysimplify.d.ts +0 -1
  47. package/dist/poly/quad.d.ts +0 -48
  48. package/dist/poly/selfintersect.d.ts +0 -1
  49. package/dist/poly/shamos.d.ts +0 -1
  50. package/dist/poly/simplify.d.ts +0 -2
  51. package/dist/poly/topo.d.ts +0 -46
  52. package/dist/poly/union.d.ts +0 -49
  53. package/dist/util/all.d.ts +0 -5
  54. package/dist/util/bintrie.d.ts +0 -93
  55. package/dist/util/countedhash.d.ts +0 -19
  56. package/dist/util/gradient.d.ts +0 -15
  57. package/dist/util/indexedarray.d.ts +0 -15
  58. package/dist/util/util.d.ts +0 -68
  59. package/docs/context.md +0 -2
  60. package/docs/filterexpr.md +0 -22
  61. package/docs/fsm.md +0 -243
  62. package/docs/logabstract.md +0 -2
  63. package/docs/logclient.md +0 -2
  64. package/docs/ot-editutil.md +0 -2
  65. package/docs/ot-js.md +0 -95
  66. package/docs/poly.md +0 -103
  67. package/docs/util.md +0 -2
  68. package/lib/all/all.ts +0 -21
  69. package/lib/context/all.ts +0 -1
  70. package/lib/context/context.ts +0 -82
  71. package/lib/filterexpr/all.ts +0 -1
  72. package/lib/filterexpr/filterexpr.ts +0 -699
  73. package/lib/fsm/all.ts +0 -1
  74. package/lib/fsm/fsm.ts +0 -559
  75. package/lib/geo/all.ts +0 -2
  76. package/lib/geo/geo.ts +0 -452
  77. package/lib/geo/vfeature.ts +0 -34
  78. package/lib/logabstract/all.ts +0 -1
  79. package/lib/logabstract/log.ts +0 -55
  80. package/lib/logclient/all.ts +0 -1
  81. package/lib/logclient/log.ts +0 -105
  82. package/lib/ot-editutil/all.ts +0 -2
  83. package/lib/ot-editutil/oteditutil.ts +0 -180
  84. package/lib/ot-editutil/otmaputil.ts +0 -209
  85. package/lib/ot-js/all.ts +0 -9
  86. package/lib/ot-js/otarray.ts +0 -1168
  87. package/lib/ot-js/otclientengine.ts +0 -327
  88. package/lib/ot-js/otcomposite.ts +0 -247
  89. package/lib/ot-js/otcounter.ts +0 -145
  90. package/lib/ot-js/otengine.ts +0 -71
  91. package/lib/ot-js/otmap.ts +0 -144
  92. package/lib/ot-js/otserverengine.ts +0 -329
  93. package/lib/ot-js/otsession.ts +0 -202
  94. package/lib/ot-js/ottypes.ts +0 -98
  95. package/lib/poly/all.ts +0 -15
  96. package/lib/poly/blend.ts +0 -27
  97. package/lib/poly/boundbox.ts +0 -102
  98. package/lib/poly/cartesian.ts +0 -130
  99. package/lib/poly/graham-scan.ts +0 -401
  100. package/lib/poly/hash.ts +0 -15
  101. package/lib/poly/matrix.ts +0 -309
  102. package/lib/poly/minbound.ts +0 -211
  103. package/lib/poly/poly.ts +0 -767
  104. package/lib/poly/polybin.ts +0 -218
  105. package/lib/poly/polylabel.ts +0 -204
  106. package/lib/poly/polypack.ts +0 -468
  107. package/lib/poly/polyround.ts +0 -30
  108. package/lib/poly/polysimplify.ts +0 -24
  109. package/lib/poly/quad.ts +0 -272
  110. package/lib/poly/selfintersect.ts +0 -87
  111. package/lib/poly/shamos.ts +0 -297
  112. package/lib/poly/simplify.ts +0 -119
  113. package/lib/poly/topo.ts +0 -499
  114. package/lib/poly/union.ts +0 -388
  115. package/lib/util/all.ts +0 -5
  116. package/lib/util/bintrie.ts +0 -603
  117. package/lib/util/countedhash.ts +0 -83
  118. package/lib/util/gradient.ts +0 -108
  119. package/lib/util/indexedarray.ts +0 -80
  120. package/lib/util/util.ts +0 -695
@@ -1,119 +0,0 @@
1
- /*
2
- Adapted from:
3
- (c) 2017, Vladimir Agafonkin
4
- Simplify.js, a high-performance JS polyline simplification library
5
- mourner.github.io/simplify-js
6
- */
7
-
8
- export type Point = [ number, number];
9
-
10
- // square distance between 2 points
11
- function getSqDist(p1: Point, p2: Point): number
12
- {
13
- var dx = p1[0] - p2[0],
14
- dy = p1[1] - p2[1];
15
-
16
- return dx * dx + dy * dy;
17
- }
18
-
19
- // square distance from a point to a segment
20
- function getSqSegDist(p: Point, p1: Point, p2: Point): number
21
- {
22
- var x = p1[0],
23
- y = p1[1],
24
- dx = p2[0] - x,
25
- dy = p2[1] - y;
26
-
27
- if (dx !== 0 || dy !== 0) {
28
-
29
- var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy);
30
-
31
- if (t > 1) {
32
- x = p2[0];
33
- y = p2[1];
34
-
35
- } else if (t > 0) {
36
- x += dx * t;
37
- y += dy * t;
38
- }
39
- }
40
-
41
- dx = p[0] - x;
42
- dy = p[1] - y;
43
-
44
- return dx * dx + dy * dy;
45
- }
46
-
47
-
48
- // rest of the code doesn't care about point format
49
-
50
- // basic distance-based simplification
51
- function simplifyRadialDist(points: Point[], sqTolerance: number): Point[]
52
- {
53
- let prevPoint: Point = points[0],
54
- newPoints: Point[] = [prevPoint],
55
- point: Point;
56
-
57
- for (let i = 1, len = points.length; i < len; i++) {
58
- point = points[i];
59
-
60
- if (getSqDist(point, prevPoint) > sqTolerance) {
61
- newPoints.push(point);
62
- prevPoint = point;
63
- }
64
- }
65
-
66
- if (prevPoint !== point) newPoints.push(point);
67
-
68
- return newPoints;
69
- }
70
-
71
- function simplifyDPStep(points: Point[], first: number, last: number, sqTolerance: number, simplified: Point[]): void
72
- {
73
- let maxSqDist: number = sqTolerance,
74
- index: number;
75
-
76
- for (let i = first + 1; i < last; i++)
77
- {
78
- let sqDist = getSqSegDist(points[i], points[first], points[last]);
79
-
80
- if (sqDist > maxSqDist)
81
- {
82
- index = i;
83
- maxSqDist = sqDist;
84
- }
85
- }
86
-
87
- if (maxSqDist > sqTolerance)
88
- {
89
- if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified);
90
- simplified.push(points[index]);
91
- if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified);
92
- }
93
- }
94
-
95
- // simplification using Ramer-Douglas-Peucker algorithm
96
- function simplifyDouglasPeucker(points: Point[], sqTolerance: number): Point[]
97
- {
98
- let last: number = points.length - 1;
99
-
100
- let simplified: Point[] = [points[0]];
101
- simplifyDPStep(points, 0, last, sqTolerance, simplified);
102
- simplified.push(points[last]);
103
-
104
- return simplified;
105
- }
106
-
107
- // both algorithms combined for awesome performance
108
- export function simplify(points: Point[], tolerance: number = 1, highestQuality: boolean = false): Point[]
109
- {
110
- if (tolerance == 0 || points.length <= 2)
111
- return points;
112
-
113
- let sqTolerance: number = tolerance * tolerance;
114
-
115
- points = highestQuality ? points : simplifyRadialDist(points, sqTolerance);
116
- points = simplifyDouglasPeucker(points, sqTolerance);
117
-
118
- return points;
119
- }
package/lib/poly/topo.ts DELETED
@@ -1,499 +0,0 @@
1
-
2
- // Forked version that supports packing
3
- import * as TopoClient from '@dra2020/topojson-client';
4
- // Forked version that fixes self-looping hole problem
5
- import * as TopoServer from '@dra2020/topojson-server';
6
- // Forked version that fixes performance problem
7
- import * as TopoSimplify from '@dra2020/topojson-simplify';
8
-
9
- import * as Util from '../util/all';
10
- import * as FSM from '../fsm/all';
11
-
12
- import * as P from './poly';
13
- import * as Q from './quad';
14
- import * as PP from './polypack';
15
- import * as PL from './polylabel';
16
- import { selfIntersectFast } from './shamos';
17
-
18
- export type Topo = any;
19
-
20
- function getGEOID(f: any): string
21
- {
22
- if (f.features && f.features.length) f = f.features[0];
23
- else if (Array.isArray(f)) f = f[0];
24
- if (f.properties.id !== undefined) return 'id';
25
- if (f.properties.GEOID !== undefined) return 'GEOID';
26
- if (f.properties.GEOID10 !== undefined) return 'GEOID10';
27
- }
28
-
29
- export function topoFromCollection(col: any): Topo
30
- {
31
- if (col == null) return null;
32
- let save = PP.featureUnpackTemporarily(col);
33
- let prop = getGEOID(col);
34
- let objects: any = {};
35
- col.features.forEach((f: any) => objects[f.properties[prop]] = f);
36
- let topo = TopoServer.topology(objects);
37
- PP.featureRepack(col, save);
38
- if (col.datasets)
39
- (topo as any).datasets = col.datasets;
40
- return topo;
41
- }
42
-
43
- function ringsCancel(outerPoly: any, innerRing: any): boolean
44
- {
45
- if (outerPoly.length != 1) return false;
46
- let outerRing = outerPoly[0];
47
- if (outerRing.length !== innerRing.length) return false;
48
- let n = outerRing.length-1;
49
- let i = 0;
50
- for (; i <= n; i++, n--)
51
- if (! Util.shallowEqual(outerRing[i], innerRing[n]))
52
- return false;
53
- return true;
54
- }
55
-
56
- function correctGeometry(f: any): any
57
- {
58
- if (f && f.geometry && f.geometry.type === 'MultiPolygon' && f.geometry.coordinates)
59
- {
60
- let multiPoly = f.geometry.coordinates;
61
-
62
- // Convert degenerate MultiPolygon to Polygon
63
- if (multiPoly.length == 1)
64
- {
65
- f.geometry.type = 'Polygon';
66
- f.geometry.coordinates = multiPoly[0];
67
- }
68
- }
69
-
70
- // TopoJSON does not guarantee proper winding order which messes up later processing. Fix it.
71
- P.featureRewind(f);
72
-
73
- return f;
74
- }
75
-
76
- export function topoContiguity(topo: Topo): any
77
- {
78
- let objects: any[] = Object.values(topo.objects);
79
- let geoid = getGEOID(objects);
80
- objects.forEach((o: any) => { o.properties.id = o.properties[geoid] });
81
- let neighbors = TopoClient.neighbors(objects, true);
82
- let result: any = {};
83
- result['OUT_OF_STATE'] = [];
84
- objects.forEach((o: any, i: number) => {
85
- result[o.properties.id] = neighbors[i].map((j: any) => {
86
- if (j >= 0)
87
- return objects[j].properties.id;
88
- else
89
- {
90
- result['OUT_OF_STATE'].push(o.properties.id);
91
- return 'OUT_OF_STATE';
92
- }
93
- });
94
- });
95
- return result;
96
- }
97
-
98
- export function topoToFeature(topo: Topo, geoid: string): any
99
- {
100
- return correctGeometry(TopoClient.feature(topo, topo.objects[geoid]));
101
- }
102
-
103
- export function topoToCollection(topo: Topo): any
104
- {
105
- let col: any = { type: 'FeatureCollection', features: [] };
106
- Object.keys(topo.objects).forEach((geoid: string) => {
107
- col.features.push(topoToFeature(topo, geoid));
108
- });
109
- if (topo.datasets) col.datasets = topo.datasets;
110
- return col;
111
- }
112
-
113
- function keepArcs(topo: any, arcs: any, keepweight: number): void
114
- {
115
- arcs.forEach((a: any) => {
116
- if (Array.isArray(a))
117
- keepArcs(topo, a, keepweight);
118
- else
119
- {
120
- let arc = topo.arcs[a < 0 ? ~a : a];
121
- arc.forEach((pt: any) => {
122
- if (pt[2] >= keepweight)
123
- pt[2] = Infinity;
124
- });
125
- }
126
- });
127
- }
128
-
129
- function fullFidelity(topo: any, arcs: any): boolean
130
- {
131
- let bFull = true;
132
-
133
- arcs.forEach((a: any) => {
134
- if (Array.isArray(a))
135
- bFull = bFull && fullFidelity(topo, a);
136
- else
137
- {
138
- let arc = topo.arcs[a < 0 ? ~a : a];
139
- arc.forEach((pt: any) => {
140
- if (bFull && pt[2] !== Infinity)
141
- bFull = false;
142
- });
143
- }
144
- });
145
- return bFull;
146
- }
147
-
148
- function misMatchPoly(p1: any, p2: any): boolean
149
- {
150
- if (p1 == null || p2 == null || p1.length != p2.length) return true;
151
- for (let i = 0; i < p1.length; i++)
152
- if (p1[i] == null || p2[i] == null) return true;
153
- return false;
154
- }
155
-
156
- function misMatchMulti(m1: any, m2: any): boolean
157
- {
158
- if (m1 == null || m2 == null || m1.length != m2.length) return true;
159
- for (let i = 0; i < m1.length; i++)
160
- if (misMatchPoly(m1[i], m2[i])) return true;
161
- return false;
162
- }
163
-
164
- function misMatchObject(o1: any, o2: any): boolean
165
- {
166
- if (o1 == null || o2 == null || o1.type !== o2.type) return true;
167
- return (o1.type === 'MultiPolygon') ? misMatchMulti(o1.arcs, o2.arcs) : misMatchPoly(o1.arcs, o2.arcs);
168
- }
169
-
170
- const MAX_TRIES = 25;
171
-
172
- function bigTimeString(ms: number): string
173
- {
174
- let seconds = Math.trunc(ms / 1000);
175
- let minutes = Math.trunc(seconds / 60);
176
- seconds -= minutes * 60;
177
- return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
178
- }
179
-
180
- export interface SimplifyOptions
181
- {
182
- minArea?: number,
183
- }
184
-
185
- const DefaultSimplifyOptions: SimplifyOptions = { minArea: 500 };
186
-
187
- function log(s: string): void
188
- {
189
- //console.log(s);
190
- }
191
-
192
- //
193
- // topoSimplifyCollection:
194
- // This implements our simplification strategy for block/precinct level shapes. The basic idea is to
195
- // ensure that all shapes generated at the block level have non-zero area and do not introduce self-crossing
196
- // edges. Since topological simplification happens at the edge level, self-crossing is a risk when opposite
197
- // edges make simplification decisions that cause the edges to cross. Crossing edges result in visual anomalies.
198
- // In addition, our basic strategy is that if we have well-formed block shapes, all other shape processing
199
- // (virtual features, precincts, counties, districts) can be done by fast merges that generate well-formed
200
- // shapes without holes, overlaps or crossing edges.
201
- // The strategy here is to first just do topological simplification at the default simplification level. We then
202
- // scan for problematic shapes (zero area, too thin and narrow or self-crossing) and keep additional points on
203
- // the edges (arcs) for those shapes, adding additional points on each iteration step until we have a good set.
204
- // For tiny shapes (zero area or short and thin) we just immediately say keep all points since these are mostly
205
- // shapes with a small number of points anyway.
206
- //
207
-
208
- export function topoSimplifyCollection(col: any, options?: SimplifyOptions): any
209
- {
210
- options = Util.shallowAssignImmutable(DefaultSimplifyOptions, options);
211
-
212
- if (col == null) return null;
213
- let elapsedTotal = new Util.Elapsed();
214
- let elapsed = new Util.Elapsed();
215
- let topo = topoFromCollection(col);
216
- log(`topoSimplifyCollection: fromCollection: ${Math.round(elapsed.ms())}ms`);
217
- elapsed.start();
218
- topo = TopoSimplify.presimplify(topo, TopoSimplify['sphericalTriangleArea']);
219
- log(`topoSimplifyCollection: presimplify: ${Math.round(elapsed.ms())}ms`);
220
- elapsed.start();
221
-
222
- // Keep iterating on removing simplification from degenerate shapes
223
- let nTries = 1;
224
- let nBadLast = Number.MAX_VALUE;
225
- let keepweight = 1E-11;
226
- let nLabelTolerance = 1E-4;
227
- let minArea = options.minArea;
228
- let keepTiny = new WeakMap<any, any>();
229
- while (true)
230
- {
231
- let testtopo = TopoSimplify.simplify(topo, 1E-10);
232
- elapsed.start();
233
- let nBad = 0;
234
- let nTiny = 0;
235
- col.features.forEach((f: any) => {
236
- let oOld: any = topo.objects[f.properties.id];
237
- let oNew: any = testtopo.objects[f.properties.id];
238
- if (! keepTiny.has(f))
239
- {
240
- // Walk through each polygon of a multipolygon separately since I may have a large non-degenerate
241
- // shape combined with degenerate smaller shapes that I want to identify. I do not examine holes
242
- // separately under the assumption that holes will have matching polygons that would be identified
243
- // and would cause those shared edges (between the hole and the filling polygon) to be preserved if necessary.
244
- //
245
- // I do make a final pass of testing for self-intersection that looks at both polygon and hole edges.
246
- //
247
- let arcs = PP.normalizeArcs(oNew.arcs);
248
- let npoly = PP.countArcPolygons(arcs);
249
- let bDecided = false;
250
- let iPoly = 0;
251
- for (; !bDecided && iPoly < npoly; iPoly++)
252
- {
253
- let pp = PP.polyPackTopoArcs(testtopo, arcs, iPoly);
254
- P.polyRewindRings(pp);
255
- let a = P.polyArea(pp);
256
- if (a <= 0)
257
- {
258
- keepTiny.set(f, f);
259
- keepArcs(topo, oOld.arcs, 0); // keeps all points to avoid reprocessing these tiny shapes
260
- nBad++, nTiny++, bDecided = true;
261
- }
262
- else if (a < minArea)
263
- {
264
- let d = PL.polyLabel(pp);
265
- if (d.d < nLabelTolerance)
266
- {
267
- keepTiny.set(f, f);
268
- keepArcs(topo, oOld.arcs, 0); // keeps all points to avoid reprocessing these tiny shapes
269
- nBad++, nTiny++, bDecided = true;
270
- }
271
- }
272
- }
273
- if (! bDecided)
274
- {
275
- let pp = PP.polyPackTopoArcs(testtopo, arcs);
276
- if (selfIntersectFast(pp))
277
- {
278
- keepArcs(topo, oOld.arcs, keepweight);
279
- nBad++;
280
- }
281
- }
282
- }
283
- });
284
- log(`topoSimplifyCollection: pass ${nTries}: ${nBad} (${nTiny} tiny) of ${col.features.length} features are degenerate`);
285
-
286
- // If not making progress, keep more points
287
- if (nBad >= nBadLast)
288
- {
289
- keepweight /= 10;
290
- log(`topoSimplifyCollection: pass ${nTries}: reducing weight limit to ${keepweight}`);
291
- }
292
- nBadLast = nBad;
293
-
294
- if (nBad && nTries > MAX_TRIES)
295
- console.error(`topoSimplifyCollection: failed to finalize simplify down to zero degenerate features`);
296
- // If no bad block shapes, or finished trying, just return result
297
- if (nBad == 0 || nTries > MAX_TRIES)
298
- {
299
- col = topoToCollection(testtopo);
300
- break;
301
- }
302
-
303
- nTries++;
304
- }
305
-
306
- log(`topoSimplifyCollection: total elapsed time: ${bigTimeString(elapsedTotal.ms())}`);
307
-
308
- return col;
309
- }
310
-
311
- export function topoMerge(topo: Topo, geoids: string[]): any
312
- {
313
- if (geoids == null || geoids.length == 0) return null;
314
- let objects: any[] = [];
315
- geoids.forEach((geoid) => objects.push(topo.objects[geoid]));
316
- return correctGeometry({ type: 'Feature', properties: {}, geometry: TopoClient.merge(topo, objects) });
317
- }
318
-
319
- export function topoMergeFeatures(topo: Topo, features: any[]): any
320
- {
321
- if (features == null || features.length == 0) return null;
322
- let prop = getGEOID(features);
323
- return topoMerge(topo, features.map(f => f.properties[prop]));
324
- }
325
-
326
- let UniqueState = FSM.FSM_CUSTOM1;
327
- let FSM_COMPUTING = UniqueState++;
328
-
329
- class FsmIncrementalUnion extends FSM.Fsm
330
- {
331
- options: P.TickOptions;
332
- key: any;
333
- map: any; // { [geoid: string]: Feature }
334
- result: any;
335
- work: Q.WorkDone;
336
-
337
- constructor(env: FSM.FsmEnvironment, options: P.TickOptions, key: any, map?: any)
338
- {
339
- super(env);
340
- this.options = options;
341
- this.key = key;
342
- this.result = null;
343
- this.map = null;
344
- if (map) this.recompute(map);
345
- }
346
-
347
- matches(key: any): boolean
348
- {
349
- return Util.shallowEqual(this.key, key);
350
- }
351
-
352
- recompute(map: any): void
353
- {
354
- if (this.map != null && map != null && Util.shallowEqual(map, this.map))
355
- {
356
- this.work = { nUnion: 0, nDifference: 0, ms: 0 };
357
- }
358
- else if (map == null || Util.isEmpty(map))
359
- {
360
- this.work = { nUnion: 0, nDifference: 0, ms: 0 };
361
- this.result = null;
362
- this.map = map;
363
- }
364
- else
365
- {
366
- let values = Object.values(map);
367
- this.work = { nUnion: values.length, nDifference: 0, ms: 0 };
368
- let elapsed = new Util.Elapsed();
369
- this.result = topoMergeFeatures(this.key.multi.allTopo(), values);
370
- this.work.ms = elapsed.ms();
371
- this.map = map;
372
- }
373
- this.setState(FSM.FSM_DONE);
374
- }
375
-
376
- cancel(): void
377
- {
378
- this.result = null;
379
- this.map = null;
380
- this.setState(FSM.FSM_DONE);
381
- }
382
-
383
- tick(): void
384
- {
385
- if (this.ready)
386
- {
387
- switch (this.state)
388
- {
389
- case FSM.FSM_STARTING:
390
- // never initialized to do work (see recompute())
391
- this.setState(FSM.FSM_DONE);
392
- break;
393
- }
394
- }
395
- }
396
- }
397
-
398
- export interface TopoUnionResult
399
- {
400
- key: any;
401
- poly: any;
402
- work: Q.WorkDone;
403
- }
404
-
405
- export class FsmTopoUnion extends FSM.Fsm
406
- {
407
- options: P.TickOptions;
408
- unions: FsmIncrementalUnion[];
409
- work: Q.WorkDone;
410
-
411
- constructor(env: FSM.FsmEnvironment, options?: P.TickOptions)
412
- {
413
- super(env);
414
- this.options = Util.shallowAssignImmutable(P.DefaultTickOptions, options);
415
- this.unions = [];
416
- this.work = { nUnion: 0, nDifference: 0, ms: 0 };
417
- }
418
-
419
- get result(): TopoUnionResult[]
420
- {
421
- if (this.unions.length > 0 && this.state === FSM.FSM_DONE)
422
- return this.unions.map((i: FsmIncrementalUnion) => ({ key: i.key, poly: i.result, work: i.work }) );
423
- else
424
- return null;
425
- }
426
-
427
- cancel(): void
428
- {
429
- this.unions.forEach((i: FsmIncrementalUnion) => {
430
- i.cancel();
431
- });
432
- this.unions = [];
433
- this.setState(FSM.FSM_DONE);
434
- }
435
-
436
- cancelOne(key: any): void
437
- {
438
- for (let i = 0; i < this.unions.length; i++)
439
- {
440
- let u = this.unions[i];
441
- if (u.matches(key))
442
- {
443
- u.cancel();
444
- return;
445
- }
446
- }
447
- }
448
-
449
- recompute(key: any, map: any): void
450
- {
451
- let fsm: FsmIncrementalUnion = this.unions.find((i: FsmIncrementalUnion) => i.matches(key));
452
- if (fsm == null)
453
- {
454
- fsm = new FsmIncrementalUnion(this.env, this.options, key, map);
455
- this.unions.push(fsm);
456
- }
457
- else
458
- fsm.recompute(map);
459
- this.work = { nUnion: 0, nDifference: 0, ms: 0 };
460
- this.unions.forEach((u) => { this.work.nUnion += u.work.nUnion; this.work.nDifference += u.work.nDifference });
461
- this.waitOn(fsm);
462
- this.setState(FSM_COMPUTING);
463
- }
464
-
465
- tick(): void
466
- {
467
- if (this.ready)
468
- {
469
- switch (this.state)
470
- {
471
- case FSM.FSM_STARTING:
472
- case FSM_COMPUTING:
473
- if (this.unions) this.unions.forEach((u) => { this.work.ms += u.work.ms });
474
- this.setState(FSM.FSM_DONE);
475
- break;
476
- }
477
- }
478
- }
479
- }
480
-
481
- export function topoPacked(topo: any): boolean
482
- {
483
- return topo.packed !== undefined;
484
- }
485
-
486
- export function topoPack(topo: any): any
487
- {
488
- let tc = TopoClient;
489
- TopoClient.packArcs(topo);
490
- TopoClient.packArcIndices(topo);
491
- return topo;
492
- }
493
-
494
- export function topoUnpack(topo: any): any
495
- {
496
- TopoClient.unpackArcs(topo);
497
- TopoClient.unpackArcIndices(topo);
498
- return topo;
499
- }