import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import DynamicTileSource from "./DynamicTileSource"; import {Utils} from "../../../Utils"; import GeoJsonSource from "../Sources/GeoJsonSource"; import {BBox} from "../../BBox"; export default class DynamicGeoJsonTileSource extends DynamicTileSource { private static whitelistCache = new Map() constructor(layer: FilteredLayer, registerLayer: (layer: FeatureSourceForLayer & Tiled) => void, state: { locationControl: UIEventSource currentBounds: UIEventSource }) { const source = layer.layerDef.source if (source.geojsonZoomLevel === undefined) { throw "Invalid layer: geojsonZoomLevel expected" } if (source.geojsonSource === undefined) { throw "Invalid layer: geojsonSource expected" } let whitelist = undefined if (source.geojsonSource.indexOf("{x}_{y}.geojson") > 0) { const whitelistUrl = source.geojsonSource .replace("{z}", "" + source.geojsonZoomLevel) .replace("{x}_{y}.geojson", "overview.json") .replace("{layer}", layer.layerDef.id) if (DynamicGeoJsonTileSource.whitelistCache.has(whitelistUrl)) { whitelist = DynamicGeoJsonTileSource.whitelistCache.get(whitelistUrl) } else { Utils.downloadJsonCached(whitelistUrl, 1000 * 60 * 60).then( json => { const data = new Map>(); for (const x in json) { if (x === "zoom") { continue } data.set(Number(x), new Set(json[x])) } console.log("The whitelist is", data, "based on ", json, "from", whitelistUrl) whitelist = data DynamicGeoJsonTileSource.whitelistCache.set(whitelistUrl, whitelist) } ).catch(err => { console.warn("No whitelist found for ", layer.layerDef.id, err) }) } } const blackList = (new Set()) super( layer, source.geojsonZoomLevel, (zxy) => { if (whitelist !== undefined) { const isWhiteListed = whitelist.get(zxy[1])?.has(zxy[2]) if (!isWhiteListed) { console.debug("Not downloading tile", ...zxy, "as it is not on the whitelist") return undefined; } } const src = new GeoJsonSource( layer, zxy, { featureIdBlacklist: blackList } ) registerLayer(src) return src }, state ); } public static RegisterWhitelist(url: string, json: any) { const data = new Map>(); for (const x in json) { if (x === "zoom") { continue } data.set(Number(x), new Set(json[x])) } DynamicGeoJsonTileSource.whitelistCache.set(url, data) } }