119 lines
No EOL
5.2 KiB
TypeScript
119 lines
No EOL
5.2 KiB
TypeScript
/**
|
|
* This feature source helps the ShowDataLayer class: it introduces the necessary extra features and indicates with what renderConfig it should be rendered.
|
|
*/
|
|
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: Store<(any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[]>;
|
|
|
|
constructor(upstream: FeatureSource, layer: LayerConfig) {
|
|
|
|
const pointRenderObjects: { rendering: PointRenderingConfig, index: number }[] = layer.mapRendering.map((r, i) => ({
|
|
rendering: r,
|
|
index: i
|
|
}))
|
|
const pointRenderings = pointRenderObjects.filter(r => r.rendering.location.has("point"))
|
|
const centroidRenderings = pointRenderObjects.filter(r => r.rendering.location.has("centroid"))
|
|
const projectedCentroidRenderings = pointRenderObjects.filter(r => r.rendering.location.has("projected_centerpoint"))
|
|
const startRenderings = pointRenderObjects.filter(r => r.rendering.location.has("start"))
|
|
const endRenderings = pointRenderObjects.filter(r => r.rendering.location.has("end"))
|
|
const hasCentroid = centroidRenderings.length > 0 || projectedCentroidRenderings.length > 0
|
|
const lineRenderObjects = layer.lineRendering
|
|
|
|
this.features = upstream.features.map(
|
|
features => {
|
|
if (features === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
|
|
const withIndex: (any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined, multiLineStringIndex: number | undefined })[] = [];
|
|
|
|
|
|
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
|
|
}
|
|
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
|
|
})
|
|
}
|
|
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) {
|
|
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
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
return withIndex;
|
|
}
|
|
);
|
|
|
|
}
|
|
|
|
} |