import GeocodingProvider, { GeoCodeResult, GeocodingOptions } from "./GeocodingProvider" export default class CombinedSearcher implements GeocodingProvider { private _providers: ReadonlyArray private _providersWithSuggest: ReadonlyArray constructor(...providers: ReadonlyArray) { this._providers = providers this._providersWithSuggest = providers.filter(pr => pr.suggest !== undefined) } /** * Merges the geocode-results from various sources. * If the same osm-id is mentioned multiple times, only the first result will be kept * @param geocoded * @private */ private merge(geocoded: GeoCodeResult[][]): GeoCodeResult[]{ const results : GeoCodeResult[] = [] const seenIds = new Set() for (const geocodedElement of geocoded) { for (const entry of geocodedElement) { const id = entry.osm_type+ entry.osm_id if(seenIds.has(id)){ continue } seenIds.add(id) results.push(entry) } } return results } async search(query: string, options?: GeocodingOptions): Promise { const results = await Promise.all(this._providers.map(pr => pr.search(query, options))) return this.merge(results) } async suggest(query: string, options?: GeocodingOptions): Promise { const results = await Promise.all(this._providersWithSuggest.map(pr => pr.suggest(query, options))) return this.merge(results) } }