delete objects (possibly not complete)
authorRichard Fairhurst <richard@systemed.net>
Sat, 9 Jan 2010 18:46:43 +0000 (18:46 +0000)
committerRichard Fairhurst <richard@systemed.net>
Sat, 9 Jan 2010 18:46:43 +0000 (18:46 +0000)
net/systemeD/halcyon/connection/Connection.as
net/systemeD/halcyon/connection/Entity.as
net/systemeD/halcyon/connection/Node.as
net/systemeD/halcyon/connection/Relation.as
net/systemeD/halcyon/connection/Way.as
net/systemeD/potlatch2/controller/SelectedWay.as

index 6bed36e..af65f7b 100755 (executable)
@@ -63,6 +63,9 @@ package net.systemeD.halcyon.connection {
         public static var NODE_MOVED:String = "node_moved";
         public static var WAY_NODE_ADDED:String = "way_node_added";
         public static var WAY_NODE_REMOVED:String = "way_node_removed";
+               public static var NODE_DELETED:String = "node_deleted";
+               public static var WAY_DELETED:String = "way_deleted";
+               public static var RELATION_DELETED:String = "relation_deleted";
 
         // store the data we download
         private var negativeID:Number = -1;
@@ -106,6 +109,7 @@ package net.systemeD.halcyon.connection {
             delete relations[oldID];
         }
 
+
                public function sendEvent(e:*,queue:Boolean):void {
                        // queue is only used for AMFConnection
                        dispatchEvent(e);
index 0b84724..e41104e 100644 (file)
@@ -11,6 +11,7 @@ package net.systemeD.halcyon.connection {
                private var _loaded:Boolean = true;
                private var parents:Dictionary = new Dictionary();
                private var locked:Boolean = false;
+               protected var deleted:Boolean = false;
 
         public function Entity(id:Number, version:uint, tags:Object, loaded:Boolean) {
             this._id = id;
@@ -112,6 +113,24 @@ package net.systemeD.halcyon.connection {
             modified = true;
         }
 
+               // Delete entity
+               
+               public function remove():void {
+                       // to be overridden
+               }
+               
+               internal function isEmpty():Boolean {
+                       return false;   // to be overridden
+               }
+
+               protected function removeFromParents():void {
+                       for each (var o:Entity in parents) {
+                               if (o is Relation) { Relation(o).removeMember(this); }
+                               else if (o is Way) { Way(o).removeNode(Node(this)); }
+                               if (o.isEmpty()) { o.remove(); }
+                       }
+               }
+
                // Parent handling
                
                public function addParent(parent:Entity):void {
@@ -129,6 +148,11 @@ package net.systemeD.halcyon.connection {
                        }
                        return a;
                }
+
+               public function get hasParents():Boolean {
+                       for (var o:Object in parents) { return true; }
+                       return false;
+               }
                
                public function get hasParentWays():Boolean {
                        for (var o:Object in parents) {
index dd716c0..853c0db 100644 (file)
@@ -55,6 +55,16 @@ package net.systemeD.halcyon.connection {
             return "Node("+id+"@"+version+"): "+lat+","+lon+" "+getTagList();
         }
 
+               public override function remove():void {
+                       removeFromParents();
+                       deleted=true;
+            dispatchEvent(new EntityEvent(Connection.NODE_DELETED, this));
+               }
+
+               internal override function isEmpty():Boolean {
+                       return deleted;
+               }
+
         public static function lat2latp(lat:Number):Number {
             return 180/Math.PI * Math.log(Math.tan(Math.PI/4+lat*(Math.PI/180)/2));
         }
index 784d6f7..f1838ce 100644 (file)
@@ -37,24 +37,50 @@ package net.systemeD.halcyon.connection {
         public function setMember(index:uint, member:RelationMember):void {
                        member.entity.addParent(this);
                        members.splice(index, 1, member);
+                       markDirty();
         }
 
         public function insertMember(index:uint, member:RelationMember):void {
                        member.entity.addParent(this);
             members.splice(index, 0, member);
+                       markDirty();
         }
 
         public function appendMember(member:RelationMember):uint {
                        member.entity.addParent(this);
             members.push(member);
+                       markDirty();
             return members.length;
         }
 
-        public function removeMember(index:uint):void {
+               public function removeMember(entity:Entity):void {
+                       var i:int;
+                       while ((i=findEntityMemberIndex(entity))>-1) {
+                               members.splice(i, 1);
+                       }
+                       entity.removeParent(this);
+                       markDirty();
+               }
+
+        public function removeMemberByIndex(index:uint):void {
             var removed:Array=members.splice(index, 1);
-                       removed[0].entity.removeParent(this);
+                       var entity:Entity=removed[0].entity;
+                       if (findEntityMemberIndex(entity)==-1) { entity.removeParent(this); }
+                       markDirty();
         }
 
+               public override function remove():void {
+                       removeFromParents();
+                       for each (var member:RelationMember in members) { member.entity.removeParent(this); }
+                       members=[];
+                       deleted=true;
+            dispatchEvent(new EntityEvent(Connection.RELATION_DELETED, this));
+               }
+
+               internal override function isEmpty():Boolean {
+                       return (deleted || (members.length==0));
+               }
+
         public function getDescription():String {
             var desc:String = "";
             var relTags:Object = getTagsHash();
index 1abcbc3..2dd503f 100644 (file)
@@ -1,5 +1,6 @@
 package net.systemeD.halcyon.connection {
     import flash.geom.Point;
+       import net.systemeD.halcyon.Globals;
 
     public class Way extends Entity {
         private var nodes:Array;
@@ -26,6 +27,10 @@ package net.systemeD.halcyon.connection {
             return nodes[index];
         }
 
+               public function getLastNode():Node {
+                       return nodes[nodes.length-1];
+               }
+
         public function insertNode(index:uint, node:Node):void {
                        node.addParent(this);
             nodes.splice(index, 0, node);
@@ -41,13 +46,31 @@ package net.systemeD.halcyon.connection {
             return nodes.length;
         }
         
+        public function prependNode(node:Node):uint {
+                       node.addParent(this);
+            nodes.unshift(node);
+            markDirty();
+            dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_ADDED, node, this, 0));
+            return nodes.length;
+        }
+        
         public function indexOfNode(node:Node):uint {
             return nodes.indexOf(node);
         }
 
-        public function removeNode(index:uint):void {
+               public function removeNode(node:Node):void {
+                       var i:int;
+                       while ((i=nodes.indexOf(i))>-1) {
+                               nodes.splice(i,1);
+               dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, node, this, i));
+                       }
+                       node.removeParent(this);
+                       markDirty();
+               }
+
+        public function removeNodeByIndex(index:uint):void {
             var removed:Array=nodes.splice(index, 1);
-                       removed[0].removeParent(this);
+                       if (nodes.indexOf(removed[0])==-1) { removed[0].removeParent(this); }
                        markDirty();
             dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, removed[0], this, index));
         }
@@ -72,6 +95,49 @@ package net.systemeD.halcyon.connection {
                        nodes.splice(start);
                }
 
+               public function mergeWith(way:Way,topos:int,frompos:int):void {
+                       var i:int;
+                       Globals.vars.root.addDebug("way "+id+", merging with "+way.id+", adding to "+topos+" , from "+frompos);
+
+                       // merge relations
+                       for each (var r:Relation in way.parentRelations) {
+                               // ** needs to copy roles as well
+                               if (r.findEntityMemberIndex(this)==-1) {
+                                       r.appendMember(new RelationMember(this, ''));
+                               }
+                       }
+
+                       // merge tags
+                       var t:Object=way.getTagsHash();
+                       for (var k:String in t) {
+                               if (getTag(k) && getTag(k)!=t[k]) {
+                                       setTag(k,getTag(k)+"; "+t[k]);
+                                       // ** send a warning about tags not matching
+                               } else {
+                                       setTag(k,t[k]);
+                               }
+                       }
+
+                       // merge nodes
+                       if (frompos==0) { for (i=0; i<way.length;    i++) { addToEnd(topos,way.getNode(i)); } }
+                                          else { for (i=way.length-1; i>=0; i--) { addToEnd(topos,way.getNode(i)); } }
+
+                       // delete way
+                       
+               }
+               
+               private function addToEnd(topos:int,node:Node):void {
+                       Globals.vars.root.addDebug("adding "+node.id+" at "+topos);
+                       if (topos==0) {
+                               if (nodes[0]==node) { return; }
+                               prependNode(node);
+                       } else {
+                               if (nodes[nodes.length-1]==node) { return; }
+                               appendNode(node);
+                       }
+               }
+
+
 
         /**
          * Finds the 1st way segment which intersects the projected
@@ -126,6 +192,21 @@ package net.systemeD.halcyon.connection {
                public function isArea():Boolean {
                        return (nodes[0].id==nodes[nodes.length-1].id && nodes.length>2);
                }
+               
+               public override function remove():void {
+                       removeFromParents();
+                       for each (var node:Node in nodes) {
+                               node.removeParent(this);
+                               if (!node.hasParentWays) { node.remove(); }
+                       }
+                       nodes=[];
+                       deleted=true;
+            dispatchEvent(new EntityEvent(Connection.WAY_DELETED, this));
+               }
+
+               internal override function isEmpty():Boolean {
+                       return (deleted || (nodes.length==0));
+               }
 
                public override function getType():String {
                        return 'way';
index 5a8154a..d4d4f7e 100644 (file)
@@ -40,6 +40,9 @@ package net.systemeD.potlatch2.controller {
                                        // start new way
                     var way:Way = controller.connection.createWay({}, [entity]);
                     return new DrawWay(way, true, false);
+                               } else if ( entity is Way && event.ctrlKey ) {
+                                       // merge way
+                                       mergeWith(entity as Way);
                                } else if ( entity is Way ) {
                                        // select way
                     selectWay(entity as Way);
@@ -75,6 +78,18 @@ package net.systemeD.potlatch2.controller {
             selectedWay.insertNodeAtClosestPosition(node, true);
                        return node;
         }
+
+               protected function mergeWith(way:Way):Boolean {
+                       Globals.vars.root.addDebug("merge with "+way.id);
+
+                       // ** needs to prefer positive to negative IDs
+                       // find common point
+                       if      (selectedWay.getNode(0)   ==way.getNode(0)   ) { selectedWay.mergeWith(way,0,0); }
+                       else if (selectedWay.getNode(0)   ==way.getLastNode()) { selectedWay.mergeWith(way,0,way.length-1); }
+                       else if (selectedWay.getLastNode()==way.getNode(0)   ) { selectedWay.mergeWith(way,selectedWay.length-1,0); }
+                       else if (selectedWay.getLastNode()==way.getLastNode()) { selectedWay.mergeWith(way,selectedWay.length-1,way.length-1); }
+                       return true;
+               }
         
         override public function enterState():void {
             selectWay(initWay);