| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | <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"; | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |   import type { SpecialVisualizationState } from "../SpecialVisualization"; | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |   export let state: SpecialVisualizationState | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |   export let bounds: UIEventSource<BBox> | 
					
						
							|  |  |  |   export let selectedElement: UIEventSource<Feature>; | 
					
						
							|  |  |  |   export let selectedLayer: UIEventSource<LayerConfig>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let searchContents: string = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let isRunning: boolean = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let inputElement: HTMLInputElement; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   let feedback: string = undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Hotkeys.RegisterHotkey( | 
					
						
							|  |  |  |     { ctrl: "F" }, | 
					
						
							|  |  |  |     Translations.t.hotkeyDocumentation.selectSearch, | 
					
						
							|  |  |  |     () => { | 
					
						
							|  |  |  |       inputElement?.focus() | 
					
						
							|  |  |  |       inputElement?.select() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  |   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.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)) | 
					
						
							|  |  |  |       const id = poi.osm_type + "/" + poi.osm_id | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |       const perLayer = state.perLayer | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |       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) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }catch (e) { | 
					
						
							|  |  |  |       console.error(e) | 
					
						
							|  |  |  |       feedback = Translations.t.search.error.txt | 
					
						
							|  |  |  |     } finally { | 
					
						
							|  |  |  |       isRunning = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <div class="flex normal-background rounded-full pl-2"> | 
					
						
							|  |  |  |   <form> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {#if isRunning} | 
					
						
							|  |  |  |       <Loading>{Translations.t.general.search.searching}</Loading> | 
					
						
							|  |  |  |       {:else if feedback !== undefined} | 
					
						
							|  |  |  |       <div class="alert" on:click={() => feedback = undefined}> | 
					
						
							|  |  |  |         {feedback} | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     {:else } | 
					
						
							|  |  |  |       <input | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |         type="search" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         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" on:click={performSearch}> | 
					
						
							|  |  |  |     <ToSvelte construct={Svg.search_ui}></ToSvelte> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </div> |