mapcomplete/Logic/FeatureSource/Sources/RenderingMultiPlexerFeatureSource.ts

94 lines
No EOL
4 KiB
TypeScript

/**
* This feature source helps the ShowDataLayer class: it introduces the necessary extra features and indiciates with what renderConfig it should be rendered.
*/
import {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 })[]>;
constructor(upstream: FeatureSource, layer: LayerConfig) {
this.features = upstream.features.map(
features => {
if (features === undefined) {
return;
}
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 startRenderings = pointRenderObjects.filter(r => r.rendering.location.has("start"))
const endRenderings = pointRenderObjects.filter(r => r.rendering.location.has("end"))
const lineRenderObjects = layer.lineRendering
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.geometry.type === "Point") {
for (const rendering of pointRenderings) {
withIndex.push({
...feat,
pointRenderingIndex: rendering.index
})
}
} else {
// This is a a line: add the centroids
for (const rendering of centroidRenderings) {
addAsPoint(feat, rendering, GeoOperations.centerpointCoordinates(feat))
}
if (feat.geometry.type === "LineString") {
// 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)
}
}
// 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;
}
);
}
}