UNPKG

3.07 kBJavaScriptView Raw
1'use strict';
2var Promise = require('bluebird');
3var utils = require('./utils');
4module.exports = remove;
5function remove(self, id, bbox, nodeID, store) {
6 store = store || self.store;
7 if (!nodeID) {
8 if (!self.root) {
9 return Promise.reject(new Error('can\'t delete it if there is nothing in the tree'));
10 } else {
11 if (!bbox) {
12 return store.get('$' + id).then(function (bboxen) {
13 return Promise.all(bboxen.map(function (bbox) {
14 return remove(self, id, bbox, self.root, store);
15 }));
16 }, function () {
17 throw new Error ('not found');
18 });
19 } else {
20 return remove(self, id, bbox, self.root, store);
21 }
22 }
23 }
24 return store.get(nodeID).then(function (root) {
25 return findPath(store, id, bbox, [[root]]);
26 }).then(function (path) {
27 var node = path.pop();
28 var toRemove = [];
29 var toUpdate = [];
30 var i = path.length - 1;
31 var tail = path[i];
32 tail.children.splice(indexById(id, tail.children), 1);
33 var bbox, index;
34 while (i) {
35 i--;
36 node = tail;
37 tail = path[i];
38 if (!node.children.length) {
39 tail.children.splice(indexById(node.id, tail.children), 1);
40 toRemove.push(node.id);
41 toUpdate.push(tail);
42 continue;
43 }
44 bbox = node.bbox;
45 node.bbox = node.children.reduce(utils.enlarger);
46 if (utils.equals(bbox, node.bbox)) {
47 break;
48 }
49 if (toUpdate.indexOf(node) === -1) {
50 toUpdate.push(node);
51 }
52 index = indexById(node.id, tail.children);
53 tail.children[index].bbox = [node.bbox[0].slice(), node.bbox[1].slice()];
54 if (toUpdate.indexOf(tail) === -1) {
55 toUpdate.push(tail);
56 }
57 }
58 return store.batch(toRemove.map(function (key) {
59 return {
60 key: key,
61 type: 'del'
62 };
63 }).concat(toUpdate.map(function (item) {
64 return {
65 key: item.id,
66 value: item
67 };
68 }), [{type: 'del', key: '$' + id}]));
69 });
70}
71
72function indexById(id, children) {
73 var i = -1;
74 var len = children.length;
75 while (++i < len) {
76 if (id === children[i].id) {
77 return i;
78 }
79 }
80 throw new Error('id not in node it is claimed to be in');
81}
82function findPath(store, id, bbox, queue) {
83 if (!queue.length) {
84 throw new Error('not found');
85 }
86 var path = queue.pop();
87 var node = path[path.length - 1];
88 var candidates = [];
89 var i = -1;
90 var len = node.children.length;
91 var child;
92 while (++i < len) {
93 child = node.children[i];
94 if (child.id === id && utils.equals(child.bbox, bbox)) {
95 path.push(child);
96 return path;
97 } else if (!child.leaf){
98 if (utils.contains(child.bbox, bbox)) {
99 candidates.push(child.id);
100 }
101 }
102 }
103 return Promise.all(candidates.map(function (id) {
104 return store.get(id);
105 })).then(function (items) {
106 items.forEach(function (item) {
107 var nPath = path.slice();
108 nPath.push(item);
109 queue.push(nPath);
110 });
111 return findPath(store, id, bbox, queue);
112 });
113}
\No newline at end of file