| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import Combine from "../Base/Combine" | 
					
						
							|  |  |  | import { Store, UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  | import { BBox } from "../../Logic/BBox" | 
					
						
							|  |  |  | import UserRelatedState from "../../Logic/State/UserRelatedState" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							|  |  |  | import { AllKnownLayouts } from "../../Customizations/AllKnownLayouts" | 
					
						
							|  |  |  | import Constants from "../../Models/Constants" | 
					
						
							|  |  |  | import { DropDown } from "../Input/DropDown" | 
					
						
							|  |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | 
					
						
							|  |  |  | import BaseLayer from "../../Models/BaseLayer" | 
					
						
							|  |  |  | import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers" | 
					
						
							|  |  |  | import Loc from "../../Models/Loc" | 
					
						
							|  |  |  | import Minimap from "../Base/Minimap" | 
					
						
							|  |  |  | import Attribution from "../BigComponents/Attribution" | 
					
						
							|  |  |  | import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer" | 
					
						
							|  |  |  | import FilteredLayer, { FilterState } from "../../Models/FilteredLayer" | 
					
						
							|  |  |  | import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource" | 
					
						
							|  |  |  | import Toggle from "../Input/Toggle" | 
					
						
							|  |  |  | import { VariableUiElement } from "../Base/VariableUIElement" | 
					
						
							|  |  |  | import { FixedUiElement } from "../Base/FixedUiElement" | 
					
						
							|  |  |  | import { FlowStep } from "./FlowStep" | 
					
						
							|  |  |  | import ScrollableFullScreen from "../Base/ScrollableFullScreen" | 
					
						
							|  |  |  | import Title from "../Base/Title" | 
					
						
							|  |  |  | import CheckBoxes from "../Input/Checkboxes" | 
					
						
							| 
									
										
										
										
											2023-02-15 18:24:08 +01:00
										 |  |  | import AllTagsPanel from "../AllTagsPanel.svelte" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import BackgroundMapSwitch from "../BigComponents/BackgroundMapSwitch" | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  | import { Feature, Point } from "geojson" | 
					
						
							|  |  |  | import DivContainer from "../Base/DivContainer" | 
					
						
							|  |  |  | import ShowDataLayer from "../ShowDataLayer/ShowDataLayer" | 
					
						
							| 
									
										
										
										
											2023-02-15 18:24:08 +01:00
										 |  |  | import SvelteUIElement from "../Base/SvelteUIElement" | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PreviewPanel extends ScrollableFullScreen { | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |     constructor(tags: UIEventSource<any>) { | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         super( | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             (_) => new FixedUiElement("Element to import"), | 
					
						
							| 
									
										
										
										
											2023-02-15 18:24:08 +01:00
										 |  |  |             (_) => | 
					
						
							|  |  |  |                 new Combine([ | 
					
						
							|  |  |  |                     "The tags are:", | 
					
						
							|  |  |  |                     new SvelteUIElement(AllTagsPanel, { tags }), | 
					
						
							|  |  |  |                 ]).SetClass("flex flex-col"), | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |             "element" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Shows the data to import on a map, asks for the correct layer to be selected | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | export class MapPreview | 
					
						
							|  |  |  |     extends Combine | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |     implements FlowStep<{ bbox: BBox; layer: LayerConfig; features: Feature<Point>[] }> | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     public readonly IsValid: Store<boolean> | 
					
						
							|  |  |  |     public readonly Value: Store<{ bbox: BBox; layer: LayerConfig; features: any[] }> | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |     constructor(state: UserRelatedState, geojson: { features: Feature[] }) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const t = Translations.t.importHelper.mapPreview | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const propertyKeys = new Set<string>() | 
					
						
							|  |  |  |         for (const f of geojson.features) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             Object.keys(f.properties).forEach((key) => propertyKeys.add(key)) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const availableLayers = AllKnownLayouts.AllPublicLayers().filter( | 
					
						
							|  |  |  |             (l) => l.name !== undefined && Constants.priviliged_layers.indexOf(l.id) < 0 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         const layerPicker = new DropDown( | 
					
						
							|  |  |  |             t.selectLayer, | 
					
						
							|  |  |  |             [{ shown: t.selectLayer, value: undefined }].concat( | 
					
						
							|  |  |  |                 availableLayers.map((l) => ({ | 
					
						
							|  |  |  |                     shown: l.name, | 
					
						
							|  |  |  |                     value: l, | 
					
						
							|  |  |  |                 })) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let autodetected = new UIEventSource(false) | 
					
						
							|  |  |  |         for (const layer of availableLayers) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const mismatched = geojson.features.some( | 
					
						
							|  |  |  |                 (f) => !layer.source.osmTags.matchesProperties(f.properties) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             ) | 
					
						
							|  |  |  |             if (!mismatched) { | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                 console.log("Autodected layer", layer.id) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 layerPicker.GetValue().setData(layer) | 
					
						
							|  |  |  |                 layerPicker.GetValue().addCallback((_) => autodetected.setData(false)) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                 autodetected.setData(true) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const withId = geojson.features.map((f, i) => { | 
					
						
							|  |  |  |             const copy = Utils.Clone(f) | 
					
						
							|  |  |  |             copy.properties.id = "to-import/" + i | 
					
						
							|  |  |  |             return copy | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |         // Create a store which has only features matching the selected layer
 | 
					
						
							|  |  |  |         const matching: Store<Feature[]> = layerPicker.GetValue().map((layer: LayerConfig) => { | 
					
						
							|  |  |  |             if (layer === undefined) { | 
					
						
							|  |  |  |                 console.log("No matching layer found") | 
					
						
							|  |  |  |                 return [] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const matching: Feature[] = [] | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             for (const feature of withId) { | 
					
						
							|  |  |  |                 if (layer.source.osmTags.matchesProperties(feature.properties)) { | 
					
						
							|  |  |  |                     matching.push(feature) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             console.log("Matching features: ", matching) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             return matching | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         const background = new UIEventSource<BaseLayer>(AvailableBaseLayers.osmCarto) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const location = new UIEventSource<Loc>({ lat: 0, lon: 0, zoom: 1 }) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         const currentBounds = new UIEventSource<BBox>(undefined) | 
					
						
							|  |  |  |         const map = Minimap.createMiniMap({ | 
					
						
							|  |  |  |             allowMoving: true, | 
					
						
							|  |  |  |             location, | 
					
						
							|  |  |  |             background, | 
					
						
							|  |  |  |             bounds: currentBounds, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             attribution: new Attribution( | 
					
						
							|  |  |  |                 location, | 
					
						
							|  |  |  |                 state.osmConnection.userDetails, | 
					
						
							|  |  |  |                 undefined, | 
					
						
							|  |  |  |                 currentBounds | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const layerControl = new BackgroundMapSwitch( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 backgroundLayer: background, | 
					
						
							|  |  |  |                 locationControl: location, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             background | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         map.SetClass("w-full").SetStyle("height: 500px") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |         layerPicker.GetValue().addCallbackAndRunD((layerToShow) => { | 
					
						
							|  |  |  |             new ShowDataLayer({ | 
					
						
							|  |  |  |                 layerToShow, | 
					
						
							|  |  |  |                 zoomToFeatures: true, | 
					
						
							|  |  |  |                 features: StaticFeatureSource.fromDateless( | 
					
						
							|  |  |  |                     matching.map((features) => features.map((feature) => ({ feature }))) | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 leafletMap: map.leafletMap, | 
					
						
							|  |  |  |                 popup: (tag) => new PreviewPanel(tag), | 
					
						
							|  |  |  |             }) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const bbox = matching.map((feats) => | 
					
						
							|  |  |  |             BBox.bboxAroundAll( | 
					
						
							|  |  |  |                 feats.map((f) => new BBox([(<Feature<Point>>f).geometry.coordinates])) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const mismatchIndicator = new VariableUiElement( | 
					
						
							|  |  |  |             matching.map((matching) => { | 
					
						
							|  |  |  |                 if (matching === undefined) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const diff = geojson.features.length - matching.length | 
					
						
							|  |  |  |                 if (diff === 0) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const obligatory = layerPicker | 
					
						
							|  |  |  |                     .GetValue() | 
					
						
							|  |  |  |                     .data?.source?.osmTags?.asHumanString(false, false, {}) | 
					
						
							|  |  |  |                 return t.mismatch.Subs({ count: diff, tags: obligatory }).SetClass("alert") | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const confirm = new CheckBoxes([t.confirm]) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         super([ | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |             new Title(t.title, 1), | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             layerPicker, | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             new Toggle(t.autodetected.SetClass("thanks"), undefined, autodetected), | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             mismatchIndicator, | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |             map, | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             new DivContainer("fullscreen"), | 
					
						
							| 
									
										
										
										
											2022-07-08 03:14:55 +02:00
										 |  |  |             layerControl, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             confirm, | 
					
						
							|  |  |  |         ]) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.Value = bbox.map( | 
					
						
							|  |  |  |             (bbox) => ({ | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                 bbox, | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |                 features: matching.data, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 layer: layerPicker.GetValue().data, | 
					
						
							|  |  |  |             }), | 
					
						
							| 
									
										
										
										
											2023-01-12 01:16:22 +01:00
										 |  |  |             [layerPicker.GetValue(), matching] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.IsValid = matching.map( | 
					
						
							|  |  |  |             (matching) => { | 
					
						
							|  |  |  |                 if (matching === undefined) { | 
					
						
							|  |  |  |                     return false | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (confirm.GetValue().data.length !== 1) { | 
					
						
							|  |  |  |                     return false | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const diff = geojson.features.length - matching.length | 
					
						
							|  |  |  |                 return diff === 0 | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             [confirm.GetValue()] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |