| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   import { Store, UIEventSource } from "../Logic/UIEventSource" | 
					
						
							|  |  |  |   import { Map as MlMap } from "maplibre-gl" | 
					
						
							|  |  |  |   import MaplibreMap from "./Map/MaplibreMap.svelte" | 
					
						
							|  |  |  |   import FeatureSwitchState from "../Logic/State/FeatureSwitchState" | 
					
						
							|  |  |  |   import MapControlButton from "./Base/MapControlButton.svelte" | 
					
						
							|  |  |  |   import ToSvelte from "./Base/ToSvelte.svelte" | 
					
						
							|  |  |  |   import If from "./Base/If.svelte" | 
					
						
							|  |  |  |   import type { Feature } from "geojson" | 
					
						
							|  |  |  |   import SelectedElementView from "./BigComponents/SelectedElementView.svelte" | 
					
						
							|  |  |  |   import LayerConfig from "../Models/ThemeConfig/LayerConfig" | 
					
						
							|  |  |  |   import ThemeViewState from "../Models/ThemeViewState" | 
					
						
							|  |  |  |   import type { MapProperties } from "../Models/MapProperties" | 
					
						
							|  |  |  |   import Geosearch from "./BigComponents/Geosearch.svelte" | 
					
						
							|  |  |  |   import Translations from "./i18n/Translations" | 
					
						
							| 
									
										
										
										
											2024-02-20 13:33:38 +01:00
										 |  |  |   import { | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |     MenuIcon, | 
					
						
							| 
									
										
										
										
											2024-02-20 13:33:38 +01:00
										 |  |  |   } from "@rgossiaux/svelte-heroicons/solid" | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   import Tr from "./Base/Tr.svelte" | 
					
						
							|  |  |  |   import FloatOver from "./Base/FloatOver.svelte" | 
					
						
							|  |  |  |   import Constants from "../Models/Constants" | 
					
						
							|  |  |  |   import LoginToggle from "./Base/LoginToggle.svelte" | 
					
						
							|  |  |  |   import ModalRight from "./Base/ModalRight.svelte" | 
					
						
							|  |  |  |   import LevelSelector from "./BigComponents/LevelSelector.svelte" | 
					
						
							|  |  |  |   import type { RasterLayerPolygon } from "../Models/RasterLayers" | 
					
						
							|  |  |  |   import { AvailableRasterLayers } from "../Models/RasterLayers" | 
					
						
							|  |  |  |   import { onDestroy } from "svelte" | 
					
						
							|  |  |  |   import OpenBackgroundSelectorButton from "./BigComponents/OpenBackgroundSelectorButton.svelte" | 
					
						
							|  |  |  |   import StateIndicator from "./BigComponents/StateIndicator.svelte" | 
					
						
							|  |  |  |   import UploadingImageCounter from "./Image/UploadingImageCounter.svelte" | 
					
						
							|  |  |  |   import PendingChangesIndicator from "./BigComponents/PendingChangesIndicator.svelte" | 
					
						
							|  |  |  |   import Cross from "../assets/svg/Cross.svelte" | 
					
						
							|  |  |  |   import Min from "../assets/svg/Min.svelte" | 
					
						
							|  |  |  |   import Plus from "../assets/svg/Plus.svelte" | 
					
						
							|  |  |  |   import Filter from "../assets/svg/Filter.svelte" | 
					
						
							|  |  |  |   import ImageOperations from "./Image/ImageOperations.svelte" | 
					
						
							| 
									
										
										
										
											2023-12-15 01:46:01 +01:00
										 |  |  |   import VisualFeedbackPanel from "./BigComponents/VisualFeedbackPanel.svelte" | 
					
						
							| 
									
										
										
										
											2023-12-18 01:58:58 +01:00
										 |  |  |   import { Orientation } from "../Sensors/Orientation" | 
					
						
							| 
									
										
										
										
											2024-08-10 12:09:55 +02:00
										 |  |  |   import GeolocationIndicator from "./BigComponents/GeolocationIndicator.svelte" | 
					
						
							| 
									
										
										
										
											2023-12-18 01:30:02 +01:00
										 |  |  |   import Compass_arrow from "../assets/svg/Compass_arrow.svelte" | 
					
						
							| 
									
										
										
										
											2023-12-19 22:21:34 +01:00
										 |  |  |   import ReverseGeocoding from "./BigComponents/ReverseGeocoding.svelte" | 
					
						
							| 
									
										
										
										
											2023-12-20 02:50:08 +01:00
										 |  |  |   import { BBox } from "../Logic/BBox" | 
					
						
							| 
									
										
										
										
											2024-05-02 15:24:31 +02:00
										 |  |  |   import ExtraLinkButton from "./BigComponents/ExtraLinkButton.svelte" | 
					
						
							| 
									
										
										
										
											2024-05-08 13:54:14 +02:00
										 |  |  |   import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource" | 
					
						
							| 
									
										
										
										
											2024-06-19 01:56:19 +02:00
										 |  |  |   import Marker from "./Map/Marker.svelte" | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |   import SelectedElementPanel from "./Base/SelectedElementPanel.svelte" | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |   import MenuDrawer from "./BigComponents/MenuDrawer.svelte" | 
					
						
							|  |  |  |   import DrawerLeft from "./Base/DrawerLeft.svelte" | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |   import Hash from "../Logic/Web/Hash" | 
					
						
							| 
									
										
										
										
											2024-08-29 12:24:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   export let state: ThemeViewState | 
					
						
							|  |  |  |   let layout = state.layout | 
					
						
							|  |  |  |   let maplibremap: UIEventSource<MlMap> = state.map | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |   let state_selectedElement = state.selectedElement | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   let selectedElement: UIEventSource<Feature> = new UIEventSource<Feature>(undefined) | 
					
						
							| 
									
										
										
										
											2023-12-16 01:29:42 +01:00
										 |  |  |   let compass = Orientation.singleton.alpha | 
					
						
							|  |  |  |   let compassLoaded = Orientation.singleton.gotMeasurement | 
					
						
							| 
									
										
										
										
											2023-12-16 01:42:45 +01:00
										 |  |  |   Orientation.singleton.startMeasurements() | 
					
						
							| 
									
										
										
										
											2023-12-19 23:02:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-19 22:08:00 +01:00
										 |  |  |   state.selectedElement.addCallback((selected) => { | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |     if (!selected) { | 
					
						
							| 
									
										
										
										
											2023-12-06 17:27:30 +01:00
										 |  |  |       selectedElement.setData(selected) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |     if (selected !== selectedElement.data) { | 
					
						
							| 
									
										
										
										
											2023-12-06 17:27:30 +01:00
										 |  |  |       // We first set the selected element to 'undefined' to force the popup to close... | 
					
						
							|  |  |  |       selectedElement.setData(undefined) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // ... we give svelte some time to update with requestAnimationFrame ... | 
					
						
							|  |  |  |     window.requestAnimationFrame(() => { | 
					
						
							| 
									
										
										
										
											2023-12-21 01:46:18 +01:00
										 |  |  |       // ... and we force a fresh popup window | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |       selectedElement.setData(selected) | 
					
						
							| 
									
										
										
										
											2023-12-06 17:27:30 +01:00
										 |  |  |     }) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-11-30 01:41:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-03 18:24:00 +01:00
										 |  |  |   let selectedLayer: Store<LayerConfig> = state.selectedElement.mapD((element) => { | 
					
						
							| 
									
										
										
										
											2024-06-27 17:37:34 +02:00
										 |  |  |     const id = element.properties.id | 
					
						
							|  |  |  |     if (id.startsWith("current_view")) { | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |       return currentViewLayer | 
					
						
							| 
									
										
										
										
											2024-04-12 15:03:45 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-07-09 13:42:08 +02:00
										 |  |  |     if (id.startsWith("summary_")) { | 
					
						
							| 
									
										
										
										
											2024-06-27 17:37:34 +02:00
										 |  |  |       console.log("Not selecting a summary object. The summary object is", element) | 
					
						
							|  |  |  |       return undefined | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (id.startsWith(LastClickFeatureSource.newPointElementId)) { | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |       return layout.layers.find((l) => l.id === "last_click") | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-06-27 17:37:34 +02:00
										 |  |  |     if (id === "location_track") { | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |       return layout.layers.find((l) => l.id === "gps_track") | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-06-27 17:37:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |     return state.layout.getMatchingLayer(element.properties) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   let currentZoom = state.mapProperties.zoom | 
					
						
							|  |  |  |   let showCrosshair = state.userRelatedState.showCrosshair | 
					
						
							| 
									
										
										
										
											2023-12-20 02:50:08 +01:00
										 |  |  |   let visualFeedback = state.visualFeedback | 
					
						
							|  |  |  |   let viewport: UIEventSource<HTMLDivElement> = new UIEventSource<HTMLDivElement>(undefined) | 
					
						
							| 
									
										
										
										
											2023-12-21 17:36:43 +01:00
										 |  |  |   let mapproperties: MapProperties = state.mapProperties | 
					
						
							| 
									
										
										
										
											2023-12-22 18:50:22 +01:00
										 |  |  |   state.mapProperties.installCustomKeyboardHandler(viewport) | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |   let canZoomIn = mapproperties.maxzoom.map( | 
					
						
							|  |  |  |     (mz) => mapproperties.zoom.data < mz, | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |     [mapproperties.zoom], | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |   ) | 
					
						
							|  |  |  |   let canZoomOut = mapproperties.minzoom.map( | 
					
						
							|  |  |  |     (mz) => mapproperties.zoom.data > mz, | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |     [mapproperties.zoom], | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |   ) | 
					
						
							| 
									
										
										
										
											2024-04-12 15:03:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-21 17:36:43 +01:00
										 |  |  |   function updateViewport() { | 
					
						
							|  |  |  |     const rect = viewport.data?.getBoundingClientRect() | 
					
						
							|  |  |  |     if (!rect) { | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const mlmap = state.map.data | 
					
						
							|  |  |  |     if (!mlmap) { | 
					
						
							|  |  |  |       return undefined | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const topLeft = mlmap.unproject([rect.left, rect.top]) | 
					
						
							|  |  |  |     const bottomRight = mlmap.unproject([rect.right, rect.bottom]) | 
					
						
							|  |  |  |     const bbox = new BBox([ | 
					
						
							|  |  |  |       [topLeft.lng, topLeft.lat], | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |       [bottomRight.lng, bottomRight.lat], | 
					
						
							| 
									
										
										
										
											2023-12-21 17:36:43 +01:00
										 |  |  |     ]) | 
					
						
							|  |  |  |     state.visualFeedbackViewportBounds.setData(bbox) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-10 14:10:55 +02:00
										 |  |  |   viewport.addCallbackAndRunD(() => { | 
					
						
							| 
									
										
										
										
											2023-12-21 17:36:43 +01:00
										 |  |  |     updateViewport() | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2024-04-10 14:10:55 +02:00
										 |  |  |   mapproperties.bounds.addCallbackAndRunD(() => { | 
					
						
							| 
									
										
										
										
											2023-12-21 17:36:43 +01:00
										 |  |  |     updateViewport() | 
					
						
							| 
									
										
										
										
											2023-12-20 02:50:08 +01:00
										 |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   let featureSwitches: FeatureSwitchState = state.featureSwitches | 
					
						
							| 
									
										
										
										
											2024-05-08 13:54:14 +02:00
										 |  |  |   let currentViewLayer: LayerConfig = layout.layers.find((l) => l.id === "current_view") | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   let rasterLayer: Store<RasterLayerPolygon> = state.mapProperties.rasterLayer | 
					
						
							| 
									
										
										
										
											2023-12-06 17:27:30 +01:00
										 |  |  |   let rasterLayerName = | 
					
						
							| 
									
										
										
										
											2024-04-13 02:40:21 +02:00
										 |  |  |     rasterLayer.data?.properties?.name ?? | 
					
						
							|  |  |  |     AvailableRasterLayers.defaultBackgroundLayer.properties.name | 
					
						
							| 
									
										
										
										
											2023-12-06 17:27:30 +01:00
										 |  |  |   onDestroy( | 
					
						
							|  |  |  |     rasterLayer.addCallbackAndRunD((l) => { | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |       rasterLayerName = l.properties.name | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |     }), | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |   ) | 
					
						
							|  |  |  |   let previewedImage = state.previewedImage | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |   let addNewFeatureMode = state.userRelatedState.addNewFeatureMode | 
					
						
							|  |  |  |   let gpsAvailable = state.geolocation.geolocationState.gpsAvailable | 
					
						
							|  |  |  |   let gpsButtonAriaLabel = state.geolocation.geolocationState.gpsStateExplanation | 
					
						
							| 
									
										
										
										
											2023-12-26 22:30:27 +01:00
										 |  |  |   let debug = state.featureSwitches.featureSwitchIsDebugging | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-30 15:24:30 +01:00
										 |  |  |   debug.addCallbackAndRun((dbg) => { | 
					
						
							|  |  |  |     if (dbg) { | 
					
						
							| 
									
										
										
										
											2023-12-26 22:30:27 +01:00
										 |  |  |       document.body.classList.add("debug") | 
					
						
							| 
									
										
										
										
											2023-12-30 15:24:30 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-12-26 22:30:27 +01:00
										 |  |  |       document.body.classList.remove("debug") | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   function forwardEventToMap(e: KeyboardEvent) { | 
					
						
							|  |  |  |     const mlmap = state.map.data | 
					
						
							| 
									
										
										
										
											2023-12-15 01:46:01 +01:00
										 |  |  |     if (!mlmap) { | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |       return | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-15 01:46:01 +01:00
										 |  |  |     if (!mlmap.keyboard.isEnabled()) { | 
					
						
							| 
									
										
										
										
											2023-12-12 17:08:59 +01:00
										 |  |  |       return | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const animation = mlmap.keyboard?.keydown(e) | 
					
						
							|  |  |  |     animation?.cameraAnimation(mlmap) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-05-08 13:54:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |   let hash = Hash.hash | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-15 02:21:18 +02:00
										 |  |  | <main> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   <div class="absolute top-0 left-0 h-screen w-screen overflow-hidden"> | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |     <MaplibreMap map={maplibremap} mapProperties={mapproperties} autorecovery={true} /> | 
					
						
							| 
									
										
										
										
											2023-12-20 02:50:08 +01:00
										 |  |  |   </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   {#if $visualFeedback} | 
					
						
							|  |  |  |     <div | 
					
						
							|  |  |  |       class="pointer-events-none absolute top-0 left-0 flex h-screen w-screen items-center justify-center overflow-hidden" | 
					
						
							| 
									
										
										
										
											2023-12-14 18:25:35 +01:00
										 |  |  |     > | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |       <div | 
					
						
							|  |  |  |         bind:this={$viewport} | 
					
						
							|  |  |  |         class:border={$visualFeedback} | 
					
						
							|  |  |  |         style="border: 2px solid #ff000044; width: 300px; height: 300px" | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   {/if} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <div class="pointer-events-none absolute top-0 left-0 w-full"> | 
					
						
							|  |  |  |     <!-- Top components --> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-29 12:24:52 +02:00
										 |  |  |     <div | 
					
						
							| 
									
										
										
										
											2024-08-29 16:19:08 +02:00
										 |  |  |       class="flex bg-black-light-transparent pointer-events-auto items-center justify-between px-4 py-1 flex-wrap-reverse"> | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  |       <!-- Top bar with tools --> | 
					
						
							|  |  |  |       <div class="flex items-center"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <MapControlButton | 
					
						
							| 
									
										
										
										
											2024-08-29 12:24:52 +02:00
										 |  |  |           cls="m-0.5 p-0.5 sm:p-1" | 
					
						
							|  |  |  |           arialabel={Translations.t.general.labels.menu} | 
					
						
							| 
									
										
										
										
											2024-09-02 00:26:02 +02:00
										 |  |  |           on:click={() => {console.log("Opening...."); state.guistate.pageStates.menu.setData(true)}} | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  |           on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2024-08-29 16:19:08 +02:00
										 |  |  |           <MenuIcon class="h-6 w-6 cursor-pointer" /> | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  |         </MapControlButton> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-27 03:39:04 +02:00
										 |  |  |         <MapControlButton | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |           on:click={() => state.guistate.pageStates.about_theme.set(true)} | 
					
						
							| 
									
										
										
										
											2024-06-27 03:39:04 +02:00
										 |  |  |           on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2024-07-09 13:42:08 +02:00
										 |  |  |           <div | 
					
						
							| 
									
										
										
										
											2024-08-29 12:24:52 +02:00
										 |  |  |             class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 mr-2" | 
					
						
							| 
									
										
										
										
											2024-07-09 13:42:08 +02:00
										 |  |  |           > | 
					
						
							| 
									
										
										
										
											2024-08-29 16:19:08 +02:00
										 |  |  |             <Marker icons={layout.icon} size="h-6 w-6 shrink-0 mr-0.5 sm:mr-1 md:mr-2" /> | 
					
						
							| 
									
										
										
										
											2024-06-27 03:39:04 +02:00
										 |  |  |             <b class="mr-1"> | 
					
						
							|  |  |  |               <Tr t={layout.title} /> | 
					
						
							|  |  |  |             </b> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </MapControlButton> | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  |       </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |       {#if $debug && $hash} | 
					
						
							|  |  |  |         <div class="alert"> | 
					
						
							|  |  |  |           {$hash} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       {/if} | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       <If condition={state.featureSwitches.featureSwitchSearch}> | 
					
						
							|  |  |  |         <div class="w-full sm:w-64 my-2 sm:mt-0"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           <Geosearch | 
					
						
							|  |  |  |             bounds={state.mapProperties.bounds} | 
					
						
							|  |  |  |             on:searchCompleted={() => { | 
					
						
							|  |  |  |             state.map?.data?.getCanvas()?.focus() | 
					
						
							|  |  |  |           }} | 
					
						
							|  |  |  |             perLayer={state.perLayer} | 
					
						
							|  |  |  |             selectedElement={state.selectedElement} | 
					
						
							|  |  |  |             geolocationState={state.geolocation.geolocationState} | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </If> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <div class="pointer-events-auto float-right mt-1 flex flex-col px-1 max-[480px]:w-full sm:m-2"> | 
					
						
							|  |  |  |       <If condition={state.visualFeedback}> | 
					
						
							|  |  |  |         {#if $selectedElement === undefined} | 
					
						
							|  |  |  |           <div class="w-fit"> | 
					
						
							|  |  |  |             <VisualFeedbackPanel {state} /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         {/if} | 
					
						
							|  |  |  |       </If> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <div class="float-left m-1 flex flex-col sm:mt-2"> | 
					
						
							|  |  |  |       <If condition={state.featureSwitches.featureSwitchWelcomeMessage}> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-27 03:39:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       </If> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |       {#if currentViewLayer?.tagRenderings && currentViewLayer.defaultIcon()} | 
					
						
							|  |  |  |         <MapControlButton | 
					
						
							|  |  |  |           on:click={() => { | 
					
						
							|  |  |  |             state.selectCurrentView() | 
					
						
							|  |  |  |           }} | 
					
						
							|  |  |  |           on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |           <div class="h-8 w-8 cursor-pointer"> | 
					
						
							|  |  |  |             <ToSvelte construct={() => currentViewLayer.defaultIcon()} /> | 
					
						
							| 
									
										
										
										
											2024-07-16 16:00:11 +02:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |         </MapControlButton> | 
					
						
							|  |  |  |       {/if} | 
					
						
							|  |  |  |       <ExtraLinkButton {state} /> | 
					
						
							|  |  |  |       <UploadingImageCounter featureId="*" showThankYou={false} {state} /> | 
					
						
							|  |  |  |       <PendingChangesIndicator {state} /> | 
					
						
							|  |  |  |       <If condition={state.featureSwitchIsTesting}> | 
					
						
							|  |  |  |         <div class="alert w-fit">Testmode</div> | 
					
						
							|  |  |  |       </If> | 
					
						
							| 
									
										
										
										
											2024-07-17 18:42:39 +02:00
										 |  |  |       {#if state.osmConnection.Backend().startsWith("https://master.apis.dev.openstreetmap.org")} | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |         <div class="thanks">Testserver</div> | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |       {/if} | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |       <If condition={state.featureSwitches.featureSwitchFakeUser}> | 
					
						
							|  |  |  |         <div class="alert w-fit">Faking a user (Testmode)</div> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |       </If> | 
					
						
							| 
									
										
										
										
											2023-05-18 15:44:54 +02:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |     <div class="flex w-full flex-col items-center justify-center"> | 
					
						
							|  |  |  |       <!-- Flex and w-full are needed for the positioning --> | 
					
						
							|  |  |  |       <!-- Centermessage --> | 
					
						
							|  |  |  |       <StateIndicator {state} /> | 
					
						
							|  |  |  |       <ReverseGeocoding {state} /> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   <div class="pointer-events-none absolute bottom-0 left-0 mb-4 w-screen"> | 
					
						
							|  |  |  |     <!-- bottom controls --> | 
					
						
							|  |  |  |     <div class="flex w-full items-end justify-between px-4"> | 
					
						
							|  |  |  |       <div class="flex flex-col"> | 
					
						
							|  |  |  |         <If condition={featureSwitches.featureSwitchEnableLogin}> | 
					
						
							| 
									
										
										
										
											2024-06-21 02:36:36 +02:00
										 |  |  |           {#if $addNewFeatureMode.indexOf("button") >= 0 && ((state.layout.hasPresets() && state.layout.enableAddNewPoints) || state.layout.hasNoteLayer())} | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |             <button | 
					
						
							|  |  |  |               class="low-interaction pointer-events-auto w-fit" | 
					
						
							|  |  |  |               class:disabled={$currentZoom < Constants.minZoomLevelToAddNewPoint} | 
					
						
							|  |  |  |               on:click={() => { | 
					
						
							|  |  |  |                 state.openNewDialog() | 
					
						
							|  |  |  |               }} | 
					
						
							|  |  |  |               on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |             > | 
					
						
							|  |  |  |               {#if $currentZoom < Constants.minZoomLevelToAddNewPoint} | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.zoomInFurther} /> | 
					
						
							|  |  |  |               {:else if state.layout.hasPresets()} | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.title} /> | 
					
						
							|  |  |  |               {:else} | 
					
						
							|  |  |  |                 <Tr t={Translations.t.notes.addAComment} /> | 
					
						
							|  |  |  |               {/if} | 
					
						
							|  |  |  |             </button> | 
					
						
							|  |  |  |           {/if} | 
					
						
							|  |  |  |         </If> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-17 04:27:08 +02:00
										 |  |  |         <div class="flex items-center"> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |           <!-- bottom left elements --> | 
					
						
							|  |  |  |           <If condition={state.featureSwitches.featureSwitchFilter}> | 
					
						
							|  |  |  |             <MapControlButton | 
					
						
							|  |  |  |               arialabel={Translations.t.general.labels.filter} | 
					
						
							|  |  |  |               on:click={() => state.guistate.openFilterView()} | 
					
						
							|  |  |  |               on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |             > | 
					
						
							|  |  |  |               <Filter class="h-6 w-6" /> | 
					
						
							|  |  |  |             </MapControlButton> | 
					
						
							|  |  |  |           </If> | 
					
						
							|  |  |  |           <If condition={state.featureSwitches.featureSwitchBackgroundSelection}> | 
					
						
							|  |  |  |             <OpenBackgroundSelectorButton | 
					
						
							|  |  |  |               hideTooltip={true} | 
					
						
							|  |  |  |               {state} | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           </If> | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |           <button | 
					
						
							| 
									
										
										
										
											2024-08-29 12:16:35 +02:00
										 |  |  |             class="unstyled bg-black-transparent pointer-events-auto ml-1 h-fit max-h-12 cursor-pointer overflow-hidden rounded-2xl px-1 text-white opacity-50 hover:opacity-100" | 
					
						
							|  |  |  |             style="background: #00000088; padding: 0.25rem; border-radius: 2rem;" | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |             on:click={() => {state.guistate.pageStates.copyright.set(true)}} | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |           > | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |             © <span class="hidden sm:inline sm:pr-2"> | 
					
						
							|  |  |  |               OpenStreetMap | 
					
						
							|  |  |  |               <span class="hidden w-24 md:inline md:pr-2">, {rasterLayerName}</span> | 
					
						
							|  |  |  |             </span> | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |           </button> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |       </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |       <div class="flex flex-col items-end"> | 
					
						
							|  |  |  |         <!-- bottom right elements --> | 
					
						
							|  |  |  |         <If condition={state.floors.map((f) => f.length > 1)}> | 
					
						
							|  |  |  |           <div class="pointer-events-auto mr-0.5"> | 
					
						
							|  |  |  |             <LevelSelector | 
					
						
							|  |  |  |               floors={state.floors} | 
					
						
							|  |  |  |               layerState={state.layerState} | 
					
						
							|  |  |  |               zoom={state.mapProperties.zoom} | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </If> | 
					
						
							|  |  |  |         <MapControlButton | 
					
						
							|  |  |  |           arialabel={Translations.t.general.labels.zoomIn} | 
					
						
							|  |  |  |           enabled={canZoomIn} | 
					
						
							|  |  |  |           on:click={() => mapproperties.zoom.update((z) => z + 1)} | 
					
						
							|  |  |  |           on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <Plus class="h-8 w-8" /> | 
					
						
							|  |  |  |         </MapControlButton> | 
					
						
							|  |  |  |         <MapControlButton | 
					
						
							|  |  |  |           enabled={canZoomOut} | 
					
						
							|  |  |  |           arialabel={Translations.t.general.labels.zoomOut} | 
					
						
							|  |  |  |           on:click={() => mapproperties.zoom.update((z) => z - 1)} | 
					
						
							|  |  |  |           on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <Min class="h-8 w-8" /> | 
					
						
							|  |  |  |         </MapControlButton> | 
					
						
							|  |  |  |         <If condition={featureSwitches.featureSwitchGeolocation}> | 
					
						
							|  |  |  |           <div class="relative m-0"> | 
					
						
							|  |  |  |             <MapControlButton | 
					
						
							| 
									
										
										
										
											2024-08-09 14:37:57 +02:00
										 |  |  |               enabled={gpsAvailable} | 
					
						
							| 
									
										
										
										
											2024-08-09 10:53:09 +02:00
										 |  |  |               arialabelDynamic={gpsButtonAriaLabel} | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |               on:click={() => state.geolocationControl.handleClick()} | 
					
						
							|  |  |  |               on:keydown={forwardEventToMap} | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2024-08-10 12:09:55 +02:00
										 |  |  |               <GeolocationIndicator {state} /> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |               <!-- h-8 w-8 + p-0.5 sm:p-1 + 2px border => 9 sm: 10 in total--> | 
					
						
							|  |  |  |             </MapControlButton> | 
					
						
							|  |  |  |             {#if $compassLoaded} | 
					
						
							|  |  |  |               <div class="absolute top-0 left-0 m-0.5 h-0 w-0 sm:m-1"> | 
					
						
							|  |  |  |                 <Compass_arrow | 
					
						
							|  |  |  |                   class="compass_arrow" | 
					
						
							|  |  |  |                   style={`rotate: calc(${-$compass}deg + 45deg); transform-origin: 50% 50%;`} | 
					
						
							|  |  |  |                 /> | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |             {/if} | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </If> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |     </div> | 
					
						
							|  |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   <LoginToggle ignoreLoading={true} {state}> | 
					
						
							|  |  |  |     {#if ($showCrosshair === "yes" && $currentZoom >= 17) || $showCrosshair === "always" || $visualFeedback} | 
					
						
							|  |  |  |       <!-- Don't use h-full: h-full does _not_ include the area under the URL-bar, which offsets the crosshair a bit --> | 
					
						
							|  |  |  |       <div | 
					
						
							|  |  |  |         class="pointer-events-none absolute top-0 left-0 flex w-full items-center justify-center" | 
					
						
							|  |  |  |         style="height: 100vh" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <Cross class="h-4 w-4" /> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |     {/if} | 
					
						
							|  |  |  |     <!-- Add in an empty container to remove error messages if login fails --> | 
					
						
							|  |  |  |     <svelte:fragment slot="error" /> | 
					
						
							|  |  |  |   </LoginToggle> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-02 00:26:02 +02:00
										 |  |  |   <DrawerLeft shown={state.guistate.pageStates.menu}> | 
					
						
							| 
									
										
										
										
											2024-08-29 23:11:59 +02:00
										 |  |  |     <div class="h-screen overflow-y-auto"> | 
					
						
							|  |  |  |       <MenuDrawer onlyLink={true} {state} /> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2024-08-29 02:46:51 +02:00
										 |  |  |   </DrawerLeft> | 
					
						
							|  |  |  |   <MenuDrawer onlyLink={false} {state} /> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   {#if $selectedElement !== undefined && $selectedLayer !== undefined && !$selectedLayer.popupInFloatover} | 
					
						
							|  |  |  |     <!-- right modal with the selected element view --> | 
					
						
							|  |  |  |     <ModalRight | 
					
						
							|  |  |  |       on:close={() => { | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |         state.selectedElement.setData(undefined) | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |       }} | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <div slot="close-button" /> | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |       <SelectedElementPanel {state} selected={$state_selectedElement} /> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |     </ModalRight> | 
					
						
							|  |  |  |   {/if} | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   {#if $selectedElement !== undefined && $selectedLayer !== undefined && $selectedLayer.popupInFloatover} | 
					
						
							|  |  |  |     <!-- Floatover with the selected element, if applicable --> | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     {#if $selectedLayer.popupInFloatover === "title"} | 
					
						
							|  |  |  |       <FloatOver | 
					
						
							|  |  |  |         on:close={() => { | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |           state.selectedElement.setData(undefined) | 
					
						
							|  |  |  |         }} | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |       > | 
					
						
							|  |  |  |         <span slot="close-button" /> | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |         <SelectedElementPanel absolute={false} {state} selected={$state_selectedElement} /> | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |       </FloatOver> | 
					
						
							|  |  |  |     {:else} | 
					
						
							|  |  |  |       <FloatOver | 
					
						
							|  |  |  |         on:close={() => { | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |           state.selectedElement.setData(undefined) | 
					
						
							|  |  |  |         }} | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |       > | 
					
						
							| 
									
										
										
										
											2024-09-02 03:39:40 +02:00
										 |  |  |         <SelectedElementView {state} layer={$selectedLayer} selectedElement={$state_selectedElement} /> | 
					
						
							| 
									
										
										
										
											2024-07-22 17:24:30 +02:00
										 |  |  |       </FloatOver> | 
					
						
							|  |  |  |     {/if} | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   {/if} | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 12:09:55 +02:00
										 |  |  |   <!-- Image preview --> | 
					
						
							| 
									
										
										
										
											2024-06-16 16:41:57 +02:00
										 |  |  |   <If condition={state.previewedImage.map((i) => i !== undefined)}> | 
					
						
							|  |  |  |     <FloatOver on:close={() => state.previewedImage.setData(undefined)}> | 
					
						
							|  |  |  |       <ImageOperations image={$previewedImage} /> | 
					
						
							|  |  |  |     </FloatOver> | 
					
						
							|  |  |  |   </If> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-15 02:21:18 +02:00
										 |  |  | </main> |