<script lang="ts"> import {UIEventSource} from "../../Logic/UIEventSource"; import type {Feature} from "geojson"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import ToSvelte from "../Base/ToSvelte.svelte"; import Svg from "../../Svg.js"; import Translations from "../i18n/Translations"; import Loading from "../Base/Loading.svelte"; import Hotkeys from "../Base/Hotkeys"; import {Geocoding} from "../../Logic/Osm/Geocoding"; import {BBox} from "../../Logic/BBox"; import {GeoIndexedStoreForLayer} from "../../Logic/FeatureSource/Actors/GeoIndexedStore"; import {createEventDispatcher, onDestroy} from "svelte"; export let perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer> | undefined = undefined; export let bounds: UIEventSource<BBox>; export let selectedElement: UIEventSource<Feature> | undefined = undefined; export let selectedLayer: UIEventSource<LayerConfig> | undefined = undefined; let searchContents: string = "" export let triggerSearch: UIEventSource<any> = new UIEventSource<any>(undefined) onDestroy(triggerSearch.addCallback(_ => { console.log("TriggerRun pinged") performSearch() })) let isRunning: boolean = false; let inputElement: HTMLInputElement; let feedback: string = undefined; Hotkeys.RegisterHotkey( {ctrl: "F"}, Translations.t.hotkeyDocumentation.selectSearch, () => { inputElement?.focus(); inputElement?.select(); } ); const dispatch = createEventDispatcher<{ searchCompleted, searchIsValid: boolean }>() $: { if (!searchContents?.trim()) { dispatch("searchIsValid", false) }else{ dispatch("searchIsValid", true) } } async function performSearch() { try { isRunning = true; searchContents = searchContents?.trim() ?? ""; if (searchContents === "") { return; } const result = await Geocoding.Search(searchContents, bounds.data); if (result.length == 0) { feedback = Translations.t.general.search.nothing.txt; return; } const poi = result[0]; const [lat0, lat1, lon0, lon1] = poi.boundingbox; bounds.set(new BBox([[lon0, lat0], [lon1, lat1]]).pad(0.01)); if (perLayer !== undefined) { const id = poi.osm_type + "/" + poi.osm_id; const layers = Array.from(perLayer?.values() ?? []); for (const layer of layers) { const found = layer.features.data.find(f => f.properties.id === id); selectedElement?.setData(found); selectedLayer?.setData(layer.layer.layerDef); } } searchContents = "" dispatch("searchIsValid", false) dispatch("searchCompleted") } catch (e) { console.error(e); feedback = Translations.t.general.search.error.txt; } finally { isRunning = false; } } </script> <div class="flex normal-background rounded-full pl-2 justify-between"> <form class="w-full"> {#if isRunning} <Loading>{Translations.t.general.search.searching}</Loading> {:else if feedback !== undefined} <div class="alert" on:click={() => feedback = undefined}> {feedback} </div> {:else } <input type="search" class="w-full" bind:this={inputElement} on:keypress={keypr => keypr.key === "Enter" ? performSearch() : undefined} bind:value={searchContents} placeholder={Translations.t.general.search.search}> {/if} </form> <div class="w-6 h-6 self-end" on:click={performSearch}> <ToSvelte construct={Svg.search_svg}></ToSvelte> </div> </div>