diff --git a/src/UI/Popup/MinimapViz.svelte b/src/UI/Popup/MinimapViz.svelte new file mode 100644 index 0000000000..13f490c098 --- /dev/null +++ b/src/UI/Popup/MinimapViz.svelte @@ -0,0 +1,86 @@ + + +
+ +
diff --git a/src/UI/Popup/MinimapViz.ts b/src/UI/Popup/MinimapViz.ts deleted file mode 100644 index 2c459033f3..0000000000 --- a/src/UI/Popup/MinimapViz.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Store, UIEventSource } from "../../Logic/UIEventSource" -import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource" -import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization" -import { Feature } from "geojson" -import { MapLibreAdaptor } from "../Map/MapLibreAdaptor" -import SvelteUIElement from "../Base/SvelteUIElement" -import MaplibreMap from "../Map/MaplibreMap.svelte" -import ShowDataLayer from "../Map/ShowDataLayer" -import { GeoOperations } from "../../Logic/GeoOperations" -import { BBox } from "../../Logic/BBox" - -export class MinimapViz implements SpecialVisualization { - funcName = "minimap" - docs = "A small map showing the selected feature." - needsUrls = [] - args = [ - { - doc: "The (maximum) zoomlevel: the target zoomlevel after fitting the entire feature. The minimap will fit the entire feature, then zoom out to this zoom level. The higher, the more zoomed in with 1 being the entire world and 19 being really close", - name: "zoomlevel", - defaultValue: "18", - }, - { - doc: "(Matches all resting arguments) This argument should be the key of a property of the feature. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. (Note: if the key is 'id', list interpration is disabled)", - name: "idKey", - defaultValue: "id", - }, - ] - example: "`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`" - - constr( - state: SpecialVisualizationState, - tagSource: UIEventSource>, - args: string[], - feature: Feature - ) { - if (state === undefined || feature === undefined) { - return undefined - } - const keys = [...args] - keys.splice(0, 1) - const featuresToShow: Store = state.indexedFeatures.featuresById.map( - (featuresById) => { - if (featuresById === undefined) { - return [] - } - const properties = tagSource.data - const features: Feature[] = [] - for (const key of keys) { - const value = properties[key] - if (value === undefined || value === null) { - continue - } - - let idList = [value] - if (Array.isArray(value)) { - idList = value - } else if ( - key !== "id" && - typeof value === "string" && - value?.startsWith("[") - ) { - // This is a list of values - idList = JSON.parse(value) - } - - for (const id of idList) { - const feature = featuresById.get(id) - if (feature === undefined) { - console.warn("No feature found for id ", id) - continue - } - features.push(feature) - } - } - return features - }, - [tagSource] - ) - - const mlmap = new UIEventSource(undefined) - const [lon, lat] = GeoOperations.centerpointCoordinates(feature) - const mla = new MapLibreAdaptor(mlmap, { - rasterLayer: state.mapProperties.rasterLayer, - zoom: new UIEventSource(17), - maxzoom: new UIEventSource(17), - }) - - mla.allowMoving.setData(false) - mla.allowZooming.setData(false) - mla.location.setData({ lon, lat }) - - if (args[0]) { - const parsed = Number(args[0]) - if (!isNaN(parsed) && parsed > 0 && parsed < 25) { - mla.zoom.setData(parsed) - } - } - mlmap.addCallbackAndRun((map) => console.log("Map for minimap vis is now", map)) - - ShowDataLayer.showMultipleLayers( - mlmap, - new StaticFeatureSource(featuresToShow), - state.layout.layers, - { zoomToFeatures: true } - ) - - return new SvelteUIElement(MaplibreMap, { - interactive: false, - map: mlmap, - mapProperties: mla, - }) - .SetClass("h-40 rounded") - .SetStyle("overflow: hidden; pointer-events: none;") - } -} diff --git a/src/UI/SpecialVisualizations.ts b/src/UI/SpecialVisualizations.ts index e260b810fa..bdbb46da3f 100644 --- a/src/UI/SpecialVisualizations.ts +++ b/src/UI/SpecialVisualizations.ts @@ -8,7 +8,7 @@ import { SpecialVisualizationState, } from "./SpecialVisualization" import { HistogramViz } from "./Popup/HistogramViz" -import { MinimapViz } from "./Popup/MinimapViz" +import MinimapViz from "./Popup/MinimapViz.svelte" import { ShareLinkViz } from "./Popup/ShareLinkViz" import { UploadToOsmViz } from "./Popup/UploadToOsmViz" import { MultiApplyViz } from "./Popup/MultiApplyViz" @@ -125,7 +125,7 @@ class NearbyImageVis implements SpecialVisualization { args: string[], feature: Feature, layer: LayerConfig - ): BaseUIElement { + ): SvelteUIElement { const isOpen = args[0] === "open" const readonly = args[1] === "readonly" const [lon, lat] = GeoOperations.centerpointCoordinates(feature) @@ -240,7 +240,7 @@ export class QuestionViz implements SpecialVisualization { args: string[], feature: Feature, layer: LayerConfig - ): BaseUIElement { + ): SvelteUIElement { const labels = args[0] ?.split(";") ?.map((s) => s.trim()) @@ -346,26 +346,6 @@ export default class SpecialVisualizations { return firstPart + "\n\n" + helpTexts.join("\n\n") } - // noinspection JSUnusedGlobalSymbols - public static renderExampleOfSpecial( - state: SpecialVisualizationState, - s: SpecialVisualization - ): BaseUIElement { - const examples = - s.structuredExamples === undefined - ? [] - : s.structuredExamples().map((e) => { - return s.constr( - state, - new UIEventSource>(e.feature.properties), - e.args, - e.feature, - undefined - ) - }) - return new Combine([new Title(s.funcName), s.docs, ...examples]) - } - private static initList(): SpecialVisualization[] { const specialVisualizations: SpecialVisualization[] = [ new QuestionViz(), @@ -426,7 +406,34 @@ export default class SpecialVisualizations { }, new HistogramViz(), new StealViz(), - new MinimapViz(), + { + funcName : "minimap", + docs :"A small map showing the selected feature.", + needsUrls : [], + args : [ + { + doc: "The (maximum) zoomlevel: the target zoomlevel after fitting the entire feature. The minimap will fit the entire feature, then zoom out to this zoom level. The higher, the more zoomed in with 1 being the entire world and 19 being really close", + name: "zoomlevel", + defaultValue: "18", + }, + { + doc: "(Matches all resting arguments) This argument should be the key of a property of the feature. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. (Note: if the key is 'id', list interpration is disabled)", + name: "idKey", + defaultValue: "id", + }, + ], + example: "`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`", + + constr( + state: SpecialVisualizationState, + tagSource: UIEventSource>, + args: string[], + feature: Feature + + ): SvelteUIElement { + return new SvelteUIElement(MinimapViz, {state, args, feature, tagSource}) + } + }, { funcName: "split_button", docs: "Adds a button which allows to split a way",