UNPKG

2.8 kBJavaScriptView Raw
1'use strict';
2var utils = require('./utils');
3var Promise = require('bluebird');
4var uuid = require('node-uuid');
5module.exports = function (self, array) {
6 var todo = [load(self, array)];
7 var current;
8 var done = [];
9 var i, j, clen, len, node;
10 function strip(item) {
11 var out = {
12 id: item.id,
13 bbox: [item.bbox[0].slice(), item.bbox[1].slice()]
14 };
15 if ('leaf' in item) {
16 out.leaf = item.leaf;
17 }
18 return out;
19 }
20 while (todo.length) {
21 current = todo;
22 todo = [];
23 i = -1;
24 len = current.length;
25 while (++i < len) {
26 node = current[i];
27 clen = node.children.length;
28 j = -1;
29 // so root will always be first
30 done.push(node);
31 while (++j < clen) {
32 if (node.children[j].children) {
33 todo.push(node.children[j]);
34 } else {
35 node.children[j].leaf = true;
36 done.push(node.children[j]);
37 }
38 node.children[j] = strip(node.children[j]);
39 }
40 }
41 }
42 return done;
43};
44function load(self, array, level, height) {
45 level = level || 0;
46 var len = array.length;
47 var node;
48 //var self.MAX = self.MAX;
49 if (len <= self.MAX) {
50 node = {
51 children: array,
52 level: 1,
53 id: uuid.v4()
54 };
55 node.bbox = node.children.length > 1? node.children.reduce(utils.enlarger): node.children[0].bbox;
56 return node;
57 }
58
59 if (!level) {
60 // target height of the bulk-loaded tree
61 height = Math.ceil(Math.log(len) / Math.log(self.MAX));
62
63 // target number of root entries to maximize storage utilization
64 //self.MAX = Math.ceil(len / Math.pow(self.MAX, height - 1));
65
66 utils.chooseAxis(array, self.MIN);
67 }
68
69 // TODO eliminate recursion?
70
71 node = {
72 children: [],
73 id: uuid.v4()
74 };
75
76 var len1 = Math.ceil(len / self.MAX) * Math.ceil(Math.sqrt(self.MAX));
77 var len2 = utils.max(Math.ceil(len / self.MAX), self.MIN);
78 var i = 0 - len1;
79 var j, slice, sliceLen, childNode;
80 var out = [];
81 //console.log(len1, len2, len);
82 // split the items into M mostly square tiles.exit
83 while ((i += len1) < len) {
84 if ((i + len1 + len1) > len) {
85 slice = array.slice(i);
86 i += len1;
87 } else {
88 slice = array.slice(i, i + len1);
89 }
90 utils.chooseAxis(slice, self.MIN);
91 j = 0 - len2;
92 sliceLen = slice.length;
93 while ((j += len2) < sliceLen) {
94 // pack each entry recursively
95 out.push(slice.slice(j, j + len2));
96 }
97 }
98 var children = out.map(function (slice) {
99 return load(self, slice, level + 1, height - 1);
100 });
101 node.children = children;
102 node.bbox = node.children.length > 1? node.children.reduce(utils.enlarger): node.children[0].bbox;
103 node.level = (Math.max.apply(Math, node.children.map(function (child) {
104 return child.level;
105 })) + 1);
106 return node;
107}
\No newline at end of file