** 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
*/
controller.setState(SelectedWayNode(controller.state).splitWay());
}
}
+
+ public function doParallelise():void {
+ if (entity is Way) {
+ controller.setState(new SelectedParallelWay(Way(entity)));
+ }
+ }
}
}
--- /dev/null
+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";
+ }
+ }
+}
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.*;
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;
--- /dev/null
+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; }
+
+ }
+}
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>