2021-01-03 03:09:52 +01:00
|
|
|
import FeatureSource from "./FeatureSource";
|
|
|
|
import {UIEventSource} from "../UIEventSource";
|
|
|
|
import LayerConfig from "../../Customizations/JSON/LayerConfig";
|
|
|
|
import Loc from "../../Models/Loc";
|
2021-05-13 13:04:17 +02:00
|
|
|
import Hash from "../Web/Hash";
|
2021-01-03 03:09:52 +01:00
|
|
|
|
|
|
|
export default class FilteringFeatureSource implements FeatureSource {
|
|
|
|
public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
|
2021-05-06 01:33:09 +02:00
|
|
|
public readonly name = "FilteringFeatureSource"
|
|
|
|
|
2021-02-20 01:45:51 +01:00
|
|
|
constructor(layers: UIEventSource<{
|
2021-01-03 03:09:52 +01:00
|
|
|
isDisplayed: UIEventSource<boolean>,
|
|
|
|
layerDef: LayerConfig
|
2021-02-20 01:45:51 +01:00
|
|
|
}[]>,
|
2021-01-03 03:09:52 +01:00
|
|
|
location: UIEventSource<Loc>,
|
2021-05-06 01:33:09 +02:00
|
|
|
selectedElement: UIEventSource<any>,
|
2021-01-03 03:09:52 +01:00
|
|
|
upstream: FeatureSource) {
|
|
|
|
|
|
|
|
const self = this;
|
2021-01-04 04:06:21 +01:00
|
|
|
|
2021-01-03 03:09:52 +01:00
|
|
|
function update() {
|
2021-02-20 01:45:51 +01:00
|
|
|
|
|
|
|
const layerDict = {};
|
2021-05-06 01:33:09 +02:00
|
|
|
if (layers.data.length == 0) {
|
2021-05-17 00:17:21 +02:00
|
|
|
console.warn("No layers defined!")
|
|
|
|
return;
|
2021-04-23 16:51:44 +02:00
|
|
|
}
|
2021-02-20 01:45:51 +01:00
|
|
|
for (const layer of layers.data) {
|
|
|
|
layerDict[layer.layerDef.id] = layer;
|
|
|
|
}
|
|
|
|
|
2021-01-03 03:09:52 +01:00
|
|
|
const features: { feature: any, freshness: Date }[] = upstream.features.data;
|
2021-02-20 01:45:51 +01:00
|
|
|
|
2021-04-23 16:51:44 +02:00
|
|
|
const missingLayers = new Set<string>();
|
2021-02-20 01:45:51 +01:00
|
|
|
|
2021-01-03 03:09:52 +01:00
|
|
|
const newFeatures = features.filter(f => {
|
2021-01-04 04:06:21 +01:00
|
|
|
const layerId = f.feature._matching_layer_id;
|
2021-03-25 15:19:44 +01:00
|
|
|
|
2021-05-13 13:04:17 +02:00
|
|
|
if(selectedElement.data?.id === f.feature.id || f.feature.id === Hash.hash.data){
|
2021-05-06 01:33:09 +02:00
|
|
|
// This is the selected object - it gets a free pass even if zoom is not sufficient
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-02-14 19:45:02 +01:00
|
|
|
if (layerId !== undefined) {
|
|
|
|
const layer: {
|
|
|
|
isDisplayed: UIEventSource<boolean>,
|
|
|
|
layerDef: LayerConfig
|
|
|
|
} = layerDict[layerId];
|
|
|
|
if (layer === undefined) {
|
2021-04-23 16:51:44 +02:00
|
|
|
missingLayers.add(layerId)
|
2021-02-14 19:45:02 +01:00
|
|
|
return true;
|
|
|
|
}
|
2021-05-06 01:33:09 +02:00
|
|
|
|
2021-03-25 15:19:44 +01:00
|
|
|
const isShown = layer.layerDef.isShown
|
|
|
|
const tags = f.feature.properties;
|
2021-05-06 01:33:09 +02:00
|
|
|
if (isShown.IsKnown(tags)) {
|
2021-03-25 15:19:44 +01:00
|
|
|
const result = layer.layerDef.isShown.GetRenderValue(f.feature.properties).txt;
|
2021-05-06 01:33:09 +02:00
|
|
|
if (result !== "yes") {
|
2021-03-25 15:19:44 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2021-05-06 01:33:09 +02:00
|
|
|
|
2021-02-14 19:45:02 +01:00
|
|
|
if (FilteringFeatureSource.showLayer(layer, location)) {
|
|
|
|
return true;
|
|
|
|
}
|
2021-01-08 04:06:10 +01:00
|
|
|
}
|
2021-02-14 19:45:02 +01:00
|
|
|
// Does it match any other layer - e.g. because of a switch?
|
2021-02-20 01:45:51 +01:00
|
|
|
for (const toCheck of layers.data) {
|
2021-01-08 14:23:12 +01:00
|
|
|
if (!FilteringFeatureSource.showLayer(toCheck, location)) {
|
2021-01-08 04:06:10 +01:00
|
|
|
continue;
|
|
|
|
}
|
2021-03-21 00:44:23 +01:00
|
|
|
if (toCheck.layerDef.source.osmTags.matchesProperties(f.feature.properties)) {
|
2021-01-08 04:06:10 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2021-01-08 14:23:12 +01:00
|
|
|
|
2021-01-03 03:09:52 +01:00
|
|
|
});
|
2021-05-03 16:04:35 +02:00
|
|
|
console.log("Filtering layer source: input: ", upstream.features.data?.length, "output:", newFeatures.length)
|
2021-01-03 03:09:52 +01:00
|
|
|
self.features.setData(newFeatures);
|
2021-05-06 01:33:09 +02:00
|
|
|
if (missingLayers.size > 0) {
|
2021-04-23 16:51:44 +02:00
|
|
|
console.error("Some layers were not found: ", Array.from(missingLayers))
|
|
|
|
}
|
2021-01-03 03:09:52 +01:00
|
|
|
}
|
2021-01-04 04:06:21 +01:00
|
|
|
|
2021-02-14 19:45:02 +01:00
|
|
|
|
2021-01-04 04:06:21 +01:00
|
|
|
upstream.features.addCallback(() => {
|
2021-01-08 14:23:12 +01:00
|
|
|
update()
|
|
|
|
});
|
2021-01-05 10:56:25 +01:00
|
|
|
location.map(l => {
|
|
|
|
// We want something that is stable for the shown layers
|
|
|
|
const displayedLayerIndexes = [];
|
2021-02-20 01:45:51 +01:00
|
|
|
for (let i = 0; i < layers.data.length; i++) {
|
|
|
|
const layer = layers.data[i];
|
|
|
|
if (l.zoom < layer.layerDef.minzoom) {
|
2021-01-05 11:17:12 +01:00
|
|
|
continue;
|
2021-01-05 10:56:25 +01:00
|
|
|
}
|
2021-05-06 01:33:09 +02:00
|
|
|
if (l.zoom > layer.layerDef.maxzoom) {
|
2021-03-21 01:36:34 +01:00
|
|
|
continue;
|
|
|
|
}
|
2021-02-20 01:45:51 +01:00
|
|
|
if (!layer.isDisplayed.data) {
|
2021-01-05 11:17:12 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
displayedLayerIndexes.push(i);
|
2021-01-05 10:56:25 +01:00
|
|
|
}
|
|
|
|
return displayedLayerIndexes.join(",")
|
2021-02-20 01:45:51 +01:00
|
|
|
}).addCallback(() => {
|
|
|
|
update();
|
|
|
|
});
|
2021-05-06 01:33:09 +02:00
|
|
|
|
2021-02-20 01:45:51 +01:00
|
|
|
layers.addCallback(update);
|
2021-05-06 01:33:09 +02:00
|
|
|
|
2021-02-20 01:45:51 +01:00
|
|
|
const registered = new Set<UIEventSource<boolean>>();
|
2021-03-14 01:53:37 +01:00
|
|
|
layers.addCallbackAndRun(layers => {
|
2021-02-20 01:45:51 +01:00
|
|
|
for (const layer of layers) {
|
2021-05-06 01:33:09 +02:00
|
|
|
if (registered.has(layer.isDisplayed)) {
|
2021-02-20 01:45:51 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
registered.add(layer.isDisplayed);
|
2021-03-14 01:53:37 +01:00
|
|
|
layer.isDisplayed.addCallback(() => update());
|
2021-02-20 01:45:51 +01:00
|
|
|
}
|
|
|
|
})
|
2021-01-03 03:09:52 +01:00
|
|
|
|
2021-01-15 00:29:07 +01:00
|
|
|
update();
|
2021-01-03 03:09:52 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-01-08 14:23:12 +01:00
|
|
|
private static showLayer(layer: {
|
|
|
|
isDisplayed: UIEventSource<boolean>,
|
|
|
|
layerDef: LayerConfig
|
|
|
|
}, location: UIEventSource<Loc>) {
|
2021-03-21 01:36:34 +01:00
|
|
|
return layer.isDisplayed.data && (layer.layerDef.minzoom <= location.data.zoom) && (layer.layerDef.maxzoom >= location.data.zoom)
|
2021-01-08 14:23:12 +01:00
|
|
|
}
|
2021-01-03 03:09:52 +01:00
|
|
|
}
|