diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 5fedaf2..5488aea 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -11,7 +11,6 @@ import ScrollableFullScreen from "../Base/ScrollableFullScreen"; import {Utils} from "../../Utils"; export default class FeatureInfoBox extends ScrollableFullScreen { - private static featureInfoboxCache: Map, FeatureInfoBox>> = new Map, FeatureInfoBox>>(); private constructor( tags: UIEventSource, @@ -28,8 +27,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { } static construct(tags: UIEventSource, layer: LayerConfig): FeatureInfoBox { - let innerMap = Utils.getOrSetDefault(FeatureInfoBox.featureInfoboxCache, layer,() => new Map, FeatureInfoBox>()) - return Utils.getOrSetDefault(innerMap, tags, () => new FeatureInfoBox(tags, layer)); + return new FeatureInfoBox(tags, layer) } private static GenerateTitleBar(tags: UIEventSource, diff --git a/UI/ShowDataLayer.ts b/UI/ShowDataLayer.ts index 0e231bc..6014f74 100644 --- a/UI/ShowDataLayer.ts +++ b/UI/ShowDataLayer.ts @@ -6,10 +6,8 @@ import * as L from "leaflet" import "leaflet.markercluster" import LayerConfig from "../Customizations/JSON/LayerConfig"; import State from "../State"; -import LazyElement from "./Base/LazyElement"; import FeatureInfoBox from "./Popup/FeatureInfoBox"; import LayoutConfig from "../Customizations/JSON/LayoutConfig"; -import {GeoOperations} from "../Logic/GeoOperations"; export default class ShowDataLayer { @@ -17,6 +15,8 @@ export default class ShowDataLayer { private _layerDict; private readonly _leafletMap: UIEventSource; + private readonly _popups = new Map(); + constructor(features: UIEventSource<{ feature: any, freshness: Date }[]>, leafletMap: UIEventSource, layoutToUse: UIEventSource) { @@ -72,6 +72,35 @@ export default class ShowDataLayer { features.addCallback(() => update()); leafletMap.addCallback(() => update()); update(); + + + State.state.selectedElement.addCallbackAndRun(selected => { + if (selected === undefined) { + mp.closePopup(); + return; + } + const marker = self._popups.get(selected); + if (marker === undefined) { + return; + } + marker.openPopup(); + + const popup = marker.getPopup(); + const tags = State.state.allElements.getEventSourceFor(selected); + const layer: LayerConfig = this._layerDict[selected._matching_layer_id]; + const infoBox = FeatureInfoBox.construct(tags, layer); + + infoBox.isShown.addCallback(isShown => { + if (!isShown) { + State.state.selectedElement.setData(undefined); + } + }); + + popup.setContent(infoBox.Render()); + infoBox.Activate(); + infoBox.Update(); + }) + } @@ -107,9 +136,10 @@ export default class ShowDataLayer { }); } + private postProcessFeature(feature, leafletLayer: L.Layer) { const layer: LayerConfig = this._layerDict[feature._matching_layer_id]; - if(layer === undefined){ + if (layer === undefined) { console.warn("No layer found for object (probably a now disabled layer)", feature, this._layerDict) return; } @@ -123,53 +153,15 @@ export default class ShowDataLayer { closeButton: false }, leafletLayer); - const tags = State.state.allElements.getEventSourceFor(feature); - const uiElement = new LazyElement(() => { - const infoBox = FeatureInfoBox.construct(tags, layer); - infoBox.isShown.addCallback(isShown => { - if(!isShown){ - State.state.selectedElement.setData(undefined); - leafletLayer.closePopup(); - popup.remove(); - } - }); - return infoBox; - }, - "
Rendering
"); // By setting 50vh, leaflet will attempt to fit the entire screen and move the feature down - popup.setContent(uiElement.Render()); + // By setting 50vh, leaflet will attempt to fit the entire screen and move the feature down + popup.setContent("
Rendering
"); + leafletLayer.bindPopup(popup); - // We first render the UIelement (which'll still need an update later on...) - // But at least it'll be visible already - - leafletLayer.on("popupopen", () => { - State.state.selectedElement.setData(feature); - uiElement.Activate(); - }) + State.state.selectedElement.setData(feature) + }); - State.state.selectedElement.addCallbackAndRun(selected => { - - if (selected === undefined) { - if (popup.isOpen()) { - popup.remove(); - } - } else if (selected == feature && selected.geometry.type === feature.geometry.type) { - // If wayhandling introduces a centerpoint and an area, this code might become unstable: - // The popup for the centerpoint would open, a bit later the area would close the first popup and open it's own - // In the process, the 'selectedElement' is set to undefined and to the other feature again, causing an infinite loop - - // This is why we check for the geometry-type too - - const mp = this._leafletMap.data; - if (!popup.isOpen() && mp !== undefined) { - popup - .setLatLng(GeoOperations.centerpointCoordinates(feature)) - .openOn(mp); - uiElement.Activate(); - } - } - } - ); + this._popups.set(feature, leafletLayer); }