@dra2020/district-analytics 15.4.6 → 15.6.1

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.
@@ -440,74 +440,76 @@ class Districts {
440
440
  bNotEmpty = true;
441
441
  // ... loop over the geoIDs creating district-by-district statistics
442
442
  geoIDs.forEach(function (geoID) {
443
- // Skip water-only features
444
- if (!(U.isWaterOnly(geoID))) {
445
- // Map from geoID to feature index
446
- let featureID = outerThis._session.features.featureID(geoID);
447
- let f = outerThis._session.features.featureByIndex(featureID);
448
- if (f == undefined) {
449
- if (bLog)
450
- console.log("Statistics: Skipping undefined feature in district statistics: GEOID =", geoID, "Feature ID =", featureID);
443
+ // 01-04-22 -- Removed water-only guard
444
+ // // Skip water-only features
445
+ // if (!(U.isWaterOnly(geoID)))
446
+ // {
447
+ // Map from geoID to feature index
448
+ let featureID = outerThis._session.features.featureID(geoID);
449
+ let f = outerThis._session.features.featureByIndex(featureID);
450
+ if (f == undefined) {
451
+ if (bLog)
452
+ console.log("Statistics: Skipping undefined feature in district statistics: GEOID =", geoID, "Feature ID =", featureID);
453
+ }
454
+ else {
455
+ // ACCUMULATE VALUES
456
+ // Total population of each feature
457
+ // NOTE - This result is used more than once
458
+ // 03-27-21
459
+ const dkCENSUS = outerThis._session.features._keys["CENSUS" /* CENSUS */];
460
+ featurePop = fieldForFeature(f, dkCENSUS, 0 /* TotalPop */);
461
+ // featurePop = outerThis._session.features.fieldForFeature(f, T.Dataset.CENSUS, T.FeatureField.TotalPop);
462
+ // Total district population
463
+ totalPop += featurePop;
464
+ // Ignore features when the county is unrecognized
465
+ const countyFIPS = U.parseGeoID(geoID)['county'];
466
+ if (U.keyExists(countyFIPS, outerThis._session.counties.index)) {
467
+ // Total population by counties w/in a district,
468
+ // except the dummy unassigned district 0
469
+ if (i > 0)
470
+ countySplits[outerThis.getCountyIndex(geoID)] += featurePop;
451
471
  }
452
472
  else {
453
- // ACCUMULATE VALUES
454
- // Total population of each feature
455
- // NOTE - This result is used more than once
456
- // 03-27-21
457
- const dkCENSUS = outerThis._session.features._keys["CENSUS" /* CENSUS */];
458
- featurePop = fieldForFeature(f, dkCENSUS, 0 /* TotalPop */);
459
- // featurePop = outerThis._session.features.fieldForFeature(f, T.Dataset.CENSUS, T.FeatureField.TotalPop);
460
- // Total district population
461
- totalPop += featurePop;
462
- // Ignore features when the county is unrecognized
463
- const countyFIPS = U.parseGeoID(geoID)['county'];
464
- if (U.keyExists(countyFIPS, outerThis._session.counties.index)) {
465
- // Total population by counties w/in a district,
466
- // except the dummy unassigned district 0
467
- if (i > 0)
468
- countySplits[outerThis.getCountyIndex(geoID)] += featurePop;
469
- }
470
- else {
471
- if (bLog)
472
- console.log("Statistics: County not recognized:", geoID);
473
- }
474
- // Democratic and Republican vote totals
475
- // 10-22-2020 - Added Other votes
476
- // 10-24-2020 - Added guard against inconsistent election data
477
- // 03-27-2021
478
- const dkELECTION = outerThis._session.features._keys["ELECTION" /* ELECTION */];
479
- const featureDem = fieldForFeature(f, dkELECTION, 7 /* DemVotes */);
480
- // const featureDem = outerThis._session.features.fieldForFeature(f, T.Dataset.ELECTION, T.FeatureField.DemVotes);
481
- const featureRep = fieldForFeature(f, dkELECTION, 8 /* RepVotes */);
482
- const featureTot = fieldForFeature(f, dkELECTION, 9 /* TotalVotes */);
483
- demVotes += featureDem;
484
- repVotes += featureRep;
485
- totVotes += featureTot;
486
- // NOTE: Unless you grab the values above before accumulating them,
487
- // you can't accumulate othVotes for districts. You must calculate
488
- // them by implication later.
489
- if (bLog) {
490
- const bBadElection = (featureDem + featureRep > featureTot) ? true : false;
491
- if (bBadElection)
492
- console.log("Statistics: Inconsistent election data for precinct:", geoID, featureDem, featureRep, featureTot);
493
- }
494
- // Voting-age demographic breakdowns (or citizen voting-age)
495
- // 03-27-21
496
- const dkVAP = outerThis._session.features._keys["VAP" /* VAP */];
497
- totalVAP += fieldForFeature(f, dkVAP, 0 /* TotalPop */);
498
- // totalVAP += outerThis._session.features.fieldForFeature(f, T.Dataset.VAP, T.FeatureField.TotalPop);
499
- whitePop += fieldForFeature(f, dkVAP, 1 /* WhitePop */);
500
- blackPop += fieldForFeature(f, dkVAP, 2 /* BlackPop */);
501
- hispanicPop += fieldForFeature(f, dkVAP, 3 /* HispanicPop */);
502
- pacificPop += fieldForFeature(f, dkVAP, 5 /* PacificPop */);
503
- asianPop += fieldForFeature(f, dkVAP, 4 /* AsianPop */);
504
- nativePop += fieldForFeature(f, dkVAP, 6 /* NativePop */);
473
+ if (bLog)
474
+ console.log("Statistics: County not recognized:", geoID);
505
475
  }
476
+ // Democratic and Republican vote totals
477
+ // 10-22-2020 - Added Other votes
478
+ // 10-24-2020 - Added guard against inconsistent election data
479
+ // 03-27-2021
480
+ const dkELECTION = outerThis._session.features._keys["ELECTION" /* ELECTION */];
481
+ const featureDem = fieldForFeature(f, dkELECTION, 7 /* DemVotes */);
482
+ // const featureDem = outerThis._session.features.fieldForFeature(f, T.Dataset.ELECTION, T.FeatureField.DemVotes);
483
+ const featureRep = fieldForFeature(f, dkELECTION, 8 /* RepVotes */);
484
+ const featureTot = fieldForFeature(f, dkELECTION, 9 /* TotalVotes */);
485
+ demVotes += featureDem;
486
+ repVotes += featureRep;
487
+ totVotes += featureTot;
488
+ // NOTE: Unless you grab the values above before accumulating them,
489
+ // you can't accumulate othVotes for districts. You must calculate
490
+ // them by implication later.
491
+ if (bLog) {
492
+ const bBadElection = (featureDem + featureRep > featureTot) ? true : false;
493
+ if (bBadElection)
494
+ console.log("Statistics: Inconsistent election data for precinct:", geoID, featureDem, featureRep, featureTot);
495
+ }
496
+ // Voting-age demographic breakdowns (or citizen voting-age)
497
+ // 03-27-21
498
+ const dkVAP = outerThis._session.features._keys["VAP" /* VAP */];
499
+ totalVAP += fieldForFeature(f, dkVAP, 0 /* TotalPop */);
500
+ // totalVAP += outerThis._session.features.fieldForFeature(f, T.Dataset.VAP, T.FeatureField.TotalPop);
501
+ whitePop += fieldForFeature(f, dkVAP, 1 /* WhitePop */);
502
+ blackPop += fieldForFeature(f, dkVAP, 2 /* BlackPop */);
503
+ hispanicPop += fieldForFeature(f, dkVAP, 3 /* HispanicPop */);
504
+ pacificPop += fieldForFeature(f, dkVAP, 5 /* PacificPop */);
505
+ asianPop += fieldForFeature(f, dkVAP, 4 /* AsianPop */);
506
+ nativePop += fieldForFeature(f, dkVAP, 6 /* NativePop */);
506
507
  }
507
- else {
508
- if (bLog)
509
- console.log("Statistics: Skipping water-only feature in district statistics:", geoID);
510
- }
508
+ // }
509
+ // else
510
+ // {
511
+ // if (bLog) console.log("Statistics: Skipping water-only feature in district statistics:", geoID);
512
+ // }
511
513
  });
512
514
  // COMPUTE DERIVED VALUES
513
515
  // Population deviation % and equal population (boolean) by district.
@@ -998,47 +1000,75 @@ exports.fieldForFeature = fieldForFeature;
998
1000
  // f is a direct GeoJSON feature
999
1001
  // p is a geoID
1000
1002
  function _getFeatures(f, datasetKey, p) {
1001
- // Shim to load sample data2.json from disk for command-line scaffolding
1002
- if (f.properties && f.properties['datasets']) {
1003
- if (!f.properties['datasets'][datasetKey]) {
1004
- // Feature is missing the dataset
1005
- nMissingDataset += 1;
1006
- // console.log(`${nMissingDataset}: Data ${datasetKey} missing for feature ${f} Returning zero.`);
1007
- return 0;
1003
+ if (!f.properties || !f.properties.datasets)
1004
+ return 0;
1005
+ if (datasetKey && !f.properties.datasets[datasetKey])
1006
+ return 0;
1007
+ let n = datasetKey ? f.properties.datasets[datasetKey][p] : f.properties[p];
1008
+ return !n || isNaN(n) ? 0 : n;
1009
+ }
1010
+ /* 01-04-22 -- Replaced with the above
1011
+ function _getFeatures(f: any, datasetKey: string, p: string): any
1012
+ {
1013
+ // Shim to load sample data2.json from disk for command-line scaffolding
1014
+ if (f.properties && f.properties['datasets'])
1015
+ {
1016
+ if (!f.properties['datasets'][datasetKey])
1017
+ {
1018
+ // Feature is missing the dataset
1019
+ nMissingDataset += 1;
1020
+ // console.log(`${nMissingDataset}: Data ${datasetKey} missing for feature ${f} Returning zero.`);
1021
+
1022
+ return 0;
1023
+ }
1024
+
1025
+ return f.properties['datasets'][datasetKey][p];
1026
+ }
1027
+
1028
+ // NOTE - The fGetW() code from dra-client below here ...
1029
+
1030
+ // Direct property?
1031
+ if (f.properties && f.properties[p] !== undefined)
1032
+ {
1033
+ return f.properties[p];
1034
+ }
1035
+
1036
+ // Joined property?
1037
+ let a: any[] = _fGetJoined(f);
1038
+ if (a)
1039
+ {
1040
+ for (let i: number = 0; i < a.length; i++)
1041
+ {
1042
+ let o: any = a[i];
1043
+ if (!datasetKey)
1044
+ {
1045
+ if (o[p] !== undefined)
1046
+ {
1047
+ return o[p];
1008
1048
  }
1009
- return f.properties['datasets'][datasetKey][p];
1010
- }
1011
- // NOTE - The fGetW() code from dra-client below here ...
1012
- // Direct property?
1013
- if (f.properties && f.properties[p] !== undefined) {
1014
- return f.properties[p];
1015
- }
1016
- // Joined property?
1017
- let a = _fGetJoined(f);
1018
- if (a) {
1019
- for (let i = 0; i < a.length; i++) {
1020
- let o = a[i];
1021
- if (!datasetKey) {
1022
- if (o[p] !== undefined) {
1023
- return o[p];
1024
- }
1025
- }
1026
- else {
1027
- if (o['datasets'] && o['datasets'][datasetKey]) {
1028
- let v = (o['datasets'][datasetKey][p]);
1029
- if ((!(v == null)) && (!(v == undefined))) {
1030
- return o['datasets'][datasetKey][p];
1031
- }
1032
- }
1033
- }
1049
+ }
1050
+ else
1051
+ {
1052
+ if (o['datasets'] && o['datasets'][datasetKey])
1053
+ {
1054
+ let v = (o['datasets'][datasetKey][p]);
1055
+ if ((!(v == null)) && (!(v == undefined)))
1056
+ {
1057
+ return o['datasets'][datasetKey][p];
1058
+ }
1034
1059
  }
1060
+ }
1035
1061
  }
1036
- // Feature is missing the property
1037
- nMissingProperty += 1;
1038
- // console.log(`${nMissingProperty}: ${p} value undefined for ${f.properties['GEOID10']}. Returning zero.`);
1039
- return 0;
1040
- // return undefined;
1062
+ }
1063
+
1064
+ // Feature is missing the property
1065
+ nMissingProperty += 1;
1066
+ // console.log(`${nMissingProperty}: ${p} value undefined for ${f.properties['GEOID10']}. Returning zero.`);
1067
+
1068
+ return 0;
1069
+ // return undefined;
1041
1070
  }
1071
+ */
1042
1072
  function _fGetJoined(f) {
1043
1073
  return (f.properties && f.properties.joined) ? f.properties.joined : undefined;
1044
1074
  }
@@ -1598,7 +1628,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
1598
1628
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1599
1629
  };
1600
1630
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1601
- exports.uncertaintyOfMembership = exports.effectiveSplits = exports.avgSVError = exports.isAntimajoritarian = exports.ratePartisanBias = exports.estSeatProbability = exports.inferSelectedMinority = exports.fieldForFeature = exports.geoIDForFeature = void 0;
1631
+ exports.uncertaintyOfMembership = exports.effectiveSplits = exports.avgSVError = exports.isAntimajoritarian = exports.normalizePartisanBias = exports.ratePartisanBias = exports.estSeatProbability = exports.inferSelectedMinority = exports.fieldForFeature = exports.geoIDForFeature = void 0;
1602
1632
  __exportStar(__webpack_require__(/*! ./_api */ "./src/_api.ts"), exports);
1603
1633
  var _data_1 = __webpack_require__(/*! ./_data */ "./src/_data.ts");
1604
1634
  Object.defineProperty(exports, "geoIDForFeature", ({ enumerable: true, get: function () { return _data_1.geoIDForFeature; } }));
@@ -1611,6 +1641,7 @@ __exportStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"), exports);
1611
1641
  const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
1612
1642
  exports.estSeatProbability = dra_analytics_1.Partisan.estSeatProbability;
1613
1643
  exports.ratePartisanBias = dra_analytics_1.Rate.ratePartisanBias;
1644
+ exports.normalizePartisanBias = dra_analytics_1.Rate.normalizePartisanBias;
1614
1645
  exports.isAntimajoritarian = dra_analytics_1.Rate.isAntimajoritarian;
1615
1646
  exports.avgSVError = dra_analytics_1.Partisan.avgSVError;
1616
1647
  exports.effectiveSplits = dra_analytics_1.Splitting.effectiveSplits;