forked from MapComplete/MapComplete
Huge refactoring of state and initial UI setup
This commit is contained in:
parent
4e43673de5
commit
eff6b5bfad
37 changed files with 5232 additions and 4907 deletions
172
Logic/State/FeaturePipelineState.ts
Normal file
172
Logic/State/FeaturePipelineState.ts
Normal file
|
@ -0,0 +1,172 @@
|
|||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||
import FeaturePipeline from "../FeatureSource/FeaturePipeline";
|
||||
import State from "../../State";
|
||||
import {Tiles} from "../../Models/TileRange";
|
||||
import ShowDataLayer from "../../UI/ShowDataLayer/ShowDataLayer";
|
||||
import {TileHierarchyAggregator} from "../../UI/ShowDataLayer/TileHierarchyAggregator";
|
||||
import ShowTileInfo from "../../UI/ShowDataLayer/ShowTileInfo";
|
||||
import {UIEventSource} from "../UIEventSource";
|
||||
import MapState from "./MapState";
|
||||
import SelectedFeatureHandler from "../Actors/SelectedFeatureHandler";
|
||||
import Hash from "../Web/Hash";
|
||||
import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen";
|
||||
import Translations from "../../UI/i18n/Translations";
|
||||
import SimpleAddUI from "../../UI/BigComponents/SimpleAddUI";
|
||||
import StrayClickHandler from "../Actors/StrayClickHandler";
|
||||
|
||||
export default class FeaturePipelineState extends MapState {
|
||||
|
||||
/**
|
||||
* The piece of code which fetches data from various sources and shows it on the background map
|
||||
*/
|
||||
public readonly featurePipeline: FeaturePipeline;
|
||||
private readonly featureAggregator: TileHierarchyAggregator;
|
||||
|
||||
constructor(layoutToUse: LayoutConfig) {
|
||||
super(layoutToUse);
|
||||
|
||||
const clustering = layoutToUse.clustering
|
||||
this.featureAggregator = TileHierarchyAggregator.createHierarchy();
|
||||
const clusterCounter = this.featureAggregator
|
||||
const self = this;
|
||||
this.featurePipeline = new FeaturePipeline(
|
||||
source => {
|
||||
|
||||
clusterCounter.addTile(source)
|
||||
|
||||
// Do show features indicates if the 'showDataLayer' should be shown
|
||||
const doShowFeatures = source.features.map(
|
||||
f => {
|
||||
const z = State.state.locationControl.data.zoom
|
||||
|
||||
if (!source.layer.isDisplayed.data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bounds = State.state.currentBounds.data
|
||||
if (bounds === undefined) {
|
||||
// Map is not yet displayed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source.bbox.overlapsWith(bounds)) {
|
||||
// Not within range -> features are hidden
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
if (z < source.layer.layerDef.minzoom) {
|
||||
// Layer is always hidden for this zoom level
|
||||
return false;
|
||||
}
|
||||
|
||||
if (z > clustering.maxZoom) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (f.length > clustering.minNeededElements) {
|
||||
// This tile alone already has too much features
|
||||
return false
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
if (clusterCounter.getTile(Tiles.tile_index(tileZ, tileX, tileY))?.totalValue > clustering.minNeededElements) {
|
||||
// To much elements
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}, [State.state.currentBounds, source.layer.isDisplayed]
|
||||
)
|
||||
|
||||
new ShowDataLayer(
|
||||
{
|
||||
features: source,
|
||||
leafletMap: self.leafletMap,
|
||||
layerToShow: source.layer.layerDef,
|
||||
doShowLayer: doShowFeatures,
|
||||
allElements: self.allElements,
|
||||
selectedElement: self.selectedElement
|
||||
}
|
||||
);
|
||||
}, this
|
||||
);
|
||||
new SelectedFeatureHandler(Hash.hash, this)
|
||||
|
||||
this.AddClusteringToMap(this.leafletMap)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the cluster-tiles to the given map
|
||||
* @param leafletMap: a UIEventSource possible having a leaflet map
|
||||
* @constructor
|
||||
*/
|
||||
public AddClusteringToMap(leafletMap: UIEventSource<any>) {
|
||||
const clustering = this.layoutToUse.clustering
|
||||
new ShowDataLayer({
|
||||
features: this.featureAggregator.getCountsForZoom(clustering, this.locationControl, clustering.minNeededElements),
|
||||
leafletMap: leafletMap,
|
||||
layerToShow: ShowTileInfo.styling,
|
||||
enablePopups: false,
|
||||
})
|
||||
}
|
||||
|
||||
public setupClickDialogOnMap(filterViewIsOpened: UIEventSource<boolean>, leafletMap: UIEventSource<any>) {
|
||||
|
||||
const self = this
|
||||
function setup(){
|
||||
let presetCount = 0;
|
||||
for (const layer of self.layoutToUse.layers) {
|
||||
for (const preset of layer.presets) {
|
||||
presetCount++;
|
||||
}
|
||||
}
|
||||
if (presetCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newPointDialogIsShown = new UIEventSource<boolean>(false);
|
||||
const addNewPoint = new ScrollableFullScreen(
|
||||
() => Translations.t.general.add.title.Clone(),
|
||||
() => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, self),
|
||||
"new",
|
||||
newPointDialogIsShown
|
||||
);
|
||||
addNewPoint.isShown.addCallback((isShown) => {
|
||||
if (!isShown) {
|
||||
self.LastClickLocation.setData(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
new StrayClickHandler(
|
||||
self.LastClickLocation,
|
||||
self.selectedElement,
|
||||
self.filteredLayers,
|
||||
leafletMap,
|
||||
addNewPoint
|
||||
);
|
||||
}
|
||||
|
||||
this.featureSwitchAddNew.addCallbackAndRunD(addNewAllowed => {
|
||||
if (addNewAllowed) {
|
||||
setup()
|
||||
return true;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue