in modules/services/nsi.js [257:353]
function gatherNames(tags) {
const empty = { primary: new Set(), alternate: new Set() };
let primary = new Set();
let alternate = new Set();
let foundSemi = false;
let testNameFragments = false;
let patterns;
// Patterns for matching OSM keys that might contain namelike values.
// These roughly correspond to the "trees" concept in name-suggestion-index,
let t = identifyTree(tags);
if (!t) return empty;
if (t === 'transit') {
patterns = {
primary: /^network$/i,
alternate: /^(operator|operator:\w+|network:\w+|\w+_name|\w+_name:\w+)$/i
};
} else if (t === 'flags') {
patterns = {
primary: /^(flag:name|flag:name:\w+)$/i,
alternate: /^(flag|flag:\w+|subject|subject:\w+)$/i // note: no `country`, we special-case it below
};
} else if (t === 'brands') {
testNameFragments = true;
patterns = {
primary: /^(name|name:\w+)$/i,
alternate: /^(brand|brand:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i,
};
} else if (t === 'operators') {
testNameFragments = true;
patterns = {
primary: /^(name|name:\w+|operator|operator:\w+)$/i,
alternate: /^(brand|brand:\w+|\w+_name|\w+_name:\w+)/i,
};
} else { // unknown/multiple
testNameFragments = true;
patterns = {
primary: /^(name|name:\w+)$/i,
alternate: /^(brand|brand:\w+|network|network:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i,
};
}
// Test `name` fragments, longest to shortest, to fit them into a "Name Branch" pattern.
// e.g. "TUI ReiseCenter - Neuss Innenstadt" -> ["TUI", "ReiseCenter", "Neuss", "Innenstadt"]
if (tags.name && testNameFragments) {
const nameParts = tags.name.split(/[\s\-\/,.]/);
for (let split = nameParts.length; split > 0; split--) {
const name = nameParts.slice(0, split).join(' '); // e.g. "TUI ReiseCenter"
primary.add(name);
}
}
// Check all tags
Object.keys(tags).forEach(osmkey => {
const osmvalue = tags[osmkey];
if (!osmvalue) return;
if (isNamelike(osmkey, 'primary')) {
if (/;/.test(osmvalue)) {
foundSemi = true;
} else {
primary.add(osmvalue);
alternate.delete(osmvalue);
}
} else if (!primary.has(osmvalue) && isNamelike(osmkey, 'alternate')) {
if (/;/.test(osmvalue)) {
foundSemi = true;
} else {
alternate.add(osmvalue);
}
}
});
// For flags only, fallback to `country` tag only if no other namelike values were found.
// See https://github.com/openstreetmap/iD/pull/8305#issuecomment-769174070
if (tags.man_made === 'flagpole' && !primary.size && !alternate.size && !!tags.country) {
const osmvalue = tags.country;
if (/;/.test(osmvalue)) {
foundSemi = true;
} else {
alternate.add(osmvalue);
}
}
// If any namelike value contained a semicolon, return empty set and don't try matching anything.
if (foundSemi) {
return empty;
} else {
return { primary: primary, alternate: alternate };
}
function isNamelike(osmkey, which) {
if (osmkey === 'old_name') return false;
return patterns[which].test(osmkey) && !notNames.test(osmkey);
}
}