forked from MapComplete/MapComplete
refactoring
This commit is contained in:
parent
b94a8f5745
commit
5d0fe31c41
114 changed files with 2412 additions and 2958 deletions
136
Logic/FeatureSource/Sources/LayoutSource.ts
Normal file
136
Logic/FeatureSource/Sources/LayoutSource.ts
Normal file
|
@ -0,0 +1,136 @@
|
|||
import GeoJsonSource from "./GeoJsonSource"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import FeatureSource from "../FeatureSource"
|
||||
import { Or } from "../../Tags/Or"
|
||||
import FeatureSwitchState from "../../State/FeatureSwitchState"
|
||||
import OverpassFeatureSource from "./OverpassFeatureSource"
|
||||
import { Store } from "../../UIEventSource"
|
||||
import OsmFeatureSource from "./OsmFeatureSource"
|
||||
import FeatureSourceMerger from "./FeatureSourceMerger"
|
||||
import DynamicGeoJsonTileSource from "../TiledFeatureSource/DynamicGeoJsonTileSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeatureSource"
|
||||
|
||||
/**
|
||||
* This source will fetch the needed data from various sources for the given layout.
|
||||
*
|
||||
* Note that special layers (with `source=null` will be ignored)
|
||||
*/
|
||||
export default class LayoutSource extends FeatureSourceMerger {
|
||||
constructor(
|
||||
layers: LayerConfig[],
|
||||
featureSwitches: FeatureSwitchState,
|
||||
newAndChangedElements: FeatureSource,
|
||||
mapProperties: { bounds: Store<BBox>; zoom: Store<number> },
|
||||
backend: string,
|
||||
isDisplayed: (id: string) => Store<boolean>
|
||||
) {
|
||||
const { bounds, zoom } = mapProperties
|
||||
// remove all 'special' layers
|
||||
layers = layers.filter((flayer) => flayer.source !== null)
|
||||
|
||||
const geojsonlayers = layers.filter((layer) => layer.source.geojsonSource !== undefined)
|
||||
const osmLayers = layers.filter((layer) => layer.source.geojsonSource === undefined)
|
||||
const fromCache = osmLayers.map(
|
||||
(l) =>
|
||||
new LocalStorageFeatureSource(l.id, 15, mapProperties, {
|
||||
isActive: isDisplayed(l.id),
|
||||
})
|
||||
)
|
||||
const overpassSource = LayoutSource.setupOverpass(osmLayers, bounds, zoom, featureSwitches)
|
||||
const osmApiSource = LayoutSource.setupOsmApiSource(
|
||||
osmLayers,
|
||||
bounds,
|
||||
zoom,
|
||||
backend,
|
||||
featureSwitches
|
||||
)
|
||||
const geojsonSources: FeatureSource[] = geojsonlayers.map((l) =>
|
||||
LayoutSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id))
|
||||
)
|
||||
|
||||
const expiryInSeconds = Math.min(...(layers?.map((l) => l.maxAgeOfCache) ?? []))
|
||||
super(overpassSource, osmApiSource, newAndChangedElements, ...geojsonSources, ...fromCache)
|
||||
}
|
||||
|
||||
private static setupGeojsonSource(
|
||||
layer: LayerConfig,
|
||||
mapProperties: { zoom: Store<number>; bounds: Store<BBox> },
|
||||
isActive?: Store<boolean>
|
||||
): FeatureSource {
|
||||
const source = layer.source
|
||||
isActive = mapProperties.zoom.map(
|
||||
(z) => (isActive?.data ?? true) && z >= layer.maxzoom,
|
||||
[isActive]
|
||||
)
|
||||
if (source.geojsonZoomLevel === undefined) {
|
||||
// This is a 'load everything at once' geojson layer
|
||||
return new GeoJsonSource(layer, { isActive })
|
||||
} else {
|
||||
return new DynamicGeoJsonTileSource(layer, mapProperties, { isActive })
|
||||
}
|
||||
}
|
||||
|
||||
private static setupOsmApiSource(
|
||||
osmLayers: LayerConfig[],
|
||||
bounds: Store<BBox>,
|
||||
zoom: Store<number>,
|
||||
backend: string,
|
||||
featureSwitches: FeatureSwitchState
|
||||
): FeatureSource {
|
||||
const minzoom = Math.min(...osmLayers.map((layer) => layer.minzoom))
|
||||
const isActive = zoom.mapD((z) => {
|
||||
if (z < minzoom) {
|
||||
// We are zoomed out over the zoomlevel of any layer
|
||||
console.debug("Disabling overpass source: zoom < minzoom")
|
||||
return false
|
||||
}
|
||||
|
||||
// Overpass should handle this if zoomed out a bit
|
||||
return z > featureSwitches.overpassMaxZoom.data
|
||||
})
|
||||
const allowedFeatures = new Or(osmLayers.map((l) => l.source.osmTags)).optimize()
|
||||
if (typeof allowedFeatures === "boolean") {
|
||||
throw "Invalid filter to init OsmFeatureSource: it optimizes away to " + allowedFeatures
|
||||
}
|
||||
return new OsmFeatureSource({
|
||||
allowedFeatures,
|
||||
bounds,
|
||||
backend,
|
||||
isActive,
|
||||
})
|
||||
}
|
||||
|
||||
private static setupOverpass(
|
||||
osmLayers: LayerConfig[],
|
||||
bounds: Store<BBox>,
|
||||
zoom: Store<number>,
|
||||
featureSwitches: FeatureSwitchState
|
||||
): FeatureSource {
|
||||
const minzoom = Math.min(...osmLayers.map((layer) => layer.minzoom))
|
||||
const isActive = zoom.mapD((z) => {
|
||||
if (z < minzoom) {
|
||||
// We are zoomed out over the zoomlevel of any layer
|
||||
console.debug("Disabling overpass source: zoom < minzoom")
|
||||
return false
|
||||
}
|
||||
|
||||
return z <= featureSwitches.overpassMaxZoom.data
|
||||
})
|
||||
|
||||
return new OverpassFeatureSource(
|
||||
{
|
||||
zoom,
|
||||
bounds,
|
||||
layoutToUse: featureSwitches.layoutToUse,
|
||||
overpassUrl: featureSwitches.overpassUrl,
|
||||
overpassTimeout: featureSwitches.overpassTimeout,
|
||||
overpassMaxZoom: featureSwitches.overpassMaxZoom,
|
||||
},
|
||||
{
|
||||
padToTiles: zoom.map((zoom) => Math.min(15, zoom + 1)),
|
||||
isActive,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue