[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