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