Files
iD/js/id/core/tree.js
2013-07-22 15:30:09 -07:00

114 lines
3.1 KiB
JavaScript

iD.Tree = function(graph) {
var rtree = rbush(),
head = graph,
queuedCreated = [],
queuedModified = [],
rectangles = {},
rebased;
function extentRectangle(extent) {
return [
extent[0][0],
extent[0][1],
extent[1][0],
extent[1][1]
];
}
function entityRectangle(entity) {
var rect = extentRectangle(entity.extent(head));
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;
};