1 package net.systemeD.halcyon.connection {
3 import net.systemeD.halcyon.connection.actions.*;
5 public class Node extends Entity {
6 private var _lat:Number;
7 private var _latproj:Number;
8 private var _lon:Number;
10 public function Node(connection:Connection, id:Number, version:uint, tags:Object, loaded:Boolean, lat:Number, lon:Number, uid:Number = NaN, timestamp:String = null, user:String = null) {
11 super(connection, id, version, tags, loaded, uid, timestamp, user);
13 this._latproj = lat2latp(lat);
17 public function update(version:uint, tags:Object, loaded:Boolean, parentsLoaded:Boolean, lat:Number, lon:Number, uid:Number = NaN, timestamp:String = null, user:String = null):void {
18 updateEntityProperties(version,tags,loaded,parentsLoaded,uid,timestamp,user); setLatLonImmediate(lat,lon);
21 public function get lat():Number {
25 public function get latp():Number {
29 public function get lon():Number {
33 private function setLatLonImmediate(lat:Number, lon:Number):void {
34 connection.removeDupe(this);
36 this._latproj = lat2latp(lat);
38 connection.addDupe(this);
39 for each (var way:Way in this.parentWays) {
44 public function set lat(lat:Number):void {
45 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, lat, _lon, setLatLonImmediate));
48 public function set latp(latproj:Number):void {
49 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, latp2lat(latproj), _lon, setLatLonImmediate));
52 public function set lon(lon:Number):void {
53 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, _lat, lon, setLatLonImmediate));
56 public function setLatLon(lat:Number, lon:Number, performAction:Function):void {
57 performAction(new MoveNodeAction(this, lat, lon, setLatLonImmediate));
60 public function setLonLatp(lon:Number,latproj:Number, performAction:Function):void {
61 performAction(new MoveNodeAction(this, latp2lat(latproj), lon, setLatLonImmediate));
64 public override function toString():String {
65 return "Node("+id+"@"+version+"): "+lat+","+lon+" "+getTagList();
68 public override function remove(performAction:Function):void {
69 performAction(new DeleteNodeAction(this, setDeletedState));
72 public override function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
73 if (_lon<left || _lon>right || _lat<bottom || _lat>top || deleted) { return false; }
77 public function unjoin(selectedWay:Way, performAction:Function):void {
78 if (parentWays.length > 1) {
79 performAction(new UnjoinNodeAction(this, selectedWay));
81 trace("not enough ways");
86 * Insert this node into the list of ways, and remove dupes at the same time.
87 * Please, don't call this on a node from a vector background, chaos will ensue.
89 public function join(ways:Array, performAction:Function):void {
90 if (this.isDupe() || ways.length > 0) {
91 var nodes:Array = connection.getNodesAtPosition(lat,lon);
92 // filter the nodes array to remove any occurances of this.
93 // Pass "this" as thisObject to get "this" into the callback function
94 var dupes:Array = nodes.filter(
95 function(element:*, index:int, arr:Array):Boolean {
96 return (element != this);
100 performAction(new JoinNodeAction(this, dupes, ways));
105 * Replace all occurances of this node with the given target node
107 public function replaceWith(target:Node, performAction:Function):void {
108 performAction(new ReplaceNodeAction(this, target));
110 public function replaceWithNew(connection:Connection, lat:Number, lon:Number, tags:Object, performAction:Function):Node {
111 var action:ReplaceNodeWithNewAction = new ReplaceNodeWithNewAction(this, connection, lat, lon, tags);
112 performAction(action);
113 return action.replacement;
116 public function isDupe():Boolean {
117 if (connection.getNode(this.id) == this // node could be part of a vector layer
118 && connection.nodesAtPosition(lat, lon) > 1) {
124 internal override function isEmpty():Boolean {
128 public static function lat2latp(lat:Number):Number {
129 return 180/Math.PI * Math.log(Math.tan(Math.PI/4+lat*(Math.PI/180)/2));
132 public static function latp2lat(a:Number):Number {
133 return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2);
136 public override function getType():String {
140 /** Merge another node into this one, removing the other one. */
141 public function mergeWith(node:Node, performAction:Function):MergeNodesAction {
142 var mna:MergeNodesAction = new MergeNodesAction(this, node);
144 return mna; // Access to the action is useful for stacking more actions onto it.