Remove caches as they would break interactivity
This commit is contained in:
parent
14309e29b0
commit
1a74dd460b
2 changed files with 40 additions and 50 deletions
|
@ -11,7 +11,6 @@ import ScrollableFullScreen from "../Base/ScrollableFullScreen";
|
||||||
import {Utils} from "../../Utils";
|
import {Utils} from "../../Utils";
|
||||||
|
|
||||||
export default class FeatureInfoBox extends ScrollableFullScreen {
|
export default class FeatureInfoBox extends ScrollableFullScreen {
|
||||||
private static featureInfoboxCache: Map<LayerConfig, Map<UIEventSource<any>, FeatureInfoBox>> = new Map<LayerConfig, Map<UIEventSource<any>, FeatureInfoBox>>();
|
|
||||||
|
|
||||||
private constructor(
|
private constructor(
|
||||||
tags: UIEventSource<any>,
|
tags: UIEventSource<any>,
|
||||||
|
@ -28,8 +27,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
static construct(tags: UIEventSource<any>, layer: LayerConfig): FeatureInfoBox {
|
static construct(tags: UIEventSource<any>, layer: LayerConfig): FeatureInfoBox {
|
||||||
let innerMap = Utils.getOrSetDefault(FeatureInfoBox.featureInfoboxCache, layer,() => new Map<UIEventSource<any>, FeatureInfoBox>())
|
return new FeatureInfoBox(tags, layer)
|
||||||
return Utils.getOrSetDefault(innerMap, tags, () => new FeatureInfoBox(tags, layer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GenerateTitleBar(tags: UIEventSource<any>,
|
private static GenerateTitleBar(tags: UIEventSource<any>,
|
||||||
|
|
|
@ -6,10 +6,8 @@ import * as L from "leaflet"
|
||||||
import "leaflet.markercluster"
|
import "leaflet.markercluster"
|
||||||
import LayerConfig from "../Customizations/JSON/LayerConfig";
|
import LayerConfig from "../Customizations/JSON/LayerConfig";
|
||||||
import State from "../State";
|
import State from "../State";
|
||||||
import LazyElement from "./Base/LazyElement";
|
|
||||||
import FeatureInfoBox from "./Popup/FeatureInfoBox";
|
import FeatureInfoBox from "./Popup/FeatureInfoBox";
|
||||||
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
|
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
|
||||||
import {GeoOperations} from "../Logic/GeoOperations";
|
|
||||||
|
|
||||||
|
|
||||||
export default class ShowDataLayer {
|
export default class ShowDataLayer {
|
||||||
|
@ -17,6 +15,8 @@ export default class ShowDataLayer {
|
||||||
private _layerDict;
|
private _layerDict;
|
||||||
private readonly _leafletMap: UIEventSource<L.Map>;
|
private readonly _leafletMap: UIEventSource<L.Map>;
|
||||||
|
|
||||||
|
private readonly _popups = new Map<any, L.Layer>();
|
||||||
|
|
||||||
constructor(features: UIEventSource<{ feature: any, freshness: Date }[]>,
|
constructor(features: UIEventSource<{ feature: any, freshness: Date }[]>,
|
||||||
leafletMap: UIEventSource<L.Map>,
|
leafletMap: UIEventSource<L.Map>,
|
||||||
layoutToUse: UIEventSource<LayoutConfig>) {
|
layoutToUse: UIEventSource<LayoutConfig>) {
|
||||||
|
@ -72,6 +72,35 @@ export default class ShowDataLayer {
|
||||||
features.addCallback(() => update());
|
features.addCallback(() => update());
|
||||||
leafletMap.addCallback(() => update());
|
leafletMap.addCallback(() => update());
|
||||||
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,6 +136,7 @@ export default class ShowDataLayer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private postProcessFeature(feature, leafletLayer: L.Layer) {
|
private postProcessFeature(feature, leafletLayer: L.Layer) {
|
||||||
const layer: LayerConfig = this._layerDict[feature._matching_layer_id];
|
const layer: LayerConfig = this._layerDict[feature._matching_layer_id];
|
||||||
if (layer === undefined) {
|
if (layer === undefined) {
|
||||||
|
@ -123,53 +153,15 @@ export default class ShowDataLayer {
|
||||||
closeButton: false
|
closeButton: false
|
||||||
}, leafletLayer);
|
}, leafletLayer);
|
||||||
|
|
||||||
const tags = State.state.allElements.getEventSourceFor(feature);
|
// By setting 50vh, leaflet will attempt to fit the entire screen and move the feature down
|
||||||
const uiElement = new LazyElement(() => {
|
popup.setContent("<div style='height: 50vh'>Rendering</div>");
|
||||||
const infoBox = FeatureInfoBox.construct(tags, layer);
|
|
||||||
infoBox.isShown.addCallback(isShown => {
|
|
||||||
if(!isShown){
|
|
||||||
State.state.selectedElement.setData(undefined);
|
|
||||||
leafletLayer.closePopup();
|
|
||||||
popup.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return infoBox;
|
|
||||||
},
|
|
||||||
"<div style='height: 50vh'>Rendering</div>"); // By setting 50vh, leaflet will attempt to fit the entire screen and move the feature down
|
|
||||||
popup.setContent(uiElement.Render());
|
|
||||||
leafletLayer.bindPopup(popup);
|
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", () => {
|
leafletLayer.on("popupopen", () => {
|
||||||
State.state.selectedElement.setData(feature);
|
State.state.selectedElement.setData(feature)
|
||||||
uiElement.Activate();
|
});
|
||||||
})
|
|
||||||
|
|
||||||
State.state.selectedElement.addCallbackAndRun(selected => {
|
this._popups.set(feature, leafletLayer);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue