name-suggestion-index
Version:
Canonical common brand names for OpenStreetMap
115 lines • 5.4 kB
TypeScript
import type { HasLocationSet, HasLocationSetID, LocationSetID, Vec2 } from '@rapideditor/location-conflation';
import type { MatchHit, NsiData } from './types.ts';
/** LocationConflation _structural_ type - see name-suggestion-index#12150 **/
export interface LocationResolver {
registerLocationSets<T extends HasLocationSet>(objects: T[]): (T & HasLocationSetID)[];
locationSetsAt(loc: Vec2): Map<LocationSetID, number>;
getLocationSetArea(locationSetID: LocationSetID): number | undefined;
}
/**
* Matches OpenStreetMap `[key, value, name]` tuples against the
* Name Suggestion Index (NSI) canonical items.
*
* Typical usage:
* ```ts
* const matcher = new Matcher();
* matcher.buildMatchIndex(data);
* matcher.buildLocationIndex(data, loco); // optional
* const hits = matcher.match('amenity', 'bank', 'Wells Fargo', [-122.4, 37.8]);
* ```
*/
export declare class Matcher {
/** Primary match index: `kv → { primary, alternate, excludeGeneric, excludeNamed }`. */
private matchIndex;
/** Map of generic-word pattern strings to compiled RegExp objects. */
private genericWords;
/** The location resolver used to resolve locationSets (set by {@link buildLocationIndex}). */
private loco;
/** Map of item id → locationSetID, populated by {@link buildLocationIndex}. */
private itemLocationSetID;
/** Warnings collected during index building (e.g. duplicate cache keys). */
private warnings;
/**
* Creates a new Matcher and initialises the generic-word regex table
* from `config/genericWords.json`.
*/
constructor();
/**
* Builds the primary match index from NSI category data.
* After calling this method the matcher is ready to use via {@link match}.
*
* `data` must be an object keyed by `tree/key/value` paths, e.g.:
* ```json
* {
* "brands/amenity/bank": { "properties": {}, "items": [ … ] },
* "brands/amenity/bar": { "properties": {}, "items": [ … ] }
* }
* ```
* (typically the cache built by `fileTree.read` or loaded from `dist/nsi.json`)
*
* @param data - NSI category data indexed by `tree/key/value` path
*/
buildMatchIndex(data: NsiData): void;
/**
* Registers every item's `locationSet` with the supplied {@link LocationConflation}
* instance so that {@link match} can do location-aware filtering. This is optional —
* skip it if you don't need location-aware matching.
*
* Under the hood this just calls `loco.registerLocationSets(items)`, which:
* - assigns `item.locationSetID` in place (e.g. `'+[Q30]'`),
* - builds an inverted spatial index without resolving combined polygons,
* - is tolerant of bad/empty locationSets (falls back to world).
*
* `data` must be an object keyed by `tree/key/value` paths (same format as
* {@link buildMatchIndex}).
*
* @param data - NSI category data indexed by `tree/key/value` path
* @param loco - Optional `LocationConflation` instance used to index locationSets.
* If omitted, a new bare instance is created internally. Callers that have their
* own configured instance (e.g. with a FeatureCollection of custom `.geojson`
* features) should pass it in so indexing and lookups share the same cache.
* Whichever instance is used, the matcher keeps a reference and delegates
* `locationSetsAt` / `getLocationSetArea` calls to it at match time.
*/
buildLocationIndex(data: NsiData, loco?: LocationResolver): void;
/**
* Matches a `[key, value, name]` tuple against the index and returns results.
*
* **Case 1 — canonical match:**
* Returns an array of {@link Hit} objects sorted by match quality:
* - `"primary"` hits (matches `name` tag) come first,
* - `"alternate"` hits (matches `alt_name`, `brand`, etc.) come second.
*
* Within each group, results are sorted by area:
* - **area descending** (worldwide → local) when no `loc` is given,
* - **area ascending** (local → worldwide) when `loc` is given.
*
* Each hit includes the item's `area` in km².
*
* **Case 2 — exclude match:**
* Returns a single-element array with either:
* - `{ match: 'excludeGeneric', pattern, kv }` — a generic word (e.g. "Food Court")
* that is probably not a real name.
* - `{ match: 'excludeNamed', pattern, kv }` — a real but common name (e.g. "Kebabai")
* that is not a brand.
*
* **Case 3 — no match:**
* Returns `null`.
*
* @param k - OSM key (e.g. `"amenity"`)
* @param v - OSM value (e.g. `"bank"`)
* @param n - A name-like string to look up (e.g. `"Wells Fargo"`)
* @param loc - Optional `[lon, lat]` coordinate to restrict results by location
* @returns An array of {@link Hit} results, or `null` if nothing matched.
* @throws {Error} If the match index has not been built yet.
*/
match(k: string, v: string, n: string, loc?: Vec2): Array<MatchHit> | null;
/**
* Returns any warnings discovered while building the match index
* (e.g. duplicate cache keys across trees).
*
* @returns An array of warning message strings (may be empty).
*/
getWarnings(): Array<string>;
}
//# sourceMappingURL=matcher.d.ts.map