/** * This feature source helps the ShowDataLayer class: it introduces the necessary extra features and indicates with what renderConfig it should be rendered. */ import {Store} from "../../UIEventSource"; import {GeoOperations} from "../../GeoOperations"; import FeatureSource from "../FeatureSource"; import PointRenderingConfig from "../../../Models/ThemeConfig/PointRenderingConfig"; import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; import LineRenderingConfig from "../../../Models/ThemeConfig/LineRenderingConfig"; export default class RenderingMultiPlexerFeatureSource { public readonly features: Store<(any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[]>; private readonly pointRenderings: { rendering: PointRenderingConfig; index: number }[]; private centroidRenderings: { rendering: PointRenderingConfig; index: number }[]; private projectedCentroidRenderings: { rendering: PointRenderingConfig; index: number }[]; private startRenderings: { rendering: PointRenderingConfig; index: number }[]; private endRenderings: { rendering: PointRenderingConfig; index: number }[]; private hasCentroid: boolean; private lineRenderObjects: LineRenderingConfig[]; private inspectFeature(feat, addAsPoint: (feat, rendering, centerpoint: [number, number]) => void, withIndex: any[]){ if (feat.geometry.type === "Point") { for (const rendering of this.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(this.hasCentroid){ centerpoint = GeoOperations.centerpointCoordinates(feat) if(this.projectedCentroidRenderings.length > 0){ projectedCenterPoint = <[number,number]> GeoOperations.nearestPoint(feat, centerpoint).geometry.coordinates } } for (const rendering of this.centroidRenderings) { addAsPoint(feat, rendering, centerpoint) } if (feat.geometry.type === "LineString") { for (const rendering of this.projectedCentroidRenderings) { addAsPoint(feat, rendering, projectedCenterPoint) } // Add start- and endpoints const coordinates = feat.geometry.coordinates for (const rendering of this.startRenderings) { addAsPoint(feat, rendering, coordinates[0]) } for (const rendering of this.endRenderings) { const coordinate = coordinates[coordinates.length - 1] addAsPoint(feat, rendering, coordinate) } }else{ for (const rendering of this.projectedCentroidRenderings) { addAsPoint(feat, rendering, centerpoint) } } // AT last, add it 'as is' to what we should render for (let i = 0; i < this.lineRenderObjects.length; i++) { withIndex.push({ ...feat, lineRenderingIndex: i }) } } } constructor(upstream: FeatureSource, layer: LayerConfig) { const pointRenderObjects: { rendering: PointRenderingConfig, index: number }[] = layer.mapRendering.map((r, i) => ({ rendering: r, index: i })) this.pointRenderings = pointRenderObjects.filter(r => r.rendering.location.has("point")) this.centroidRenderings = pointRenderObjects.filter(r => r.rendering.location.has("centroid")) this.projectedCentroidRenderings = pointRenderObjects.filter(r => r.rendering.location.has("projected_centerpoint")) this.startRenderings = pointRenderObjects.filter(r => r.rendering.location.has("start")) this.endRenderings = pointRenderObjects.filter(r => r.rendering.location.has("end")) this.hasCentroid = this.centroidRenderings.length > 0 || this.projectedCentroidRenderings.length > 0 this.lineRenderObjects = layer.lineRendering this.features = upstream.features.map( features => { if (features === undefined) { return undefined; } const withIndex: any[] = []; function addAsPoint(feat, rendering, coordinate) { const patched = { ...feat, pointRenderingIndex: rendering.index } patched.geometry = { type: "Point", coordinates: coordinate } withIndex.push(patched) } for (const f of features) { const feat = f.feature; if(feat === undefined){ continue } this.inspectFeature(feat, addAsPoint, withIndex) } return withIndex; } ); } }