forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			91 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import FeatureSource, { FeatureSourceForLayer, Tiled } from "../FeatureSource"
 | 
						|
import { OsmNode, OsmObject, OsmWay } from "../../Osm/OsmObject"
 | 
						|
import SimpleFeatureSource from "../Sources/SimpleFeatureSource"
 | 
						|
import FilteredLayer from "../../../Models/FilteredLayer"
 | 
						|
import { UIEventSource } from "../../UIEventSource"
 | 
						|
import { OsmTags } from "../../../Models/OsmFeature";
 | 
						|
import { BBox } from "../../BBox";
 | 
						|
import { Feature, Point } from "geojson";
 | 
						|
 | 
						|
export default class FullNodeDatabaseSource {
 | 
						|
    public readonly loadedTiles = new Map<number, FeatureSource & Tiled>()
 | 
						|
    private readonly onTileLoaded: (tile: Tiled & FeatureSourceForLayer) => void
 | 
						|
    private readonly layer: FilteredLayer
 | 
						|
    private readonly nodeByIds = new Map<number, OsmNode>()
 | 
						|
    private readonly parentWays = new Map<number, UIEventSource<OsmWay[]>>()
 | 
						|
 | 
						|
    constructor(layer: FilteredLayer, onTileLoaded: (tile: Tiled & FeatureSourceForLayer) => void) {
 | 
						|
        this.onTileLoaded = onTileLoaded
 | 
						|
        this.layer = layer
 | 
						|
        if (this.layer === undefined) {
 | 
						|
            throw "Layer is undefined"
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public handleOsmJson(osmJson: any, tileId: number) {
 | 
						|
        const allObjects = OsmObject.ParseObjects(osmJson.elements)
 | 
						|
        const nodesById = new Map<number, OsmNode>()
 | 
						|
 | 
						|
        for (const osmObj of allObjects) {
 | 
						|
            if (osmObj.type !== "node") {
 | 
						|
                continue
 | 
						|
            }
 | 
						|
            const osmNode = <OsmNode>osmObj
 | 
						|
            nodesById.set(osmNode.id, osmNode)
 | 
						|
            this.nodeByIds.set(osmNode.id, osmNode)
 | 
						|
        }
 | 
						|
 | 
						|
        for (const osmObj of allObjects) {
 | 
						|
            if (osmObj.type !== "way") {
 | 
						|
                continue
 | 
						|
            }
 | 
						|
            const osmWay = <OsmWay>osmObj
 | 
						|
            for (const nodeId of osmWay.nodes) {
 | 
						|
                if (!this.parentWays.has(nodeId)) {
 | 
						|
                    const src = new UIEventSource<OsmWay[]>([])
 | 
						|
                    this.parentWays.set(nodeId, src)
 | 
						|
                    src.addCallback((parentWays) => {
 | 
						|
                        const tgs = nodesById.get(nodeId).tags
 | 
						|
                        tgs["parent_ways"] = JSON.stringify(parentWays.map((w) => w.tags))
 | 
						|
                        tgs["parent_way_ids"] = JSON.stringify(parentWays.map((w) => w.id))
 | 
						|
                    })
 | 
						|
                }
 | 
						|
                const src = this.parentWays.get(nodeId)
 | 
						|
                src.data.push(osmWay)
 | 
						|
                src.ping()
 | 
						|
            }
 | 
						|
        }
 | 
						|
        const asGeojsonFeatures = Array.from(nodesById.values()).map((osmNode) =>
 | 
						|
            osmNode.asGeoJson()
 | 
						|
        )
 | 
						|
 | 
						|
        const featureSource = new SimpleFeatureSource(this.layer, tileId)
 | 
						|
        featureSource.features.setData(asGeojsonFeatures)
 | 
						|
        this.loadedTiles.set(tileId, featureSource)
 | 
						|
        this.onTileLoaded(featureSource)
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the OsmNode with the corresponding id (undefined if not found)
 | 
						|
     * Note that this OsmNode will have a calculated tag 'parent_ways' and 'parent_way_ids', which are resp. stringified lists of parent way tags and ids
 | 
						|
     * @param id
 | 
						|
     * @constructor
 | 
						|
     */
 | 
						|
    public GetNode(id: number): OsmNode {
 | 
						|
        return this.nodeByIds.get(id)
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gets the parent way list
 | 
						|
     * @param nodeId
 | 
						|
     * @constructor
 | 
						|
     */
 | 
						|
    public GetParentWays(nodeId: number): UIEventSource<OsmWay[]> {
 | 
						|
        return this.parentWays.get(nodeId)
 | 
						|
    }
 | 
						|
 | 
						|
    getNodesWithin(bBox: BBox) : Feature<Point, OsmTags>[]{
 | 
						|
        // TODO
 | 
						|
        throw "TODO"
 | 
						|
    }
 | 
						|
}
 |