@dra2020/district-analytics 1.0.4 → 1.0.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/.prettierrc +5 -0
- package/dist/_api.d.ts +27 -0
- package/dist/_data.d.ts +130 -0
- package/dist/analyze.d.ts +4 -0
- package/dist/cli.js +12091 -0
- package/dist/cli.js.map +1 -0
- package/dist/cohesive.d.ts +4 -0
- package/dist/compact.d.ts +5 -0
- package/dist/constants.d.ts +6 -0
- package/dist/district-analytics.js +102 -52
- package/dist/district-analytics.js.map +1 -0
- package/dist/equal.d.ts +4 -0
- package/dist/geofeature.d.ts +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/minority.d.ts +3 -0
- package/dist/political.d.ts +8 -0
- package/dist/preprocess.d.ts +2 -0
- package/dist/report.d.ts +15 -0
- package/dist/settings.d.ts +5 -0
- package/dist/test/_cli.d.ts +5 -0
- package/dist/types.d.ts +110 -0
- package/dist/utils.d.ts +28 -0
- package/dist/valid.d.ts +8 -0
- package/jestconfig.json +14 -0
- package/lib/HelloWorld.d.ts +3 -0
- package/lib/HelloWorld.js +11 -0
- package/lib/_api.js +91 -0
- package/lib/_api.js.map +1 -0
- package/lib/_cli.js +434 -0
- package/lib/_cli.js.map +1 -0
- package/lib/_data.js +425 -0
- package/lib/_data.js.map +1 -0
- package/lib/analyze.d.ts +3 -0
- package/lib/analyze.js +69 -0
- package/lib/analyze.js.map +1 -0
- package/lib/api.d.ts +34 -0
- package/lib/api.js +117 -0
- package/lib/api.js.map +1 -0
- package/lib/cli.d.ts +1 -0
- package/lib/cli.js +386 -0
- package/lib/cli.js.map +1 -0
- package/lib/cohesive.d.ts +4 -0
- package/lib/cohesive.js +132 -0
- package/lib/cohesive.js.map +1 -0
- package/lib/compact.d.ts +4 -0
- package/lib/compact.js +183 -0
- package/lib/compact.js.map +1 -0
- package/lib/constants.js +367 -0
- package/lib/constants.js.map +1 -0
- package/lib/data.js +188 -0
- package/lib/data.js.map +1 -0
- package/lib/equal.d.ts +4 -0
- package/lib/equal.js +59 -0
- package/lib/equal.js.map +1 -0
- package/lib/features.js +19 -0
- package/lib/features.js.map +1 -0
- package/lib/geofeature.js +112 -0
- package/lib/geofeature.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/minority.d.ts +3 -0
- package/lib/minority.js +61 -0
- package/lib/minority.js.map +1 -0
- package/lib/political.d.ts +7 -0
- package/lib/political.js +88 -0
- package/lib/political.js.map +1 -0
- package/lib/preprocess.d.ts +4 -0
- package/lib/preprocess.js +101 -0
- package/lib/preprocess.js.map +1 -0
- package/lib/report.d.ts +14 -0
- package/lib/report.js +817 -0
- package/lib/report.js.map +1 -0
- package/lib/sample.d.ts +1 -0
- package/lib/sample.js +32 -0
- package/lib/sample.js.map +1 -0
- package/lib/scorecard.d.ts +4 -0
- package/lib/scorecard.js +237 -0
- package/lib/scorecard.js.map +1 -0
- package/lib/settings.d.ts +5 -0
- package/lib/settings.js +18 -0
- package/lib/settings.js.map +1 -0
- package/lib/types.d.ts +125 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/lib/utils.d.ts +20 -0
- package/lib/utils.js +223 -0
- package/lib/utils.js.map +1 -0
- package/lib/valid.d.ts +5 -0
- package/lib/valid.js +230 -0
- package/lib/valid.js.map +1 -0
- package/main.js +4 -0
- package/package.json +2 -7
- package/src/_api.ts +121 -0
- package/src/_data.ts +595 -0
- package/src/analyze.ts +92 -0
- package/src/cohesive.ts +156 -0
- package/src/compact.ts +208 -0
- package/src/constants.ts +371 -0
- package/src/equal.ts +75 -0
- package/src/geofeature.ts +138 -0
- package/src/index.ts +6 -0
- package/src/minority.ts +70 -0
- package/src/political.ts +114 -0
- package/src/preprocess.ts +132 -0
- package/src/report.ts +1022 -0
- package/src/settings.ts +20 -0
- package/src/types.ts +185 -0
- package/src/utils.ts +245 -0
- package/src/valid.ts +275 -0
- package/tsconfig.json +25 -0
- package/tslint.json +3 -0
- package/types/polygon-clipping/index.d.ts +1 -0
- package/webpack.config.js +73 -0
package/lib/data.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// DATA ABSTRACTION LAYER
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const parse = require("csv-parse/lib/sync");
|
|
9
|
+
function nFeatures(s) {
|
|
10
|
+
return s._data.features.length;
|
|
11
|
+
}
|
|
12
|
+
exports.nFeatures = nFeatures;
|
|
13
|
+
function getFeature(s, i) {
|
|
14
|
+
return s._data.features[i];
|
|
15
|
+
}
|
|
16
|
+
exports.getFeature = getFeature;
|
|
17
|
+
function getFeatureID(s, f) {
|
|
18
|
+
return f.properties['GEOID'];
|
|
19
|
+
}
|
|
20
|
+
exports.getFeatureID = getFeatureID;
|
|
21
|
+
// Hide dataset & field key details from the main analytics code
|
|
22
|
+
function getFeatureData(s, f, dt, fk) {
|
|
23
|
+
let dk = s._config['datasets'][dt];
|
|
24
|
+
return _getFeatureData(f, dk, fk);
|
|
25
|
+
}
|
|
26
|
+
exports.getFeatureData = getFeatureData;
|
|
27
|
+
// NOTE - This accessor is cloned from fGetW() in dra-client/restrict.ts
|
|
28
|
+
// f is a direct GeoJSON feature
|
|
29
|
+
// p is a geoID
|
|
30
|
+
function _getFeatureData(f, datasetKey, p) {
|
|
31
|
+
// Shim to load sample data2.json from disk for command-line scaffolding
|
|
32
|
+
if (f.properties && f.properties['datasets']) {
|
|
33
|
+
return f.properties['datasets'][datasetKey][p];
|
|
34
|
+
}
|
|
35
|
+
// NOTE - The fGetW() code from dra-client below here ...
|
|
36
|
+
// Direct property?
|
|
37
|
+
if (f.properties && f.properties[p] !== undefined)
|
|
38
|
+
return f.properties[p];
|
|
39
|
+
// Joined property?
|
|
40
|
+
let a = _fGetJoined(f);
|
|
41
|
+
if (a) {
|
|
42
|
+
for (let i = 0; i < a.length; i++) {
|
|
43
|
+
let o = a[i];
|
|
44
|
+
if (!datasetKey) {
|
|
45
|
+
if (o[p] !== undefined)
|
|
46
|
+
return o[p];
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
if (o['datasets'] && o['datasets'][datasetKey])
|
|
50
|
+
if (o['datasets'][datasetKey][p])
|
|
51
|
+
return o['datasets'][datasetKey][p];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
function _fGetJoined(f) {
|
|
58
|
+
return (f.properties && f.properties.joined) ? f.properties.joined : undefined;
|
|
59
|
+
}
|
|
60
|
+
function getCounties(s) {
|
|
61
|
+
return s._countyFeatures.features;
|
|
62
|
+
}
|
|
63
|
+
exports.getCounties = getCounties;
|
|
64
|
+
function getCountyProperties(f) {
|
|
65
|
+
return f.properties;
|
|
66
|
+
}
|
|
67
|
+
exports.getCountyProperties = getCountyProperties;
|
|
68
|
+
function releaseCounties(s) {
|
|
69
|
+
s._countyFeatures = {};
|
|
70
|
+
}
|
|
71
|
+
exports.releaseCounties = releaseCounties;
|
|
72
|
+
// HELPERS TO LOAD SAMPLE DATA FROM DISK
|
|
73
|
+
// A clone of 'carefulRead' in DRA-CLI
|
|
74
|
+
function readJSONcareful(file) {
|
|
75
|
+
try {
|
|
76
|
+
let s = fs.readFileSync(file, 'utf8');
|
|
77
|
+
let o = JSON.parse(s);
|
|
78
|
+
return o;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
console.log("Error reading JSON file ...");
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.readJSONcareful = readJSONcareful;
|
|
86
|
+
function readJSON(file) {
|
|
87
|
+
let fullPath;
|
|
88
|
+
if (path.isAbsolute(file)) {
|
|
89
|
+
fullPath = file;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
fullPath = path.join(__dirname, file);
|
|
93
|
+
}
|
|
94
|
+
return readJSONcareful(fullPath);
|
|
95
|
+
}
|
|
96
|
+
exports.readJSON = readJSON;
|
|
97
|
+
// Following the clone above, except for CSV, using the csv-parse/sync API
|
|
98
|
+
function readCSV(file) {
|
|
99
|
+
try {
|
|
100
|
+
let input = fs.readFileSync(file, 'utf8');
|
|
101
|
+
let dictRows = parse(input, {
|
|
102
|
+
columns: true,
|
|
103
|
+
skip_empty_lines: true
|
|
104
|
+
});
|
|
105
|
+
return dictRows;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
console.log("Error reading CSV file ...");
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.readCSV = readCSV;
|
|
113
|
+
// Read a plan from a .csv file
|
|
114
|
+
function readPlanCSV(file) {
|
|
115
|
+
var plan = {};
|
|
116
|
+
let fullPath;
|
|
117
|
+
if (path.isAbsolute(file)) {
|
|
118
|
+
fullPath = file;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
fullPath = path.join(__dirname, file);
|
|
122
|
+
}
|
|
123
|
+
var csvArray = readCSV(fullPath);
|
|
124
|
+
for (let dictRow of csvArray) {
|
|
125
|
+
let geoID = dictRow['GEOID'];
|
|
126
|
+
let districtID = Number(dictRow['DISTRICT']);
|
|
127
|
+
// TODO - DISTRICT_ID
|
|
128
|
+
// let districtID: number = dictRow['DISTRICT'];
|
|
129
|
+
plan[geoID] = districtID;
|
|
130
|
+
}
|
|
131
|
+
return plan;
|
|
132
|
+
}
|
|
133
|
+
exports.readPlanCSV = readPlanCSV;
|
|
134
|
+
// Read Census data from a .csv file
|
|
135
|
+
function readCensusCSV(file) {
|
|
136
|
+
var census = {};
|
|
137
|
+
let fullPath;
|
|
138
|
+
if (path.isAbsolute(file)) {
|
|
139
|
+
fullPath = file;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
fullPath = path.join(__dirname, file);
|
|
143
|
+
}
|
|
144
|
+
var csvArray = readCSV(fullPath);
|
|
145
|
+
for (let dictRow of csvArray) {
|
|
146
|
+
let geoID = dictRow['GEOID'];
|
|
147
|
+
let censusSelect = {};
|
|
148
|
+
censusSelect['total'] = Number(dictRow['TOTAL']);
|
|
149
|
+
censusSelect['white'] = Number(dictRow['WHITE']);
|
|
150
|
+
censusSelect['black'] = Number(dictRow['BLACK']);
|
|
151
|
+
censusSelect['hispanic'] = Number(dictRow['HISPANIC']);
|
|
152
|
+
// TODO - INTEGRATION: data2.json - Minority breakdowns
|
|
153
|
+
censusSelect['whiteHispanic'] = 0;
|
|
154
|
+
censusSelect['total18'] = Number(dictRow['TOTAL18']);
|
|
155
|
+
censusSelect['white18'] = Number(dictRow['WHITE18']);
|
|
156
|
+
censusSelect['black18'] = Number(dictRow['BLACK18']);
|
|
157
|
+
censusSelect['hispanic18'] = Number(dictRow['HISPANIC18']);
|
|
158
|
+
// TODO - INTEGRATION: data2.json - Minority breakdowns
|
|
159
|
+
censusSelect['whiteHispanic18'] = 0;
|
|
160
|
+
census[geoID] = censusSelect;
|
|
161
|
+
}
|
|
162
|
+
return census;
|
|
163
|
+
}
|
|
164
|
+
exports.readCensusCSV = readCensusCSV;
|
|
165
|
+
// Read election data from a .csv file
|
|
166
|
+
function readElectionCSV(file) {
|
|
167
|
+
var election = {};
|
|
168
|
+
let fullPath;
|
|
169
|
+
if (path.isAbsolute(file)) {
|
|
170
|
+
fullPath = file;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
fullPath = path.join(__dirname, file);
|
|
174
|
+
}
|
|
175
|
+
var csvArray = readCSV(fullPath);
|
|
176
|
+
for (let dictRow of csvArray) {
|
|
177
|
+
let geoID = dictRow['GEOID'];
|
|
178
|
+
// TODO - This should be '[]', I think.
|
|
179
|
+
let electionSelect = {};
|
|
180
|
+
electionSelect[0 /* Democratic */] = Number(dictRow['DEM']);
|
|
181
|
+
electionSelect[1 /* Republican */] = Number(dictRow['REP']);
|
|
182
|
+
electionSelect[2 /* Total */] = Number(dictRow['TOT']);
|
|
183
|
+
election[geoID] = electionSelect;
|
|
184
|
+
}
|
|
185
|
+
return election;
|
|
186
|
+
}
|
|
187
|
+
exports.readElectionCSV = readElectionCSV;
|
|
188
|
+
//# sourceMappingURL=data.js.map
|
package/lib/data.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
|
package/lib/equal.d.ts
ADDED
package/lib/equal.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// EQUAL POPULATION
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const U = require("./utils");
|
|
7
|
+
const D = require("./_data");
|
|
8
|
+
function doPopulationDeviation(s) {
|
|
9
|
+
let test = s.getTest(4 /* PopulationDeviation */);
|
|
10
|
+
// Compute the min, max, and average district populations,
|
|
11
|
+
// excluding the dummy 'unassigned' 0 and N+1 summary "districts."
|
|
12
|
+
let totPopByDistrict = s.districts.statistics[D.DistrictField.TotalPop];
|
|
13
|
+
totPopByDistrict = totPopByDistrict.slice(1, -1);
|
|
14
|
+
let min = U.minArray(totPopByDistrict);
|
|
15
|
+
let max = U.maxArray(totPopByDistrict);
|
|
16
|
+
let total = U.sumArray(totPopByDistrict);
|
|
17
|
+
// Calculate the raw population deviation.
|
|
18
|
+
// The target size is the average population.
|
|
19
|
+
let avg = total / s.state.nDistricts;
|
|
20
|
+
let popDev = (max - min) / avg;
|
|
21
|
+
// Round the raw value to the desired level of precision
|
|
22
|
+
popDev = U.trim(popDev);
|
|
23
|
+
// Populate the test entry
|
|
24
|
+
test['score'] = popDev;
|
|
25
|
+
test['details'] = { 'maxDeviation': max - min };
|
|
26
|
+
// Populate the N+1 summary "district" in district.statistics
|
|
27
|
+
let totalPop = s.districts.statistics[D.DistrictField.TotalPop];
|
|
28
|
+
let popDevPct = s.districts.statistics[D.DistrictField.PopDevPct];
|
|
29
|
+
let summaryRow = s.districts.numberOfRows() - 1;
|
|
30
|
+
totalPop[summaryRow] = avg; // aka "target size"
|
|
31
|
+
popDevPct[summaryRow] = popDev;
|
|
32
|
+
return test;
|
|
33
|
+
}
|
|
34
|
+
exports.doPopulationDeviation = doPopulationDeviation;
|
|
35
|
+
// NOTE - This validity check is *derived* and depends on population deviation %
|
|
36
|
+
// being computed (above) and normalized in test log & scorecard generation.
|
|
37
|
+
function doHasEqualPopulations(s) {
|
|
38
|
+
let test = s.getTest(3 /* EqualPopulation */);
|
|
39
|
+
// Get the normalized population deviation %
|
|
40
|
+
let popDevTest = s.getTest(4 /* PopulationDeviation */);
|
|
41
|
+
let popDevPct = popDevTest['score'];
|
|
42
|
+
let popDevNormalized = popDevTest['normalizedScore'];
|
|
43
|
+
// Populate the test entry
|
|
44
|
+
if (popDevNormalized > 0) {
|
|
45
|
+
test['score'] = true;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
test['score'] = false;
|
|
49
|
+
}
|
|
50
|
+
test['details']['deviation'] = popDevPct;
|
|
51
|
+
test['details']['thresholds'] = popDevTest['details']['scale'];
|
|
52
|
+
// Populate the N+1 summary "district" in district.statistics
|
|
53
|
+
let bEqualPop = s.districts.statistics[D.DistrictField.bEqualPop];
|
|
54
|
+
let summaryRow = s.districts.numberOfRows() - 1;
|
|
55
|
+
bEqualPop[summaryRow] = test['score'];
|
|
56
|
+
return test;
|
|
57
|
+
}
|
|
58
|
+
exports.doHasEqualPopulations = doHasEqualPopulations;
|
|
59
|
+
//# sourceMappingURL=equal.js.map
|
package/lib/equal.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"equal.js","sourceRoot":"","sources":["../src/equal.ts"],"names":[],"mappings":"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"}
|
package/lib/features.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// GEO-FEATURES UTILITIES
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
// SHIM OVER 'POLY' FUNCTIONS
|
|
7
|
+
function featureArea() {
|
|
8
|
+
console.log("featureArea() - NIY ");
|
|
9
|
+
}
|
|
10
|
+
exports.featureArea = featureArea;
|
|
11
|
+
function featurePerimeter() {
|
|
12
|
+
console.log("featurePerimeter() - NIY ");
|
|
13
|
+
}
|
|
14
|
+
exports.featurePerimeter = featurePerimeter;
|
|
15
|
+
function featureDiameter() {
|
|
16
|
+
console.log("featureDiameter() - NIY ");
|
|
17
|
+
}
|
|
18
|
+
exports.featureDiameter = featureDiameter;
|
|
19
|
+
//# sourceMappingURL=features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.js","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,yBAAyB;AACzB,EAAE;;AAOF,6BAA6B;AAE7B,SAAgB,WAAW;IACzB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;AACrC,CAAC;AAFD,kCAEC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;AAC1C,CAAC;AAFD,4CAEC;AAED,SAAgB,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;AACzC,CAAC;AAFD,0CAEC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// GEO-FEATURES UTILITIES
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const Poly = require("@dra2020/poly");
|
|
7
|
+
// CARTESIAN SHIMS OVER 'POLY' FUNCTIONS
|
|
8
|
+
// TODO - Terry: Confirm Cartesian calculations
|
|
9
|
+
function gfArea(poly) {
|
|
10
|
+
let area = _polygonArea(poly);
|
|
11
|
+
// let polyOptions = { noLatitudeCorrection: false } DELETE
|
|
12
|
+
// let area: number = Poly.polyArea(poly, polyOptions);
|
|
13
|
+
return area;
|
|
14
|
+
}
|
|
15
|
+
exports.gfArea = gfArea;
|
|
16
|
+
// Algorithm for the area of a simple/single planar polygon:
|
|
17
|
+
// https://algorithmtutor.com/Computational-Geometry/Area-of-a-polygon-given-a-set-of-points/
|
|
18
|
+
// https://mathopenref.com/coordpolygonarea2.html
|
|
19
|
+
//
|
|
20
|
+
// function polygonArea(X, Y, numPoints)
|
|
21
|
+
// {
|
|
22
|
+
// area = 0; // Accumulates area in the loop
|
|
23
|
+
// j = numPoints-1; // The last vertex is the 'previous' one to the first
|
|
24
|
+
// for (i=0; i<numPoints; i++)
|
|
25
|
+
// { area = area + (X[j]+X[i]) * (Y[j]-Y[i]);
|
|
26
|
+
// j = i; //j is previous vertex to i
|
|
27
|
+
// }
|
|
28
|
+
// return area/2;
|
|
29
|
+
// }
|
|
30
|
+
// Reimplemented to use polygons vs. X & Y vectors
|
|
31
|
+
function _polygonSimpleArea(p) {
|
|
32
|
+
let area = 0; // Accumulates area in the loop
|
|
33
|
+
let n = p.length;
|
|
34
|
+
let j = n - 1; // The last vertex is the 'previous' one to the first
|
|
35
|
+
for (let i = 0; i < n; i++) {
|
|
36
|
+
area = area + (p[j][0] + p[i][0]) * (p[j][1] - p[i][1]);
|
|
37
|
+
// area = area + (X[j] + X[i]) * (Y[j] - Y[i]);
|
|
38
|
+
j = i; // j is previous vertex to i
|
|
39
|
+
}
|
|
40
|
+
return Math.abs(area / 2);
|
|
41
|
+
}
|
|
42
|
+
// Generalizes the above for MultiPolygons -- cloned from polyArea() in 'poly'
|
|
43
|
+
function _polygonArea(poly) {
|
|
44
|
+
let polyOptions = { noLatitudeCorrection: true }; // NO-OP?
|
|
45
|
+
poly = Poly.polyNormalize(poly, polyOptions); // TODO - Discuss w/ Terry
|
|
46
|
+
let a = 0;
|
|
47
|
+
// A MultiPolygon is a set of polygons
|
|
48
|
+
for (let i = 0; poly && i < poly.length; i++) {
|
|
49
|
+
// A single polygon is an exterior ring with interior holes. Holes are subtracted.
|
|
50
|
+
let p = poly[i];
|
|
51
|
+
for (let j = 0; j < p.length; j++) {
|
|
52
|
+
let sp = p[j];
|
|
53
|
+
a += _polygonSimpleArea(sp) * (j == 0 ? 1 : -1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return a;
|
|
57
|
+
}
|
|
58
|
+
// TODO - Terry: Confirm Cartesian calculations
|
|
59
|
+
// The perimeter calculation already just computes cartesian distance if you
|
|
60
|
+
// pass in the noLatitudeCorrection flag. You would need to divide by
|
|
61
|
+
// Poly.EARTH_RADIUS to go from the returned units of meters to Lat/Lon “units”.
|
|
62
|
+
function gfPerimeter(poly) {
|
|
63
|
+
let perimeter = _polygonPerimeter(poly);
|
|
64
|
+
// let polyOptions = { noLatitudeCorrection: true } // Cartesian distance
|
|
65
|
+
// let perimeter: number = Poly.polyPerimeter(poly, polyOptions); DELETE
|
|
66
|
+
return perimeter;
|
|
67
|
+
// return perimeter / Poly.EARTH_RADIUS; DELETE
|
|
68
|
+
}
|
|
69
|
+
exports.gfPerimeter = gfPerimeter;
|
|
70
|
+
// TODO - Terry: Confirm Cartesian calculations
|
|
71
|
+
// Cloned from polyPerimeter() in 'poly' and revised to use Cartesian distance
|
|
72
|
+
// NOTE: No conversion of degrees to radians!
|
|
73
|
+
function _polygonPerimeter(poly) {
|
|
74
|
+
let polyOptions = { noLatitudeCorrection: true }; // Cartesian distance
|
|
75
|
+
poly = Poly.polyNormalize(poly, polyOptions);
|
|
76
|
+
let perimeter = 0;
|
|
77
|
+
for (let i = 0; poly && i < poly.length; i++) {
|
|
78
|
+
// Ignore holes so only look at first polyline
|
|
79
|
+
let p = poly[i][0];
|
|
80
|
+
for (let j = 0; j < p.length - 1; j++)
|
|
81
|
+
perimeter += _distance(p[j][0], p[j][1], p[j + 1][0], p[j + 1][1]);
|
|
82
|
+
// perimeter += haversine(p[j][0], p[j][1], p[j + 1][0], p[j + 1][1], options); DELETE
|
|
83
|
+
if (p.length > 2 && (p[0][0] != p[p.length - 1][0] || p[0][1] != p[p.length - 1][1]))
|
|
84
|
+
perimeter += _distance(p[0][0], p[0][1], p[p.length - 1][0], p[p.length - 1][1]);
|
|
85
|
+
// perimeter += haversine(p[0][0], p[0][1], p[p.length - 1][0], p[p.length - 1][1], options); DELETE
|
|
86
|
+
}
|
|
87
|
+
return perimeter;
|
|
88
|
+
}
|
|
89
|
+
function _distance(x1, y1, x2, y2) {
|
|
90
|
+
let dLat = y2 - y1;
|
|
91
|
+
let dLon = x2 - x1;
|
|
92
|
+
let d;
|
|
93
|
+
d = Math.sqrt((dLat * dLat) + (dLon * dLon));
|
|
94
|
+
return d;
|
|
95
|
+
}
|
|
96
|
+
// TODO - Terry: Confirm Cartesian calculations
|
|
97
|
+
// As I mentioned, the polyCircle code was already just treating the coordinate
|
|
98
|
+
// system as Cartesian. I then did polyFromCircle to convert it to a polygon that
|
|
99
|
+
// then could be passed to polyArea in order to take into account the projection.
|
|
100
|
+
// If instead, you compute area directly from the circle as PI R squared, then
|
|
101
|
+
// you should have your cartesian circular area.
|
|
102
|
+
function gfDiameter(poly) {
|
|
103
|
+
let polyOptions = { noLatitudeCorrection: true }; // NO-OP
|
|
104
|
+
let circle = Poly.polyToCircle(poly, polyOptions);
|
|
105
|
+
// let circleArea: number = Poly.polyArea(Poly.polyFromCircle(circle, undefined, polyOptions), polyOptions);
|
|
106
|
+
// let circleRadius: number = Math.sqrt(circleArea / Math.PI);
|
|
107
|
+
// let diameter: number = circleRadius * 2; DELETE
|
|
108
|
+
let diameter = circle.r * 2;
|
|
109
|
+
return diameter;
|
|
110
|
+
}
|
|
111
|
+
exports.gfDiameter = gfDiameter;
|
|
112
|
+
//# sourceMappingURL=geofeature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geofeature.js","sourceRoot":"","sources":["../src/geofeature.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// THE DISTRICT-ANALYTICS NODE PACKAGE API
|
|
4
|
+
//
|
|
5
|
+
function __export(m) {
|
|
6
|
+
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
__export(require("./_api"));
|
|
10
|
+
__export(require("./types"));
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0CAA0C;AAC1C,EAAE;;;;;AAEF,4BAAuB;AACvB,6BAAwB"}
|
package/lib/minority.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// PROTECTS MINORITIES
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
// TODO - This definition is wrong. Need to fix it.
|
|
7
|
+
//
|
|
8
|
+
// MINORITY-PROTECTION ANALYTICS NEED THE FOLLOWING DATA:
|
|
9
|
+
//
|
|
10
|
+
// The TOTAL, WHITE, BLACK, and HISPANIC counts from the Census, aggregated by
|
|
11
|
+
// district. We *might* also ultimately need TOTAL18, WHITE18, BLACK18, and
|
|
12
|
+
// HISPANIC18 counts by feature for these analytics.
|
|
13
|
+
//
|
|
14
|
+
// The minority population of a feature will probably be calculated as everyone
|
|
15
|
+
// exceot non-Hispanic Whites:
|
|
16
|
+
//
|
|
17
|
+
// MINORITY = TOTAL - (WHITE - HISPANIC)
|
|
18
|
+
//
|
|
19
|
+
// That could be calculated as part of preprocessing the Census data, or it
|
|
20
|
+
// could be computed on the fly. Since it's derived data and the formula might
|
|
21
|
+
// change, it's probably best to compute it on the fly.
|
|
22
|
+
//
|
|
23
|
+
// In addition to the Census extract, these analytics need:
|
|
24
|
+
// - The # of districts in the map, for determining minority proportionality
|
|
25
|
+
// - Minorities as a % of the total population; possibly the voting age share
|
|
26
|
+
//
|
|
27
|
+
// TODO - Is the # of districts passed as a parameter or inferred from the # in
|
|
28
|
+
// the map?
|
|
29
|
+
// TODO - Is minority share preprocessed once and passed as a parameter or
|
|
30
|
+
// computed in a initialization routine?
|
|
31
|
+
function doMajorityMinorityDistricts(s) {
|
|
32
|
+
let test = s.getTest(14 /* MajorityMinorityDistricts */);
|
|
33
|
+
console.log("TODO - Calculating # of majority-minority districts ...");
|
|
34
|
+
return test;
|
|
35
|
+
}
|
|
36
|
+
exports.doMajorityMinorityDistricts = doMajorityMinorityDistricts;
|
|
37
|
+
// SAVE THESE NOTES, IN CASE WE NEED TO REWORK HOW WE DO PERFORM THESE CALCS.
|
|
38
|
+
// THEY REFLECT HOW I/ALEC DID THESE IN PYTHON.
|
|
39
|
+
//
|
|
40
|
+
// MINORITY-PROTECTION ANALYTICS WILL NEED THE FOLLOWING DATA,
|
|
41
|
+
// IN ADDITION TO THE MAP (IDEALLY, GEO_IDS INDEXED BY DISTRICT_ID)
|
|
42
|
+
//
|
|
43
|
+
// Census data by geo_id - { total population | white | black | hispanic }
|
|
44
|
+
//
|
|
45
|
+
// The minority population of a feature will probably be calculated as the # of
|
|
46
|
+
// non-White Hispanics:
|
|
47
|
+
//
|
|
48
|
+
// MINORITY = TOTAL - (WHITE - HISPANIC)
|
|
49
|
+
//
|
|
50
|
+
// That could be calculated as part of preprocessing the Census data, or it
|
|
51
|
+
// could be computed on the fly.
|
|
52
|
+
//
|
|
53
|
+
// And probably:
|
|
54
|
+
// 'districts' - The # of districts for determining minority proportionality.
|
|
55
|
+
// 'minority_share' - Minorities as a % of the total population
|
|
56
|
+
//
|
|
57
|
+
// TODO - Is the # of districts passed as a parameter or inferred from the # in
|
|
58
|
+
// the map?
|
|
59
|
+
// TODO - Is minority share preprocessed once and passed as a parameter or
|
|
60
|
+
// computed in a initialization routine?
|
|
61
|
+
//# sourceMappingURL=minority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minority.js","sourceRoot":"","sources":["../src/minority.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,sBAAsB;AACtB,EAAE;;AASF,mDAAmD;AACnD,EAAE;AACF,yDAAyD;AACzD,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,8BAA8B;AAC9B,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,uDAAuD;AACvD,EAAE;AACF,2DAA2D;AAC3D,4EAA4E;AAC5E,6EAA6E;AAC7E,EAAE;AACF,+EAA+E;AAC/E,aAAa;AACb,0EAA0E;AAC1E,0CAA0C;AAG1C,SAAgB,2BAA2B,CAAC,CAAmB;IAC7D,IAAI,IAAI,GAAG,CAAC,CAAC,OAAO,oCAAiD,CAAC;IAEtE,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IAEvE,OAAO,IAAI,CAAC;AACd,CAAC;AAND,kEAMC;AAED,6EAA6E;AAC7E,+CAA+C;AAC/C,EAAE;AACF,8DAA8D;AAC9D,mEAAmE;AACnE,EAAE;AACF,0EAA0E;AAC1E,EAAE;AACF,+EAA+E;AAC/E,uBAAuB;AACvB,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,gCAAgC;AAChC,EAAE;AACF,gBAAgB;AAChB,6EAA6E;AAC7E,+DAA+D;AAC/D,EAAE;AACF,+EAA+E;AAC/E,aAAa;AACb,0EAA0E;AAC1E,0CAA0C"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as T from './types';
|
|
2
|
+
import { AnalyticsSession } from './api';
|
|
3
|
+
export declare function doSeatsBias(s: AnalyticsSession): T.TestEntry;
|
|
4
|
+
export declare function doVotesBias(s: AnalyticsSession): T.TestEntry;
|
|
5
|
+
export declare function doResponsiveness(s: AnalyticsSession): T.TestEntry;
|
|
6
|
+
export declare function doResponsiveDistricts(s: AnalyticsSession): T.TestEntry;
|
|
7
|
+
export declare function doEfficiencyGap(s: AnalyticsSession): T.TestEntry;
|
package/lib/political.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// FAIR/PROPORTIONAL
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const assert_1 = require("assert");
|
|
7
|
+
const U = require("./utils");
|
|
8
|
+
const D = require("./_data");
|
|
9
|
+
// Partisan analytics need the following data:
|
|
10
|
+
//
|
|
11
|
+
// An "election model" by geo_id, where each item has 4 pieces of data:
|
|
12
|
+
//
|
|
13
|
+
// { geo_id, Democratic votes, Republican votes, Total votes }
|
|
14
|
+
//
|
|
15
|
+
// NOTE: D + R <= Total, because there could be third-party or write-in votes.
|
|
16
|
+
//
|
|
17
|
+
// An election model can simply represent one election, e.g., President 2012,
|
|
18
|
+
// or combine multiple elections in some fashion. An election model is used to
|
|
19
|
+
// computer a single index of the likely partisan weight / lean / preference
|
|
20
|
+
// for the districts in a plan. An election model and the associated index go
|
|
21
|
+
// hand in hand. So much so that the index frequently stands in as the name for
|
|
22
|
+
// both, e.g., Cook's PVI is one example, Nagle's 7s, Hofeller's Formula, NDRC's
|
|
23
|
+
// DPI.
|
|
24
|
+
//
|
|
25
|
+
// I'm labelling this general concept a "Voter Preference Index (VPI)," a
|
|
26
|
+
// conscious +1 letter play on Cook's "PVI" acronymn.
|
|
27
|
+
// MEASURING BIAS & RESPONSIVENESS (NAGLE'S METHOD)
|
|
28
|
+
function doSeatsBias(s) {
|
|
29
|
+
let test = s.getTest(9 /* SeatsBias */);
|
|
30
|
+
console.log("TODO - Calculating seats bias ...");
|
|
31
|
+
return test;
|
|
32
|
+
}
|
|
33
|
+
exports.doSeatsBias = doSeatsBias;
|
|
34
|
+
function doVotesBias(s) {
|
|
35
|
+
let test = s.getTest(10 /* VotesBias */);
|
|
36
|
+
console.log("TODO - Calculating votes bias ...");
|
|
37
|
+
return test;
|
|
38
|
+
}
|
|
39
|
+
exports.doVotesBias = doVotesBias;
|
|
40
|
+
function doResponsiveness(s) {
|
|
41
|
+
let test = s.getTest(11 /* Responsiveness */);
|
|
42
|
+
console.log("TODO - Calculating responsiveness ...");
|
|
43
|
+
return test;
|
|
44
|
+
}
|
|
45
|
+
exports.doResponsiveness = doResponsiveness;
|
|
46
|
+
function doResponsiveDistricts(s) {
|
|
47
|
+
let test = s.getTest(12 /* ResponsiveDistricts */);
|
|
48
|
+
console.log("TODO - Calculating # of responsive districts ...");
|
|
49
|
+
return test;
|
|
50
|
+
}
|
|
51
|
+
exports.doResponsiveDistricts = doResponsiveDistricts;
|
|
52
|
+
// OTHER MEASURES OF PARTISAN BIAS
|
|
53
|
+
// TODO - This formula might need to be inverted for D vs. R +/-
|
|
54
|
+
// TODO - Normalize the results.
|
|
55
|
+
function doEfficiencyGap(s) {
|
|
56
|
+
console.log("TODO - Calculating the efficiency gap ...");
|
|
57
|
+
let test = s.getTest(13 /* EfficiencyGap */);
|
|
58
|
+
// Get partisan statistics by districts.
|
|
59
|
+
// Use Democratic votes, seats, and shares by convention.
|
|
60
|
+
let DVotes = s.districts.statistics[D.DistrictField.DemVotes];
|
|
61
|
+
let DSeats = s.districts.statistics[D.DistrictField.DemSeat];
|
|
62
|
+
let TPVotes = s.districts.statistics[D.DistrictField.TwoPartyVote];
|
|
63
|
+
// Exclude the dummy unassigned '0' and N+1 summary "districts"
|
|
64
|
+
DVotes = DVotes.slice(1, -1);
|
|
65
|
+
DSeats = DSeats.slice(1, -1);
|
|
66
|
+
TPVotes = TPVotes.slice(1, -1);
|
|
67
|
+
// Calculate D vote share & D seat share
|
|
68
|
+
let DVoteShare = U.sumArray(DVotes) / U.sumArray(TPVotes);
|
|
69
|
+
let DSeatShare = U.sumArray(DSeats) / s.state.nDistricts;
|
|
70
|
+
// Finally, calculate the Efficiency Gap
|
|
71
|
+
let efficiencyGap = (DSeatShare - 0.5) - (2.0 * (DVoteShare - 0.5));
|
|
72
|
+
// Round the raw value to the desired level of precision
|
|
73
|
+
efficiencyGap = U.trim(efficiencyGap);
|
|
74
|
+
// Populate the test entry
|
|
75
|
+
test['score'] = efficiencyGap;
|
|
76
|
+
// test['normalizedScore'] = 0; /* TODO - Normalize the raw score */
|
|
77
|
+
test['details'] = {}; /* TODO - Add details, if any */
|
|
78
|
+
return test;
|
|
79
|
+
}
|
|
80
|
+
exports.doEfficiencyGap = doEfficiencyGap;
|
|
81
|
+
// HELPERS
|
|
82
|
+
function fptpWin(demPct) {
|
|
83
|
+
// Vote shares should be fractions in the range [0.0 – 1.0]
|
|
84
|
+
assert_1.strict((demPct <= 1.0) && (demPct >= 0.));
|
|
85
|
+
return ((demPct > 0.5) ? 1 : 0);
|
|
86
|
+
}
|
|
87
|
+
exports.fptpWin = fptpWin;
|
|
88
|
+
//# sourceMappingURL=political.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"political.js","sourceRoot":"","sources":["../src/political.ts"],"names":[],"mappings":"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"}
|