@dra2020/dra-analytics 4.1.4 → 4.1.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.
- package/dist/dra-analytics.js +493 -330
- package/dist/dra-analytics.js.map +1 -1
- package/dist/lib/compactness/compactness.d.ts +1 -0
- package/dist/lib/compactness/features.d.ts +3 -1
- package/dist/lib/minority/minority.d.ts +5 -5
- package/lib/compactness/compactness.ts +28 -2
- package/lib/compactness/features.ts +11 -9
- package/lib/graph/connected.ts +1 -1
- package/package.json +7 -7
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as GeoJSON from 'geojson';
|
|
2
2
|
import * as T from '../types/all';
|
|
3
|
+
export declare function excessivelyFragmented(shapes: GeoJSON.FeatureCollection): boolean;
|
|
3
4
|
export declare function makeCompactnessScorecard(shapes: GeoJSON.FeatureCollection, bLog?: boolean): T.CompactnessScorecard;
|
|
4
5
|
export declare function calcCompactness(shapes: GeoJSON.FeatureCollection): T.CompactnessJSONReady;
|
|
@@ -7,4 +7,6 @@ export declare function calcBoundingBox(poly: any): number;
|
|
|
7
7
|
export declare function calcPolsbyPopper(area: number, perimeter: number): number;
|
|
8
8
|
export declare function calcConvexHullFeature(area: number, chArea: number): number;
|
|
9
9
|
export declare function calcSchwartzberg(area: number, perimeter: number): number;
|
|
10
|
-
export declare function featureizePoly(poly: any, options?: Poly.PolyOptions
|
|
10
|
+
export declare function featureizePoly(poly: any, options?: Poly.PolyOptions, { bKIWYSIFeatures }?: {
|
|
11
|
+
bKIWYSIFeatures?: boolean;
|
|
12
|
+
}): T.CompactnessFeatures;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as T from '../types/all';
|
|
2
2
|
declare const enum Demographic {
|
|
3
|
-
Minority = 0
|
|
4
|
-
Black = 1
|
|
5
|
-
Hispanic = 2
|
|
6
|
-
Pacific = 3
|
|
7
|
-
Asian = 4
|
|
3
|
+
Minority = 0,// 'Minority'
|
|
4
|
+
Black = 1,// 'Black'
|
|
5
|
+
Hispanic = 2,// 'Hispanic'
|
|
6
|
+
Pacific = 3,// 'Pacific'
|
|
7
|
+
Asian = 4,// 'Asian'
|
|
8
8
|
Native = 5
|
|
9
9
|
}
|
|
10
10
|
export declare function makeMinorityScorecard(statewideDemos: T.Demographics, demosByDistrict: T.Demographics[], bLog?: boolean): T.MinorityScorecard;
|
|
@@ -10,6 +10,28 @@ import {scoreFeatureSet} from './kiwysi';
|
|
|
10
10
|
import * as T from '../types/all';
|
|
11
11
|
import {ratePolsby, rateReock} from '../rate/dra-ratings';
|
|
12
12
|
|
|
13
|
+
export function excessivelyFragmented(shapes: GeoJSON.FeatureCollection): boolean
|
|
14
|
+
{
|
|
15
|
+
const threshold: number = 20;
|
|
16
|
+
let fragments: number = 0;
|
|
17
|
+
for (let i = 0; i < shapes.features.length; i++)
|
|
18
|
+
{
|
|
19
|
+
const f: any = shapes.features[i];
|
|
20
|
+
if (f.geometry.type == 'MultiPolygon')
|
|
21
|
+
{
|
|
22
|
+
fragments += f.geometry.coordinates.length;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const avgFragmentation: number = fragments / shapes.features.length;
|
|
26
|
+
|
|
27
|
+
if (avgFragmentation > threshold)
|
|
28
|
+
{
|
|
29
|
+
console.log(`Average fragmentation (${avgFragmentation}) exceeds threshold (${threshold}).`);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
13
35
|
|
|
14
36
|
// Use this to get average Reock, Polsby-Popper, and KIWYSI compactness and by district for a set of shapes
|
|
15
37
|
// This is used by DRA
|
|
@@ -23,13 +45,17 @@ export function makeCompactnessScorecard(shapes: GeoJSON.FeatureCollection, bLog
|
|
|
23
45
|
let totPolsby: number = 0;
|
|
24
46
|
let totKIWYSI: number = 0;
|
|
25
47
|
|
|
48
|
+
// 12-11-24: Skip featurization for KIWYSI compactness, when the districts in a map are too fragmented on average
|
|
49
|
+
const bKIWYSIFeatures: boolean = excessivelyFragmented(shapes) ? false : true;
|
|
50
|
+
|
|
26
51
|
// For returning compactness by district to DRA
|
|
27
52
|
// Note, these use the Cartesian (flat earth) measurements
|
|
28
53
|
let byDistrict: T.Compactness[] = [];
|
|
29
54
|
|
|
30
55
|
for (let i = 0; i < shapes.features.length; i++)
|
|
31
56
|
{
|
|
32
|
-
const
|
|
57
|
+
const f: any = shapes.features[i];
|
|
58
|
+
const features: T.CompactnessFeatures = featureizePoly(f, options, {bKIWYSIFeatures: bKIWYSIFeatures});
|
|
33
59
|
|
|
34
60
|
const reockFlat: number = features.reockFlat;
|
|
35
61
|
const polsbyFlat: number = features.polsbyFlat;
|
|
@@ -40,7 +66,7 @@ export function makeCompactnessScorecard(shapes: GeoJSON.FeatureCollection, bLog
|
|
|
40
66
|
const normalizedReock: number = rateReock(reockFlat);
|
|
41
67
|
const normalizedPolsby: number = ratePolsby(polsbyFlat);
|
|
42
68
|
|
|
43
|
-
let kiwysiRank: number = scoreFeatureSet(features, pca);
|
|
69
|
+
let kiwysiRank: number = bKIWYSIFeatures ? scoreFeatureSet(features, pca) : 100;
|
|
44
70
|
// Constrain values to the range [1–100]
|
|
45
71
|
kiwysiRank = Math.min(Math.max(kiwysiRank, 1), 100);
|
|
46
72
|
// Raw KIWYSI scores ("ranks") are 1–100 where smaller is better
|
|
@@ -230,7 +230,7 @@ export function calcSchwartzberg(area: number, perimeter: number): number
|
|
|
230
230
|
|
|
231
231
|
// CALCULATE THE 7 COMPACTNESS "FEATURES" FOR A POLYGON FOR THE KIWYSI COMPACTNESS MODEL
|
|
232
232
|
|
|
233
|
-
export function featureizePoly(poly: any, options?: Poly.PolyOptions): T.CompactnessFeatures
|
|
233
|
+
export function featureizePoly(poly: any, options?: Poly.PolyOptions, {bKIWYSIFeatures = true}: {bKIWYSIFeatures?: boolean} = {}): T.CompactnessFeatures
|
|
234
234
|
{
|
|
235
235
|
if (options === undefined) options = Poly.DefaultOptions;
|
|
236
236
|
|
|
@@ -247,15 +247,17 @@ export function featureizePoly(poly: any, options?: Poly.PolyOptions): T.Compact
|
|
|
247
247
|
const hullArea: number = Poly.polyArea(ch);
|
|
248
248
|
|
|
249
249
|
const result: T.CompactnessFeatures = {
|
|
250
|
+
// 12-10-24: Skip featurization for KIWYSI compactness, when MultiPolygons are too fragmented
|
|
250
251
|
// For the "correct" geodesic calculations that the KIWYSI AI uses
|
|
251
|
-
sym_x: calcXSymmetry(poly),
|
|
252
|
-
sym_y: calcYSymmetry(poly),
|
|
253
|
-
reock: calcReock(area, diameter),
|
|
254
|
-
bbox: calcBoundingBox(poly),
|
|
255
|
-
polsby: calcPolsbyPopper(area, perimeter),
|
|
256
|
-
hull: calcConvexHullFeature(area, hullArea),
|
|
257
|
-
schwartzberg: calcSchwartzberg(area, perimeter),
|
|
258
|
-
|
|
252
|
+
sym_x: bKIWYSIFeatures ? calcXSymmetry(poly) : 0.0,
|
|
253
|
+
sym_y: bKIWYSIFeatures ? calcYSymmetry(poly) : 0.0,
|
|
254
|
+
reock: bKIWYSIFeatures ? calcReock(area, diameter) : 0.0,
|
|
255
|
+
bbox: bKIWYSIFeatures ? calcBoundingBox(poly) : 0.0,
|
|
256
|
+
polsby: bKIWYSIFeatures ? calcPolsbyPopper(area, perimeter) : 0.0,
|
|
257
|
+
hull: bKIWYSIFeatures ? calcConvexHullFeature(area, hullArea) : 0.0,
|
|
258
|
+
schwartzberg: bKIWYSIFeatures ? calcSchwartzberg(area, perimeter) : 0.0,
|
|
259
|
+
|
|
260
|
+
// But still do the basic calculations for Reock and Polsby-Popper
|
|
259
261
|
// For the Cartesian (flat earth) calculations that are typically done
|
|
260
262
|
reockFlat: calcReock(areaFlat, diameterFlat),
|
|
261
263
|
polsbyFlat: calcPolsbyPopper(areaFlat, perimeterFlat)
|
package/lib/graph/connected.ts
CHANGED
|
@@ -13,7 +13,7 @@ export function isConnected(featureIDs: T.FeatureGroup, graph: T.ContiguityGraph
|
|
|
13
13
|
|
|
14
14
|
// Start processing with the first feature in the set
|
|
15
15
|
let iter = featureIDs.values();
|
|
16
|
-
toProcess.push(iter.next().value);
|
|
16
|
+
toProcess.push(iter.next().value as string);
|
|
17
17
|
|
|
18
18
|
// While there are features in the set that haven't been processed,
|
|
19
19
|
// i.e., stop when you've visited all the features in the set
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dra2020/dra-analytics",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.5",
|
|
4
4
|
"description": "DRA analytics",
|
|
5
5
|
"main": "dist/dra-analytics.js",
|
|
6
6
|
"types": "./dist/lib/all/all.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://github.com/dra2020/dra-analytics#readme",
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/geojson": "^7946.0.
|
|
35
|
+
"@types/geojson": "^7946.0.16",
|
|
36
36
|
"@types/jest": "^29.5.1",
|
|
37
37
|
"@types/node": "^18.11.17",
|
|
38
38
|
"@types/yargs": "^11.1.8",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
"json-loader": "^0.5.7",
|
|
42
42
|
"prettier": "^2.8.8",
|
|
43
43
|
"shapefile": "^0.6.6",
|
|
44
|
-
"source-map-loader": "^
|
|
44
|
+
"source-map-loader": "^5.0.0",
|
|
45
45
|
"ts-jest": "^29.1.0",
|
|
46
|
-
"ts-loader": "^9.
|
|
46
|
+
"ts-loader": "^9.5.2",
|
|
47
47
|
"tsify": "^5.0.4",
|
|
48
48
|
"tslint": "^6.1.3",
|
|
49
49
|
"tslint-config-prettier": "^1.18.0",
|
|
50
|
-
"typescript": "^
|
|
51
|
-
"webpack": "^5.
|
|
52
|
-
"webpack-cli": "^
|
|
50
|
+
"typescript": "^5.8.3",
|
|
51
|
+
"webpack": "^5.99.5",
|
|
52
|
+
"webpack-cli": "^6.0.1"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@dra2020/baseclient": "^1.0.153",
|