summaryrefslogtreecommitdiffhomepage
path: root/gui/scripts/prepare-rtree.ts
blob: 27fabb2f136aa64a57286873e83cb5aeb391332c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//
// Script that generates r-trees for geo data.
// run with `npm exec ts-node geo-data/prepare-rtree.ts`
//

import * as fs from 'fs';
import * as path from 'path';
import { Topology, GeometryCollection } from 'topojson-specification';
import rbush from 'rbush';

interface GeometryTopologyObjects {
  [key: string]: any;
  geometry: GeometryCollection;
}

function main() {
  const GEOMETRY_DATA_FILES = ['geometry', 'states-provinces-lines'];
  const OUTPUT_DIR = path.join(__dirname, 'out');

  for (const name of GEOMETRY_DATA_FILES) {
    const source = path.join(OUTPUT_DIR, `${name}.json`);
    const destination = path.join(OUTPUT_DIR, `${name}.rbush.json`);

    try {
      processGeometry(source, destination);
    } catch (e) {
      const error = e as Error;
      console.error(`Failed to process ${name}: ${error.message}`);
    }
  }
}

function processGeometry(source: string, destination: string) {
  const collection = JSON.parse(
    fs.readFileSync(source, { encoding: 'utf8' }),
  ) as Topology<GeometryTopologyObjects>;

  const { geometry } = collection.objects;
  const treeData = geometry.geometries.map((object, i) => {
    if (!object.bbox) {
      throw new Error(`Expected a geometry at index ${i} to have a bbox property.`);
    }

    const [minX, minY, maxX, maxY] = object.bbox;
    return {
      ...object,
      minX,
      minY,
      maxX,
      maxY,
    };
  });

  const tree = rbush();
  tree.load(treeData);
  fs.writeFileSync(destination, JSON.stringify(tree.toJSON()));

  console.log(`Saved a rbush to ${destination}`);
}

main();