forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			102 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import FilteredLayer from "../../../Models/FilteredLayer"
 | |
| import { FeatureSourceForLayer, Tiled } from "../FeatureSource"
 | |
| import { UIEventSource } from "../../UIEventSource"
 | |
| 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<string, any>()
 | |
| 
 | |
|     constructor(
 | |
|         layer: FilteredLayer,
 | |
|         registerLayer: (layer: FeatureSourceForLayer & Tiled) => void,
 | |
|         state: {
 | |
|             locationControl?: UIEventSource<{ zoom?: number }>
 | |
|             currentBounds: UIEventSource<BBox>
 | |
|         }
 | |
|     ) {
 | |
|         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<number, Set<number>>()
 | |
|                         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<string>()
 | |
|         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<number, Set<number>>()
 | |
|         for (const x in json) {
 | |
|             if (x === "zoom") {
 | |
|                 continue
 | |
|             }
 | |
|             data.set(Number(x), new Set(json[x]))
 | |
|         }
 | |
|         DynamicGeoJsonTileSource.whitelistCache.set(url, data)
 | |
|     }
 | |
| }
 |