Use Set, simplify util functions to collect entities with children

This commit is contained in:
Bryan Housel
2019-04-05 11:05:04 -04:00
parent 6508edf820
commit f17ebee402
2 changed files with 50 additions and 47 deletions

View File

@@ -300,8 +300,8 @@ export function coreContext() {
var features;
context.features = function() { return features; };
context.hasHiddenConnections = function(id) {
var graph = history.graph(),
entity = graph.entity(id);
var graph = history.graph();
var entity = graph.entity(id);
return features.hasHiddenConnections(entity, graph);
};

View File

@@ -6,10 +6,9 @@ import { fixRTLTextForSvg, rtlRegex } from './svg_paths_rtl_fix';
export function utilTagText(entity) {
var obj = (entity && entity.tags) || {};
return Object.keys(obj).map(function(k) {
var v = obj[k];
return k + '=' + v;
}).join(', ');
return Object.keys(obj)
.map(function(k) { return k + '=' + obj[k]; })
.join(', ');
}
@@ -18,47 +17,44 @@ export function utilEntitySelector(ids) {
}
// returns an selector to select entity ids for:
// - entityIDs passed in
// - shallow descendant entityIDs for any of those entities that are relations
export function utilEntityOrMemberSelector(ids, graph) {
var s = utilEntitySelector(ids);
var seen = new Set(ids);
ids.forEach(collectShallowDescendants);
return utilEntitySelector(Array.from(seen));
ids.forEach(function(id) {
function collectShallowDescendants(id) {
var entity = graph.hasEntity(id);
if (entity && entity.type === 'relation') {
entity.members.forEach(function(member) {
s += ',.' + member.id;
});
}
});
if (!entity || entity.type !== 'relation') return;
return s;
entity.members
.map(function(member) { return member.id; })
.forEach(function(id) { seen.add(id); });
}
}
// returns an selector to select entity ids for:
// - entityIDs passed in
// - deep descendant entityIDs for any of those entities that are relations
export function utilEntityOrDeepMemberSelector(ids, graph) {
var seen = {};
var allIDs = [];
var seen = new Set();
ids.forEach(collectDeepDescendants);
return utilEntitySelector(Array.from(seen));
function addEntityAndMembersIfNotYetSeen(id) {
// avoid infinite recursion for circular relations by skipping seen entities
if (seen[id]) return;
// mark the entity as seen
seen[id] = true;
// add the id;
allIDs.push(id);
if (graph.hasEntity(id)) {
var entity = graph.entity(id);
if (entity.type === 'relation' && entity.members) {
entity.members.forEach(function(member){
addEntityAndMembersIfNotYetSeen(member.id);
});
}
}
function collectDeepDescendants(id) {
if (seen.has(id)) return;
seen.add(id);
var entity = graph.hasEntity(id);
if (!entity || entity.type !== 'relation') return;
entity.members
.map(function(member) { return member.id; })
.forEach(collectDeepDescendants); // recurse
}
ids.forEach(function(id) {
addEntityAndMembersIfNotYetSeen(id);
});
return utilEntitySelector(allIDs);
}
@@ -70,25 +66,32 @@ export function utilHighlightEntities(ids, highlighted, context) {
}
// returns an Array that is the union of:
// - nodes for any nodeIDs passed in
// - child nodes of any wayIDs passed in
// - descendant member and child nodes of relationIDs passed in
export function utilGetAllNodes(ids, graph) {
var seen = {};
var nodes = [];
ids.forEach(getNodes);
return nodes;
var seen = new Set();
var nodes = new Set();
function getNodes(id) {
if (seen[id]) return;
seen[id] = true;
ids.forEach(collectNodes);
return Array.from(nodes);
function collectNodes(id) {
if (seen.has(id)) return;
seen.add(id);
var entity = graph.hasEntity(id);
if (!entity) return;
if (entity.type === 'node') {
nodes.push(entity);
nodes.add(entity);
} else if (entity.type === 'way') {
entity.nodes.forEach(getNodes);
entity.nodes.forEach(collectNodes);
} else {
entity.members.map(function(member) { return member.id; }).forEach(getNodes);
entity.members
.map(function(member) { return member.id; })
.forEach(collectNodes); // recurse
}
}
}