- Timestamp:
- 2019-10-06T11:41:29+02:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java
r14397 r15428 12 12 import java.util.Comparator; 13 13 import java.util.HashMap; 14 import java.util.HashSet; 14 15 import java.util.LinkedList; 15 16 import java.util.List; 16 17 import java.util.Map; 17 18 import java.util.Set; 18 import java.util.SortedSet; 19 import java .util.TreeSet;19 20 import javax.swing.JOptionPane; 20 21 21 22 import org.openstreetmap.josm.command.ChangeCommand; … … 33 34 import org.openstreetmap.josm.gui.MainApplication; 34 35 import org.openstreetmap.josm.gui.MapView; 36 import org.openstreetmap.josm.gui.Notification; 35 37 import org.openstreetmap.josm.tools.Geometry; 36 38 import org.openstreetmap.josm.tools.MultiMap; … … 98 100 for (Node node : selectedNodes) { 99 101 List<WaySegment> wss = mapView.getNearestWaySegments(mapView.getPoint(node), OsmPrimitive::isSelectable); 100 MultiMap<Way, Integer> insertPoints = newMultiMap<>();102 Set<Way> seenWays = new HashSet<>(); 101 103 for (WaySegment ws : wss) { 102 104 // Maybe cleaner to pass a "isSelected" predicate to getNearestWaySegments, but this is less invasive. … … 104 106 continue; 105 107 } 106 107 if (!ws.getFirstNode().equals(node) && !ws.getSecondNode().equals(node)) { 108 insertPoints.put(ws.way, ws.lowerIndex); 108 // only use the closest WaySegment of each way and ignore those that already contain the node 109 if (!ws.getFirstNode().equals(node) && !ws.getSecondNode().equals(node) 110 && !seenWays.contains(ws.way)) { 111 MultiMap<Integer, Node> innerMap = data.get(ws.way); 112 if (innerMap == null) { 113 innerMap = new MultiMap<>(); 114 data.put(ws.way, innerMap); 115 } 116 innerMap.put(ws.lowerIndex, node); 117 seenWays.add(ws.way); 109 118 } 110 119 } 111 for (Map.Entry<Way, Set<Integer>> entry : insertPoints.entrySet()) {112 final Way w = entry.getKey();113 final Set<Integer> insertPointsForWay = entry.getValue();114 for (int i : pruneSuccs(insertPointsForWay)) {115 MultiMap<Integer, Node> innerMap;116 if (!data.containsKey(w)) {117 innerMap = new MultiMap<>();118 } else {119 innerMap = data.get(w);120 }121 innerMap.put(i, node);122 data.put(w, innerMap);123 }124 }125 120 } 126 121 127 122 // Execute phase: traverse the structure "data" and finally put the nodes into place 123 Map<Node, EastNorth> movedNodes = new HashMap<>(); 128 124 for (Map.Entry<Way, MultiMap<Integer, Node>> entry : data.entrySet()) { 129 125 final Way w = entry.getKey(); … … 143 139 w.getNode(segmentIndex+1).getEastNorth(), 144 140 node.getEastNorth()); 145 MoveCommand c = new MoveCommand( 146 node, ProjectionRegistry.getProjection().eastNorth2latlon(newPosition)); 147 // Avoid moving a given node several times at the same position in case of overlapping ways 148 if (!cmds.contains(c)) { 149 cmds.add(c); 141 EastNorth prevMove = movedNodes.get(node); 142 if (prevMove != null) { 143 if (!prevMove.equalsEpsilon(newPosition, 1e-4)) { 144 new Notification(tr("Multiple target ways, no common point found. Nothing was changed.")) 145 .setIcon(JOptionPane.INFORMATION_MESSAGE) 146 .show(); 147 return; 148 } 149 continue; 150 150 } 151 MoveCommand c = new MoveCommand(node, 152 ProjectionRegistry.getProjection().eastNorth2latlon(newPosition)); 153 cmds.add(c); 154 movedNodes.put(node, newPosition); 151 155 } 152 156 } … … 166 170 } 167 171 168 private static SortedSet<Integer> pruneSuccs(Collection<Integer> is) {169 SortedSet<Integer> is2 = new TreeSet<>();170 for (int i : is) {171 if (!is2.contains(i - 1) && !is2.contains(i + 1)) {172 is2.add(i);173 }174 }175 return is2;176 }177 178 172 /** 179 173 * Sorts collinear nodes by their distance to a common reference node.
Note:
See TracChangeset
for help on using the changeset viewer.