forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			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;
 | 
						|
            }
 | 
						|
        );
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
} |