Files
iD/js/id/core/tree.js
T
Vladimir Agafonkin 3cedc84c74 fix accidental error
2013-07-21 19:15:13 +03:00

115 lines
3.1 KiB
JavaScript

iD.Tree = function(graph) {
var rtree = rbush(),
m = 1000 * 1000 * 100,
head = graph,
queuedCreated = [],
queuedModified = [],
rectangles = {},
x, y, dx, dy, rebased;
function extentRectangle(extent) {
return [
~~(m * extent[0][0]),
~~(m * extent[0][1]),
~~(m * extent[1][0]),
~~(m * extent[1][1])
];
}
function entityRectangle(entity) {
var rect = extentRectangle(entity.extent(head), entity.id);
rect.id = entity.id;
rectangles[entity.id] = rect;
return rect;
}
function remove(entity) {
rtree.remove(rectangles[entity.id]);
delete rectangles[entity.id];
}
function bulkInsert(entities) {
for (var i = 0, rects = []; i < entities.length; i++) {
rects.push(entityRectangle(entities[i]));
}
rtree.load(rects);
}
function bulkReinsert(entities) {
entities.forEach(remove);
bulkInsert(entities);
}
var tree = {
rebase: function(entities) {
for (var i = 0, inserted = []; i < entities.length; i++) {
if (!graph.entities.hasOwnProperty(entities[i])) {
inserted.push(graph.entity(entities[i]));
}
}
bulkInsert(inserted);
rebased = true;
return tree;
},
intersects: function(extent, g) {
head = g;
if (graph !== head || rebased) {
var diff = iD.Difference(graph, head),
modified = {};
diff.modified().forEach(function(d) {
var loc = graph.entities[d.id].loc;
if (!loc || loc[0] !== d.loc[0] || loc[1] !== d.loc[1]) {
modified[d.id] = d;
}
});
var created = diff.created().concat(queuedCreated);
modified = d3.values(diff.addParents(modified))
// some parents might be created, not modified
.filter(function(d) { return !!graph.hasEntity(d.id); })
.concat(queuedModified);
queuedCreated = [];
queuedModified = [];
var reinserted = [],
inserted = [];
modified.forEach(function(d) {
if (head.hasAllChildren(d)) reinserted.push(d);
else queuedModified.push(d);
});
created.forEach(function(d) {
if (head.hasAllChildren(d)) inserted.push(d);
else queuedCreated.push(d);
});
bulkReinsert(reinserted);
bulkInsert(inserted);
diff.deleted().forEach(remove);
graph = head;
rebased = false;
}
return rtree.search(extentRectangle(extent)).map(function (rect) {
return graph.entities[rect.id];
});
},
graph: function() {
return graph;
}
};
return tree;
};