03d5a6c399f528d8188499b803d5fcc60ef44068
[potlatch2.git] / net / systemeD / halcyon / connection / AMFConnection.as
1 package net.systemeD.halcyon.connection {
2
3     import flash.events.Event;
4     import flash.net.URLLoader;
5     import flash.net.URLRequest;
6
7         import flash.system.Security;
8         import flash.net.*;
9
10         public class AMFConnection extends Connection {
11
12                 public var readConnection:NetConnection;
13                 public var writeConnection:NetConnection;
14                 private var mapLoader:URLLoader;
15
16                 private var eventTarget:AMFCounter;
17                 private var bboxrequests:Array=new Array();
18
19                 // ------------------------------------------------------------
20                 // Constructor for new AMFConnection
21
22                 public function AMFConnection() {
23
24                         if (Connection.policyURL!='')
25                 Security.loadPolicyFile(Connection.policyURL);
26
27                         readConnection=new NetConnection();
28                         readConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
29                         readConnection.connect(Connection.apiBaseURL+"amf/read");
30                         
31                         writeConnection=new NetConnection();
32                         writeConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
33                         writeConnection.connect(Connection.apiBaseURL+"amf/write");
34                         
35                 }
36
37                 override public function getEnvironment(responder:Responder):void {
38                         readConnection.call("getpresets",responder,null,"en");
39                 }
40                 
41                 override public function loadBbox(left:Number,right:Number,
42                                                                 top:Number,bottom:Number):void {
43                         readConnection.call("whichways",new Responder(gotBbox, error),left,bottom,right,top);
44                 }
45                 
46                 override public function sendEvent(e:*,queue:Boolean):void {
47                         if (queue) { eventTarget.addEvent(e); }
48                               else { dispatchEvent(e); }
49                 }
50
51         private function gotBbox(r:Object):void {
52                         var code:uint=r.shift();
53             if (code) {
54                 error(new Array(r.shift()));
55                 return;
56             }
57
58                         var message:String    =r.shift();
59                         var waylist:Array     =r[0];
60                         var pointlist:Array   =r[1];
61                         var relationlist:Array=r[2];
62                         var id:Number, version:uint;
63                         var requests:AMFCounter=new AMFCounter(this);
64                         eventTarget=requests;
65
66                         // Load relations
67
68                         for each (var a:Array in relationlist) {
69                                 id=Number(a[0]);
70                 version=uint(a[1]);
71
72                 var relation:Relation = getRelation(id);
73                 if ( relation == null || !relation.loaded  ) {
74                     loadRelation(id);
75                                         requests.addRelationRequest(id);
76                 }
77                         }
78
79                         // Load ways
80
81                         for each (var w:Array in waylist) {
82                                 id=Number(w[0]);
83                 version=uint(w[1]);
84
85                 var way:Way = getWay(id);
86                 if ( way == null || !way.loaded ) {
87                     loadWay(id);
88                                         requests.addWayRequest(id);
89                 }
90                         }
91
92                         // Create POIs
93
94                         for each (var p:Array in pointlist) {
95                                 id = Number(p[0]);
96                 version = uint(p[4]);
97
98                 var node:Node = getNode(id);
99                 if ( node == null || !node.loaded ) {
100                     var lat:Number = Number(p[2]);
101                     var lon:Number = Number(p[1]);
102                     var tags:Object = p[3];
103                     node = new Node(id, version, tags, true, lat, lon);
104                     setNode(node,true);
105                 }
106                 registerPOI(node);
107                         }
108
109                         bboxrequests.push(requests);
110         }
111
112         private function error(r:Object):void {}
113
114                 private function loadWay(id:uint):void {
115                         readConnection.call("getway",new Responder(gotWay, error),id);
116                 }
117
118                 private function gotWay(r:Object):void {
119                         var code:uint = r.shift();
120             if (code) {
121                 error(new Array(r.shift()));
122                 return;
123             }
124
125                         var message:String=r.shift();
126             var id:Number = Number(r[0]);
127                         var version:uint = uint(r[3]);
128
129             var way:Way = getWay(id);
130             if ( way != null && way.loaded ) {
131                                 gotRequest(id+"way");
132                 return;
133                         }
134
135             var nodesAMF:Array = r[1];
136                         var tags:Object = r[2];
137                         
138             var nodes:Array = [];
139                         for each (var p:Array in nodesAMF) {
140                 var nodeID:Number = Number(p[2]);
141                 var nodeVersion:uint = uint(p[4]);
142                 var lon:Number = Number(p[0]);
143                 var lat:Number = Number(p[1]);
144
145                 var node:Node = getNode(nodeID);
146                 if ( node == null ) {
147                     var nodeTags:Object = p[3];
148                     node = new Node(nodeID, nodeVersion, nodeTags, true, lat, lon);
149                 } else if (!node.loaded) {
150                                         node.update(nodeVersion, nodeTags, true, lat, lon);
151                                 }
152                 setNode(node,true);
153                 nodes.push(node);
154                         }
155
156                         if (way==null) {
157                 way = new Way(id, version, tags, true, nodes);
158                         } else {
159                                 way.update(version, tags, true, nodes);
160                         }
161                 setWay(way,true);
162                         gotRequest(id+"way");
163                 }
164
165
166                 private function loadRelation(id:uint):void {
167                         readConnection.call("getrelation",new Responder(gotRelation, error),id);
168                 }
169
170                 private function gotRelation(r:Object):void {
171                         var code:uint = r.shift();
172             if (code) { error(new Array(r.shift())); return; }
173                         var message:String=r.shift();
174
175             var id:Number = Number(r[0]);
176                         var version:uint = uint(r[3]);
177
178             var relation:Relation = getRelation(id);
179             if ( relation != null && relation.loaded ) {
180                                 gotRequest(id+"rel");
181                                 return;
182                         }
183
184                         var tags:Object = r[1];
185             var membersAMF:Array = r[2];
186                         var members:Array = [];
187                         for each (var p:Array in membersAMF) {
188                                 var type:String=p[0];
189                                 var memid:Number=p[1];
190                                 var role:String=p[2];
191                                 var e:Entity;
192                                 switch (type) {
193                                         case 'Node':
194                                                 e=getNode(memid);
195                                                 if (e==null) { e=new Node(memid,0,{},false,0,0); setNode(Node(e),true); }
196                                                 break;
197                                         case 'Way':
198                                                 e=getWay(memid);
199                                                 if (e==null) { e=new Way(memid,0,{},false,[]); setWay(Way(e),true); }
200                                                 break;
201                                         case 'Relation':
202                                                 e=getRelation(memid);
203                                                 if (e==null) { e=new Relation(memid,0,{},false,[]); setRelation(Relation(e),true); }
204                                                 break;
205                                 }
206                                 members.push(new RelationMember(e,role));
207                         }
208                         if (relation==null) {
209                     relation = new Relation(id, version, tags, true, members);
210                         } else {
211                                 relation.update(version,tags,true,members);
212                         }
213             setRelation(relation,true);
214                         gotRequest(id+"rel");
215                 }
216                 
217                 private function gotRequest(n:String):void {
218                         for each (var c:AMFCounter in bboxrequests) {
219                                 if (c.removeRequest(n)) { break; }
220                         }
221                         while (bboxrequests.length>0 && bboxrequests[0].count==0) {
222                                 bboxrequests.shift();
223                         }
224                 }
225         }
226 }