forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
| <script lang="ts">
 | |
|     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 {onDestroy} from "svelte";
 | |
| 
 | |
|     /**
 | |
|      * 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
 | |
| 
 | |
|     export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined);
 | |
|     let mla = new MapLibreAdaptor(map, mapProperties);
 | |
|     mapProperties.location.syncWith(value)
 | |
|     if (onCreated) {
 | |
|         onCreated(value, map, mla)
 | |
|     }
 | |
| 
 | |
|     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)
 | |
| 
 | |
|             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
 | |
|             }
 | |
|         }))
 | |
|     }
 | |
| </script>
 | |
| 
 | |
| <div class="relative h-full min-h-32 cursor-pointer overflow-hidden">
 | |
|     <div class="w-full h-full absolute top-0 left-0 cursor-pointer">
 | |
|         <MaplibreMap {map}/>
 | |
|     </div>
 | |
| 
 | |
|     <div class="w-full h-full absolute top-0 left-0 p-8 pointer-events-none opacity-50 flex items-center">
 | |
|         <img class="h-full max-h-24" src="./assets/svg/move-arrows.svg"/>
 | |
|     </div>
 | |
| 
 | |
|     <DragInvitation hideSignal={mla.location.stabilized(3000)}></DragInvitation>
 | |
| 
 | |
| </div>
 |