Be smarter about identifying what tree an osm feature might be in

Needed this after I added `highway=bus_stop` to the transit tree
This commit is contained in:
Bryan Housel
2021-03-11 16:28:26 -05:00
parent 9f30ebf551
commit 19a8fd16d2

View File

@@ -198,6 +198,43 @@ function gatherKVs(tags) {
}
// `identifyTree()`
// NSI has a concept of trees: "brands", "operators", "flags", "transit".
// The tree determines things like which tags are namelike, and which tags hold important wikidata.
// This takes an Object of tags and tries to identify what tree to use.
//
// Arguments
// `tags`: `Object` containing the feature's OSM tags
// Returns
// `string` the name of the tree if known
// or 'unknown' if it could match several trees (e.g. amenity/yes)
// or null if no match
//
function identifyTree(tags) {
let unknown;
let t;
// Check all tags
Object.keys(tags).forEach(osmkey => {
if (t) return; // found already
const osmvalue = tags[osmkey];
if (!osmvalue) return;
const vmap = _nsi.kvt.get(osmkey);
if (!vmap) return; // this key is not in nsi
if (osmvalue === 'yes') {
unknown = 'unknown';
} else {
t = vmap.get(osmvalue);
}
});
return t || unknown || null;
}
// `gatherNames()`
// Gather all the namelike values that we will run through the NSI matcher.
// It will gather values primarily from tags `name`, `name:ru`, `flag:name`
@@ -221,26 +258,37 @@ function gatherNames(tags) {
// Patterns for matching OSM keys that might contain namelike values.
// These roughly correspond to the "trees" concept in name-suggestion-index,
// but they can't be trees because there is overlap between different trees
// (e.g. 'amenity/yes' could match something from the "brands" tree or the "operators" tree)
if (tags.route) {
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 (tags.man_made === 'flagpole') {
} 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 {
} else if (t === 'brands') {
patterns = {
primary: /^(name|name:\w+)$/i,
alternate: /^(brand|brand:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i,
};
} else if (t === 'operators') {
patterns = {
primary: /^(name|name:\w+|operator|operator:\w+)$/i,
alternate: /^(brand|brand:\w+|\w+_name|\w+_name:\w+)/i,
};
} else { // unknown/multiple
patterns = {
primary: /^(name|name:\w+)$/i,
alternate: /^(brand|brand:\w+|network|network:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i,
};
}
// Check other tags
// Check all tags
Object.keys(tags).forEach(osmkey => {
const osmvalue = tags[osmkey];
if (!osmvalue) return;