[josm-dev] [PATCH 18/26] clean up SplitWayAction

Dave Hansen dave at sr71.net
Tue Apr 29 03:03:01 BST 2008


This patch removes almost twice as much code as it adds.  It greatly
simplifies SplitWayAction and makes it much more readable in the
process.



---

 core-dave/src/org/openstreetmap/josm/actions/SplitWayAction.java |  110 +++-------
 1 file changed, 36 insertions(+), 74 deletions(-)

diff -puN src/org/openstreetmap/josm/actions/SplitWayAction.java~SplitWayAction src/org/openstreetmap/josm/actions/SplitWayAction.java
--- core/src/org/openstreetmap/josm/actions/SplitWayAction.java~SplitWayAction	2008-04-28 18:59:30.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/actions/SplitWayAction.java	2008-04-28 18:59:30.000000000 -0700
@@ -13,16 +13,14 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
 
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.command.*;
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -174,85 +172,49 @@ public class SplitWayAction extends Josm
 	 * @param nodes the node(s) to split the way at; must be part of the way.
 	 */
 	private void splitWay() {
-		// We take our way's list of nodes and copy them to a way chunk (a
-		// list of nodes).  Whenever we stumble upon a selected node, we start
-		// a new way chunk.
-
-		Set<Node> nodeSet = new HashSet<Node>(selectedNodes);
-		List<List<Node>> wayChunks = new LinkedList<List<Node>>();
-		List<Node> currentWayChunk = new ArrayList<Node>();
-		wayChunks.add(currentWayChunk);
-
-		Iterator<Node> it = selectedWay.nodes.iterator();
-		while (it.hasNext()) {
-			Node currentNode = it.next();
-			boolean atEndOfWay = currentWayChunk.isEmpty() || !it.hasNext();
-			currentWayChunk.add(currentNode);
-			if (nodeSet.contains(currentNode) && !atEndOfWay) {
-				currentWayChunk = new ArrayList<Node>();
-				currentWayChunk.add(currentNode);
-				wayChunks.add(currentWayChunk);
-			}
-		}
-
-		// Handle circular ways specially.
-		// If you split at a circular way at two nodes, you just want to split
-		// it at these points, not also at the former endpoint.
-		// So if the last node is the same first node, join the last and the
-		// first way chunk.
-		List<Node> lastWayChunk = wayChunks.get(wayChunks.size() - 1);
-		if (wayChunks.size() >= 2
-				&& wayChunks.get(0).get(0) == lastWayChunk.get(lastWayChunk.size() - 1)
-				&& !nodeSet.contains(wayChunks.get(0).get(0))) {
-			if (wayChunks.size() == 2) {
-				JOptionPane.showMessageDialog(Main.parent, tr("You must select two or more nodes to split a circular way."));
-				return;
+		List<Command> commandList = new LinkedList<Command>();
+		LinkedList<Way> newWays = new LinkedList<Way>();
+		
+		Way currentWay = null;
+		int removedNodes = 0;
+		for (int i = 0 ; i < selectedWay.nodes.size(); i++) {
+			Node n = selectedWay.nodes.get(i);
+			if (currentWay != null) {
+				commandList.add(new RemoveNodeInWayCommand(selectedWay, n, i-removedNodes));
+				commandList.add(new AddNodeToWayCommand(currentWay, n));
+				removedNodes++;
+			}
+			if (selectedNodes == null || selectedWay == null) {
+				Main.debug("selectedNode: " + selectedNodes);
+				Main.debug("selectedWay: " + selectedWay);
+			}
+			if (selectedNodes.contains(n)) {
+				currentWay = new Way();
+				if (selectedWay.keys != null) {
+					currentWay.keys = new HashMap<String, String>(selectedWay.keys);
+					currentWay.checkTagged();
+				}
+				commandList.add(new AddCommand(currentWay));
+				newWays.add(currentWay);
+				commandList.add(new AddNodeToWayCommand(currentWay, n));
 			}
-			lastWayChunk.remove(lastWayChunk.size() - 1);
-			lastWayChunk.addAll(wayChunks.get(0));
-			wayChunks.remove(wayChunks.size() - 1);
-			wayChunks.set(0, lastWayChunk);
 		}
 
-		if (wayChunks.size() < 2) {
-			JOptionPane.showMessageDialog(Main.parent, tr("The way cannot be split at the selected nodes. (Hint: Select nodes in the middle of the way.)"));
-			return;
+		// Check for circular way, merge the last of the
+		// new pieces into the original way.
+		if (selectedWay.firstNode() == selectedWay.lastNode()) {
+			Way lastNewWay = newWays.remove(newWays.size() - 1);
+			Command c = new MergeWaysCommand(selectedWay, lastNewWay);
+			commandList.add(c);
 		}
-		Main.debug("wayChunks.size(): " + wayChunks.size());
-		Main.debug("way id: " + selectedWay.id);
-
-		// build a list of commands, and also a new selection list
-		Collection<Command> commandList = new ArrayList<Command>(wayChunks.size());
-		Collection<Way> newSelection = new ArrayList<Way>(wayChunks.size());
-		
-		Iterator<List<Node>> chunkIt = wayChunks.iterator();
-		
-		// First, change the original way
-		Way changedWay = new Way(selectedWay);
-		changedWay.nodes.clear();
-		changedWay.nodes.addAll(chunkIt.next());
-		commandList.add(new ChangeCommand(selectedWay, changedWay));
+		Collection<Way> newSelection = new ArrayList<Way>(newWays);
 		newSelection.add(selectedWay);
-
-		// Second, create new ways
-		while (chunkIt.hasNext()) {
-			Way wayToAdd = new Way();
-			if (selectedWay.keys != null) {
-				wayToAdd.keys = new HashMap<String, String>(selectedWay.keys);
-				wayToAdd.checkTagged();
-                                wayToAdd.checkDirectionTagged();
-			}
-			wayToAdd.nodes.addAll(chunkIt.next());
-			commandList.add(new AddCommand(wayToAdd));
-			Main.debug("wayToAdd: " + wayToAdd);
-			newSelection.add(wayToAdd);
-		}
-
+		
 		NameVisitor v = new NameVisitor();
 		v.visit(selectedWay);
 		Main.main.undoRedo.add(
 			new SequenceCommand(tr("Split way {0} into {1} parts",
-				v.name, wayChunks.size()),
+				v.name, newWays.size()+1),
 			commandList));
 		Main.ds.setSelected(newSelection);
 	}
_




More information about the josm-dev mailing list