package net.systemeD.halcyon.connection {
import flash.geom.Point;
- import net.systemeD.halcyon.Globals;
- import net.systemeD.halcyon.connection.actions.*;
+
+ import net.systemeD.halcyon.connection.actions.*;
public class Way extends Entity {
private var nodes:Array;
private var edge_b:Number;
public static var entity_type:String = 'way';
- public function Way(id:Number, version:uint, tags:Object, loaded:Boolean, nodes:Array) {
- super(id, version, tags, loaded);
+ public function Way(id:Number, version:uint, tags:Object, loaded:Boolean, nodes:Array, uid:Number = NaN, timestamp:String = null) {
+ super(id, version, tags, loaded, uid, timestamp);
this.nodes = nodes;
for each (var node:Node in nodes) { node.addParent(this); }
calculateBbox();
}
- public function update(version:uint, tags:Object, loaded:Boolean, nodes:Array):void {
+ public function update(version:uint, tags:Object, loaded:Boolean, parentsLoaded:Boolean, nodes:Array, uid:Number = NaN, timestamp:String = null):void {
var node:Node;
for each (node in this.nodes) { node.removeParent(this); }
- updateEntityProperties(version,tags,loaded); this.nodes=nodes;
+ updateEntityProperties(version,tags,loaded,parentsLoaded,uid,timestamp); this.nodes=nodes;
for each (node in nodes) { node.addParent(this); }
calculateBbox();
}
}
public override function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
- if ((edge_l<left && edge_r<left ) ||
+ if (!edge_l ||
+ (edge_l<left && edge_r<left ) ||
(edge_l>right && edge_r>right ) ||
(edge_b<bottom && edge_t<bottom) ||
- (edge_b>top && edge_b>top )) { return false; }
+ (edge_b>top && edge_b>top ) || deleted) { return false; }
return true;
}
public function getLastNode():Node {
return nodes[nodes.length-1];
}
+
+ /** Given one node, return the next in sequence, cycling around a loop if necessary. */
+ // TODO make behave correctly for P-shaped topologies?
+ public function getNextNode(node:Node):Node {
+ // If the last node in a loop is selected, this behaves correctly.
+ var i:uint = indexOfNode(node);
+ if(i < length-1)
+ return nodes[i+1];
+ return null;
+ // What should happen for very short lengths?
+ }
+
+ // TODO make behave correctly for P-shaped topologies?
+ /** Given one node, return the previous, cycling around a loop if necessary. */
+ public function getPrevNode(node:Node):Node {
+ var i:uint = indexOfNode(node);
+ if(i > 0)
+ return nodes[i-1];
+ if(i == 0 && isArea() )
+ return nodes[nodes.length - 2]
+ return null;
+ // What should happen for very short lengths?
+ }
public function insertNode(index:uint, node:Node, performAction:Function):void {
performAction(new AddNodeToWayAction(this, node, nodes, index));
return nodes.indexOf(node);
}
+ public function hasOnceOnly(node:Node):Boolean {
+ return nodes.indexOf(node)==nodes.lastIndexOf(node);
+ }
+
+ public function hasLockedNodes():Boolean {
+ for each (var node:Node in nodes) {
+ if (node.locked) { return true; }
+ }
+ return false;
+ }
+
public function removeNode(node:Node, performAction:Function):void {
performAction(new RemoveNodeFromWayAction(this, node, nodes));
}
// splice in new node
if ( isSnap ) {
- newNode.latp = snapped.y;
- newNode.lon = snapped.x;
+ newNode.setLonLatp(snapped.x, snapped.y, performAction);
}
insertNode(newIndex, newNode, performAction);
return newIndex;
return (nodes[0].id==nodes[nodes.length-1].id && nodes.length>2);
}
+ public function endsWith(node:Node):Boolean {
+ return (nodes[0]==node || nodes[nodes.length-1]==node);
+ }
+
public override function remove(performAction:Function):void {
performAction(new DeleteWayAction(this, setDeletedState, nodes));
}
+ public override function nullify():void {
+ nullifyEntity();
+ nodes=[];
+ edge_l=edge_r=edge_t=edge_b=NaN;
+ }
+
public function get clockwise():Boolean {
var lowest:uint=0;
var xmin:Number=-999999; var ymin:Number=-999999;
return left;
}
+ public function get angle():Number {
+ var dx:Number = nodes[nodes.length-1].lon - nodes[0].lon;
+ var dy:Number = nodes[nodes.length-1].latp - nodes[0].latp;
+ if (dx != 0 || dy != 0) {
+ return Math.atan2(dx,dy)*(180/Math.PI);
+ } else {
+ return 0;
+ }
+ }
+
internal override function isEmpty():Boolean {
return (deleted || (nodes.length==0));
}