FIX way splitting: P shaped ways are now handled correctly. Had to modify SplitWayAct...
authorSteve Bennett <stevagewp@gmail.com>
Mon, 31 Jan 2011 22:32:55 +0000 (22:32 +0000)
committerSteve Bennett <stevagewp@gmail.com>
Mon, 31 Jan 2011 22:32:55 +0000 (22:32 +0000)
net/systemeD/halcyon/connection/Way.as
net/systemeD/halcyon/connection/actions/SplitWayAction.as
net/systemeD/potlatch2/controller/SelectedWayNode.as

index 6561368..f0b7ce9 100644 (file)
@@ -56,6 +56,10 @@ package net.systemeD.halcyon.connection {
             return nodes[index];
         }
 
+        public function getFirstNode():Node {
+            return nodes[0];
+        }
+
                public function getLastNode():Node {
                        return nodes[nodes.length-1];
                }
@@ -265,6 +269,24 @@ package net.systemeD.halcyon.connection {
                        if (str=='area' &&  isArea()) return true;
                        return false;
                }
+               
+               /** Whether the way has a loop that joins back midway along its length */
+               public function isPShape():Boolean {
+                       return getFirstNode() != getLastNode() && (!hasOnceOnly(getFirstNode()) || !hasOnceOnly(getLastNode()) );
+               }
+               
+               /** Given a P-shaped way, return the index of midway node that one end connects back to. */
+               public function getPJunctionNodeIndex():uint {
+                       if (isPShape()) {
+                           if (hasOnceOnly(getFirstNode())) {
+                               // nodes[0] is the free end
+                               return nodes.indexOf(getLastNode());
+                           } else {
+                               // nodes[0] is in the loop
+                               return nodes.lastIndexOf(getFirstNode());
+                           }
+                       }
+                       return null;
+               }
     }
-
 }
index b6b815f..b79efbd 100644 (file)
@@ -1,25 +1,24 @@
 package net.systemeD.halcyon.connection.actions {
 
     import net.systemeD.halcyon.connection.*;
-       import net.systemeD.halcyon.Globals;
     
     public class SplitWayAction extends CompositeUndoableAction {
     
         private var selectedWay:Way;
-        private var selectedNode:Node;
+        private var nodeIndex:uint; // Index rather than node required as nodes can occur multiple times
         private var newWay:Way;
     
-        public function SplitWayAction(selectedWay:Way, selectedNode:Node) {
+        public function SplitWayAction(selectedWay:Way, nodeIndex:uint) {
             super("Split way "+selectedWay.id);
             this.selectedWay = selectedWay;
-            this.selectedNode = selectedNode;
+            this.nodeIndex = nodeIndex;
         }
     
         public override function doAction():uint {
             if (newWay==null) {
                                newWay = Connection.getConnection().createWay(
                                        selectedWay.getTagsCopy(), 
-                                       selectedWay.sliceNodes(selectedWay.indexOfNode(selectedNode),selectedWay.length),
+                                       selectedWay.sliceNodes(nodeIndex,selectedWay.length),
                                        push);
 
                                // we reverse the list, which is already sorted by position. This way positions aren't affected
@@ -74,7 +73,7 @@ package net.systemeD.halcyon.connection.actions {
                 }
                 
                 // now that we're done with the selectedWay, remove the nodes
-                selectedWay.deleteNodesFrom(selectedWay.indexOfNode(selectedNode)+1, push);
+                selectedWay.deleteNodesFrom(nodeIndex+1, push);
 
                                // and remove from any turn restrictions that aren't relevant
                                for each (var r:Relation in selectedWay.findParentRelationsOfType('restriction')) {
index 363baf9..4dca787 100644 (file)
@@ -125,14 +125,23 @@ package net.systemeD.potlatch2.controller {
                            return new DrawWay(selectedWay, isLast, true);
         }
 
+               /** Splits a way into two separate ways, at the currently selected node. Handles simple loops and P-shapes. Untested for anything funkier. */
                public function splitWay():ControllerState {
+                       var n:Node=firstSelected as Node;
+                       var ni:uint = parentWay.indexOfNode(n);
                        // abort if start or end
-                       if (parentWay.getNode(0)    == firstSelected) { return this; }
-                       if (parentWay.getLastNode() == firstSelected) { return this; }
+                       if (parentWay.isPShape() && !parentWay.hasOnceOnly(n)) {
+                               // If P-shaped, we want to split at the midway point on the stem, not at the end of the loop
+                               ni = parentWay.getPJunctionNodeIndex();
+                               
+                       } else {
+                           if (parentWay.getNode(0)    == n) { return this; }
+                           if (parentWay.getLastNode() == n) { return this; }
+                       }
 
                        controller.map.setHighlightOnNodes(parentWay, { selectedway: false } );
                        controller.map.setPurgable([parentWay],true);
-            MainUndoStack.getGlobalStack().addAction(new SplitWayAction(parentWay, firstSelected as Node));
+            MainUndoStack.getGlobalStack().addAction(new SplitWayAction(parentWay, ni));
 
                        return new SelectedWay(parentWay);
                }