mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 09:12:52 +00:00
Since d5e427289, the tree head graph will not update if only tags have
changed - it requires an addition, deletion, or geometry change.
This makes the tree a little more efficient, but we do need to make
sure to return the current entities to the caller.
107 lines
3.0 KiB
JavaScript
107 lines
3.0 KiB
JavaScript
import rbush from 'rbush';
|
|
|
|
import { coreDifference } from './difference';
|
|
|
|
|
|
export function coreTree(head) {
|
|
var rtree = rbush();
|
|
var bboxes = {};
|
|
var tree = {};
|
|
|
|
|
|
function entityBBox(entity) {
|
|
var bbox = entity.extent(head).bbox();
|
|
bbox.id = entity.id;
|
|
bboxes[entity.id] = bbox;
|
|
return bbox;
|
|
}
|
|
|
|
|
|
function updateParents(entity, insertions, memo) {
|
|
head.parentWays(entity).forEach(function(way) {
|
|
if (bboxes[way.id]) {
|
|
rtree.remove(bboxes[way.id]);
|
|
insertions[way.id] = way;
|
|
}
|
|
updateParents(way, insertions, memo);
|
|
});
|
|
|
|
head.parentRelations(entity).forEach(function(relation) {
|
|
if (memo[entity.id]) return;
|
|
memo[entity.id] = true;
|
|
if (bboxes[relation.id]) {
|
|
rtree.remove(bboxes[relation.id]);
|
|
insertions[relation.id] = relation;
|
|
}
|
|
updateParents(relation, insertions, memo);
|
|
});
|
|
}
|
|
|
|
|
|
tree.rebase = function(entities, force) {
|
|
var insertions = {};
|
|
|
|
for (var i = 0; i < entities.length; i++) {
|
|
var entity = entities[i];
|
|
if (!entity.visible) continue;
|
|
|
|
if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
|
|
if (!force) {
|
|
continue;
|
|
} else if (bboxes[entity.id]) {
|
|
rtree.remove(bboxes[entity.id]);
|
|
}
|
|
}
|
|
|
|
insertions[entity.id] = entity;
|
|
updateParents(entity, insertions, {});
|
|
}
|
|
|
|
rtree.load(Object.values(insertions).map(entityBBox));
|
|
|
|
return tree;
|
|
};
|
|
|
|
|
|
tree.intersects = function(extent, graph) {
|
|
if (graph !== head) {
|
|
var diff = coreDifference(head, graph);
|
|
var changed = diff.didChange;
|
|
|
|
if (changed.addition || changed.deletion || changed.geometry) {
|
|
var insertions = {};
|
|
head = graph;
|
|
|
|
if (changed.deletion) {
|
|
diff.deleted().forEach(function(entity) {
|
|
rtree.remove(bboxes[entity.id]);
|
|
delete bboxes[entity.id];
|
|
});
|
|
}
|
|
|
|
if (changed.geometry) {
|
|
diff.modified().forEach(function(entity) {
|
|
rtree.remove(bboxes[entity.id]);
|
|
insertions[entity.id] = entity;
|
|
updateParents(entity, insertions, {});
|
|
});
|
|
}
|
|
|
|
if (changed.addition) {
|
|
diff.created().forEach(function(entity) {
|
|
insertions[entity.id] = entity;
|
|
});
|
|
}
|
|
|
|
rtree.load(Object.values(insertions).map(entityBBox));
|
|
}
|
|
}
|
|
|
|
return rtree.search(extent.bbox())
|
|
.map(function(bbox) { return graph.entity(bbox.id); });
|
|
};
|
|
|
|
|
|
return tree;
|
|
}
|