| 
									
										
										
										
											2023-03-29 17:21:20 +02:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   import { Store, UIEventSource } from "../../../Logic/UIEventSource" | 
					
						
							|  |  |  |   import type { MapProperties } from "../../../Models/MapProperties" | 
					
						
							|  |  |  |   import { Map as MlMap } from "maplibre-gl" | 
					
						
							|  |  |  |   import { MapLibreAdaptor } from "../../Map/MapLibreAdaptor" | 
					
						
							|  |  |  |   import MaplibreMap from "../../Map/MaplibreMap.svelte" | 
					
						
							|  |  |  |   import DragInvitation from "../../Base/DragInvitation.svelte" | 
					
						
							|  |  |  |   import { GeoOperations } from "../../../Logic/GeoOperations" | 
					
						
							|  |  |  |   import ShowDataLayer from "../../Map/ShowDataLayer" | 
					
						
							|  |  |  |   import * as boundsdisplay from "../../../assets/layers/range/range.json" | 
					
						
							|  |  |  |   import StaticFeatureSource from "../../../Logic/FeatureSource/Sources/StaticFeatureSource" | 
					
						
							|  |  |  |   import * as turf from "@turf/turf" | 
					
						
							|  |  |  |   import LayerConfig from "../../../Models/ThemeConfig/LayerConfig" | 
					
						
							|  |  |  |   import { createEventDispatcher, onDestroy } from "svelte" | 
					
						
							| 
									
										
										
										
											2023-05-19 01:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * A visualisation to pick a location on a map background | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   export let value: UIEventSource<{ lon: number; lat: number }> | 
					
						
							|  |  |  |   export let initialCoordinate: { lon: number; lat: number } | 
					
						
							|  |  |  |   initialCoordinate = initialCoordinate ?? value.data | 
					
						
							|  |  |  |   export let maxDistanceInMeters: number = undefined | 
					
						
							|  |  |  |   export let mapProperties: Partial<MapProperties> & { | 
					
						
							|  |  |  |     readonly location: UIEventSource<{ lon: number; lat: number }> | 
					
						
							|  |  |  |   } = undefined | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Called when setup is done, can be used to add more layers to the map | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   export let onCreated: ( | 
					
						
							|  |  |  |     value: Store<{ | 
					
						
							|  |  |  |       lon: number | 
					
						
							|  |  |  |       lat: number | 
					
						
							|  |  |  |     }>, | 
					
						
							|  |  |  |     map: Store<MlMap>, | 
					
						
							|  |  |  |     mapProperties: MapProperties | 
					
						
							|  |  |  |   ) => void = undefined | 
					
						
							| 
									
										
										
										
											2023-05-19 01:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   const dispatch = createEventDispatcher<{ click: { lon: number; lat: number } }>() | 
					
						
							| 
									
										
										
										
											2023-05-19 01:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined) | 
					
						
							|  |  |  |   let mla = new MapLibreAdaptor(map, mapProperties) | 
					
						
							|  |  |  |   mla.lastClickLocation.addCallbackAndRunD((lastClick) => { | 
					
						
							|  |  |  |     dispatch("click", lastClick) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   mapProperties.location.syncWith(value) | 
					
						
							|  |  |  |   if (onCreated) { | 
					
						
							|  |  |  |     onCreated(value, map, mla) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-05-19 01:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   let rangeIsShown = false | 
					
						
							|  |  |  |   if (maxDistanceInMeters) { | 
					
						
							|  |  |  |     onDestroy( | 
					
						
							|  |  |  |       mla.location.addCallbackD((newLocation) => { | 
					
						
							|  |  |  |         const l = [newLocation.lon, newLocation.lat] | 
					
						
							|  |  |  |         const c: [number, number] = [initialCoordinate.lon, initialCoordinate.lat] | 
					
						
							|  |  |  |         const d = GeoOperations.distanceBetween(l, c) | 
					
						
							|  |  |  |         console.log("distance is", d, l, c) | 
					
						
							|  |  |  |         if (d <= maxDistanceInMeters) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // This is too far away - let's move back | 
					
						
							|  |  |  |         const correctLocation = GeoOperations.along(c, l, maxDistanceInMeters - 10) | 
					
						
							|  |  |  |         window.setTimeout(() => { | 
					
						
							|  |  |  |           mla.location.setData({ lon: correctLocation[0], lat: correctLocation[1] }) | 
					
						
							|  |  |  |         }, 25) | 
					
						
							| 
									
										
										
										
											2023-06-14 23:21:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |         if (!rangeIsShown) { | 
					
						
							|  |  |  |           new ShowDataLayer(map, { | 
					
						
							|  |  |  |             layer: new LayerConfig(boundsdisplay), | 
					
						
							|  |  |  |             features: new StaticFeatureSource([ | 
					
						
							|  |  |  |               turf.circle(c, maxDistanceInMeters, { | 
					
						
							|  |  |  |                 units: "meters", | 
					
						
							|  |  |  |                 properties: { range: "yes", id: "0" }, | 
					
						
							|  |  |  |               }), | 
					
						
							|  |  |  |             ]), | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |           rangeIsShown = true | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-03-29 17:21:20 +02:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 20:44:01 +02:00
										 |  |  | <div class="min-h-32 relative h-full cursor-pointer overflow-hidden"> | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   <div class="absolute top-0 left-0 h-full w-full cursor-pointer"> | 
					
						
							|  |  |  |     <MaplibreMap {map} /> | 
					
						
							|  |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2023-05-19 01:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   <div | 
					
						
							|  |  |  |     class="pointer-events-none absolute top-0 left-0 flex h-full w-full items-center p-8 opacity-50" | 
					
						
							|  |  |  |   > | 
					
						
							|  |  |  |     <img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" /> | 
					
						
							|  |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2023-03-29 17:21:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:12:46 +02:00
										 |  |  |   <DragInvitation hideSignal={mla.location} /> | 
					
						
							| 
									
										
										
										
											2023-03-29 17:21:20 +02:00
										 |  |  | </div> |