Add blacklist of ids to geojson source in order to avoid duplicate features to be loaded multiple times

This commit is contained in:
pietervdvn 2021-09-29 17:48:15 +02:00
parent fdcda66e5c
commit 36d62f9923
2 changed files with 28 additions and 2 deletions

View file

@ -21,14 +21,26 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled {
public readonly tileIndex public readonly tileIndex
public readonly bbox; public readonly bbox;
/**
* Only used if the actual source is a tiled geojson.
* A big feature might be contained in multiple tiles.
* However, we only want to load them once. The blacklist thus contains all ids of all features previously seen
* @private
*/
private readonly featureIdBlacklist?: UIEventSource<Set<string>>
public constructor(flayer: FilteredLayer, public constructor(flayer: FilteredLayer,
zxy?: [number, number, number]) { zxy?: [number, number, number],
options?: {
featureIdBlacklist?: UIEventSource<Set<string>>
}) {
if (flayer.layerDef.source.geojsonZoomLevel !== undefined && zxy === undefined) { if (flayer.layerDef.source.geojsonZoomLevel !== undefined && zxy === undefined) {
throw "Dynamic layers are not supported. Use 'DynamicGeoJsonTileSource instead" throw "Dynamic layers are not supported. Use 'DynamicGeoJsonTileSource instead"
} }
this.layer = flayer; this.layer = flayer;
this.featureIdBlacklist = options?.featureIdBlacklist
let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id); let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id);
if (zxy !== undefined) { if (zxy !== undefined) {
const [z, x, y] = zxy; const [z, x, y] = zxy;
@ -68,6 +80,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled {
const props = feature.properties const props = feature.properties
for (const key in props) { for (const key in props) {
if (typeof props[key] !== "string") { if (typeof props[key] !== "string") {
// Make sure all the values are string, it crashes stuff otherwise
props[key] = "" + props[key] props[key] = "" + props[key]
} }
} }
@ -82,6 +95,10 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled {
continue; continue;
} }
self.seenids.add(props.id) self.seenids.add(props.id)
if(self.featureIdBlacklist?.data?.has(props.id)){
continue;
}
let freshness: Date = time; let freshness: Date = time;
if (feature.properties["_last_edit:timestamp"] !== undefined) { if (feature.properties["_last_edit:timestamp"] !== undefined) {

View file

@ -37,6 +37,8 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource {
console.warn("No whitelist found for ", layer.layerDef.id, err) console.warn("No whitelist found for ", layer.layerDef.id, err)
}) })
const seenIds = new Set<string>();
const blackList = new UIEventSource(seenIds)
super( super(
layer, layer,
source.geojsonZoomLevel, source.geojsonZoomLevel,
@ -50,8 +52,15 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource {
const src = new GeoJsonSource( const src = new GeoJsonSource(
layer, layer,
zxy zxy,
{
featureIdBlacklist: blackList
}
) )
src.features.addCallbackAndRunD(feats => {
feats.forEach(feat => seenIds.add(feat.feature.properties.id))
blackList.ping();
})
registerLayer(src) registerLayer(src)
return src return src
}, },