@dra2020/district-analytics 2.0.4 → 2.0.5

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.
@@ -139,6 +139,13 @@ class AnalyticsSession {
139
139
  this.features = new D.Features(this, SessionRequest['data'], this.config['datasets']);
140
140
  this.plan = new D.Plan(this, SessionRequest['plan']);
141
141
  this.districts = new D.Districts(this, SessionRequest['districtShapes']);
142
+ // TODO - Confirming that the graph includes OUT_OF_STATE neighbors
143
+ // if (U.keyExists(S.OUT_OF_STATE, this.graph._graph)) {
144
+ // console.log("Contiguity graph includes out-of-state neighbors.");
145
+ // }
146
+ // else {
147
+ // console.log("Contiguity graph does NOT include out-of-state neighbors.");
148
+ // }
142
149
  // NOTE: I've pulled these out of the individual analytics to here. Eventually,
143
150
  // we could want them to passed into an analytics session as data, along with
144
151
  // everything else. For now, this keeps branching out of the main code.
@@ -248,6 +255,9 @@ const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"
248
255
  const valid_1 = __webpack_require__(/*! ./valid */ "./src/valid.ts");
249
256
  const compact_1 = __webpack_require__(/*! ./compact */ "./src/compact.ts");
250
257
  const political_1 = __webpack_require__(/*! ./political */ "./src/political.ts");
258
+ // DEBUG COUNTERS
259
+ let nMissingDataset = 0;
260
+ let nMissingProperty = 0;
251
261
  // DISTRICT STATISTICS
252
262
  // Indexes for statistics fields in Districts
253
263
  // NOTE - Not a const, so the number can be determined dynamically
@@ -332,6 +342,9 @@ class Districts {
332
342
  // TODO - OPTIMIZE by async'ing this?
333
343
  // TODO - Is there a way to do this programmatically off data? Does it matter?
334
344
  recalcStatistics(bLog = false) {
345
+ // Initialize debug counters
346
+ nMissingDataset = 0;
347
+ nMissingProperty = 0;
335
348
  // Compute these once per recalc cycle
336
349
  let targetSize = this._session.state.totalPop / this._session.state.nDistricts;
337
350
  let deviationThreshold = this._session.populationDeviationThreshold();
@@ -569,6 +582,8 @@ class Districts {
569
582
  this.statistics[DistrictField.AsianPct][summaryRow] = stateAsianPop / stateVAPPop;
570
583
  this.statistics[DistrictField.NativePct][summaryRow] = stateNativePop / stateVAPPop;
571
584
  }
585
+ console.log(`${nMissingDataset} features with missing datasets.`);
586
+ console.log(`${nMissingProperty} features with missing properties.`);
572
587
  }
573
588
  // NOTE - I did not roll these into district statistics, because creating the
574
589
  // district shapes themselves is the big district-by-district activity, these
@@ -623,36 +638,46 @@ exports.Features = Features;
623
638
  // f is a direct GeoJSON feature
624
639
  // p is a geoID
625
640
  function _getFeatures(f, datasetKey, p) {
626
- // Echo parameters for debugging
627
- // console.log("f =", f, "k = ", datasetKey, "p =", p);
628
641
  // Shim to load sample data2.json from disk for command-line scaffolding
629
642
  if (f.properties && f.properties['datasets']) {
643
+ if (!f.properties['datasets'][datasetKey]) {
644
+ // Feature is missing the dataset
645
+ nMissingDataset += 1;
646
+ console.log(`${nMissingDataset}: Data ${datasetKey} missing for feature ${f} Returning zero.`);
647
+ return 0;
648
+ }
630
649
  return f.properties['datasets'][datasetKey][p];
631
650
  }
632
651
  // NOTE - The fGetW() code from dra-client below here ...
633
652
  // Direct property?
634
- if (f.properties && f.properties[p] !== undefined)
653
+ if (f.properties && f.properties[p] !== undefined) {
635
654
  return f.properties[p];
655
+ }
636
656
  // Joined property?
637
657
  let a = _fGetJoined(f);
638
658
  if (a) {
639
659
  for (let i = 0; i < a.length; i++) {
640
660
  let o = a[i];
641
661
  if (!datasetKey) {
642
- if (o[p] !== undefined)
662
+ if (o[p] !== undefined) {
643
663
  return o[p];
664
+ }
644
665
  }
645
666
  else {
646
667
  if (o['datasets'] && o['datasets'][datasetKey]) {
647
668
  let v = (o['datasets'][datasetKey][p]);
648
- if ((!(v == null)) && (!(v == undefined)))
669
+ if ((!(v == null)) && (!(v == undefined))) {
649
670
  return o['datasets'][datasetKey][p];
671
+ }
650
672
  }
651
673
  }
652
674
  }
653
675
  }
654
- console.log(`${p} value undefined for ${f.properties['GEOID10']}!`);
655
- return undefined;
676
+ // Feature is missing the property
677
+ nMissingProperty += 1;
678
+ console.log(`${nMissingProperty}: ${p} value undefined for ${f.properties['GEOID10']}. Returning zero.`);
679
+ return 0;
680
+ // return undefined;
656
681
  }
657
682
  function _fGetJoined(f) {
658
683
  return (f.properties && f.properties.joined) ? f.properties.joined : undefined;
@@ -697,6 +722,7 @@ class Plan {
697
722
  }
698
723
  // NOTE - DON'T remove water-only features from the plan, as they may be required
699
724
  // for contiguity. Just skip them in aggregating district statistics.
725
+ //
700
726
  // removeWaterOnlyFeatures(plan: T.PlanByGeoID): T.PlanByGeoID {
701
727
  // let newPlan = {} as T.PlanByGeoID;
702
728
  // for (let geoID in plan) {
@@ -1200,7 +1226,7 @@ exports.doFindCountiesSplitUnexpectedly = doFindCountiesSplitUnexpectedly;
1200
1226
  function doFindSplitVTDs(s, bLog = false) {
1201
1227
  let test = s.getTest(10 /* VTDSplits */);
1202
1228
  let splitVTDs = [];
1203
- // TODO - SPLITTING: Flesh this out, using Terry's virtual VTD's ...
1229
+ // TODO - SPLITTING: Flesh this out, using virtual VTD's ...
1204
1230
  test['score'] = splitVTDs.length;
1205
1231
  test['details']['splitVTDs'] = splitVTDs;
1206
1232
  return test;
@@ -1860,9 +1886,9 @@ function doPreprocessCensus(s, bLog = false) {
1860
1886
  // Sum total population by county
1861
1887
  totalByCounty[countyFIPS] += value;
1862
1888
  }
1863
- // else {
1864
- // console.log("Skipping water-only feature in Census preprocessing:", geoID);
1865
- // }
1889
+ else {
1890
+ console.log("Skipping water-only feature in Census preprocessing:", geoID);
1891
+ }
1866
1892
  }
1867
1893
  // NOTE - The above could be replaced, if I got totals on county.geojson.
1868
1894
  // CREATE A FIPS CODE-ORDINAL MAP