forked from MapComplete/MapComplete
Huge refactoring: split readonly and writable stores
This commit is contained in:
parent
0946d8ac9c
commit
4283b76f36
95 changed files with 819 additions and 625 deletions
|
@ -3,12 +3,12 @@
|
|||
* Data coming from upstream will always overwrite a previous value
|
||||
*/
|
||||
import FeatureSource, {Tiled} from "../FeatureSource";
|
||||
import {UIEventSource} from "../../UIEventSource";
|
||||
import {Store, UIEventSource} from "../../UIEventSource";
|
||||
import {BBox} from "../../BBox";
|
||||
|
||||
export default class RememberingSource implements FeatureSource, Tiled {
|
||||
|
||||
public readonly features: UIEventSource<{ feature: any, freshness: Date }[]>;
|
||||
public readonly features: Store<{ feature: any, freshness: Date }[]>;
|
||||
public readonly name;
|
||||
public readonly tileIndex: number
|
||||
public readonly bbox: BBox
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/**
|
||||
* This feature source helps the ShowDataLayer class: it introduces the necessary extra features and indicates with what renderConfig it should be rendered.
|
||||
*/
|
||||
import {UIEventSource} from "../../UIEventSource";
|
||||
import {Store, UIEventSource} from "../../UIEventSource";
|
||||
import {GeoOperations} from "../../GeoOperations";
|
||||
import FeatureSource from "../FeatureSource";
|
||||
import PointRenderingConfig from "../../../Models/ThemeConfig/PointRenderingConfig";
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
|
||||
|
||||
export default class RenderingMultiPlexerFeatureSource {
|
||||
public readonly features: UIEventSource<(any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[]>;
|
||||
public readonly features: Store<(any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[]>;
|
||||
|
||||
constructor(upstream: FeatureSource, layer: LayerConfig) {
|
||||
|
||||
|
@ -27,7 +27,7 @@ export default class RenderingMultiPlexerFeatureSource {
|
|||
this.features = upstream.features.map(
|
||||
features => {
|
||||
if (features === undefined) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,59 +48,64 @@ export default class RenderingMultiPlexerFeatureSource {
|
|||
|
||||
for (const f of features) {
|
||||
const feat = f.feature;
|
||||
if(feat === undefined){
|
||||
continue
|
||||
}
|
||||
if(feat.geometry === undefined){
|
||||
console.error("No geometry in ", feat,"provided by", upstream.features.tag, upstream.name)
|
||||
}
|
||||
if (feat.geometry.type === "Point") {
|
||||
|
||||
for (const rendering of pointRenderings) {
|
||||
withIndex.push({
|
||||
...feat,
|
||||
pointRenderingIndex: rendering.index
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// This is a a line: add the centroids
|
||||
let centerpoint: [number, number] = undefined;
|
||||
let projectedCenterPoint : [number, number] = undefined
|
||||
if(hasCentroid){
|
||||
centerpoint = GeoOperations.centerpointCoordinates(feat)
|
||||
if(projectedCentroidRenderings.length > 0){
|
||||
projectedCenterPoint = <[number,number]> GeoOperations.nearestPoint(feat, centerpoint).geometry.coordinates
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// This is a a line: add the centroids
|
||||
let centerpoint: [number, number] = undefined;
|
||||
let projectedCenterPoint: [number, number] = undefined
|
||||
if (hasCentroid) {
|
||||
centerpoint = GeoOperations.centerpointCoordinates(feat)
|
||||
if (projectedCentroidRenderings.length > 0) {
|
||||
projectedCenterPoint = <[number, number]>GeoOperations.nearestPoint(feat, centerpoint).geometry.coordinates
|
||||
}
|
||||
for (const rendering of centroidRenderings) {
|
||||
}
|
||||
for (const rendering of centroidRenderings) {
|
||||
addAsPoint(feat, rendering, centerpoint)
|
||||
}
|
||||
|
||||
|
||||
if (feat.geometry.type === "LineString") {
|
||||
|
||||
for (const rendering of projectedCentroidRenderings) {
|
||||
addAsPoint(feat, rendering, projectedCenterPoint)
|
||||
}
|
||||
|
||||
// Add start- and endpoints
|
||||
const coordinates = feat.geometry.coordinates
|
||||
for (const rendering of startRenderings) {
|
||||
addAsPoint(feat, rendering, coordinates[0])
|
||||
}
|
||||
for (const rendering of endRenderings) {
|
||||
const coordinate = coordinates[coordinates.length - 1]
|
||||
addAsPoint(feat, rendering, coordinate)
|
||||
}
|
||||
|
||||
} else {
|
||||
for (const rendering of projectedCentroidRenderings) {
|
||||
addAsPoint(feat, rendering, centerpoint)
|
||||
}
|
||||
|
||||
|
||||
if (feat.geometry.type === "LineString") {
|
||||
|
||||
for (const rendering of projectedCentroidRenderings) {
|
||||
addAsPoint(feat, rendering, projectedCenterPoint)
|
||||
}
|
||||
|
||||
// Add start- and endpoints
|
||||
const coordinates = feat.geometry.coordinates
|
||||
for (const rendering of startRenderings) {
|
||||
addAsPoint(feat, rendering, coordinates[0])
|
||||
}
|
||||
for (const rendering of endRenderings) {
|
||||
const coordinate = coordinates[coordinates.length - 1]
|
||||
addAsPoint(feat, rendering, coordinate)
|
||||
}
|
||||
|
||||
}else{
|
||||
for (const rendering of projectedCentroidRenderings) {
|
||||
addAsPoint(feat, rendering, centerpoint)
|
||||
}
|
||||
}
|
||||
|
||||
// AT last, add it 'as is' to what we should render
|
||||
for (let i = 0; i < lineRenderObjects.length; i++) {
|
||||
withIndex.push({
|
||||
...feat,
|
||||
lineRenderingIndex: i
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AT last, add it 'as is' to what we should render
|
||||
for (let i = 0; i < lineRenderObjects.length; i++) {
|
||||
withIndex.push({
|
||||
...feat,
|
||||
lineRenderingIndex: i
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class SimpleFeatureSource implements FeatureSourceForLayer, Tiled
|
|||
public readonly bbox: BBox = BBox.global;
|
||||
public readonly tileIndex: number;
|
||||
|
||||
constructor(layer: FilteredLayer, tileIndex: number, featureSource?: UIEventSource<{ feature: any; freshness: Date }[]>) {
|
||||
constructor(layer: FilteredLayer, tileIndex: number, featureSource?: UIEventSource<{ feature: any; freshness: Date }[]> ) {
|
||||
this.name = "SimpleFeatureSource(" + layer.layerDef.id + ")"
|
||||
this.layer = layer
|
||||
this.tileIndex = tileIndex ?? 0;
|
||||
|
|
|
@ -1,31 +1,55 @@
|
|||
import FeatureSource from "../FeatureSource";
|
||||
import {UIEventSource} from "../../UIEventSource";
|
||||
import FeatureSource, {FeatureSourceForLayer, Tiled} from "../FeatureSource";
|
||||
import {ImmutableStore, Store, UIEventSource} from "../../UIEventSource";
|
||||
import {stat} from "fs";
|
||||
import FilteredLayer from "../../../Models/FilteredLayer";
|
||||
import {BBox} from "../../BBox";
|
||||
|
||||
/**
|
||||
* A simple dummy implementation for whenever it is needed
|
||||
* A simple, read only feature store.
|
||||
*/
|
||||
export default class StaticFeatureSource implements FeatureSource {
|
||||
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
|
||||
public readonly name: string = "StaticFeatureSource"
|
||||
public readonly features: Store<{ feature: any; freshness: Date }[]>;
|
||||
public readonly name: string
|
||||
|
||||
constructor(features: any[] | UIEventSource<any[] | UIEventSource<{ feature: any, freshness: Date }>>, useFeaturesDirectly) {
|
||||
const now = new Date();
|
||||
if(features === undefined){
|
||||
constructor(features: Store<{ feature: any, freshness: Date }[]>, name = "StaticFeatureSource") {
|
||||
if (features === undefined) {
|
||||
throw "Static feature source received undefined as source"
|
||||
}
|
||||
if (useFeaturesDirectly) {
|
||||
// @ts-ignore
|
||||
this.features = features
|
||||
} else if (features instanceof UIEventSource) {
|
||||
// @ts-ignore
|
||||
this.features = features.map(features => features?.map(f => ({feature: f, freshness: now}) ?? []))
|
||||
} else {
|
||||
this.features = new UIEventSource(features?.map(f => ({
|
||||
feature: f,
|
||||
freshness: now
|
||||
}))??[])
|
||||
}
|
||||
this.name = name;
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
public static fromGeojsonAndDate(features: { feature: any, freshness: Date }[], name = "StaticFeatureSourceFromGeojsonAndDate"): StaticFeatureSource {
|
||||
return new StaticFeatureSource(new ImmutableStore(features), name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public static fromGeojson(geojson: any[], name = "StaticFeatureSourceFromGeojson"): StaticFeatureSource {
|
||||
const now = new Date();
|
||||
return StaticFeatureSource.fromGeojsonAndDate(geojson.map(feature => ({feature, freshness: now})), name);
|
||||
}
|
||||
|
||||
static fromDateless(featureSource: Store<{ feature: any }[]>, name = "StaticFeatureSourceFromDateless") {
|
||||
const now = new Date();
|
||||
return new StaticFeatureSource(featureSource.map(features => features.map(feature => ({
|
||||
feature: feature.feature,
|
||||
freshness: now
|
||||
}))), name);
|
||||
}
|
||||
}
|
||||
|
||||
export class TiledStaticFeatureSource extends StaticFeatureSource implements Tiled, FeatureSourceForLayer{
|
||||
|
||||
public readonly bbox: BBox = BBox.global;
|
||||
public readonly tileIndex: number;
|
||||
public readonly layer: FilteredLayer;
|
||||
|
||||
constructor(features: Store<{ feature: any, freshness: Date }[]>, layer: FilteredLayer ,tileIndex : number = 0) {
|
||||
super(features);
|
||||
this.tileIndex = tileIndex ;
|
||||
this.layer= layer;
|
||||
this.bbox = BBox.fromTileIndex(this.tileIndex)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue