forked from MapComplete/MapComplete
		
	Add 'CreateNewWayWithNodeReuse'-action, use it in the GRB-theme
This commit is contained in:
		
							parent
							
								
									4e3f408d53
								
							
						
					
					
						commit
						63acca1638
					
				
					 10 changed files with 473 additions and 133 deletions
				
			
		| 
						 | 
				
			
			@ -3,21 +3,6 @@ import FeatureSource, {FeatureSourceForLayer, Tiled} from "../FeatureSource";
 | 
			
		|||
import {OsmNode, OsmObject, OsmWay} from "../../Osm/OsmObject";
 | 
			
		||||
import SimpleFeatureSource from "../Sources/SimpleFeatureSource";
 | 
			
		||||
import FilteredLayer from "../../../Models/FilteredLayer";
 | 
			
		||||
import {TagsFilter} from "../../Tags/TagsFilter";
 | 
			
		||||
import OsmChangeAction from "../../Osm/Actions/OsmChangeAction";
 | 
			
		||||
import StaticFeatureSource from "../Sources/StaticFeatureSource";
 | 
			
		||||
import {OsmConnection} from "../../Osm/OsmConnection";
 | 
			
		||||
import {GeoOperations} from "../../GeoOperations";
 | 
			
		||||
import {Utils} from "../../../Utils";
 | 
			
		||||
import {UIEventSource} from "../../UIEventSource";
 | 
			
		||||
import {BBox} from "../../BBox";
 | 
			
		||||
import FeaturePipeline from "../FeaturePipeline";
 | 
			
		||||
import {Tag} from "../../Tags/Tag";
 | 
			
		||||
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig";
 | 
			
		||||
import {ChangeDescription} from "../../Osm/Actions/ChangeDescription";
 | 
			
		||||
import CreateNewNodeAction from "../../Osm/Actions/CreateNewNodeAction";
 | 
			
		||||
import ChangeTagAction from "../../Osm/Actions/ChangeTagAction";
 | 
			
		||||
import {And} from "../../Tags/And";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default class FullNodeDatabaseSource implements TileHierarchy<FeatureSource & Tiled> {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,70 +19,7 @@ export default class FullNodeDatabaseSource implements TileHierarchy<FeatureSour
 | 
			
		|||
            throw "Layer is undefined"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Given a list of coordinates, will search already existing OSM-points to snap onto.
 | 
			
		||||
     * Either the geometry will be moved OR the existing point will be moved, depending on configuration and tags.
 | 
			
		||||
     * This requires the 'type_node'-layer to be activated
 | 
			
		||||
     */
 | 
			
		||||
    public static MergePoints(
 | 
			
		||||
        state: {
 | 
			
		||||
            filteredLayers: UIEventSource<FilteredLayer[]>,
 | 
			
		||||
            featurePipeline: FeaturePipeline,
 | 
			
		||||
            layoutToUse: LayoutConfig
 | 
			
		||||
        },
 | 
			
		||||
        newGeometryLngLats: [number, number][],
 | 
			
		||||
        configs: ConflationConfig[],
 | 
			
		||||
    ) {
 | 
			
		||||
        const typeNode = state.filteredLayers.data.filter(l => l.layerDef.id === "type_node")[0]
 | 
			
		||||
        if (typeNode === undefined) {
 | 
			
		||||
            throw "Type Node layer is not defined. Add 'type_node' as layer to your layerconfig to use this feature"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const bbox = new BBox(newGeometryLngLats)
 | 
			
		||||
        const bbox_padded = bbox.pad(1.2)
 | 
			
		||||
        const allNodes: any[] = [].concat(...state.featurePipeline.GetFeaturesWithin("type_node", bbox).map(tile => tile.filter(
 | 
			
		||||
            feature => bbox_padded.contains(GeoOperations.centerpointCoordinates(feature))
 | 
			
		||||
        )))
 | 
			
		||||
        // The strategy: for every point of the new geometry, we search a point that is closeby and matches
 | 
			
		||||
        // If multiple options match, we choose the most optimal (aka closest)
 | 
			
		||||
 | 
			
		||||
        const maxDistance = Math.max(...configs.map(c => c.withinRangeOfM))
 | 
			
		||||
        for (const coordinate of newGeometryLngLats) {
 | 
			
		||||
 | 
			
		||||
            let closestNode = undefined;
 | 
			
		||||
            let closestNodeDistance = undefined
 | 
			
		||||
            for (const node of allNodes) {
 | 
			
		||||
                const d = GeoOperations.distanceBetween(GeoOperations.centerpointCoordinates(node), coordinate)
 | 
			
		||||
                if (d > maxDistance) {
 | 
			
		||||
                    continue
 | 
			
		||||
                }
 | 
			
		||||
                let matchesSomeConfig = false
 | 
			
		||||
                for (const config of configs) {
 | 
			
		||||
                    if (d > config.withinRangeOfM) {
 | 
			
		||||
                        continue
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!config.ifMatches.matchesProperties(node.properties)) {
 | 
			
		||||
                        continue
 | 
			
		||||
                    }
 | 
			
		||||
                    matchesSomeConfig = true;
 | 
			
		||||
                }
 | 
			
		||||
                if (!matchesSomeConfig) {
 | 
			
		||||
                    continue
 | 
			
		||||
                }
 | 
			
		||||
                if (closestNode === undefined || closestNodeDistance > d) {
 | 
			
		||||
                    closestNode = node;
 | 
			
		||||
                    closestNodeDistance = d;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
    
 | 
			
		||||
    public handleOsmJson(osmJson: any, tileId: number) {
 | 
			
		||||
 | 
			
		||||
        const allObjects = OsmObject.ParseObjects(osmJson.elements)
 | 
			
		||||
| 
						 | 
				
			
			@ -143,8 +65,3 @@ export default class FullNodeDatabaseSource implements TileHierarchy<FeatureSour
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ConflationConfig {
 | 
			
		||||
    withinRangeOfM: number,
 | 
			
		||||
    ifMatches: TagsFilter,
 | 
			
		||||
    mode: "reuse_osm_point" | "move_osm_point"
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue