Ticket #5133: 0001-Action-to-disconnect-nodes-from-ways.3.patch
| File 0001-Action-to-disconnect-nodes-from-ways.3.patch, 10.9 KB (added by , 13 years ago) |
|---|
-
new file 2001
From 87b6c43e098c34d7a3f12ce07557f991c5bfaff6 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> Date: Mon, 29 Jul 2013 08:29:30 +0200 Subject: [PATCH] Action to disconnect nodes from ways A RemoveNodes command is also added to simplify undo management. --- images/unjoinnodeway.png | Bin 0 -> 385 bytes .../josm/actions/UnJoinNodeWayAction.java | 138 +++++++++++++++++++++ .../josm/command/RemoveNodesCommand.java | 56 +++++++++ src/org/openstreetmap/josm/gui/MainMenu.java | 3 + 4 files changed, 197 insertions(+) create mode 100644 images/unjoinnodeway.png create mode 100644 src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java create mode 100644 src/org/openstreetmap/josm/command/RemoveNodesCommand.java diff --git a/images/unjoinnodeway.png b/images/unjoinnodeway.png new file mode 100644 index 0000000000000000000000000000000000000000..4179e6902577640d66deab6f78cab43c8b0a4786 GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYYs>cdx@v7EBjq`Ssnvp>D3WU3=E8Xo-U3d9>?Ea-s{H{D8Tx_-@z~{ zQbL-=Y@@jL+J&1w&#Y0FW4M3d$h{-1Nl7Lf4FegKvp1VZhPx;oS@AHWxc=Ns<Kp)p zOv7|H9x+*?<D`-oHu;T})$8@iElW0NEdT1~zxOitX|8JvOqjPf<X$oGu;iWdKtc5M zVwqjRvx1(<nF%};*nPvjr+7<Ym-UxjYj1rq@0fj6Wy+1*t1jt(rArDLPw$A#ea<8E zkjq~qN!|FXb4;?uTG!(h9;|K)&mVNy^}pkJPlmx9mUFvVb{fSO&gW7Q=Ha<y?WuN< zeM(XM>PdD13OpY_bvE99@ag*bi}z>$`QKZlmY48ZeUjL|S_|fFVharAyNW+4_gt>9 cd3i{>Jl~Te!YJi0Ft8XrUHx3vIVCg!02-y3CIA2c -
new file src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java
literal 0 HcmV?d00001 diff --git a/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java b/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java new file mode 100644 index 0000000..c1c3f14
- + 1 //License: GPL. Copyright 2007 by Immanuel Scholz and others 2 package org.openstreetmap.josm.actions; 3 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 5 import static org.openstreetmap.josm.tools.I18n.tr; 6 import static org.openstreetmap.josm.tools.I18n.trn; 7 8 import java.awt.event.ActionEvent; 9 import java.awt.event.KeyEvent; 10 import java.util.ArrayList; 11 import java.util.Collection; 12 import java.util.Collections; 13 import java.util.Iterator; 14 import java.util.List; 15 16 import javax.swing.JOptionPane; 17 18 import org.openstreetmap.josm.Main; 19 import org.openstreetmap.josm.command.RemoveNodesCommand; 20 import org.openstreetmap.josm.command.Command; 21 import org.openstreetmap.josm.data.osm.Node; 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 23 import org.openstreetmap.josm.data.osm.Way; 24 import org.openstreetmap.josm.tools.Shortcut; 25 26 public class UnJoinNodeWayAction extends JosmAction { 27 public UnJoinNodeWayAction() { 28 super(tr("Disconnect Node from Way"), "unjoinnodeway", 29 tr("Disconnect nodes from a way they currently belong to"), 30 Shortcut.registerShortcut("tools:unjoinnodeway", 31 tr("Tool: {0}", tr("Disconnect Node from Way")), KeyEvent.VK_J, Shortcut.ALT), true); 32 putValue("help", ht("/Action/UnJoinNodeWay")); 33 } 34 35 @Override 36 public void actionPerformed(ActionEvent e) { 37 38 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected(); 39 40 List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class); 41 List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class); 42 List<Way> applicableWays = getApplicableWays(selectedWays, selectedNodes); 43 44 if (applicableWays == null) { 45 JOptionPane.showMessageDialog( 46 Main.parent, 47 tr("Select at least one node to be disconnected."), 48 tr("Warning"), 49 JOptionPane.WARNING_MESSAGE); 50 return; 51 } else if (applicableWays.isEmpty()) { 52 JOptionPane.showMessageDialog(Main.parent, 53 trn("Selected node cannot be disconnected from anything.", 54 "Selected nodes cannot be disconnected from anything.", 55 selectedNodes.size()), 56 tr("Warning"), 57 JOptionPane.WARNING_MESSAGE); 58 return; 59 } else if (applicableWays.size() > 1) { 60 JOptionPane.showMessageDialog(Main.parent, 61 trn("There is more than one way using the node you selected. Please select the way also.", 62 "There is more than one way using the nodes you selected. Please select the way also.", 63 selectedNodes.size()), 64 tr("Warning"), 65 JOptionPane.WARNING_MESSAGE); 66 return; 67 } else if (applicableWays.get(0).getRealNodesCount() < selectedNodes.size() + 2) { 68 // there is only one affected way, but removing the selected nodes would only leave it 69 // with less than 2 nodes 70 JOptionPane.showMessageDialog(Main.parent, 71 trn("The affected way would disappear after disconnecting the selected node.", 72 "The affected way would disappear after disconnecting the selected nodes.", 73 selectedNodes.size()), 74 tr("Warning"), 75 JOptionPane.WARNING_MESSAGE); 76 return; 77 } 78 79 80 // Finally, applicableWays contains only one perfect way 81 Way selectedWay = applicableWays.get(0); 82 83 // I'm sure there's a better way to handle this 84 Main.main.undoRedo.add(new RemoveNodesCommand(selectedWay, selectedNodes)); 85 Main.map.repaint(); 86 } 87 88 // Find ways to which the disconnect can be applied. This is the list of ways with more 89 // than two nodes which pass through all the given nodes, intersected with the selected ways (if any) 90 private List<Way> getApplicableWays(List<Way> selectedWays, List<Node> selectedNodes) { 91 if (selectedNodes.isEmpty()) 92 return null; 93 94 // List of ways shared by all nodes 95 List<Way> result = new ArrayList<Way>(OsmPrimitive.getFilteredList(selectedNodes.get(0).getReferrers(), Way.class)); 96 for (int i=1; i<selectedNodes.size(); i++) { 97 List<OsmPrimitive> ref = selectedNodes.get(i).getReferrers(); 98 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { 99 if (!ref.contains(it.next())) { 100 it.remove(); 101 } 102 } 103 } 104 105 // Remove broken ways 106 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { 107 if (it.next().getNodesCount() <= 2) { 108 it.remove(); 109 } 110 } 111 112 if (selectedWays.isEmpty()) 113 return result; 114 else { 115 // Return only selected ways 116 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { 117 if (!selectedWays.contains(it.next())) { 118 it.remove(); 119 } 120 } 121 return result; 122 } 123 } 124 125 @Override 126 protected void updateEnabledState() { 127 if (getCurrentDataSet() == null) { 128 setEnabled(false); 129 } else { 130 updateEnabledState(getCurrentDataSet().getSelected()); 131 } 132 } 133 134 @Override 135 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { 136 setEnabled(selection != null && !selection.isEmpty()); 137 } 138 } -
new file src/org/openstreetmap/josm/command/RemoveNodesCommand.java
diff --git a/src/org/openstreetmap/josm/command/RemoveNodesCommand.java b/src/org/openstreetmap/josm/command/RemoveNodesCommand.java new file mode 100644 index 0000000..5959a08
- + 1 // License: GPL. See LICENSE file for details. 2 package org.openstreetmap.josm.command; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.util.Collection; 7 import java.util.HashSet; 8 import java.util.List; 9 import javax.swing.Icon; 10 11 import org.openstreetmap.josm.data.osm.Node; 12 import org.openstreetmap.josm.data.osm.Way; 13 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 15 import org.openstreetmap.josm.gui.DefaultNameFormatter; 16 import org.openstreetmap.josm.tools.ImageProvider; 17 18 /** 19 * Command that removes a set of nodes from a way. 20 * The same can be done with ChangeNodesCommand, but this is more 21 * efficient. (Needed for the tool to disconnect nodes from ways.) 22 * 23 * @author Giuseppe Bilotta 24 */ 25 public class RemoveNodesCommand extends Command { 26 27 private final Way way; 28 private final HashSet<Node> rmNodes; 29 30 public RemoveNodesCommand(Way way, List<Node> rmNodes) { 31 super(); 32 this.way = way; 33 this.rmNodes = new HashSet<Node>(rmNodes); 34 } 35 36 @Override public boolean executeCommand() { 37 super.executeCommand(); 38 way.removeNodes(rmNodes); 39 way.setModified(true); 40 return true; 41 } 42 43 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 44 modified.add(way); 45 } 46 47 @Override 48 public String getDescriptionText() { 49 return tr("Removed nodes from {0}", way.getDisplayName(DefaultNameFormatter.getInstance())); 50 } 51 52 @Override 53 public Icon getDescriptionIcon() { 54 return ImageProvider.get(OsmPrimitiveType.WAY); 55 } 56 } -
src/org/openstreetmap/josm/gui/MainMenu.java
diff --git a/src/org/openstreetmap/josm/gui/MainMenu.java b/src/org/openstreetmap/josm/gui/MainMenu.java index 7671796..ec867ba 100644
a b import org.openstreetmap.josm.actions.SimplifyWayAction; 84 84 import org.openstreetmap.josm.actions.SplitWayAction; 85 85 import org.openstreetmap.josm.actions.ToggleGPXLinesAction; 86 86 import org.openstreetmap.josm.actions.UnGlueAction; 87 import org.openstreetmap.josm.actions.UnJoinNodeWayAction; 87 88 import org.openstreetmap.josm.actions.UndoAction; 88 89 import org.openstreetmap.josm.actions.UnselectAllAction; 89 90 import org.openstreetmap.josm.actions.UpdateDataAction; … … public class MainMenu extends JMenuBar { 187 188 public final JosmAction createCircle = new CreateCircleAction(); 188 189 public final JosmAction mergeNodes = new MergeNodesAction(); 189 190 public final JosmAction joinNodeWay = new JoinNodeWayAction(); 191 public final JosmAction unJoinNodeWay = new UnJoinNodeWayAction(); 190 192 public final JosmAction unglueNodes = new UnGlueAction(); 191 193 public final JosmAction joinAreas = new JoinAreasAction(); 192 194 public final JosmAction createMultipolygon = new CreateMultipolygonAction(); … … public class MainMenu extends JMenuBar { 607 609 toolsMenu.addSeparator(); 608 610 add(toolsMenu, mergeNodes); 609 611 add(toolsMenu, joinNodeWay); 612 add(toolsMenu, unJoinNodeWay); 610 613 add(toolsMenu, unglueNodes); 611 614 toolsMenu.addSeparator(); 612 615 add(toolsMenu, joinAreas);
