Files
iD/js/id/core/tree.js
2013-02-27 17:50:42 -05:00

94 lines
2.6 KiB
JavaScript

iD.Tree = function(graph) {
var rtree = new RTree(),
m = 1000 * 1000 * 100,
head = graph,
queuedCreated = [],
queuedModified = [],
x, y, dx, dy, rebased;
function extentRectangle(extent) {
x = m * extent[0][0],
y = m * extent[0][1],
dx = m * extent[1][0] - x || 2,
dy = m * extent[1][1] - y || 2;
return new RTree.Rectangle(~~x, ~~y, ~~dx - 1, ~~dy - 1);
}
function insert(entity) {
rtree.insert(extentRectangle(entity.extent(head)), entity.id);
}
function remove(entity) {
rtree.remove(extentRectangle(entity.extent(graph)), entity.id);
}
function reinsert(entity) {
remove(graph.entities[entity.id]);
insert(entity);
}
var tree = {
rebase: function(entities) {
for (var i = 0; i < entities.length; i++) {
if (!graph.entities.hasOwnProperty(entities[i])) {
insert(graph.entity(entities[i]), true);
}
}
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.entity(d.id); })
.concat(queuedModified);
queuedCreated = [];
queuedModified = [];
modified.forEach(function(d) {
if (head.hasAllChildren(d)) reinsert(d);
else queuedModified.push(d);
});
created.forEach(function(d) {
if (head.hasAllChildren(d)) insert(d);
else queuedCreated.push(d);
});
diff.deleted().forEach(remove);
graph = head;
rebased = false;
}
return rtree.search(extentRectangle(extent))
.map(function(id) { return graph.entity(id); });
},
graph: function() {
return graph;
}
};
return tree;
};