@dra2020/dra-types 1.0.16 → 1.1.0

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.
@@ -1,3 +1,9 @@
1
+ export declare type BlockMap = {
2
+ [id: string]: number;
3
+ };
4
+ export declare type BlockMapping = {
5
+ [id: string]: string;
6
+ };
1
7
  export interface Comment {
2
8
  userid: string;
3
9
  text: string;
@@ -34,6 +40,7 @@ export declare type DistrictToSplitBlock = {
34
40
  };
35
41
  export declare function vgeoidToGeoid(vgeoid: string): string;
36
42
  export declare function vgeoidToChunk(vgeoid: string): string;
43
+ export declare function vgeoidToHash(vgeoid: string): string;
37
44
  export declare function isVfeature(geoid: string): boolean;
38
45
  export declare function splitToCacheKey(s: SplitBlock): string;
39
46
  export declare function splitToChunkKey(s: SplitBlock): string;
@@ -47,3 +54,17 @@ export declare type DistrictOrder = {
47
54
  [districtID: string]: number;
48
55
  };
49
56
  export declare function canonicalDistrictIDOrdering(order: DistrictOrder): DistrictOrder;
57
+ export interface ConvertResult {
58
+ inBlockMap: BlockMapping;
59
+ inStateMap: BlockMapping;
60
+ outValid: boolean;
61
+ outState: string;
62
+ outMap: BlockMapping;
63
+ outOrder: DistrictOrder;
64
+ outDistrictToSplit: DistrictToSplitBlock;
65
+ }
66
+ export declare function blockmapToState(blockMap: BlockMapping): string;
67
+ export declare function blockmapToVTDmap(blockMap: BlockMapping, stateMap: BlockMapping): ConvertResult;
68
+ export declare const GEOIDToState: any;
69
+ export declare const StateToGEOID: any;
70
+ export declare function geoidToState(geoid: string): string;
package/dist/dra-types.js CHANGED
@@ -126,6 +126,7 @@ __export(__webpack_require__(/*! ./dra-types */ "./lib/dra-types.ts"));
126
126
  Object.defineProperty(exports, "__esModule", { value: true });
127
127
  // Public libraries
128
128
  const Hash = __webpack_require__(/*! object-hash */ "object-hash");
129
+ const Util = __webpack_require__(/*! @dra2020/util */ "@dra2020/util");
129
130
  // Canonical hashing of splitblock data
130
131
  function hash(o) {
131
132
  return Hash(o, { respectType: false,
@@ -156,6 +157,17 @@ function vgeoidToChunk(vgeoid) {
156
157
  return vgeoid;
157
158
  }
158
159
  exports.vgeoidToChunk = vgeoidToChunk;
160
+ function vgeoidToHash(vgeoid) {
161
+ // vgeoid is string of form: "vfeature_[geoid]_[chunkid]_[hash]"
162
+ let re = /vfeature_([^_]*)_([^_*])_(.*)/;
163
+ let a = re.exec(vgeoid);
164
+ if (a && a.length == 4)
165
+ vgeoid = a[3];
166
+ else
167
+ vgeoid = null;
168
+ return vgeoid;
169
+ }
170
+ exports.vgeoidToHash = vgeoidToHash;
159
171
  function isVfeature(geoid) {
160
172
  return geoid.indexOf('vfeature') === 0;
161
173
  }
@@ -192,7 +204,6 @@ exports.cacheKeysToChunkHash = cacheKeysToChunkHash;
192
204
  let reNumeric = /^(\D*)(\d*)(\D*)$/;
193
205
  let reDistrictNumber = /^\d+$/;
194
206
  let reDistrictNumeric = /^\d/;
195
- let reLeadingZero = /^0+(.*)/;
196
207
  // Normalize any numeric part to have no padded leading zeros
197
208
  function canonicalDistrictID(districtID) {
198
209
  let a = reNumeric.exec(districtID);
@@ -255,31 +266,242 @@ function canonicalDistrictIDOrdering(order) {
255
266
  let i;
256
267
  let a = [];
257
268
  let template = undefined;
258
- for (i = 0; i < keys.length; i++) {
259
- let s = keys[i];
260
- keys[i] = canonicalSortingDistrictID(s);
261
- let n = canonicalNumericFromDistrictID(s);
262
- if (n > 0) {
263
- if (template === undefined)
264
- template = s;
265
- a[n] = true;
266
- }
267
- }
268
- if (template !== undefined) {
269
- for (i = 1; i < a.length; i++)
270
- if (a[i] === undefined)
271
- keys.push(canonicalDistrictIDFromNumber(template, i));
272
- }
269
+ keys = keys.map((s) => canonicalSortingDistrictID(s));
273
270
  keys.sort();
274
271
  order = {};
275
272
  for (i = 0; i < keys.length; i++)
276
273
  order[canonicalDistrictID(keys[i])] = i + 1;
274
+ // Remove water districts
277
275
  if (order['ZZZ'])
278
276
  delete order['ZZZ'];
279
277
  return order;
280
278
  }
281
279
  exports.canonicalDistrictIDOrdering = canonicalDistrictIDOrdering;
280
+ function blockmapToState(blockMap) {
281
+ for (var id in blockMap)
282
+ if (blockMap.hasOwnProperty(id))
283
+ return geoidToState(id);
284
+ return null;
285
+ }
286
+ exports.blockmapToState = blockmapToState;
287
+ // blockToVTD:
288
+ // Take BlockMapping (simple map of GEOID to districtID) and a per-state map of block-level GEOID to VTD
289
+ // and return the output mapping of VTD to districtID, as well a data structure that describes any VTD's
290
+ // that need to be split between districtIDs. Also returns the DistrictOrder structure that defines the
291
+ // districtIDs that were used by the file.
292
+ //
293
+ // The state (as specified by the first two digits of the GEOID) is also determined. If the GEOID's do
294
+ // not all specify the same state, the mapping is considered invalid and the outValid flag is set to false.
295
+ //
296
+ function blockmapToVTDmap(blockMap, stateMap) {
297
+ let res = {
298
+ inBlockMap: blockMap,
299
+ inStateMap: stateMap,
300
+ outValid: true,
301
+ outState: null,
302
+ outMap: {},
303
+ outOrder: {},
304
+ outDistrictToSplit: {}
305
+ };
306
+ let bmGather = {};
307
+ let revMap = {};
308
+ let id;
309
+ if (stateMap)
310
+ for (id in stateMap)
311
+ if (stateMap.hasOwnProperty(id))
312
+ revMap[stateMap[id]] = null;
313
+ // First aggregate into features across all the blocks
314
+ for (id in blockMap)
315
+ if (blockMap.hasOwnProperty(id)) {
316
+ let state = geoidToState(id);
317
+ if (res.outState == null)
318
+ res.outState = state;
319
+ else if (res.outState !== state) {
320
+ res.outValid = false;
321
+ break;
322
+ }
323
+ let districtID = canonicalDistrictID(blockMap[id]);
324
+ // Just ignore ZZZ (water) blocks
325
+ if (districtID === 'ZZZ')
326
+ continue;
327
+ let n = id.length;
328
+ let geoid;
329
+ // Simple test for block id (vs. voting district or block group) id
330
+ if (n >= 15) {
331
+ if (stateMap && stateMap[id] !== undefined)
332
+ geoid = stateMap[id];
333
+ else {
334
+ geoid = id.substr(0, 12); // heuristic for mapping blockID to blockgroupID
335
+ if (revMap[geoid] === undefined) {
336
+ res.outValid = false;
337
+ break;
338
+ }
339
+ }
340
+ }
341
+ else
342
+ geoid = id;
343
+ if (res.outOrder[districtID] === undefined)
344
+ res.outOrder[districtID] = 0;
345
+ let districtToBlocks = bmGather[geoid];
346
+ if (districtToBlocks === undefined)
347
+ bmGather[geoid] = { [districtID]: { [id]: true } };
348
+ else {
349
+ let thisDistrict = districtToBlocks[districtID];
350
+ if (thisDistrict === undefined) {
351
+ thisDistrict = {};
352
+ districtToBlocks[districtID] = thisDistrict;
353
+ }
354
+ thisDistrict[id] = true;
355
+ }
356
+ }
357
+ // Now determine actual mapping of blocks to features, looking for split features
358
+ for (let geoid in bmGather)
359
+ if (bmGather.hasOwnProperty(geoid)) {
360
+ let districtToBlocks = bmGather[geoid];
361
+ if (Util.countKeys(districtToBlocks) == 1) {
362
+ res.outMap[geoid] = Util.nthKey(districtToBlocks);
363
+ }
364
+ else {
365
+ for (let districtID in districtToBlocks)
366
+ if (districtToBlocks.hasOwnProperty(districtID)) {
367
+ let split = { state: '', datasource: '', geoid: geoid, blocks: Object.keys(districtToBlocks[districtID]) };
368
+ let splits = res.outDistrictToSplit[districtID];
369
+ if (splits === undefined) {
370
+ splits = [];
371
+ res.outDistrictToSplit[districtID] = splits;
372
+ }
373
+ splits.push(split);
374
+ }
375
+ }
376
+ }
377
+ res.outOrder = canonicalDistrictIDOrdering(res.outOrder);
378
+ return res;
379
+ }
380
+ exports.blockmapToVTDmap = blockmapToVTDmap;
381
+ exports.GEOIDToState = {
382
+ '01': 'AL',
383
+ '02': 'AK',
384
+ '04': 'AZ',
385
+ '05': 'AR',
386
+ '06': 'CA',
387
+ '08': 'CO',
388
+ '09': 'CT',
389
+ '10': 'DE',
390
+ '12': 'FL',
391
+ '13': 'GA',
392
+ '15': 'HI',
393
+ '16': 'ID',
394
+ '17': 'IL',
395
+ '18': 'IN',
396
+ '19': 'IA',
397
+ '20': 'KS',
398
+ '21': 'KY',
399
+ '22': 'LA',
400
+ '23': 'ME',
401
+ '24': 'MD',
402
+ '25': 'MA',
403
+ '26': 'MI',
404
+ '27': 'MN',
405
+ '28': 'MS',
406
+ '29': 'MO',
407
+ '30': 'MT',
408
+ '31': 'NE',
409
+ '32': 'NV',
410
+ '33': 'NH',
411
+ '34': 'NJ',
412
+ '35': 'NM',
413
+ '36': 'NY',
414
+ '37': 'NC',
415
+ '38': 'ND',
416
+ '39': 'OH',
417
+ '40': 'OK',
418
+ '41': 'OR',
419
+ '42': 'PA',
420
+ '44': 'RI',
421
+ '45': 'SC',
422
+ '46': 'SD',
423
+ '47': 'TN',
424
+ '48': 'TX',
425
+ '49': 'UT',
426
+ '50': 'VT',
427
+ '51': 'VA',
428
+ '53': 'WA',
429
+ '54': 'WV',
430
+ '55': 'WI',
431
+ '56': 'WY',
432
+ };
433
+ exports.StateToGEOID = {
434
+ 'AL': '01',
435
+ 'AK': '02',
436
+ 'AZ': '04',
437
+ 'AR': '05',
438
+ 'CA': '06',
439
+ 'CO': '08',
440
+ 'CT': '09',
441
+ 'DE': '10',
442
+ 'FL': '12',
443
+ 'GA': '13',
444
+ 'HI': '15',
445
+ 'ID': '16',
446
+ 'IL': '17',
447
+ 'IN': '18',
448
+ 'IA': '19',
449
+ 'KS': '20',
450
+ 'KY': '21',
451
+ 'LA': '22',
452
+ 'ME': '23',
453
+ 'MD': '24',
454
+ 'MA': '25',
455
+ 'MI': '26',
456
+ 'MN': '27',
457
+ 'MS': '28',
458
+ 'MO': '29',
459
+ 'MT': '30',
460
+ 'NE': '31',
461
+ 'NV': '32',
462
+ 'NH': '33',
463
+ 'NJ': '34',
464
+ 'NM': '35',
465
+ 'NY': '36',
466
+ 'NC': '37',
467
+ 'ND': '38',
468
+ 'OH': '39',
469
+ 'OK': '40',
470
+ 'OR': '41',
471
+ 'PA': '42',
472
+ 'RI': '44',
473
+ 'SC': '45',
474
+ 'SD': '46',
475
+ 'TN': '47',
476
+ 'TX': '48',
477
+ 'UT': '49',
478
+ 'VT': '50',
479
+ 'VA': '51',
480
+ 'WA': '53',
481
+ 'WV': '54',
482
+ 'WI': '55',
483
+ 'WY': '56',
484
+ };
485
+ function geoidToState(geoid) {
486
+ let re = /^(..).*$/;
487
+ let a = re.exec(geoid);
488
+ if (a == null || a.length != 2)
489
+ return null;
490
+ return exports.GEOIDToState[a[1]];
491
+ }
492
+ exports.geoidToState = geoidToState;
493
+
494
+
495
+ /***/ }),
496
+
497
+ /***/ "@dra2020/util":
498
+ /*!********************************!*\
499
+ !*** external "@dra2020/util" ***!
500
+ \********************************/
501
+ /*! no static exports found */
502
+ /***/ (function(module, exports) {
282
503
 
504
+ module.exports = require("@dra2020/util");
283
505
 
284
506
  /***/ }),
285
507
 
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://dra-types/webpack/universalModuleDefinition","webpack://dra-types/webpack/bootstrap","webpack://dra-types/./lib/all.ts","webpack://dra-types/./lib/dra-types.ts","webpack://dra-types/external \"object-hash\""],"names":[],"mappings":"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","file":"dra-types.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"dra-types\"] = factory();\n\telse\n\t\troot[\"dra-types\"] = factory();\n})(global, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./lib/all.ts\");\n","export * from './dra-types';\n","// Public libraries\nimport * as Hash from 'object-hash';\n\n// Type for single comment\nexport interface Comment\n{\n userid: string;\n text: string;\n date: string;\n recommend: number;\n}\n\n// Comment record associated with a map\nexport interface CommentList\n{\n id?: string;\n [commentid: string]: Comment | string; // Really just Comment but make TypeScript happy\n}\n\n// Supported like kinds\nexport type LikeKind = 'like' | 'love' | 'wow' | 'angry' | 'funny';\n\n// Like record for an individual like\nexport interface Like\n{\n date: string;\n kind: LikeKind;\n}\n\n// Record for likes associated with a map\nexport interface LikeList\n{\n id?: string;\n [userid: string]: Like | string; // Really just Like but make TypeScript happy\n}\n\n// Record for likes an individual user has performed\nexport interface UserLikes\n{\n id?: string;\n [aid: string]: Like | string; // Really just Like but make TypeScript happy\n}\n\nexport interface SplitBlock\n{\n id?: string;\n chunk?: string;\n state: string;\n datasource: string;\n geoid: string;\n blocks: string[];\n}\n\nexport type DistrictToSplitBlock = { [districtID: string]: SplitBlock[] };\n\n// Canonical hashing of splitblock data\nfunction hash(o: any): string\n{\n return Hash(o,\n { respectType: false,\n unorderedArrays: true,\n unorderedObjects: true,\n excludeKeys: (k: string) => (k === 'id' || k === 'chunk')\n });\n}\n\nexport function vgeoidToGeoid(vgeoid: string): string\n{\n let re = /vfeature_([^_]*)_.*/;\n let a = re.exec(vgeoid);\n if (a == null || a.length != 2)\n return '';\n else\n return a[1];\n}\n\nexport function vgeoidToChunk(vgeoid: string): string\n{\n // vgeoid is string of form: \"vfeature_[geoid]_[chunkid]_[hash]\"\n // the contents are chunked into a file of form \"vfeature_chunk_[chunkid]\"\n // So extract the chunk ID and download that.\n let re = /vfeature_([^_]*)_([^_*])_(.*)/;\n let a = re.exec(vgeoid);\n if (a && a.length == 4)\n vgeoid = `vfeature_chunk_${a[2]}`;\n else\n vgeoid = null;\n\n return vgeoid;\n}\n\nexport function isVfeature(geoid: string): boolean\n{\n return geoid.indexOf('vfeature') === 0;\n}\n\nexport function splitToCacheKey(s: SplitBlock): string\n{\n if (s.id === undefined)\n s.id = hash(s);\n if (s.chunk === undefined)\n s.chunk = \"0\";\n\n return `_${s.state}_${s.datasource}_vfeature_${s.geoid}_${s.chunk}_${s.id}.geojson`;\n}\n\nexport function splitToChunkKey(s: SplitBlock): string\n{\n if (s.chunk === undefined)\n s.chunk = \"0\";\n\n return `_${s.state}_${s.datasource}_vfeature_chunk_${s.chunk}.geojson`;\n}\n\nexport function splitToPrefix(s: SplitBlock): string\n{\n if (s.blocks === undefined)\n {\n let re = /_([^_]*)_(.*)_vfeature.*\\.geojson$/;\n let a = re.exec(s.id);\n if (a && a.length == 3)\n return `_${a[1]}_${a[2]}`;\n return s.id;\n }\n return `_${s.state}_${s.datasource}`;\n}\n\nexport function cacheKeysToChunkHash(keys: string[]): string\n{\n return hash(keys);\n}\n\nlet reNumeric = /^(\\D*)(\\d*)(\\D*)$/;\nlet reDistrictNumber = /^\\d+$/;\nlet reDistrictNumeric = /^\\d/;\nlet reLeadingZero = /^0+(.*)/;\n\n// Normalize any numeric part to have no padded leading zeros\nexport function canonicalDistrictID(districtID: string): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n if (a[2].length > 0)\n a[2] = String(Number(a[2]));\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n return districtID;\n}\n\n// Normalize any numeric part to have four digits with padded leading zeros\nexport function canonicalSortingDistrictID(districtID: string): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n let s = a[2];\n if (s.length > 0)\n {\n switch (s.length)\n {\n case 1: s = `000${s}`; break;\n case 2: s = `00${s}`; break;\n case 3: s = `0${s}`; break;\n }\n a[2] = s;\n }\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n return districtID;\n}\n\n// Return numeric part of districtID (or -1 if there is none)\nexport function canonicalNumericFromDistrictID(districtID: string): number\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n let s = a[2];\n if (s.length > 0)\n return Number(s);\n }\n return -1;\n}\n\nexport function canonicalDistrictIDFromNumber(districtID: string, n: number): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n a[2] = String(n);\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n else\n districtID = String(n);\n return districtID;\n}\n\n// Numbers start at 1\nexport type DistrictOrder = { [districtID: string]: number };\n\nexport function canonicalDistrictIDOrdering(order: DistrictOrder): DistrictOrder\n{\n let keys = Object.keys(order);\n let i: number;\n let a: any = [];\n let template: string = undefined;\n\n for (i = 0; i < keys.length; i++)\n {\n let s = keys[i];\n keys[i] = canonicalSortingDistrictID(s);\n let n = canonicalNumericFromDistrictID(s);\n if (n > 0)\n {\n if (template === undefined)\n template = s;\n a[n] = true;\n }\n }\n if (template !== undefined)\n {\n for (i = 1; i < a.length; i++)\n if (a[i] === undefined)\n keys.push(canonicalDistrictIDFromNumber(template, i));\n }\n keys.sort();\n order = {};\n for (i = 0; i < keys.length; i++)\n order[canonicalDistrictID(keys[i])] = i+1;\n if (order['ZZZ'])\n delete order['ZZZ'];\n return order;\n}\n","module.exports = require(\"object-hash\");"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://dra-types/webpack/universalModuleDefinition","webpack://dra-types/webpack/bootstrap","webpack://dra-types/./lib/all.ts","webpack://dra-types/./lib/dra-types.ts","webpack://dra-types/external \"@dra2020/util\"","webpack://dra-types/external \"object-hash\""],"names":[],"mappings":"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AAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC;AAEW,oBAAY,GAAQ;IAC/B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC;AAEF,SAAgB,YAAY,CAAC,KAAa;IAExC,IAAI,EAAE,GAAG,UAAU,CAAC;IAEpB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,oBAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAPD,oCAOC;;;;;;;;;;;;ACveD,0C;;;;;;;;;;;ACAA,wC","file":"dra-types.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"dra-types\"] = factory();\n\telse\n\t\troot[\"dra-types\"] = factory();\n})(global, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./lib/all.ts\");\n","export * from './dra-types';\n","// Public libraries\nimport * as Hash from 'object-hash';\nimport * as Util from '@dra2020/util';\n\n// Used internally to index into District Properties Array\nexport type BlockMap = { [id: string]: number };\n\n// Used more generically and allows string districtIDs\nexport type BlockMapping = { [id: string]: string };\n\n// Type for single comment\nexport interface Comment\n{\n userid: string;\n text: string;\n date: string;\n recommend: number;\n}\n\n// Comment record associated with a map\nexport interface CommentList\n{\n id?: string;\n [commentid: string]: Comment | string; // Really just Comment but make TypeScript happy\n}\n\n// Supported like kinds\nexport type LikeKind = 'like' | 'love' | 'wow' | 'angry' | 'funny';\n\n// Like record for an individual like\nexport interface Like\n{\n date: string;\n kind: LikeKind;\n}\n\n// Record for likes associated with a map\nexport interface LikeList\n{\n id?: string;\n [userid: string]: Like | string; // Really just Like but make TypeScript happy\n}\n\n// Record for likes an individual user has performed\nexport interface UserLikes\n{\n id?: string;\n [aid: string]: Like | string; // Really just Like but make TypeScript happy\n}\n\nexport interface SplitBlock\n{\n id?: string;\n chunk?: string;\n state: string;\n datasource: string;\n geoid: string;\n blocks: string[];\n}\n\nexport type DistrictToSplitBlock = { [districtID: string]: SplitBlock[] };\n\n// Canonical hashing of splitblock data\nfunction hash(o: any): string\n{\n return Hash(o,\n { respectType: false,\n unorderedArrays: true,\n unorderedObjects: true,\n excludeKeys: (k: string) => (k === 'id' || k === 'chunk')\n });\n}\n\nexport function vgeoidToGeoid(vgeoid: string): string\n{\n let re = /vfeature_([^_]*)_.*/;\n let a = re.exec(vgeoid);\n if (a == null || a.length != 2)\n return '';\n else\n return a[1];\n}\n\nexport function vgeoidToChunk(vgeoid: string): string\n{\n // vgeoid is string of form: \"vfeature_[geoid]_[chunkid]_[hash]\"\n // the contents are chunked into a file of form \"vfeature_chunk_[chunkid]\"\n // So extract the chunk ID and download that.\n let re = /vfeature_([^_]*)_([^_*])_(.*)/;\n let a = re.exec(vgeoid);\n if (a && a.length == 4)\n vgeoid = `vfeature_chunk_${a[2]}`;\n else\n vgeoid = null;\n\n return vgeoid;\n}\n\nexport function vgeoidToHash(vgeoid: string): string\n{\n // vgeoid is string of form: \"vfeature_[geoid]_[chunkid]_[hash]\"\n let re = /vfeature_([^_]*)_([^_*])_(.*)/;\n let a = re.exec(vgeoid);\n if (a && a.length == 4)\n vgeoid = a[3];\n else\n vgeoid = null;\n\n return vgeoid;\n}\n\nexport function isVfeature(geoid: string): boolean\n{\n return geoid.indexOf('vfeature') === 0;\n}\n\nexport function splitToCacheKey(s: SplitBlock): string\n{\n if (s.id === undefined)\n s.id = hash(s);\n if (s.chunk === undefined)\n s.chunk = \"0\";\n\n return `_${s.state}_${s.datasource}_vfeature_${s.geoid}_${s.chunk}_${s.id}.geojson`;\n}\n\nexport function splitToChunkKey(s: SplitBlock): string\n{\n if (s.chunk === undefined)\n s.chunk = \"0\";\n\n return `_${s.state}_${s.datasource}_vfeature_chunk_${s.chunk}.geojson`;\n}\n\nexport function splitToPrefix(s: SplitBlock): string\n{\n if (s.blocks === undefined)\n {\n let re = /_([^_]*)_(.*)_vfeature.*\\.geojson$/;\n let a = re.exec(s.id);\n if (a && a.length == 3)\n return `_${a[1]}_${a[2]}`;\n return s.id;\n }\n return `_${s.state}_${s.datasource}`;\n}\n\nexport function cacheKeysToChunkHash(keys: string[]): string\n{\n return hash(keys);\n}\n\nlet reNumeric = /^(\\D*)(\\d*)(\\D*)$/;\nlet reDistrictNumber = /^\\d+$/;\nlet reDistrictNumeric = /^\\d/;\n\n// Normalize any numeric part to have no padded leading zeros\nexport function canonicalDistrictID(districtID: string): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n if (a[2].length > 0)\n a[2] = String(Number(a[2]));\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n return districtID;\n}\n\n// Normalize any numeric part to have four digits with padded leading zeros\nexport function canonicalSortingDistrictID(districtID: string): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n let s = a[2];\n if (s.length > 0)\n {\n switch (s.length)\n {\n case 1: s = `000${s}`; break;\n case 2: s = `00${s}`; break;\n case 3: s = `0${s}`; break;\n }\n a[2] = s;\n }\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n return districtID;\n}\n\n// Return numeric part of districtID (or -1 if there is none)\nexport function canonicalNumericFromDistrictID(districtID: string): number\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n let s = a[2];\n if (s.length > 0)\n return Number(s);\n }\n return -1;\n}\n\nexport function canonicalDistrictIDFromNumber(districtID: string, n: number): string\n{\n let a = reNumeric.exec(districtID);\n if (a && a.length == 4)\n {\n a[2] = String(n);\n districtID = `${a[1]}${a[2]}${a[3]}`;\n }\n else\n districtID = String(n);\n return districtID;\n}\n\n// Numbers start at 1\nexport type DistrictOrder = { [districtID: string]: number };\n\nexport function canonicalDistrictIDOrdering(order: DistrictOrder): DistrictOrder\n{\n let keys = Object.keys(order);\n let i: number;\n let a: any = [];\n let template: string = undefined;\n\n keys = keys.map((s: string) => canonicalSortingDistrictID(s));\n keys.sort();\n order = {};\n for (i = 0; i < keys.length; i++)\n order[canonicalDistrictID(keys[i])] = i+1;\n\n // Remove water districts\n if (order['ZZZ'])\n delete order['ZZZ'];\n\n return order;\n}\n\nexport interface ConvertResult\n{\n inBlockMap: BlockMapping;\n inStateMap: BlockMapping;\n outValid: boolean;\n outState: string;\n outMap: BlockMapping;\n outOrder: DistrictOrder;\n outDistrictToSplit: DistrictToSplitBlock;\n}\n\nexport function blockmapToState(blockMap: BlockMapping): string\n{\n for (var id in blockMap) if (blockMap.hasOwnProperty(id))\n return geoidToState(id);\n return null;\n}\n\n// blockToVTD:\n// Take BlockMapping (simple map of GEOID to districtID) and a per-state map of block-level GEOID to VTD\n// and return the output mapping of VTD to districtID, as well a data structure that describes any VTD's\n// that need to be split between districtIDs. Also returns the DistrictOrder structure that defines the\n// districtIDs that were used by the file.\n//\n// The state (as specified by the first two digits of the GEOID) is also determined. If the GEOID's do\n// not all specify the same state, the mapping is considered invalid and the outValid flag is set to false.\n//\n\nexport function blockmapToVTDmap(blockMap: BlockMapping, stateMap: BlockMapping): ConvertResult\n{\n let res: ConvertResult = {\n inBlockMap: blockMap,\n inStateMap: stateMap,\n outValid: true,\n outState: null,\n outMap: {},\n outOrder: {},\n outDistrictToSplit: {}\n };\n\n let bmGather: { [geoid: string]: { [district: string]: { [blockid: string]: boolean } } } = {};\n let revMap: BlockMapping = {};\n let id: string;\n\n if (stateMap)\n for (id in stateMap) if (stateMap.hasOwnProperty(id))\n revMap[stateMap[id]] = null;\n\n // First aggregate into features across all the blocks\n for (id in blockMap) if (blockMap.hasOwnProperty(id))\n {\n let state = geoidToState(id);\n if (res.outState == null)\n res.outState = state;\n else if (res.outState !== state)\n {\n res.outValid = false;\n break;\n }\n\n let districtID: string = canonicalDistrictID(blockMap[id]);\n\n // Just ignore ZZZ (water) blocks\n if (districtID === 'ZZZ')\n continue;\n\n let n: number = id.length;\n let geoid: string;\n\n // Simple test for block id (vs. voting district or block group) id\n if (n >= 15)\n {\n if (stateMap && stateMap[id] !== undefined)\n geoid = stateMap[id];\n else\n {\n geoid = id.substr(0, 12); // heuristic for mapping blockID to blockgroupID\n if (revMap[geoid] === undefined)\n {\n res.outValid = false;\n break;\n }\n }\n }\n else\n geoid = id;\n\n if (res.outOrder[districtID] === undefined)\n res.outOrder[districtID] = 0;\n\n let districtToBlocks: { [districtID: string]: { [blockid: string]: boolean } } = bmGather[geoid];\n if (districtToBlocks === undefined)\n bmGather[geoid] = { [districtID]: { [id]: true } };\n else\n {\n let thisDistrict: { [blockid: string]: boolean } = districtToBlocks[districtID];\n if (thisDistrict === undefined)\n {\n thisDistrict = { };\n districtToBlocks[districtID] = thisDistrict;\n }\n thisDistrict[id] = true;\n }\n }\n\n // Now determine actual mapping of blocks to features, looking for split features\n for (let geoid in bmGather) if (bmGather.hasOwnProperty(geoid))\n {\n let districtToBlocks = bmGather[geoid];\n if (Util.countKeys(districtToBlocks) == 1)\n {\n res.outMap[geoid] = Util.nthKey(districtToBlocks);\n }\n else\n {\n for (let districtID in districtToBlocks) if (districtToBlocks.hasOwnProperty(districtID))\n {\n let split: SplitBlock = { state: '', datasource: '', geoid: geoid, blocks: Object.keys(districtToBlocks[districtID]) };\n let splits = res.outDistrictToSplit[districtID];\n if (splits === undefined)\n {\n splits = [];\n res.outDistrictToSplit[districtID] = splits;\n }\n splits.push(split);\n }\n }\n }\n\n res.outOrder = canonicalDistrictIDOrdering(res.outOrder);\n\n return res;\n}\n\nexport const GEOIDToState: any = {\n '01': 'AL',\n '02': 'AK',\n '04': 'AZ',\n '05': 'AR',\n '06': 'CA',\n '08': 'CO',\n '09': 'CT',\n '10': 'DE',\n '12': 'FL',\n '13': 'GA',\n '15': 'HI',\n '16': 'ID',\n '17': 'IL',\n '18': 'IN',\n '19': 'IA',\n '20': 'KS',\n '21': 'KY',\n '22': 'LA',\n '23': 'ME',\n '24': 'MD',\n '25': 'MA',\n '26': 'MI',\n '27': 'MN',\n '28': 'MS',\n '29': 'MO',\n '30': 'MT',\n '31': 'NE',\n '32': 'NV',\n '33': 'NH',\n '34': 'NJ',\n '35': 'NM',\n '36': 'NY',\n '37': 'NC',\n '38': 'ND',\n '39': 'OH',\n '40': 'OK',\n '41': 'OR',\n '42': 'PA',\n '44': 'RI',\n '45': 'SC',\n '46': 'SD',\n '47': 'TN',\n '48': 'TX',\n '49': 'UT',\n '50': 'VT',\n '51': 'VA',\n '53': 'WA',\n '54': 'WV',\n '55': 'WI',\n '56': 'WY',\n};\n\nexport const StateToGEOID: any = {\n 'AL': '01',\n 'AK': '02',\n 'AZ': '04',\n 'AR': '05',\n 'CA': '06',\n 'CO': '08',\n 'CT': '09',\n 'DE': '10',\n 'FL': '12',\n 'GA': '13',\n 'HI': '15',\n 'ID': '16',\n 'IL': '17',\n 'IN': '18',\n 'IA': '19',\n 'KS': '20',\n 'KY': '21',\n 'LA': '22',\n 'ME': '23',\n 'MD': '24',\n 'MA': '25',\n 'MI': '26',\n 'MN': '27',\n 'MS': '28',\n 'MO': '29',\n 'MT': '30',\n 'NE': '31',\n 'NV': '32',\n 'NH': '33',\n 'NJ': '34',\n 'NM': '35',\n 'NY': '36',\n 'NC': '37',\n 'ND': '38',\n 'OH': '39',\n 'OK': '40',\n 'OR': '41',\n 'PA': '42',\n 'RI': '44',\n 'SC': '45',\n 'SD': '46',\n 'TN': '47',\n 'TX': '48',\n 'UT': '49',\n 'VT': '50',\n 'VA': '51',\n 'WA': '53',\n 'WV': '54',\n 'WI': '55',\n 'WY': '56',\n};\n\nexport function geoidToState(geoid: string): string\n{\n let re = /^(..).*$/;\n\n let a = re.exec(geoid);\n if (a == null || a.length != 2) return null;\n return GEOIDToState[a[1]];\n}\n","module.exports = require(\"@dra2020/util\");","module.exports = require(\"object-hash\");"],"sourceRoot":""}
package/lib/dra-types.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  // Public libraries
2
2
  import * as Hash from 'object-hash';
3
+ import * as Util from '@dra2020/util';
4
+
5
+ // Used internally to index into District Properties Array
6
+ export type BlockMap = { [id: string]: number };
7
+
8
+ // Used more generically and allows string districtIDs
9
+ export type BlockMapping = { [id: string]: string };
3
10
 
4
11
  // Type for single comment
5
12
  export interface Comment
@@ -89,6 +96,19 @@ export function vgeoidToChunk(vgeoid: string): string
89
96
  return vgeoid;
90
97
  }
91
98
 
99
+ export function vgeoidToHash(vgeoid: string): string
100
+ {
101
+ // vgeoid is string of form: "vfeature_[geoid]_[chunkid]_[hash]"
102
+ let re = /vfeature_([^_]*)_([^_*])_(.*)/;
103
+ let a = re.exec(vgeoid);
104
+ if (a && a.length == 4)
105
+ vgeoid = a[3];
106
+ else
107
+ vgeoid = null;
108
+
109
+ return vgeoid;
110
+ }
111
+
92
112
  export function isVfeature(geoid: string): boolean
93
113
  {
94
114
  return geoid.indexOf('vfeature') === 0;
@@ -133,7 +153,6 @@ export function cacheKeysToChunkHash(keys: string[]): string
133
153
  let reNumeric = /^(\D*)(\d*)(\D*)$/;
134
154
  let reDistrictNumber = /^\d+$/;
135
155
  let reDistrictNumeric = /^\d/;
136
- let reLeadingZero = /^0+(.*)/;
137
156
 
138
157
  // Normalize any numeric part to have no padded leading zeros
139
158
  export function canonicalDistrictID(districtID: string): string
@@ -206,29 +225,264 @@ export function canonicalDistrictIDOrdering(order: DistrictOrder): DistrictOrder
206
225
  let a: any = [];
207
226
  let template: string = undefined;
208
227
 
209
- for (i = 0; i < keys.length; i++)
210
- {
211
- let s = keys[i];
212
- keys[i] = canonicalSortingDistrictID(s);
213
- let n = canonicalNumericFromDistrictID(s);
214
- if (n > 0)
215
- {
216
- if (template === undefined)
217
- template = s;
218
- a[n] = true;
219
- }
220
- }
221
- if (template !== undefined)
222
- {
223
- for (i = 1; i < a.length; i++)
224
- if (a[i] === undefined)
225
- keys.push(canonicalDistrictIDFromNumber(template, i));
226
- }
228
+ keys = keys.map((s: string) => canonicalSortingDistrictID(s));
227
229
  keys.sort();
228
230
  order = {};
229
231
  for (i = 0; i < keys.length; i++)
230
232
  order[canonicalDistrictID(keys[i])] = i+1;
233
+
234
+ // Remove water districts
231
235
  if (order['ZZZ'])
232
236
  delete order['ZZZ'];
237
+
233
238
  return order;
234
239
  }
240
+
241
+ export interface ConvertResult
242
+ {
243
+ inBlockMap: BlockMapping;
244
+ inStateMap: BlockMapping;
245
+ outValid: boolean;
246
+ outState: string;
247
+ outMap: BlockMapping;
248
+ outOrder: DistrictOrder;
249
+ outDistrictToSplit: DistrictToSplitBlock;
250
+ }
251
+
252
+ export function blockmapToState(blockMap: BlockMapping): string
253
+ {
254
+ for (var id in blockMap) if (blockMap.hasOwnProperty(id))
255
+ return geoidToState(id);
256
+ return null;
257
+ }
258
+
259
+ // blockToVTD:
260
+ // Take BlockMapping (simple map of GEOID to districtID) and a per-state map of block-level GEOID to VTD
261
+ // and return the output mapping of VTD to districtID, as well a data structure that describes any VTD's
262
+ // that need to be split between districtIDs. Also returns the DistrictOrder structure that defines the
263
+ // districtIDs that were used by the file.
264
+ //
265
+ // The state (as specified by the first two digits of the GEOID) is also determined. If the GEOID's do
266
+ // not all specify the same state, the mapping is considered invalid and the outValid flag is set to false.
267
+ //
268
+
269
+ export function blockmapToVTDmap(blockMap: BlockMapping, stateMap: BlockMapping): ConvertResult
270
+ {
271
+ let res: ConvertResult = {
272
+ inBlockMap: blockMap,
273
+ inStateMap: stateMap,
274
+ outValid: true,
275
+ outState: null,
276
+ outMap: {},
277
+ outOrder: {},
278
+ outDistrictToSplit: {}
279
+ };
280
+
281
+ let bmGather: { [geoid: string]: { [district: string]: { [blockid: string]: boolean } } } = {};
282
+ let revMap: BlockMapping = {};
283
+ let id: string;
284
+
285
+ if (stateMap)
286
+ for (id in stateMap) if (stateMap.hasOwnProperty(id))
287
+ revMap[stateMap[id]] = null;
288
+
289
+ // First aggregate into features across all the blocks
290
+ for (id in blockMap) if (blockMap.hasOwnProperty(id))
291
+ {
292
+ let state = geoidToState(id);
293
+ if (res.outState == null)
294
+ res.outState = state;
295
+ else if (res.outState !== state)
296
+ {
297
+ res.outValid = false;
298
+ break;
299
+ }
300
+
301
+ let districtID: string = canonicalDistrictID(blockMap[id]);
302
+
303
+ // Just ignore ZZZ (water) blocks
304
+ if (districtID === 'ZZZ')
305
+ continue;
306
+
307
+ let n: number = id.length;
308
+ let geoid: string;
309
+
310
+ // Simple test for block id (vs. voting district or block group) id
311
+ if (n >= 15)
312
+ {
313
+ if (stateMap && stateMap[id] !== undefined)
314
+ geoid = stateMap[id];
315
+ else
316
+ {
317
+ geoid = id.substr(0, 12); // heuristic for mapping blockID to blockgroupID
318
+ if (revMap[geoid] === undefined)
319
+ {
320
+ res.outValid = false;
321
+ break;
322
+ }
323
+ }
324
+ }
325
+ else
326
+ geoid = id;
327
+
328
+ if (res.outOrder[districtID] === undefined)
329
+ res.outOrder[districtID] = 0;
330
+
331
+ let districtToBlocks: { [districtID: string]: { [blockid: string]: boolean } } = bmGather[geoid];
332
+ if (districtToBlocks === undefined)
333
+ bmGather[geoid] = { [districtID]: { [id]: true } };
334
+ else
335
+ {
336
+ let thisDistrict: { [blockid: string]: boolean } = districtToBlocks[districtID];
337
+ if (thisDistrict === undefined)
338
+ {
339
+ thisDistrict = { };
340
+ districtToBlocks[districtID] = thisDistrict;
341
+ }
342
+ thisDistrict[id] = true;
343
+ }
344
+ }
345
+
346
+ // Now determine actual mapping of blocks to features, looking for split features
347
+ for (let geoid in bmGather) if (bmGather.hasOwnProperty(geoid))
348
+ {
349
+ let districtToBlocks = bmGather[geoid];
350
+ if (Util.countKeys(districtToBlocks) == 1)
351
+ {
352
+ res.outMap[geoid] = Util.nthKey(districtToBlocks);
353
+ }
354
+ else
355
+ {
356
+ for (let districtID in districtToBlocks) if (districtToBlocks.hasOwnProperty(districtID))
357
+ {
358
+ let split: SplitBlock = { state: '', datasource: '', geoid: geoid, blocks: Object.keys(districtToBlocks[districtID]) };
359
+ let splits = res.outDistrictToSplit[districtID];
360
+ if (splits === undefined)
361
+ {
362
+ splits = [];
363
+ res.outDistrictToSplit[districtID] = splits;
364
+ }
365
+ splits.push(split);
366
+ }
367
+ }
368
+ }
369
+
370
+ res.outOrder = canonicalDistrictIDOrdering(res.outOrder);
371
+
372
+ return res;
373
+ }
374
+
375
+ export const GEOIDToState: any = {
376
+ '01': 'AL',
377
+ '02': 'AK',
378
+ '04': 'AZ',
379
+ '05': 'AR',
380
+ '06': 'CA',
381
+ '08': 'CO',
382
+ '09': 'CT',
383
+ '10': 'DE',
384
+ '12': 'FL',
385
+ '13': 'GA',
386
+ '15': 'HI',
387
+ '16': 'ID',
388
+ '17': 'IL',
389
+ '18': 'IN',
390
+ '19': 'IA',
391
+ '20': 'KS',
392
+ '21': 'KY',
393
+ '22': 'LA',
394
+ '23': 'ME',
395
+ '24': 'MD',
396
+ '25': 'MA',
397
+ '26': 'MI',
398
+ '27': 'MN',
399
+ '28': 'MS',
400
+ '29': 'MO',
401
+ '30': 'MT',
402
+ '31': 'NE',
403
+ '32': 'NV',
404
+ '33': 'NH',
405
+ '34': 'NJ',
406
+ '35': 'NM',
407
+ '36': 'NY',
408
+ '37': 'NC',
409
+ '38': 'ND',
410
+ '39': 'OH',
411
+ '40': 'OK',
412
+ '41': 'OR',
413
+ '42': 'PA',
414
+ '44': 'RI',
415
+ '45': 'SC',
416
+ '46': 'SD',
417
+ '47': 'TN',
418
+ '48': 'TX',
419
+ '49': 'UT',
420
+ '50': 'VT',
421
+ '51': 'VA',
422
+ '53': 'WA',
423
+ '54': 'WV',
424
+ '55': 'WI',
425
+ '56': 'WY',
426
+ };
427
+
428
+ export const StateToGEOID: any = {
429
+ 'AL': '01',
430
+ 'AK': '02',
431
+ 'AZ': '04',
432
+ 'AR': '05',
433
+ 'CA': '06',
434
+ 'CO': '08',
435
+ 'CT': '09',
436
+ 'DE': '10',
437
+ 'FL': '12',
438
+ 'GA': '13',
439
+ 'HI': '15',
440
+ 'ID': '16',
441
+ 'IL': '17',
442
+ 'IN': '18',
443
+ 'IA': '19',
444
+ 'KS': '20',
445
+ 'KY': '21',
446
+ 'LA': '22',
447
+ 'ME': '23',
448
+ 'MD': '24',
449
+ 'MA': '25',
450
+ 'MI': '26',
451
+ 'MN': '27',
452
+ 'MS': '28',
453
+ 'MO': '29',
454
+ 'MT': '30',
455
+ 'NE': '31',
456
+ 'NV': '32',
457
+ 'NH': '33',
458
+ 'NJ': '34',
459
+ 'NM': '35',
460
+ 'NY': '36',
461
+ 'NC': '37',
462
+ 'ND': '38',
463
+ 'OH': '39',
464
+ 'OK': '40',
465
+ 'OR': '41',
466
+ 'PA': '42',
467
+ 'RI': '44',
468
+ 'SC': '45',
469
+ 'SD': '46',
470
+ 'TN': '47',
471
+ 'TX': '48',
472
+ 'UT': '49',
473
+ 'VT': '50',
474
+ 'VA': '51',
475
+ 'WA': '53',
476
+ 'WV': '54',
477
+ 'WI': '55',
478
+ 'WY': '56',
479
+ };
480
+
481
+ export function geoidToState(geoid: string): string
482
+ {
483
+ let re = /^(..).*$/;
484
+
485
+ let a = re.exec(geoid);
486
+ if (a == null || a.length != 2) return null;
487
+ return GEOIDToState[a[1]];
488
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dra2020/dra-types",
3
- "version": "1.0.16",
3
+ "version": "1.1.0",
4
4
  "description": "Shared types used between client and server.",
5
5
  "main": "dist/dra-types.js",
6
6
  "types": "./dist/all.d.ts",
@@ -33,6 +33,7 @@
33
33
  "webpack-cli": "^3.3.9"
34
34
  },
35
35
  "dependencies": {
36
+ "@dra2020/util": "^1.0.38",
36
37
  "object-hash": "^2.0.0"
37
38
  }
38
39
  }
package/webpack.config.js CHANGED
@@ -10,6 +10,12 @@ fs.readdirSync('node_modules')
10
10
  nodeModules[mod] = 'commonjs ' + mod;
11
11
  });
12
12
 
13
+ fs.readdirSync('node_modules/@dra2020')
14
+ .forEach((mod) => {
15
+ mod = '@dra2020/' + mod;
16
+ nodeModules[mod] = 'commonjs ' + mod;
17
+ });
18
+
13
19
  var libConfig = {
14
20
  entry: {
15
21
  library: './lib/all.ts'