| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | <script lang="ts"> | 
					
						
							|  |  |  |   import type { SpecialVisualizationState } from "../SpecialVisualization"; | 
					
						
							|  |  |  |   import LocationInput from "../InputElement/Helpers/LocationInput.svelte"; | 
					
						
							|  |  |  |   import { UIEventSource } from "../../Logic/UIEventSource"; | 
					
						
							|  |  |  |   import { Tiles } from "../../Models/TileRange"; | 
					
						
							|  |  |  |   import { Map as MlMap } from "maplibre-gl"; | 
					
						
							|  |  |  |   import { BBox } from "../../Logic/BBox"; | 
					
						
							|  |  |  |   import type { MapProperties } from "../../Models/MapProperties"; | 
					
						
							|  |  |  |   import ShowDataLayer from "../Map/ShowDataLayer"; | 
					
						
							|  |  |  |   import type { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   import SnappingFeatureSource from "../../Logic/FeatureSource/Sources/SnappingFeatureSource"; | 
					
						
							|  |  |  |   import FeatureSourceMerger from "../../Logic/FeatureSource/Sources/FeatureSourceMerger"; | 
					
						
							|  |  |  |   import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; | 
					
						
							|  |  |  |   import { Utils } from "../../Utils"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * An advanced location input, which has support to: | 
					
						
							|  |  |  |    * - Show more layers | 
					
						
							|  |  |  |    * - Snap to layers | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * This one is mostly used to insert new points | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   export let state: SpecialVisualizationState; | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * The start coordinate | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   export let coordinate: { lon: number, lat: number }; | 
					
						
							|  |  |  |   export let snapToLayers: string[] | undefined; | 
					
						
							|  |  |  |   export let targetLayer: LayerConfig; | 
					
						
							|  |  |  |   export let maxSnapDistance: number = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   export let snappedTo: UIEventSource<string | undefined>; | 
					
						
							|  |  |  |   export let value: UIEventSource<{ lon: number, lat: number }>; | 
					
						
							|  |  |  |   if (value.data === undefined) { | 
					
						
							|  |  |  |     value.setData(coordinate); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let preciseLocation: UIEventSource<{ lon: number, lat: number }> = new UIEventSource<{ lon: number; lat: number }>(coordinate); | 
					
						
							|  |  |  |   const xyz = Tiles.embedded_tile(coordinate.lat, coordinate.lon, 16); | 
					
						
							|  |  |  |   const map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined); | 
					
						
							|  |  |  |   let initialMapProperties: Partial<MapProperties> = { | 
					
						
							|  |  |  |     zoom: new UIEventSource<number>(19), | 
					
						
							|  |  |  |     maxbounds: new UIEventSource(undefined), | 
					
						
							|  |  |  |     /*If no snapping needed: the value is simply the map location; | 
					
						
							|  |  |  |     * If snapping is needed: the value will be set later on by the snapping feature source | 
					
						
							|  |  |  |     * */ | 
					
						
							| 
									
										
										
										
											2023-04-06 02:20:25 +02:00
										 |  |  |     location: snapToLayers?.length > 0 ? new UIEventSource<{ lon: number; lat: number }>(coordinate) :value, | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     bounds: new UIEventSource<BBox>(undefined), | 
					
						
							|  |  |  |     allowMoving: new UIEventSource<boolean>(true), | 
					
						
							|  |  |  |     allowZooming: new UIEventSource<boolean>(true), | 
					
						
							|  |  |  |     minzoom: new UIEventSource<number>(18) | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   initialMapProperties.bounds.addCallbackAndRunD((bounds: BBox) => { | 
					
						
							|  |  |  |     const max = bounds.pad(3).squarify(); | 
					
						
							|  |  |  |     initialMapProperties.maxbounds.setData(max); | 
					
						
							|  |  |  |     return true; // unregister | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (snapToLayers?.length > 0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const snapSources: FeatureSource[] = []; | 
					
						
							|  |  |  |     for (const layerId of (snapToLayers ?? [])) { | 
					
						
							|  |  |  |       const layer: FeatureSourceForLayer = state.perLayer.get(layerId); | 
					
						
							|  |  |  |       snapSources.push(layer); | 
					
						
							|  |  |  |       if (layer.features === undefined) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       new ShowDataLayer(map, { | 
					
						
							|  |  |  |         layer: layer.layer.layerDef, | 
					
						
							|  |  |  |         zoomToFeatures: false, | 
					
						
							|  |  |  |         features: layer | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const snappedLocation = new SnappingFeatureSource( | 
					
						
							|  |  |  |       new FeatureSourceMerger(...Utils.NoNull(snapSources)), | 
					
						
							|  |  |  |       // We snap to the (constantly updating) map location | 
					
						
							|  |  |  |       initialMapProperties.location, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         maxDistance: maxSnapDistance ?? 15, | 
					
						
							|  |  |  |         allowUnsnapped: true, | 
					
						
							|  |  |  |         snappedTo, | 
					
						
							|  |  |  |         snapLocation: value | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new ShowDataLayer(map, { | 
					
						
							|  |  |  |       layer: targetLayer, | 
					
						
							|  |  |  |       features: snappedLocation | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 13:57:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |   <LocationInput {map} mapProperties={initialMapProperties} | 
					
						
							|  |  |  |                  value={preciseLocation}></LocationInput> |