@dra2020/district-analytics 5.1.0 → 5.2.2
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/cli.js +7980 -4935
- package/dist/cli.js.map +1 -1
- package/dist/district-analytics.js +6 -145
- package/dist/district-analytics.js.map +1 -1
- package/dist/src/geofeature.d.ts +0 -5
- package/package.json +16 -17
|
@@ -122,7 +122,7 @@ const analyze_1 = __webpack_require__(/*! ./analyze */ "./src/analyze.ts");
|
|
|
122
122
|
const score_1 = __webpack_require__(/*! ./score */ "./src/score.ts");
|
|
123
123
|
const results_1 = __webpack_require__(/*! ./results */ "./src/results.ts");
|
|
124
124
|
const results_2 = __webpack_require__(/*! ./results */ "./src/results.ts");
|
|
125
|
-
const
|
|
125
|
+
const Poly = __importStar(__webpack_require__(/*! @dra2020/poly */ "@dra2020/poly"));
|
|
126
126
|
const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
|
|
127
127
|
const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
|
|
128
128
|
class AnalyticsSession {
|
|
@@ -198,7 +198,7 @@ class AnalyticsSession {
|
|
|
198
198
|
// If a district has a shape & it is not contiguous, by definition,
|
|
199
199
|
// it will be a Multipolygon, i.e., it will have multiple pieces, some
|
|
200
200
|
// possibly embedded w/in other districts. Get & add all the pieces.
|
|
201
|
-
const districtParts =
|
|
201
|
+
const districtParts = Poly.polyParts(poly);
|
|
202
202
|
discontiguousDistrictFeatures.features.push(...districtParts.features);
|
|
203
203
|
// discontiguousDistrictFeatures.features.push(poly);
|
|
204
204
|
}
|
|
@@ -1114,7 +1114,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
1114
1114
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1115
1115
|
// NOTE - This file will NOT be empty, when legacy code is deleted.
|
|
1116
1116
|
const Poly = __importStar(__webpack_require__(/*! @dra2020/poly */ "@dra2020/poly"));
|
|
1117
|
-
const geofeature_1 = __webpack_require__(/*! ./geofeature */ "./src/geofeature.ts");
|
|
1118
1117
|
// HELPER TO EXTRACT PROPERTIES OF DISTRICT SHAPES
|
|
1119
1118
|
// TODO - Create an array, as opposed to a dict
|
|
1120
1119
|
function extractDistrictProperties(s, bLog = false) {
|
|
@@ -1122,13 +1121,12 @@ function extractDistrictProperties(s, bLog = false) {
|
|
|
1122
1121
|
for (let i = 1; i <= s.state.nDistricts; i++) {
|
|
1123
1122
|
let poly = s.districts.getDistrictShapeByID(i);
|
|
1124
1123
|
// Guard against no shape for empty districts AND null shapes
|
|
1125
|
-
let
|
|
1126
|
-
let bNull = (!Poly.polyNormalize(poly, polyOptions));
|
|
1124
|
+
let bNull = !Poly.polyNormalize(poly);
|
|
1127
1125
|
if (poly && (!bNull)) {
|
|
1128
1126
|
// TODO - OPTIMIZE: Bundle these calls?
|
|
1129
|
-
let area =
|
|
1130
|
-
let perimeter =
|
|
1131
|
-
let diameter =
|
|
1127
|
+
let area = Poly.polyAreaFlat(poly);
|
|
1128
|
+
let perimeter = Poly.polyPerimeterFlat(poly);
|
|
1129
|
+
let diameter = Poly.polyDiameterFlat(poly);
|
|
1132
1130
|
let props = [0, 0, 0]; // TODO - TERRY?!?
|
|
1133
1131
|
props[0 /* Area */] = area;
|
|
1134
1132
|
props[1 /* Diameter */] = diameter;
|
|
@@ -1219,143 +1217,6 @@ function doHasEqualPopulations(s, bLog = false) {
|
|
|
1219
1217
|
exports.doHasEqualPopulations = doHasEqualPopulations;
|
|
1220
1218
|
|
|
1221
1219
|
|
|
1222
|
-
/***/ }),
|
|
1223
|
-
|
|
1224
|
-
/***/ "./src/geofeature.ts":
|
|
1225
|
-
/*!***************************!*\
|
|
1226
|
-
!*** ./src/geofeature.ts ***!
|
|
1227
|
-
\***************************/
|
|
1228
|
-
/*! no static exports found */
|
|
1229
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
1230
|
-
|
|
1231
|
-
"use strict";
|
|
1232
|
-
|
|
1233
|
-
//
|
|
1234
|
-
// GEO-FEATURES UTILITIES
|
|
1235
|
-
//
|
|
1236
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
1237
|
-
if (mod && mod.__esModule) return mod;
|
|
1238
|
-
var result = {};
|
|
1239
|
-
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
1240
|
-
result["default"] = mod;
|
|
1241
|
-
return result;
|
|
1242
|
-
};
|
|
1243
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1244
|
-
const Poly = __importStar(__webpack_require__(/*! @dra2020/poly */ "@dra2020/poly"));
|
|
1245
|
-
// HELPER
|
|
1246
|
-
function polyParts(poly) {
|
|
1247
|
-
let parts = { type: 'FeatureCollection', features: [] };
|
|
1248
|
-
let af = parts.features;
|
|
1249
|
-
if (poly.geometry.type === 'MultiPolygon') {
|
|
1250
|
-
// Push all non-contiguous polygons
|
|
1251
|
-
for (let j = 0; j < poly.geometry.coordinates.length; j++) {
|
|
1252
|
-
let onePoly = poly.geometry.coordinates[j];
|
|
1253
|
-
af.push({ type: 'Feature', properties: { id: `${af.length + 1}` }, geometry: { type: 'Polygon', coordinates: onePoly } });
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
else {
|
|
1257
|
-
parts.features.push(poly);
|
|
1258
|
-
}
|
|
1259
|
-
return parts;
|
|
1260
|
-
}
|
|
1261
|
-
exports.polyParts = polyParts;
|
|
1262
|
-
// CARTESIAN SHIMS OVER 'POLY' FUNCTIONS
|
|
1263
|
-
// TODO - POLY: Confirm Cartesian calculations
|
|
1264
|
-
function gfArea(poly) {
|
|
1265
|
-
let area = _polygonArea(poly);
|
|
1266
|
-
return area;
|
|
1267
|
-
}
|
|
1268
|
-
exports.gfArea = gfArea;
|
|
1269
|
-
// Algorithm for the area of a simple/single planar polygon:
|
|
1270
|
-
// https://algorithmtutor.com/Computational-Geometry/Area-of-a-polygon-given-a-set-of-points/
|
|
1271
|
-
// https://mathopenref.com/coordpolygonarea2.html
|
|
1272
|
-
//
|
|
1273
|
-
// function polygonArea(X, Y, numPoints)
|
|
1274
|
-
// {
|
|
1275
|
-
// area = 0; // Accumulates area in the loop
|
|
1276
|
-
// j = numPoints-1; // The last vertex is the 'previous' one to the first
|
|
1277
|
-
// for (i=0; i<numPoints; i++)
|
|
1278
|
-
// { area = area + (X[j]+X[i]) * (Y[j]-Y[i]);
|
|
1279
|
-
// j = i; //j is previous vertex to i
|
|
1280
|
-
// }
|
|
1281
|
-
// return area/2;
|
|
1282
|
-
// }
|
|
1283
|
-
// Reimplemented to use polygons vs. X & Y vectors
|
|
1284
|
-
function _polygonSimpleArea(p) {
|
|
1285
|
-
let area = 0; // Accumulates area in the loop
|
|
1286
|
-
let n = p.length;
|
|
1287
|
-
let j = n - 1; // The last vertex is the 'previous' one to the first
|
|
1288
|
-
for (let i = 0; i < n; i++) {
|
|
1289
|
-
area = area + (p[j][0] + p[i][0]) * (p[j][1] - p[i][1]);
|
|
1290
|
-
// area = area + (X[j] + X[i]) * (Y[j] - Y[i]);
|
|
1291
|
-
j = i; // j is previous vertex to i
|
|
1292
|
-
}
|
|
1293
|
-
return Math.abs(area / 2);
|
|
1294
|
-
}
|
|
1295
|
-
// Generalizes the above for MultiPolygons -- cloned from polyArea() in 'poly'
|
|
1296
|
-
function _polygonArea(poly) {
|
|
1297
|
-
let polyOptions = { noLatitudeCorrection: true }; // NO-OP?
|
|
1298
|
-
poly = Poly.polyNormalize(poly, polyOptions); // TODO - POLY: Discuss w/ Terry
|
|
1299
|
-
let a = 0;
|
|
1300
|
-
// A MultiPolygon is a set of polygons
|
|
1301
|
-
for (let i = 0; poly && i < poly.length; i++) {
|
|
1302
|
-
// A single polygon is an exterior ring with interior holes. Holes are subtracted.
|
|
1303
|
-
let p = poly[i];
|
|
1304
|
-
for (let j = 0; j < p.length; j++) {
|
|
1305
|
-
let sp = p[j];
|
|
1306
|
-
a += _polygonSimpleArea(sp) * (j == 0 ? 1 : -1);
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
return a;
|
|
1310
|
-
}
|
|
1311
|
-
// TODO - POLY: Confirm Cartesian calculations w/ Terry
|
|
1312
|
-
// The perimeter calculation already just computes cartesian distance if you
|
|
1313
|
-
// pass in the noLatitudeCorrection flag. You would need to divide by
|
|
1314
|
-
// Poly.EARTH_RADIUS to go from the returned units of meters to Lat/Lon “units”.
|
|
1315
|
-
function gfPerimeter(poly) {
|
|
1316
|
-
let perimeter = _polygonPerimeter(poly);
|
|
1317
|
-
return perimeter;
|
|
1318
|
-
}
|
|
1319
|
-
exports.gfPerimeter = gfPerimeter;
|
|
1320
|
-
// TODO - POLY: Confirm Cartesian calculations w/ Terry
|
|
1321
|
-
// Cloned from polyPerimeter() in 'poly' and revised to use Cartesian distance
|
|
1322
|
-
// NOTE - No conversion of degrees to radians!
|
|
1323
|
-
function _polygonPerimeter(poly) {
|
|
1324
|
-
let polyOptions = { noLatitudeCorrection: true }; // Cartesian distance
|
|
1325
|
-
poly = Poly.polyNormalize(poly, polyOptions);
|
|
1326
|
-
let perimeter = 0;
|
|
1327
|
-
for (let i = 0; poly && i < poly.length; i++) {
|
|
1328
|
-
// Ignore holes so only look at first polyline
|
|
1329
|
-
let p = poly[i][0];
|
|
1330
|
-
for (let j = 0; j < p.length - 1; j++)
|
|
1331
|
-
perimeter += _distance(p[j][0], p[j][1], p[j + 1][0], p[j + 1][1]);
|
|
1332
|
-
if (p.length > 2 && (p[0][0] != p[p.length - 1][0] || p[0][1] != p[p.length - 1][1]))
|
|
1333
|
-
perimeter += _distance(p[0][0], p[0][1], p[p.length - 1][0], p[p.length - 1][1]);
|
|
1334
|
-
}
|
|
1335
|
-
return perimeter;
|
|
1336
|
-
}
|
|
1337
|
-
function _distance(x1, y1, x2, y2) {
|
|
1338
|
-
let dLat = y2 - y1;
|
|
1339
|
-
let dLon = x2 - x1;
|
|
1340
|
-
let d;
|
|
1341
|
-
d = Math.sqrt((dLat * dLat) + (dLon * dLon));
|
|
1342
|
-
return d;
|
|
1343
|
-
}
|
|
1344
|
-
// TODO - POLY: Confirm Cartesian calculations w/ Terry
|
|
1345
|
-
// As I mentioned, the polyCircle code was already just treating the coordinate
|
|
1346
|
-
// system as Cartesian. I then did polyFromCircle to convert it to a polygon that
|
|
1347
|
-
// then could be passed to polyArea in order to take into account the projection.
|
|
1348
|
-
// If instead, you compute area directly from the circle as PI R squared, then
|
|
1349
|
-
// you should have your cartesian circular area.
|
|
1350
|
-
function gfDiameter(poly) {
|
|
1351
|
-
let polyOptions = { noLatitudeCorrection: true }; // NO-OP
|
|
1352
|
-
let circle = Poly.polyToCircle(poly, polyOptions);
|
|
1353
|
-
let diameter = circle.r * 2;
|
|
1354
|
-
return diameter;
|
|
1355
|
-
}
|
|
1356
|
-
exports.gfDiameter = gfDiameter;
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
1220
|
/***/ }),
|
|
1360
1221
|
|
|
1361
1222
|
/***/ "./src/index.ts":
|