package maps.gml.editor; import javax.swing.JOptionPane; import java.util.Queue; import java.util.LinkedList; import java.util.Collection; import java.util.HashSet; import maps.gml.GMLNode; import maps.gml.GMLEdge; import maps.gml.GMLTools; import rescuecore2.log.Logger; import rescuecore2.misc.geometry.Point2D; import rescuecore2.misc.geometry.Line2D; import rescuecore2.misc.geometry.GeometryTools2D; /** A function for splitting edges that cover nearby nodes. */ public class SplitEdgesFunction extends ProgressFunction { private static final double DEFAULT_THRESHOLD = 0.001; private double threshold; /** Construct a SplitEdgesFunction. @param editor The editor instance. */ public SplitEdgesFunction(GMLEditor editor) { super(editor); } @Override public String getName() { return "Split edges"; } @Override public void execute() { String s = JOptionPane.showInputDialog(editor.getViewer(), "Enter the desired distance threshold (in m)", DEFAULT_THRESHOLD); if (s == null) { return; } threshold = Double.parseDouble(s); super.execute(); } @Override protected String getTitle() { return "Splitting edges"; } @Override protected void executeImpl() { // Go through all edges and split any that cover nearby nodes final Queue<GMLEdge> remaining = new LinkedList<GMLEdge>(); final Collection<GMLNode> nodes = new HashSet<GMLNode>(); synchronized (editor.getMap()) { remaining.addAll(editor.getMap().getEdges()); nodes.addAll(editor.getMap().getNodes()); } setProgressLimit(remaining.size()); int count = 0; while (!remaining.isEmpty()) { GMLEdge next = remaining.remove(); Line2D line = GMLTools.toLine(next); // Look for nodes that are close to the line for (GMLNode node : nodes) { if (node == next.getStart() || node == next.getEnd()) { continue; } Point2D p = GMLTools.toPoint(node); Point2D closest = GeometryTools2D.getClosestPointOnSegment(line, p); if (GeometryTools2D.getDistance(p, closest) < threshold) { // Split the edge Collection<GMLEdge> newEdges; synchronized (editor.getMap()) { newEdges = editor.getMap().splitEdge(next, node); editor.getMap().removeEdge(next); newEdges.removeAll(editor.getMap().getEdges()); } remaining.addAll(newEdges); bumpMaxProgress(newEdges.size()); ++count; break; } } bumpProgress(); } if (count != 0) { editor.setChanged(); editor.getViewer().repaint(); } Logger.debug("Split " + count + " edges"); } }