MapComplete/Logic/State/FeaturePipelineState.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

115 lines
4.4 KiB
TypeScript
Raw Normal View History

import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
import FeaturePipeline from "../FeatureSource/FeaturePipeline"
import { Tiles } from "../../Models/TileRange"
import SelectedFeatureHandler from "../Actors/SelectedFeatureHandler"
import Hash from "../Web/Hash"
2021-12-07 17:46:57 +01:00
import { BBox } from "../BBox"
2022-01-26 20:47:08 +01:00
import { FeatureSourceForLayer, Tiled } from "../FeatureSource/FeatureSource"
import MetaTagRecalculator from "../FeatureSource/Actors/MetaTagRecalculator"
2023-03-25 02:48:24 +01:00
export default class FeaturePipelineState {
/**
* The piece of code which fetches data from various sources and shows it on the background map
*/
public readonly featurePipeline: FeaturePipeline
2022-01-26 21:40:38 +01:00
private readonly metatagRecalculator: MetaTagRecalculator
2022-09-08 21:40:48 +02:00
constructor(layoutToUse: LayoutConfig) {
2022-02-22 14:13:41 +01:00
const clustering = layoutToUse?.clustering
const clusterCounter = this.featureAggregator
const self = this
2022-01-26 20:47:08 +01:00
/**
* We are a bit in a bind:
* There is the featurePipeline, which creates some sources during construction
* THere is the metatagger, which needs to have these sources registered AND which takes a FeaturePipeline as argument
2022-01-26 21:40:38 +01:00
*
2022-01-26 20:47:08 +01:00
* This is a bit of a catch-22 (except that it isn't)
2022-01-26 21:40:38 +01:00
* The sources that are registered in the constructor are saved into 'registeredSources' temporary
*
2022-01-26 20:47:08 +01:00
*/
const sourcesToRegister = []
2022-01-26 21:40:38 +01:00
function registerRaw(source: FeatureSourceForLayer & Tiled) {
if (self.metatagRecalculator === undefined) {
2022-01-26 20:47:08 +01:00
sourcesToRegister.push(source)
2022-01-26 21:40:38 +01:00
} else {
2022-01-26 20:47:08 +01:00
self.metatagRecalculator.registerSource(source)
}
}
function registerSource(source: FeatureSourceForLayer & Tiled) {
clusterCounter.addTile(source)
const sourceBBox = source.features.map((allFeatures) =>
BBox.bboxAroundAll(allFeatures.map(BBox.get))
2022-09-08 21:40:48 +02:00
)
2022-01-26 20:47:08 +01:00
// Do show features indicates if the respective 'showDataLayer' should be shown. It can be hidden by e.g. clustering
source.features.map(
2022-01-26 20:47:08 +01:00
(f) => {
const z = self.locationControl.data.zoom
if (!source.layer.isDisplayed.data) {
return false
}
2022-01-26 20:47:08 +01:00
const bounds = self.currentBounds.data
if (bounds === undefined) {
// Map is not yet displayed
return false
}
2022-01-26 20:47:08 +01:00
if (!sourceBBox.data.overlapsWith(bounds)) {
// Not within range -> features are hidden
return false
}
2022-01-26 20:47:08 +01:00
if (z < source.layer.layerDef.minzoom) {
// Layer is always hidden for this zoom level
return false
}
2022-01-26 20:47:08 +01:00
if (z > clustering.maxZoom) {
return true
}
2022-01-26 20:47:08 +01:00
if (f.length > clustering.minNeededElements) {
// This tile alone already has too much features
return false
}
2022-01-26 20:47:08 +01:00
let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex)
if (tileZ >= z) {
while (tileZ > z) {
tileZ--
tileX = Math.floor(tileX / 2)
tileY = Math.floor(tileY / 2)
}
2022-01-26 20:47:08 +01:00
if (
clusterCounter.getTile(Tiles.tile_index(tileZ, tileX, tileY))
?.totalValue > clustering.minNeededElements
) {
// To much elements
return false
}
2022-01-26 20:47:08 +01:00
}
2022-01-26 20:47:08 +01:00
return true
},
[self.currentBounds, source.layer.isDisplayed, sourceBBox]
)
}
2022-01-26 20:47:08 +01:00
this.featurePipeline = new FeaturePipeline(registerSource, this, {
handleRawFeatureSource: registerRaw,
})
this.metatagRecalculator = new MetaTagRecalculator(this, this.featurePipeline)
this.metatagRecalculator.registerSource(this.currentView)
2022-01-26 20:47:08 +01:00
sourcesToRegister.forEach((source) => self.metatagRecalculator.registerSource(source))
2022-01-26 21:40:38 +01:00
new SelectedFeatureHandler(Hash.hash, this)
}
}