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(id:Number, version:uint, tags:Object, loaded:Boolean, lat:Number, lon:Number, uid:Number = NaN, timestamp:String = null) {
11 super(id, version, tags, loaded, uid, timestamp);
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):void {
18 updateEntityProperties(version,tags,loaded,parentsLoaded,uid,timestamp); 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 var connection:Connection = Connection.getConnection();
35 connection.removeDupe(this);
37 this._latproj = lat2latp(lat);
39 connection.addDupe(this);
40 for each (var way:Way in this.parentWays) {
45 public function set lat(lat:Number):void {
46 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, lat, _lon, setLatLonImmediate));
49 public function set latp(latproj:Number):void {
50 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, latp2lat(latproj), _lon, setLatLonImmediate));
53 public function set lon(lon:Number):void {
54 MainUndoStack.getGlobalStack().addAction(new MoveNodeAction(this, _lat, lon, setLatLonImmediate));
57 public function setLatLon(lat:Number, lon:Number, performAction:Function):void {
58 performAction(new MoveNodeAction(this, lat, lon, setLatLonImmediate));
61 public function setLonLatp(lon:Number,latproj:Number, performAction:Function):void {
62 performAction(new MoveNodeAction(this, latp2lat(latproj), lon, setLatLonImmediate));
65 public override function toString():String {
66 return "Node("+id+"@"+version+"): "+lat+","+lon+" "+getTagList();
69 public override function remove(performAction:Function):void {
70 performAction(new DeleteNodeAction(this, setDeletedState));
73 public override function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
74 if (_lon<left || _lon>right || _lat<bottom || _lat>top || deleted) { return false; }
78 public function unjoin(selectedWay:Way, performAction:Function):void {
79 if (parentWays.length > 1) {
80 performAction(new UnjoinNodeAction(this, selectedWay));
82 trace("not enough ways");
87 * Insert this node into the list of ways, and remove dupes at the same time.
88 * Please, don't call this on a node from a vector background, chaos will ensue.
90 public function join(ways:Array, performAction:Function):void {
91 if (this.isDupe() || ways.length > 0) {
92 var connection:Connection = Connection.getConnection();
93 var nodes:Array = connection.getNodesAtPosition(lat,lon);
94 // filter the nodes array to remove any occurances of this.
95 // Pass "this" as thisObject to get "this" into the callback function
96 var dupes:Array = nodes.filter(
97 function(element:*, index:int, arr:Array):Boolean {
98 return (element != this);
102 performAction(new JoinNodeAction(this, dupes, ways));
107 * Replace all occurances of this node with the given target node
109 public function replaceWith(target:Node, performAction:Function):void {
110 performAction(new ReplaceNodeAction(this, target));
113 public function isDupe():Boolean {
114 var connection:Connection = Connection.getConnection();
115 if (connection.getNode(this.id) == this // node could be part of a vector layer
116 && connection.nodesAtPosition(lat, lon) > 1) {
122 internal override function isEmpty():Boolean {
126 public static function lat2latp(lat:Number):Number {
127 return 180/Math.PI * Math.log(Math.tan(Math.PI/4+lat*(Math.PI/180)/2));
130 public static function latp2lat(a:Number):Number {
131 return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2);
134 public override function getType():String {