alt-click (for now) to bring ways in from vector background layers
authorRichard Fairhurst <richard@systemed.net>
Sat, 1 May 2010 16:02:14 +0000 (16:02 +0000)
committerRichard Fairhurst <richard@systemed.net>
Sat, 1 May 2010 16:02:14 +0000 (16:02 +0000)
16 files changed:
TODO.txt
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/MapPaint.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/connection/Node.as
net/systemeD/halcyon/connection/Way.as
net/systemeD/halcyon/connection/XMLConnection.as
net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
net/systemeD/halcyon/vectorlayers/CustomVectorLayer.as
net/systemeD/halcyon/vectorlayers/SimpleVectorLayer.as
net/systemeD/halcyon/vectorlayers/VectorLayer.as
net/systemeD/potlatch2/VectorSourceDialog.mxml
net/systemeD/potlatch2/controller/ControllerState.as
net/systemeD/potlatch2/controller/DragWayNode.as
net/systemeD/potlatch2/controller/NoSelection.as
net/systemeD/potlatch2/controller/SelectedWay.as

index 1c018dfd920d71ab8b975cad2b53dcf68744190c..98bcdf62497dd90ede31f08ec6e4d47daa6e7182 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -10,11 +10,13 @@ Potlatch 2: main outstanding issues
 == Core geometry ==
 
 * Undo/redo: split, draw
+* Drag ways
 
 
 == Vector background layers ==
 
 * Remove existing interaction and add alt-click
+* TagTransform (cf http://wiki.openstreetmap.org/wiki/Osmosis/TagTransform)
 * Import from GPX
 * Import from OSM (is this worth sharing with the XML API stuff?)
 
index db20ca5d9e988b0e5883948dfedf2dc6ab735f42..95d8e2485be7c715c8cd36c42c4386d3bd2392fe 100755 (executable)
@@ -140,6 +140,7 @@ package net.systemeD.halcyon {
 
                        paint = new MapPaint(this,-5,5);                        // 2 - core paint object
                        addChild(paint);                                                        //   |
+                       paint.isBackground=false;                                       //   |
 
                        if (style) {
                                paint.ruleset=new RuleSet(MINSCALE,MAXSCALE,redraw,redrawPOIs);
index 209cb3319b56ddf50cc6f4600cc61a6985adb6a8..14dc97eb925f43e48e980ca8f1f1bbccea4b0add 100644 (file)
@@ -7,6 +7,7 @@ package net.systemeD.halcyon {
        import net.systemeD.halcyon.connection.Node;
        import net.systemeD.halcyon.connection.Way;
        import net.systemeD.halcyon.styleparser.RuleSet;
+       import net.systemeD.halcyon.vectorlayers.VectorLayer;
        import net.systemeD.halcyon.Globals;
 
     public class MapPaint extends Sprite {
@@ -17,6 +18,7 @@ package net.systemeD.halcyon {
                public var ruleset:RuleSet;                                             // rules
                public var wayuis:Object=new Object();                  // sprites for ways and (POI/tagged) nodes
                public var nodeuis:Object=new Object();                 //  |
+               public var isBackground:Boolean = true;                 // is it a background layer or the core paint object?
 
                // Set up layering
                // [layer][3]                   - names
@@ -117,6 +119,13 @@ package net.systemeD.halcyon {
                public function redrawPOIs():void {
                        for each (var p:NodeUI in nodeuis) { p.redraw(); }
                }
-
+               
+               public function findSource():VectorLayer {
+                       var v:VectorLayer;
+                       for each (v in map.vectorlayers) {
+                               if (v.paint==this) { return v; }
+                       }
+                       return null;
+               }
        }
 }
index 48872bea4ed1b7ac65034d5ee60f010b084b40b0..94a52df231869e237c546415d6f0d16d24e18b22 100755 (executable)
@@ -74,7 +74,9 @@ package net.systemeD.halcyon {
                    
                private function wayNodeRemoved(event:WayNodeEvent):void {
                    event.node.removeEventListener(Connection.NODE_MOVED, nodeMoved);
-                       paint.nodeuis[event.node.id].redraw();
+                       if (paint.nodeuis[event.node.id]) {
+                               paint.nodeuis[event.node.id].redraw();
+                       }
                    redraw();
                }
                    
index 7050a22e6c852210482097a9974558a97b74d546..8e680c19038f77cce93c8ff6e71e53df574b4dc0 100644 (file)
@@ -48,8 +48,8 @@ package net.systemeD.halcyon.connection {
             MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, _lat, lon, setLatLonImmediate));
         }
         
-        public function setLatLon(lat:Number, lon:Number, performAction:Function):void {
-            performAction(new MoveNodeAction(this, lat, lon, setLatLonImmediate));
+        public function setLatLon(lat:Number, lon:Number):void {
+            MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, lat, lon, setLatLonImmediate));
         } 
 
                public function setLonLatp(lon:Number,latproj:Number, performAction:Function):void {
index d251369d3d4479a0df93c4ebc89cc3ffb89197ab..2df20975a391edaf5572258fff26a5617c7bb845 100644 (file)
@@ -54,11 +54,13 @@ package net.systemeD.halcyon.connection {
                        performAction(new RemoveNodeFromWayAction(this, node, nodes));
                }
 
-        public function removeNodeByIndex(index:uint):void {
+        public function removeNodeByIndex(index:uint,fireEvent:Boolean=true):void {
             var removed:Array=nodes.splice(index, 1);
                        if (nodes.indexOf(removed[0])==-1) { removed[0].removeParent(this); }
                        markDirty();
-            dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, removed[0], this, index));
+                       if (fireEvent) {
+                   dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, removed[0], this, index));
+                       }
         }
 
                public function sliceNodes(start:int,end:int):Array {
@@ -142,6 +144,7 @@ package net.systemeD.halcyon.connection {
         }
 
                public function isArea():Boolean {
+                       if (nodes.length==0) { return false; }
                        return (nodes[0].id==nodes[nodes.length-1].id && nodes.length>2);
                }
                
index 44f5441b165ddbd33fab1fc2b2ed7bf24d70c725..dea20b7860f72dab71125dffa9cf9eb823dd79f5 100644 (file)
@@ -224,14 +224,14 @@ package net.systemeD.halcyon.connection {
             upload.appendChild(addCreated(changeset, getAllNodeIDs, getNode, serialiseNode));
             upload.appendChild(addCreated(changeset, getAllWayIDs, getWay, serialiseWay));
             upload.appendChild(addCreated(changeset, getAllRelationIDs, getRelation, serialiseRelation));
-            upload.appendChild(addDeleted(changeset, getAllRelationIDs, getRelation, serialiseEntityRoot));
-            upload.appendChild(addDeleted(changeset, getAllWayIDs, getWay, serialiseEntityRoot));
-            upload.appendChild(addDeleted(changeset, getAllNodeIDs, getNode, serialiseEntityRoot));
             upload.appendChild(addModified(changeset, getAllNodeIDs, getNode, serialiseNode));
             upload.appendChild(addModified(changeset, getAllWayIDs, getWay, serialiseWay));
             upload.appendChild(addModified(changeset, getAllRelationIDs, getRelation, serialiseRelation));
+            upload.appendChild(addDeleted(changeset, getAllRelationIDs, getRelation, serialiseEntityRoot));
+            upload.appendChild(addDeleted(changeset, getAllWayIDs, getWay, serialiseEntityRoot));
+            upload.appendChild(addDeleted(changeset, getAllNodeIDs, getNode, serialiseEntityRoot));
 
-            // *** TODO *** deleting items
+                       trace(upload);
             
             // now actually upload them
             // make an OAuth query
@@ -298,7 +298,7 @@ package net.systemeD.halcyon.connection {
         private function addCreated(changeset:Changeset, getIDs:Function, get:Function, serialise:Function):XML {
             var create:XML = <create version="0.6"/>
             for each( var id:Number in getIDs() ) {
-                if ( id >= 0 )
+                if ( id >= 0 || entity.deleted )
                     continue;
                     
                 var entity:Object = get(id);
index cae03113b2f78746f72dd0eb2db1807e1ba6b57e..d9fdaabd33ef803859d9562ba2bdc4391b3e9f23 100644 (file)
@@ -1,6 +1,7 @@
 package net.systemeD.halcyon.connection.actions {
 
     import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
     
     public class AddNodeToWayAction extends UndoableEntityAction {
         private var node:Node;
index fe9bb0da2e5de4dd0adf8d93980d805f5969c9ee..fb73e843c1033cb0c92c828b0ea80e4d9422ac4b 100644 (file)
@@ -12,8 +12,8 @@ package net.systemeD.halcyon.vectorlayers {
 
        public class CustomVectorLayer extends VectorLayer {
 
-               public function CustomVectorLayer(m:Map,style:String) {
-                       super(m);
+               public function CustomVectorLayer(n:String,m:Map,style:String) {
+                       super(n,m);
                        paint.ruleset=new RuleSet(m.MINSCALE,m.MAXSCALE,paint.redraw);
                        paint.ruleset.loadFromCSS(style);
                }
index d2976ff2ebebc5d42a29bd519aafa060eebc44df..07ffa97039ad2d3b89442331710323bc994b4daa 100644 (file)
@@ -1,6 +1,6 @@
 package net.systemeD.halcyon.vectorlayers {
 
-       // A CustomVectorLayer has a simpler, lines-only appearance - suitable for
+       // A SimpleVectorLayer has a simpler, lines-only appearance - suitable for
        // large quantities of data such as GPX traces.
 
        public class SimpleVectorLayer extends VectorLayer {
index b9e2d1802a5ac288c2cf9cfba986f95fc0ead2d8..3c3c2aa9cb4c6bff4b7bb894c4b7cbefa3135690 100644 (file)
@@ -2,21 +2,22 @@ package net.systemeD.halcyon.vectorlayers {
 
        import net.systemeD.halcyon.Map;
        import net.systemeD.halcyon.MapPaint;
-       import net.systemeD.halcyon.connection.Node;
-       import net.systemeD.halcyon.connection.Way;
-       import net.systemeD.halcyon.connection.Relation;
+       import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
 
        public class VectorLayer extends Object {
 
                public var map:Map;
                public var paint:MapPaint;                                              // sprites
+               public var name:String;
 
                public var ways:Object=new Object();                    // geodata
                public var nodes:Object=new Object();                   //  |
                public var relations:Object=new Object();               //  |
         private var negativeID:Number = -1;
 
-               public function VectorLayer(m:Map) {
+               public function VectorLayer(n:String,m:Map) {
+                       name=n;
                        map=m;
                        paint=new MapPaint(m,0,0);
                }
@@ -36,6 +37,33 @@ package net.systemeD.halcyon.vectorlayers {
                        relations[negativeID]=relation; negativeID--;
             return relation;
                }
+               
+               public function pullThrough(entity:Entity,connection:Connection):Way {
+                       var i:uint=0;
+                       if (entity is Way) {
+                               // copy way through to main layer
+                               // ** shouldn't do this if the nodes are already in the main layer
+                               var oldWay:Way=Way(entity);
+                               var newWay:Way=connection.createWay(oldWay.getTagsCopy(), [], MainUndoStack.getGlobalStack().addAction);
+                               for (i=0; i<oldWay.length; i++) {
+                                       var oldNode:Node = oldWay.getNode(i);
+                                       var newNode:Node = connection.createNode(
+                                               oldNode.getTagsCopy(), oldNode.lat, oldNode.lon, 
+                                               MainUndoStack.getGlobalStack().addAction);
+                                       newWay.appendNode(newNode, MainUndoStack.getGlobalStack().addAction);
+                               }
+                               // delete this way
+                               while (oldWay.length) { 
+                                       var id:int=oldWay.getNode(0).id;
+                                       oldWay.removeNodeByIndex(0,false);
+                                       delete nodes[id];
+                               }
+                               paint.wayuis[oldWay.id].redraw();
+                               ways[oldWay.id]=null;
+                               map.paint.createWayUI(newWay);
+                       }
+                       return newWay;
+               }
 
        }
 }
index 8cf2c7243250ca938ca6fc7d8862eeeb305327aa..8fc7524c765536dac5796751fa22140885c6fc3c 100644 (file)
@@ -27,7 +27,7 @@
        private function loadSHP(url:String):void {
         PopUpManager.removePopUp(this);
                var theMap:Map = Globals.vars.root;
-               var vectorlayer:CustomVectorLayer=new CustomVectorLayer(theMap,"potlatch.css");
+               var vectorlayer:CustomVectorLayer=new CustomVectorLayer(url,theMap,"potlatch.css");
                theMap.vectorlayers.push(vectorlayer);
                theMap.vectorbg.addChild(vectorlayer.paint);
 
index f1a367178d00113c49e808686ac008a9f6ee383f..864237719872e1a181c3778aa13941232a170cc3 100644 (file)
@@ -1,6 +1,8 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
+       import flash.display.*;
     import net.systemeD.halcyon.Map;
+    import net.systemeD.halcyon.MapPaint;
     import net.systemeD.halcyon.connection.*;
     import net.systemeD.potlatch2.EditController;
        import net.systemeD.halcyon.Globals;
@@ -39,6 +41,14 @@ package net.systemeD.potlatch2.controller {
                public function toString():String {
                        return "(No state)";
                }
+               
+               protected function getMapPaint(d:DisplayObject):MapPaint {
+                       while (d) {
+                               if (d is MapPaint) { return MapPaint(d); }
+                               d=d.parent;
+                       }
+                       return null;
+               }
 
     }
 }
index d11df0958b64b719814a569f79ce4847fdcc1c65..f237c307ca3efbde5a7781421c1d51b3549d9b54 100644 (file)
@@ -66,8 +66,7 @@ package net.systemeD.potlatch2.controller {
         }
         
         private function dragTo(event:MouseEvent):ControllerState {
-            draggingNode.lat = controller.map.coord2lat(event.localY);
-            draggingNode.lon = controller.map.coord2lon(event.localX);
+                       draggingNode.setLatLon( controller.map.coord2lat(event.localY), controller.map.coord2lon(event.localX) );
             return this;
         }
         
index fba7021ad88357d3b873e8310be3f26912a91381..69149aedb29073540f0f5290b96a78fe73026081 100644 (file)
@@ -1,20 +1,26 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
+       import flash.display.*;
        import net.systemeD.potlatch2.EditController;
        import net.systemeD.halcyon.connection.*;
        import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.MapPaint;
+       import net.systemeD.halcyon.vectorlayers.VectorLayer;
        import net.systemeD.halcyon.Globals;
 
        public class NoSelection extends ControllerState {
 
                public function NoSelection() {
                }
+
                override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
                        var focus:Entity = getTopLevelFocusEntity(entity);
 
                        if ( event.type == MouseEvent.MOUSE_DOWN ) {
-                               if ( entity is Way ) {
+                               var paint:MapPaint = getMapPaint(DisplayObject(event.target));
+                               if ( entity is Way && event.altKey && paint.isBackground ) {
+                                       return new SelectedWay(paint.findSource().pullThrough(entity,controller.connection));
+                               } else if ( entity is Way ) {
                                        return new SelectedWay(focus as Way);
                 } else if ( focus is Node ) {
                                        return new DragPOINode(entity as Node,event,false);
index 650ea76d9fcdccec0b56fe889f74ec9e9d7f776f..0bbd224c7af9ed30b3116fc65b4ff4e55d32c9e1 100644 (file)
@@ -1,9 +1,11 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
+       import flash.display.DisplayObject;
        import flash.ui.Keyboard;
     import net.systemeD.potlatch2.EditController;
     import net.systemeD.potlatch2.tools.Quadrilateralise;
     import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.MapPaint;
        import net.systemeD.halcyon.Globals;
 
     public class SelectedWay extends ControllerState {
@@ -52,8 +54,13 @@ package net.systemeD.potlatch2.controller {
                 } else if ( focus == null && map.dragstate!=map.DRAGGING ) {
                     return new NoSelection();
                                }
+
             } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
-                               if ( entity is Way && focus==selectedWay && event.shiftKey) {
+                               var paint:MapPaint = getMapPaint(DisplayObject(event.target));
+                               if ( entity is Way && event.altKey && paint.isBackground ) {
+                                       // pull way out of vector background layer
+                                       return new SelectedWay(paint.findSource().pullThrough(entity,controller.connection));
+                               } else if ( entity is Way && focus==selectedWay && event.shiftKey) {
                                        // insert node within way (shift-click)
                     var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event, true);
                                        d.forceDragStart();