- Timestamp:
- 2014-05-15T00:56:35+02:00 (11 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java
r7005 r7131 1 1 //License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.actions; 3 4 import org.openstreetmap.josm.Main; 5 import org.openstreetmap.josm.command.ChangeCommand; 6 import org.openstreetmap.josm.command.Command; 7 import org.openstreetmap.josm.command.MoveCommand; 8 import org.openstreetmap.josm.command.SequenceCommand; 9 import org.openstreetmap.josm.data.coor.EastNorth; 10 import org.openstreetmap.josm.data.osm.Node; 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 12 import org.openstreetmap.josm.data.osm.Way; 13 import org.openstreetmap.josm.data.osm.WaySegment; 14 import org.openstreetmap.josm.data.projection.Projections; 15 import org.openstreetmap.josm.tools.Geometry; 16 import org.openstreetmap.josm.tools.MultiMap; 17 import org.openstreetmap.josm.tools.Shortcut; 18 19 import java.awt.event.ActionEvent; 20 import java.awt.event.KeyEvent; 21 import java.util.Collection; 22 import java.util.Collections; 23 import java.util.LinkedList; 24 import java.util.List; 25 import java.util.Map; 26 import java.util.Set; 27 import java.util.SortedSet; 28 import java.util.TreeSet; 3 29 4 30 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 5 31 import static org.openstreetmap.josm.tools.I18n.tr; 6 32 7 import java.awt.event.ActionEvent;8 import java.awt.event.KeyEvent;9 import java.util.ArrayList;10 import java.util.Collection;11 import java.util.Collections;12 import java.util.HashMap;13 import java.util.HashSet;14 import java.util.LinkedList;15 import java.util.List;16 import java.util.Map;17 18 import org.openstreetmap.josm.Main;19 import org.openstreetmap.josm.command.ChangeCommand;20 import org.openstreetmap.josm.command.Command;21 import org.openstreetmap.josm.command.SequenceCommand;22 import org.openstreetmap.josm.data.osm.Node;23 import org.openstreetmap.josm.data.osm.OsmPrimitive;24 import org.openstreetmap.josm.data.osm.Way;25 import org.openstreetmap.josm.data.osm.WaySegment;26 import org.openstreetmap.josm.tools.Shortcut;27 28 33 public class JoinNodeWayAction extends JosmAction { 29 34 35 protected final boolean joinWayToNode; 36 37 protected JoinNodeWayAction(boolean joinWayToNode, String name, String iconName, String tooltip, Shortcut shortcut, boolean registerInToolbar) { 38 super(name, iconName, tooltip, shortcut, registerInToolbar); 39 this.joinWayToNode = joinWayToNode; 40 } 41 30 42 /** 31 * Constructs a new {@code JoinNodeWayAction}.43 * Constructs a Join Node to Way action. 32 44 */ 33 public JoinNodeWayAction() { 34 super(tr("Join Node to Way"), "joinnodeway", tr("Include a node into the nearest way segments"), 45 public static JoinNodeWayAction createJoinNodeToWayAction() { 46 JoinNodeWayAction action = new JoinNodeWayAction(false, 47 tr("Join Node to Way"), "joinnodeway", tr("Include a node into the nearest way segments"), 35 48 Shortcut.registerShortcut("tools:joinnodeway", tr("Tool: {0}", tr("Join Node to Way")), KeyEvent.VK_J, Shortcut.DIRECT), true); 36 putValue("help", ht("/Action/JoinNodeWay")); 49 action.putValue("help", ht("/Action/JoinNodeWay")); 50 return action; 51 } 52 53 /** 54 * Constructs a Move Node onto Way action. 55 */ 56 public static JoinNodeWayAction createMoveNodeOntoWayAction() { 57 JoinNodeWayAction action = new JoinNodeWayAction(true, 58 tr("Move Node onto Way"), "movewayontonode", tr("Move the node onto the nearest way segments and include it"), 59 null, true); 60 return action; 37 61 } 38 62 … … 45 69 if (selectedNodes.size() != 1) return; 46 70 47 Node node = selectedNodes.iterator().next();71 final Node node = selectedNodes.iterator().next(); 48 72 49 73 Collection<Command> cmds = new LinkedList<>(); … … 53 77 !getCurrentDataSet().getSelectedWays().isEmpty(); 54 78 55 List<WaySegment> wss = Main.map.mapView.getNearestWaySegments( 56 Main.map.mapView.getPoint(node), OsmPrimitive.isSelectablePredicate); 57 HashMap<Way, List<Integer>> insertPoints = new HashMap<>(); 58 for (WaySegment ws : wss) { 59 // Maybe cleaner to pass a "isSelected" predicate to getNearestWaySegments, but this is less invasive. 60 if(restrictToSelectedWays && !ws.way.isSelected()) { 61 continue; 62 } 63 64 List<Integer> is; 65 if (insertPoints.containsKey(ws.way)) { 66 is = insertPoints.get(ws.way); 67 } else { 68 is = new ArrayList<>(); 69 insertPoints.put(ws.way, is); 70 } 71 72 if (ws.way.getNode(ws.lowerIndex) != node 73 && ws.way.getNode(ws.lowerIndex+1) != node) { 74 is.add(ws.lowerIndex); 75 } 79 List<WaySegment> wss = Main.map.mapView.getNearestWaySegments( 80 Main.map.mapView.getPoint(node), OsmPrimitive.isSelectablePredicate); 81 MultiMap<Way, Integer> insertPoints = new MultiMap<>(); 82 for (WaySegment ws : wss) { 83 // Maybe cleaner to pass a "isSelected" predicate to getNearestWaySegments, but this is less invasive. 84 if (restrictToSelectedWays && !ws.way.isSelected()) { 85 continue; 76 86 } 77 87 78 for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) { 79 List<Integer> is = insertPoint.getValue(); 80 if (is.isEmpty()) { 81 continue; 88 if (ws.getFirstNode() != node && ws.getSecondNode() != node) { 89 insertPoints.put(ws.way, ws.lowerIndex); 90 } 91 } 92 93 for (Map.Entry<Way, Set<Integer>> entry : insertPoints.entrySet()) { 94 final Way w = entry.getKey(); 95 final Set<Integer> insertPointsForWay = entry.getValue(); 96 if (insertPointsForWay.isEmpty()) { 97 continue; 98 } 99 100 List<Node> nodesToAdd = w.getNodes(); 101 for (int i : pruneSuccsAndReverse(insertPointsForWay)) { 102 if (joinWayToNode) { 103 EastNorth newPosition = Geometry.closestPointToSegment( 104 w.getNode(i).getEastNorth(), w.getNode(i + 1).getEastNorth(), node.getEastNorth()); 105 cmds.add(new MoveCommand(node, Projections.inverseProject(newPosition))); 82 106 } 83 84 Way w = insertPoint.getKey(); 85 List<Node> nodesToAdd = w.getNodes(); 86 pruneSuccsAndReverse(is); 87 for (int i : is) { 88 nodesToAdd.add(i+1, node); 89 } 90 Way wnew = new Way(w); 91 wnew.setNodes(nodesToAdd); 92 cmds.add(new ChangeCommand(w, wnew)); 107 nodesToAdd.add(i + 1, node); 93 108 } 94 if (cmds.isEmpty()) return; 95 Main.main.undoRedo.add(new SequenceCommand(tr("Join Node and Line"), cmds)); 96 Main.map.repaint(); 109 Way wnew = new Way(w); 110 wnew.setNodes(nodesToAdd); 111 cmds.add(new ChangeCommand(w, wnew)); 112 } 113 if (cmds.isEmpty()) return; 114 Main.main.undoRedo.add(new SequenceCommand(getValue(NAME).toString(), cmds)); 115 Main.map.repaint(); 97 116 } 98 117 99 private static void pruneSuccsAndReverse(List<Integer> is) {100 HashSet<Integer> is2 = new HashSet<>();118 private static SortedSet<Integer> pruneSuccsAndReverse(Collection<Integer> is) { 119 SortedSet<Integer> is2 = new TreeSet<>(Collections.reverseOrder()); 101 120 for (int i : is) { 102 121 if (!is2.contains(i - 1) && !is2.contains(i + 1)) { … … 104 123 } 105 124 } 106 is.clear(); 107 is.addAll(is2); 108 Collections.sort(is); 109 Collections.reverse(is); 125 return is2; 110 126 } 111 127 -
trunk/src/org/openstreetmap/josm/gui/MainMenu.java
r7075 r7131 248 248 public final MergeNodesAction mergeNodes = new MergeNodesAction(); 249 249 /** Tools / Join Node to Way */ 250 public final JoinNodeWayAction joinNodeWay = new JoinNodeWayAction(); 250 public final JoinNodeWayAction joinNodeWay = JoinNodeWayAction.createJoinNodeToWayAction(); 251 /** Tools / Join Way to Node */ 252 public final JoinNodeWayAction moveNodeOntoWay = JoinNodeWayAction.createMoveNodeOntoWayAction(); 251 253 /** Tools / Disconnect Node from Way */ 252 254 public final UnJoinNodeWayAction unJoinNodeWay = new UnJoinNodeWayAction(); … … 737 739 add(toolsMenu, mergeNodes); 738 740 add(toolsMenu, joinNodeWay); 741 add(toolsMenu, moveNodeOntoWay); 739 742 add(toolsMenu, unJoinNodeWay); 740 743 add(toolsMenu, unglueNodes);
Note:
See TracChangeset
for help on using the changeset viewer.