parallelise
authorRichard Fairhurst <richard@systemed.net>
Mon, 17 May 2010 13:12:32 +0000 (13:12 +0000)
committerRichard Fairhurst <richard@systemed.net>
Mon, 17 May 2010 13:12:32 +0000 (13:12 +0000)
net/systemeD/potlatch2/Toolbox.as
net/systemeD/potlatch2/controller/SelectedParallelWay.as [new file with mode: 0644]
net/systemeD/potlatch2/controller/SelectedWay.as
net/systemeD/potlatch2/tools/Parallelise.as [new file with mode: 0644]
potlatch2.mxml

index 94232bd..d4de447 100644 (file)
@@ -16,6 +16,7 @@ package net.systemeD.potlatch2 {
                ** Should float above tagViewer, not beneath it
                ** Icons should be disabled depending on what's selected (setEntity can do this)
                ** Remove annoying Illustrator cruft from SVG icons!
+               ** Tooltips
 
        */
 
@@ -93,6 +94,12 @@ package net.systemeD.potlatch2 {
                                controller.setState(SelectedWayNode(controller.state).splitWay());
                        }
                }
+               
+               public function doParallelise():void {
+                       if (entity is Way) {
+                               controller.setState(new SelectedParallelWay(Way(entity)));
+                       }
+               }
 
        }
 }
diff --git a/net/systemeD/potlatch2/controller/SelectedParallelWay.as b/net/systemeD/potlatch2/controller/SelectedParallelWay.as
new file mode 100644 (file)
index 0000000..8a04bff
--- /dev/null
@@ -0,0 +1,54 @@
+package net.systemeD.potlatch2.controller {
+       import flash.events.*;
+       import flash.display.Stage;
+    import net.systemeD.halcyon.connection.*;
+    import net.systemeD.halcyon.Map;
+       import net.systemeD.potlatch2.tools.Parallelise;
+       import net.systemeD.halcyon.Globals;
+
+    public class SelectedParallelWay extends SelectedWay {
+               private var startlon:Number;
+               private var startlatp:Number;
+               private var parallelise:Parallelise;
+
+        public function SelectedParallelWay(originalWay:Way) {
+                       parallelise = new Parallelise(originalWay);
+                       selectedWay=parallelise.parallelWay;
+                       super (selectedWay);
+        }
+
+        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+                       if (event.type==MouseEvent.MOUSE_MOVE) {
+                               var lon:Number =controller.map.coord2lon(controller.map.mouseX);
+                               var latp:Number=controller.map.coord2latp(controller.map.mouseY);
+                               var offset:Number=Math.sqrt(Math.pow(lon-startlon,2)+
+                                                           Math.pow(latp-startlatp,2));
+                               if (lon<startlon) { offset=-offset; }   // ** this should be smarter than just lon<startlon
+                               parallelise.draw(offset);
+                       } else if (event.type==MouseEvent.MOUSE_UP) {
+                               return new SelectedWay(selectedWay);
+                       }
+                       return this;
+        }
+
+               private function sgn(a:Number):Number {
+                       if (a==0) return 0;
+                       if (a<0) return -1;
+                       return 1;
+               }
+
+               override public function enterState():void {
+                       startlon =controller.map.coord2lon(controller.map.mouseX);
+                       startlatp=controller.map.coord2latp(controller.map.mouseY);
+                       Globals.vars.root.addDebug("**** -> "+this);
+        }
+               override public function exitState():void {
+            clearSelection();
+                       Globals.vars.root.addDebug("**** <- "+this);
+        }
+
+        override public function toString():String {
+            return "SelectedParallelWay";
+        }
+    }
+}
index 02d5634..7762b7c 100644 (file)
@@ -3,6 +3,7 @@ package net.systemeD.potlatch2.controller {
        import flash.display.DisplayObject;
        import flash.ui.Keyboard;
     import net.systemeD.potlatch2.EditController;
+    import net.systemeD.potlatch2.tools.Parallelise;
     import net.systemeD.potlatch2.tools.Quadrilateralise;
     import net.systemeD.potlatch2.tools.Simplify;
     import net.systemeD.halcyon.connection.*;
@@ -59,6 +60,8 @@ package net.systemeD.potlatch2.controller {
         
                override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
                        switch (event.keyCode) {
+                               case 80:                                        return new SelectedParallelWay(selectedWay);
+//                             var p:Parallelise=new Parallelise(selectedWay); p.draw(0.001); return this;
                                case 81:                                        Quadrilateralise.quadrilateralise(selectedWay); return this;
                 case 82:                    selectedWay.reverseNodes(MainUndoStack.getGlobalStack().addAction); return this;         
                 case 89:                    Simplify.simplify(selectedWay, controller.map, true); return this;         
diff --git a/net/systemeD/potlatch2/tools/Parallelise.as b/net/systemeD/potlatch2/tools/Parallelise.as
new file mode 100644 (file)
index 0000000..8ba976e
--- /dev/null
@@ -0,0 +1,76 @@
+package net.systemeD.potlatch2.tools {
+
+    import net.systemeD.halcyon.connection.*;
+
+       // FIXME:
+       // ** needs to be properly undoable
+
+       public class Parallelise {
+               private var originalWay:Way;
+               public var parallelWay:Way;
+               private var connection:Connection;
+               private var offsetx:Array=[];
+               private var offsety:Array=[];
+               private var df:Array=[];
+               private var nodes:Object={};
+               
+               public function Parallelise(way:Way) {
+                       var a:Number, b:Number, h:Number, i:uint;
+                       connection  = Connection.getConnection();
+                       originalWay = way;
+                       parallelWay = connection.createWay({}, [], MainUndoStack.getGlobalStack().addAction);
+
+                       for (i=0; i<originalWay.length-1; i++) {
+                               a=originalWay.getNode(i  ).latp - originalWay.getNode(i+1).latp;
+                               b=originalWay.getNode(i+1).lon  - originalWay.getNode(i  ).lon;
+                               h=Math.sqrt(a*a+b*b);
+                               if (h!=0) { a=a/h; b=b/h; }
+                                        else { a=0; b=0; }
+                               offsetx[i]=a;
+                               offsety[i]=b;
+                       }
+
+                       for (i=1; i<originalWay.length-1; i++) {
+                               a=det(offsetx[i]-offsetx[i-1],
+                                         offsety[i]-offsety[i-1],
+                                         originalWay.getNode(i+1).lon  - originalWay.getNode(i  ).lon,
+                                         originalWay.getNode(i+1).latp - originalWay.getNode(i  ).latp);
+                               b=det(originalWay.getNode(i  ).lon  - originalWay.getNode(i-1).lon,
+                                         originalWay.getNode(i  ).latp - originalWay.getNode(i-1).latp,
+                                         originalWay.getNode(i+1).lon  - originalWay.getNode(i  ).lon,
+                                         originalWay.getNode(i+1).latp - originalWay.getNode(i  ).latp);
+                               if (b!=0) { df[i]=a/b; } else { df[i]=0; }
+                       }
+
+               }
+
+               public function draw(offset:Number):void {
+                       var x:Number, y:Number;
+                       var undo:CompositeUndoableAction = new CompositeUndoableAction("Draw parallel way");
+                       parallelWay.suspend();
+                       for (var i:int=0; i<originalWay.length; i++) {
+                               if (i==0) {
+                                       x=originalWay.getNode(0).lon + offset * offsetx[0];
+                                       y=originalWay.getNode(0).latp+ offset * offsety[0];
+                               } else if (i==originalWay.length-1) {
+                                       x=originalWay.getNode(i).lon + offset * offsetx[i-1];
+                                       y=originalWay.getNode(i).latp+ offset * offsety[i-1];
+                               } else {
+                                       x=originalWay.getNode(i).lon + offset * (offsetx[i-1] + df[i] * (originalWay.getNode(i).lon - originalWay.getNode(i-1).lon ));
+                                       y=originalWay.getNode(i).latp+ offset * (offsety[i-1] + df[i] * (originalWay.getNode(i).latp- originalWay.getNode(i-1).latp));
+                               }
+                               if (nodes[i]) {
+                                       nodes[i].setLonLatp(x,y,undo.push);
+                               } else {
+                                       nodes[i] = connection.createNode({},Node.latp2lat(y),x,undo.push);
+                                       parallelWay.appendNode(nodes[i], undo.push);
+                               }
+                       }
+                       parallelWay.resume();
+                       MainUndoStack.getGlobalStack().addAction(undo);
+               }
+               
+               private function det(a:Number,b:Number,c:Number,d:Number):Number { return a*d-b*c; }
+
+       }
+}
index 1b05d8e..c3ff6c6 100755 (executable)
@@ -81,6 +81,7 @@
                                click='toolbox.doQuadrilateralise();' 
                                width="28" height="28" textAlign="left" paddingLeft="6" paddingRight="0" />
                <mx:Button icon="@Embed('embedded/parallel.svg')" 
+                               click='toolbox.doParallelise();' 
                                width="28" height="28" textAlign="left" paddingLeft="8" paddingRight="0" />
 
                </potlatch2:Toolbox>