@dra2020/district-analytics 7.1.6 → 7.1.7

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Alec Ramsay
3
+ Copyright (c) 2020 Dave's Redistricting, LLC.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/cli.js CHANGED
@@ -93801,6 +93801,7 @@ __export(__webpack_require__(/*! ./quad */ "./lib/quad.ts"));
93801
93801
  __export(__webpack_require__(/*! ./polylabel */ "./lib/polylabel.ts"));
93802
93802
  __export(__webpack_require__(/*! ./polysimplify */ "./lib/polysimplify.ts"));
93803
93803
  __export(__webpack_require__(/*! ./polypack */ "./lib/polypack.ts"));
93804
+ __export(__webpack_require__(/*! ./polybin */ "./lib/polybin.ts"));
93804
93805
  __export(__webpack_require__(/*! ./boundbox */ "./lib/boundbox.ts"));
93805
93806
  __export(__webpack_require__(/*! ./blend */ "./lib/blend.ts"));
93806
93807
  __export(__webpack_require__(/*! ./cartesian */ "./lib/cartesian.ts"));
@@ -93878,7 +93879,7 @@ function boundboxExtend(bbox, x, y) {
93878
93879
  }
93879
93880
  function boundboxExtendPacked(pp, bbox) {
93880
93881
  let buffer = pp.buffer;
93881
- let offset = pp.buffer[pp.offset + 1];
93882
+ let offset = pp.buffer[pp.offset + 1] + pp.offset;
93882
93883
  let end = pp.offset + pp.length;
93883
93884
  for (; offset < end; offset += 2)
93884
93885
  boundboxExtend(bbox, buffer[offset], buffer[offset + 1]);
@@ -94517,6 +94518,151 @@ function npoints(poly) {
94517
94518
  exports.npoints = npoints;
94518
94519
 
94519
94520
 
94521
+ /***/ }),
94522
+
94523
+ /***/ "./lib/polybin.ts":
94524
+ /*!************************!*\
94525
+ !*** ./lib/polybin.ts ***!
94526
+ \************************/
94527
+ /*! no static exports found */
94528
+ /***/ (function(module, exports, __webpack_require__) {
94529
+
94530
+ "use strict";
94531
+
94532
+ Object.defineProperty(exports, "__esModule", { value: true });
94533
+ const PP = __webpack_require__(/*! ./polypack */ "./lib/polypack.ts");
94534
+ // Only under Node. TextEncoder/Decoder implemented directly in browser.
94535
+ const ServerCoding = __webpack_require__(/*! util */ "util");
94536
+ // Packed Buffer format:
94537
+ //
94538
+ // (strings are packed as UTF8 bytes, padded to 4 byte boundary)
94539
+ //
94540
+ // { 4 byte size (byte offset to packed coordinate buffer) }
94541
+ // { 4 byte length: property name,
94542
+ // 4 byte length: json string }*
94543
+ // { 4 byte length: 'features' }
94544
+ // { 4 byte length: length of 'features' array }
94545
+ // { 4 byte length: property name,
94546
+ // 4 byte length: json string }*
94547
+ // { padding to 8 byte boundary }
94548
+ // { packed buffer coordinates in polypack format (indexed by geometry.packed above) }
94549
+ //
94550
+ const MagicInt = 17;
94551
+ const MagicFloat = 17.17;
94552
+ let encoder = ServerCoding.TextEncoder ? (new ServerCoding.TextEncoder()) : (new TextEncoder());
94553
+ let decoder = ServerCoding.TextDecoder ? (new ServerCoding.TextDecoder('utf-8')) : (new TextDecoder('utf-8'));
94554
+ function pad(n, pad) {
94555
+ let mod = n % pad;
94556
+ return mod ? pad - mod : 0;
94557
+ }
94558
+ function sizeOfString(s) {
94559
+ let s8 = encoder.encode(s);
94560
+ return 4 + s8.length + pad(s8.length, 4);
94561
+ }
94562
+ function packString(buf8, buf32, offset, s) {
94563
+ let s8 = encoder.encode(s);
94564
+ buf32[offset >> 2] = s8.length;
94565
+ offset += 4;
94566
+ let i;
94567
+ for (i = 0; i < s8.length; i++)
94568
+ buf8[offset++] = s8[i];
94569
+ offset += pad(offset, 4);
94570
+ return offset;
94571
+ }
94572
+ function unpackString(buf8, buf32, offset) {
94573
+ let size = buf32[offset >> 2];
94574
+ let s = decoder.decode(buf8.subarray(offset + 4, offset + 4 + size));
94575
+ return s;
94576
+ }
94577
+ function packCollection(col) {
94578
+ // Compute size
94579
+ let pp = PP.featurePack(col);
94580
+ let buffer = col.features.length ? col.features[0].geometry.packed.buffer : null; // to restore, below
94581
+ let size = 16; // int endiness, offset to coordinates, float endiness
94582
+ col.features.forEach((f) => { delete f.geometry.packed.buffer; }); // reconstructed when unpacking
94583
+ let j = JSON.stringify(col);
94584
+ size += sizeOfString(j);
94585
+ size += pad(size, 8);
94586
+ let fullsize = size + pp.length * 8; // add space for coordinates
94587
+ // Now pack it
94588
+ let ab = new ArrayBuffer(fullsize);
94589
+ let buf8 = new Uint8Array(ab);
94590
+ let buf32 = new Int32Array(ab);
94591
+ let buf64 = new Float64Array(ab);
94592
+ let offset = 0;
94593
+ buf32[0] = MagicInt;
94594
+ offset += 4;
94595
+ buf32[1] = size;
94596
+ offset += 4;
94597
+ buf64[1] = MagicFloat; // Note that buf64[0] has the two ints stored above
94598
+ offset += 8;
94599
+ offset = packString(buf8, buf32, offset, j);
94600
+ offset += pad(offset, 8);
94601
+ if (offset != size)
94602
+ throw 'Oops, packing error.';
94603
+ let foff = offset >> 3;
94604
+ let buf = pp.buffer;
94605
+ for (let i = 0; i < pp.length; i++)
94606
+ buf64[foff++] = buf[i];
94607
+ // Now restore
94608
+ col.features.forEach((f) => { f.geometry.packed.buffer = buffer; });
94609
+ PP.featureUnpack(col);
94610
+ return ab;
94611
+ }
94612
+ exports.packCollection = packCollection;
94613
+ function reverse(buf8, s, n) {
94614
+ let e = s + n - 1;
94615
+ while (s < e) {
94616
+ let t = buf8[s];
94617
+ buf8[s] = buf8[e];
94618
+ buf8[e] = t;
94619
+ s++, e--;
94620
+ }
94621
+ }
94622
+ function enforceEndianness(ab) {
94623
+ let buf8 = new Uint8Array(ab);
94624
+ let buf32 = new Int32Array(ab);
94625
+ let buf64 = new Float64Array(ab);
94626
+ let reverseInts = false;
94627
+ if (buf32[0] != MagicInt) {
94628
+ reverseInts = true;
94629
+ reverse(buf8, 0, 4);
94630
+ if (buf32[0] != MagicInt)
94631
+ throw 'unpackCollection: badly formatted buffer';
94632
+ reverse(buf8, 4, 4); // size of non-floats
94633
+ }
94634
+ let reverseFloats = false;
94635
+ if (buf64[1] != MagicFloat) {
94636
+ reverseFloats = true;
94637
+ reverse(buf8, 8, 8);
94638
+ if (buf64[1] != MagicFloat)
94639
+ throw 'unpackCollection: badly formatted buffer';
94640
+ }
94641
+ if (reverseInts)
94642
+ reverse(buf8, 16, 4); // JSON string length
94643
+ if (reverseFloats) {
94644
+ let s = buf32[1]; // Offset to floats
94645
+ let e = ab.byteLength;
94646
+ for (; s < e; s += 8)
94647
+ reverse(buf8, s, 8);
94648
+ }
94649
+ }
94650
+ function unpackCollection(ab) {
94651
+ enforceEndianness(ab);
94652
+ let col = {};
94653
+ let buf8 = new Uint8Array(ab);
94654
+ let buf32 = new Int32Array(ab);
94655
+ let size = buf32[1];
94656
+ let buf64 = new Float64Array(ab, size); // offset to start of packed coordinates
94657
+ let offset = 16;
94658
+ let j = unpackString(buf8, buf32, offset);
94659
+ col = JSON.parse(j);
94660
+ col.features.forEach((f) => { f.geometry.packed.buffer = buf64; });
94661
+ return col;
94662
+ }
94663
+ exports.unpackCollection = unpackCollection;
94664
+
94665
+
94520
94666
  /***/ }),
94521
94667
 
94522
94668
  /***/ "./lib/polylabel.ts":
@@ -94728,7 +94874,7 @@ function polyPackEachRing(pack, cb) {
94728
94874
  let b = pack.buffer;
94729
94875
  let iRing;
94730
94876
  let iOffset = pack.offset;
94731
- let cOffset = b[iOffset + 1];
94877
+ let cOffset = b[iOffset + 1] + pack.offset;
94732
94878
  // Grab number of polygons
94733
94879
  let nPoly = b[iOffset++];
94734
94880
  // Move past header length
@@ -94805,7 +94951,7 @@ function polyPack(coords, prepack) {
94805
94951
  af[z++] = p[j].length;
94806
94952
  }
94807
94953
  // set header size back in header
94808
- af[prepack.offset + 1] = z;
94954
+ af[prepack.offset + 1] = z - prepack.offset;
94809
94955
  // Fill in coords
94810
94956
  for (i = 0; i < coords.length; i++) {
94811
94957
  p = coords[i];
@@ -94831,7 +94977,7 @@ function polyUnpack(prepack) {
94831
94977
  let coords = [];
94832
94978
  let h = prepack.offset;
94833
94979
  nPolys = af[h++];
94834
- let z = af[h++]; // start of coordinates
94980
+ let z = af[h++] + prepack.offset; // start of coordinates
94835
94981
  for (i = 0; i < nPolys; i++) {
94836
94982
  p = [];
94837
94983
  coords[i] = p;
@@ -95099,6 +95245,7 @@ class FsmQuadTree extends FSM.Fsm {
95099
95245
  constructor(env, options, col) {
95100
95246
  super(env);
95101
95247
  this.options = Util.shallowAssignImmutable(Poly.DefaultTickOptions, options);
95248
+ this.work = { nUnion: 0, nDifference: 0, ms: 0 };
95102
95249
  this.initialize(col);
95103
95250
  }
95104
95251
  initialize(col) {
@@ -95107,6 +95254,7 @@ class FsmQuadTree extends FSM.Fsm {
95107
95254
  this.isempty = true;
95108
95255
  if (col != null) {
95109
95256
  let features = col.features ? col.features : col;
95257
+ this.work.nUnion = features.length;
95110
95258
  this.isempty = features.length == 0;
95111
95259
  // Compute BoundBox for each feature
95112
95260
  let wrapped = features.map((f) => { return { box: BB.boundbox(f), p: featureCoords(f) }; });
@@ -95134,11 +95282,13 @@ class FsmQuadTree extends FSM.Fsm {
95134
95282
  break;
95135
95283
  case FSM.FSM_PENDING:
95136
95284
  let tickCounter = { ticks: this.options.tickStep };
95285
+ let elapsed = new Util.Elapsed();
95137
95286
  if (!this.isempty && this.asyncUnion === undefined) {
95138
95287
  this.quad.tickUnion(tickCounter);
95139
95288
  if (tickCounter.ticks != 0)
95140
95289
  this.result;
95141
95290
  }
95291
+ this.work.ms += elapsed.ms();
95142
95292
  if (this.asyncUnion !== undefined)
95143
95293
  this.setState(FSM.FSM_DONE);
95144
95294
  else
@@ -95316,6 +95466,7 @@ exports.polyIntersects = polyIntersects;
95316
95466
  class FsmDifference extends FSM.Fsm {
95317
95467
  constructor(env, accum, polys) {
95318
95468
  super(env);
95469
+ this.work = { nUnion: 0, nDifference: 0, ms: 0 };
95319
95470
  this.initialize(accum, polys);
95320
95471
  }
95321
95472
  initialize(accum, polys) {
@@ -95323,8 +95474,10 @@ class FsmDifference extends FSM.Fsm {
95323
95474
  this.polys = polys;
95324
95475
  if (polys == null || polys.length == 0)
95325
95476
  this.setState(FSM.FSM_DONE);
95326
- else
95477
+ else {
95478
+ this.work.nDifference = polys.length;
95327
95479
  this.setState(FSM.FSM_STARTING);
95480
+ }
95328
95481
  }
95329
95482
  cancel() {
95330
95483
  this.accum = null;
@@ -95344,7 +95497,9 @@ class FsmDifference extends FSM.Fsm {
95344
95497
  this.setState(FSM_COMPUTING);
95345
95498
  break;
95346
95499
  case FSM_COMPUTING:
95500
+ let elapsed = new Util.Elapsed();
95347
95501
  this.accum = _difference(this.accum, this.polys);
95502
+ this.work.ms = elapsed.ms();
95348
95503
  this.polys = null;
95349
95504
  this.setState(FSM.FSM_DONE);
95350
95505
  break;
@@ -95421,10 +95576,20 @@ class FsmIncrementalUnion extends FSM.Fsm {
95421
95576
  if (this.toSub.length == 0)
95422
95577
  this.toSub = null;
95423
95578
  }
95424
- this.fsmUnion = new Q.FsmQuadTree(this.env, this.options, polys);
95425
- this.waitOn(this.fsmUnion);
95426
- this.setState(FSM_UNION);
95427
- this.map = map;
95579
+ // Short-circuit when no work to be done
95580
+ if (polys.length == 1 && this.toSub == null && this.lastCompleteResult) {
95581
+ this.work = { nUnion: 0, nDifference: 0, ms: 0 };
95582
+ this.result = this.lastCompleteResult;
95583
+ this.map = this.lastCompleteMap;
95584
+ this.setState(FSM.FSM_DONE);
95585
+ }
95586
+ else {
95587
+ this.work = { nUnion: polys.length - 1, nDifference: this.toSub ? this.toSub.length : 0, ms: 0 };
95588
+ this.fsmUnion = new Q.FsmQuadTree(this.env, this.options, polys);
95589
+ this.waitOn(this.fsmUnion);
95590
+ this.setState(FSM_UNION);
95591
+ this.map = map;
95592
+ }
95428
95593
  }
95429
95594
  cancel() {
95430
95595
  if (this.fsmUnion) {
@@ -95449,6 +95614,8 @@ class FsmIncrementalUnion extends FSM.Fsm {
95449
95614
  this.setState(FSM.FSM_DONE);
95450
95615
  break;
95451
95616
  case FSM_UNION:
95617
+ if (this.fsmUnion)
95618
+ this.work.ms += this.fsmUnion.work.ms;
95452
95619
  this.fsmDifference = new FsmDifference(this.env, this.fsmUnion.result, this.toSub);
95453
95620
  this.waitOn(this.fsmDifference);
95454
95621
  this.toSub = null;
@@ -95457,6 +95624,7 @@ class FsmIncrementalUnion extends FSM.Fsm {
95457
95624
  break;
95458
95625
  case FSM_DIFFERENCE:
95459
95626
  this.result = this.fsmDifference.result;
95627
+ this.work.ms += this.fsmDifference.work.ms;
95460
95628
  this.lastCompleteResult = this.result;
95461
95629
  this.lastCompleteMap = this.map;
95462
95630
  this.fsmDifference = null;
@@ -95471,10 +95639,11 @@ class FsmUnion extends FSM.Fsm {
95471
95639
  super(env);
95472
95640
  this.options = Util.shallowAssignImmutable(Poly.DefaultTickOptions, options);
95473
95641
  this.unions = [];
95642
+ this.work = { nUnion: 0, nDifference: 0, ms: 0 };
95474
95643
  }
95475
95644
  get result() {
95476
95645
  if (this.unions.length > 0 && this.state === FSM.FSM_DONE)
95477
- return this.unions.map((i) => ({ key: i.key, poly: i.result }));
95646
+ return this.unions.map((i) => ({ key: i.key, poly: i.result, work: i.work }));
95478
95647
  else
95479
95648
  return null;
95480
95649
  }
@@ -95485,6 +95654,15 @@ class FsmUnion extends FSM.Fsm {
95485
95654
  this.unions = [];
95486
95655
  this.setState(FSM.FSM_DONE);
95487
95656
  }
95657
+ cancelOne(key) {
95658
+ for (let i = 0; i < this.unions.length; i++) {
95659
+ let u = this.unions[i];
95660
+ if (u.matches(key)) {
95661
+ u.cancel();
95662
+ return;
95663
+ }
95664
+ }
95665
+ }
95488
95666
  recompute(key, map) {
95489
95667
  let fsm = this.unions.find((i) => i.matches(key));
95490
95668
  if (fsm == null) {
@@ -95493,6 +95671,8 @@ class FsmUnion extends FSM.Fsm {
95493
95671
  }
95494
95672
  else
95495
95673
  fsm.recompute(map);
95674
+ this.work = { nUnion: 0, nDifference: 0, ms: 0 };
95675
+ this.unions.forEach((u) => { this.work.nUnion += u.work.nUnion; this.work.nDifference += u.work.nDifference; });
95496
95676
  this.waitOn(fsm);
95497
95677
  this.setState(FSM_COMPUTING);
95498
95678
  }
@@ -95501,6 +95681,8 @@ class FsmUnion extends FSM.Fsm {
95501
95681
  switch (this.state) {
95502
95682
  case FSM.FSM_STARTING:
95503
95683
  case FSM_COMPUTING:
95684
+ if (this.unions)
95685
+ this.unions.forEach((u) => { this.work.ms += u.work.ms; });
95504
95686
  this.setState(FSM.FSM_DONE);
95505
95687
  break;
95506
95688
  }
@@ -98068,6 +98250,17 @@ module.exports = __webpack_require__(/*! @dra2020/fsm */ "./node_modules/@dra202
98068
98250
 
98069
98251
  module.exports = __webpack_require__(/*! @dra2020/util */ "./node_modules/@dra2020/util/dist/util.js");
98070
98252
 
98253
+ /***/ }),
98254
+
98255
+ /***/ "util":
98256
+ /*!***********************!*\
98257
+ !*** external "util" ***!
98258
+ \***********************/
98259
+ /*! no static exports found */
98260
+ /***/ (function(module, exports) {
98261
+
98262
+ module.exports = __webpack_require__(/*! util */ "util");
98263
+
98071
98264
  /***/ })
98072
98265
 
98073
98266
  /******/ });
@@ -103221,6 +103414,8 @@ class Features {
103221
103414
  this._session = s;
103222
103415
  this._data = data;
103223
103416
  this._keys = keys;
103417
+ // For debugging PVI
103418
+ // console.log("Election dataset =", this._keys[Dataset.ELECTION]);
103224
103419
  }
103225
103420
  nFeatures() { return this._data.features.length; }
103226
103421
  featureByIndex(i) { return this._data.features[i]; }
@@ -103231,8 +103426,15 @@ class Features {
103231
103426
  return value;
103232
103427
  }
103233
103428
  fieldForFeature(f, dt, fk) {
103234
- let dk = this._keys[dt];
103235
- return _getFeatures(f, dk, fk);
103429
+ const dk = this._keys[dt];
103430
+ let result = undefined;
103431
+ // 07-31-2020 - Fix to post-process PVI into the expected election composite format.
103432
+ if (dk === 'P16GPR') {
103433
+ result = (_getFeatures(f, dk, (fk === 'D' ? 'D12' : 'R12')) + _getFeatures(f, dk, (fk === 'D' ? 'D16' : 'R16'))) / 2;
103434
+ }
103435
+ else
103436
+ result = _getFeatures(f, dk, fk);
103437
+ return result;
103236
103438
  }
103237
103439
  resetDataset(d, k) {
103238
103440
  this._keys[d] = k;
@@ -105051,12 +105253,16 @@ const S = __importStar(__webpack_require__(/*! ../src/settings */ "./src/setting
105051
105253
  const D = __importStar(__webpack_require__(/*! ../src/_data */ "./src/_data.ts"));
105052
105254
  // Simulate DRA unioning district shapes in the background
105053
105255
  function addToPoly(poly, polys) {
105054
- // TODO - POLY: Fix 'poly' import, so I don't have to do this workaround.
105055
- // return PC.union(poly, ...polys);
105056
- let union = PC.union;
105057
- if (union === undefined)
105058
- union = PC.default.union;
105059
- return union(poly, ...polys);
105256
+ // Terry's workaround
105257
+ let _union = undefined;
105258
+ let anyPC = PC;
105259
+ if (anyPC.union)
105260
+ _union = anyPC.union;
105261
+ if (anyPC.default.union)
105262
+ _union = anyPC.default.union;
105263
+ if (_union === undefined)
105264
+ throw 'Unable to load union function from polygon-clipping';
105265
+ return _union(poly, ...polys);
105060
105266
  }
105061
105267
  console.log("Starting command @ ", new Date());
105062
105268
  // COMMAND LINE
@@ -105500,6 +105706,17 @@ module.exports = require("stream");
105500
105706
 
105501
105707
  /***/ }),
105502
105708
 
105709
+ /***/ "util":
105710
+ /*!***********************!*\
105711
+ !*** external "util" ***!
105712
+ \***********************/
105713
+ /*! no static exports found */
105714
+ /***/ (function(module, exports) {
105715
+
105716
+ module.exports = require("util");
105717
+
105718
+ /***/ }),
105719
+
105503
105720
  /***/ "yargs":
105504
105721
  /*!************************!*\
105505
105722
  !*** external "yargs" ***!