1 package net.systemeD.halcyon.connection {
3 import flash.events.Event;
4 import flash.net.URLLoader;
5 import flash.net.URLRequest;
7 import flash.system.Security;
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
16 public class AMFConnection extends Connection {
18 public var readConnection:NetConnection;
19 public var writeConnection:NetConnection;
20 private var mapLoader:URLLoader;
22 private var eventTarget:AMFCounter;
23 private var bboxrequests:Array=new Array();
25 // ------------------------------------------------------------
26 // Constructor for new AMFConnection
28 public function AMFConnection() {
30 if (Connection.policyURL!='')
31 Security.loadPolicyFile(Connection.policyURL);
33 readConnection=new NetConnection();
34 readConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
35 readConnection.connect(Connection.apiBaseURL+"amf/read");
37 writeConnection=new NetConnection();
38 writeConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
39 writeConnection.connect(Connection.apiBaseURL+"amf/write");
43 override public function getEnvironment(responder:Responder):void {
44 readConnection.call("getpresets",responder,null,"en");
47 override public function loadBbox(left:Number,right:Number,
48 top:Number,bottom:Number):void {
49 readConnection.call("whichways",new Responder(gotBbox, error),left,bottom,right,top);
52 override public function sendEvent(e:*,queue:Boolean):void {
53 if (queue) { eventTarget.addEvent(e); }
54 else { dispatchEvent(e); }
57 private function gotBbox(r:Object):void {
58 var code:uint=r.shift();
60 error(new Array(r.shift()));
64 var message:String =r.shift();
65 var waylist:Array =r[0];
66 var pointlist:Array =r[1];
67 var relationlist:Array=r[2];
68 var id:Number, version:uint;
69 var requests:AMFCounter=new AMFCounter(this);
74 for each (var a:Array in relationlist) {
78 var relation:Relation = getRelation(id);
79 if ( relation == null || !relation.loaded ) {
81 requests.addRelationRequest(id);
87 for each (var w:Array in waylist) {
91 var way:Way = getWay(id);
92 if ( way == null || !way.loaded ) {
94 requests.addWayRequest(id);
100 for each (var p:Array in pointlist) {
102 version = uint(p[4]);
104 var node:Node = getNode(id);
105 if ( node == null || !node.loaded ) {
106 var lat:Number = Number(p[2]);
107 var lon:Number = Number(p[1]);
108 var tags:Object = p[3];
109 node = new Node(id, version, tags, true, lat, lon);
115 bboxrequests.push(requests);
118 private function error(r:Object):void {}
120 private function loadWay(id:Number):void {
121 readConnection.call("getway",new Responder(gotWay, error),id);
124 private function gotWay(r:Object):void {
125 var code:uint = r.shift();
127 error(new Array(r.shift()));
131 var message:String=r.shift();
132 var id:Number = Number(r[0]);
133 var version:uint = uint(r[3]);
135 var way:Way = getWay(id);
136 if ( way != null && way.loaded ) {
137 gotRequest(id+"way");
141 var nodesAMF:Array = r[1];
142 var tags:Object = r[2];
144 var nodes:Array = [];
145 for each (var p:Array in nodesAMF) {
146 var nodeID:Number = Number(p[2]);
147 var nodeVersion:uint = uint(p[4]);
148 var lon:Number = Number(p[0]);
149 var lat:Number = Number(p[1]);
151 var node:Node = getNode(nodeID);
152 if ( node == null ) {
153 var nodeTags:Object = p[3];
154 node = new Node(nodeID, nodeVersion, nodeTags, true, lat, lon);
155 } else if (!node.loaded) {
156 node.update(nodeVersion, nodeTags, true, lat, lon);
163 way = new Way(id, version, tags, true, nodes);
165 way.update(version, tags, true, nodes);
168 gotRequest(id+"way");
172 private function loadRelation(id:Number):void {
173 readConnection.call("getrelation",new Responder(gotRelation, error),id);
176 private function gotRelation(r:Object):void {
177 var code:uint = r.shift();
178 if (code) { error(new Array(r.shift())); return; }
179 var message:String=r.shift();
181 var id:Number = Number(r[0]);
182 var version:uint = uint(r[3]);
184 var relation:Relation = getRelation(id);
185 if ( relation != null && relation.loaded ) {
186 gotRequest(id+"rel");
190 var tags:Object = r[1];
191 var membersAMF:Array = r[2];
192 var members:Array = [];
193 for each (var p:Array in membersAMF) {
194 var type:String=p[0];
195 var memid:Number=p[1];
196 var role:String=p[2];
201 if (e==null) { e=new Node(memid,0,{},false,0,0); setNode(Node(e),true); }
205 if (e==null) { e=new Way(memid,0,{},false,[]); setWay(Way(e),true); }
208 e=getRelation(memid);
209 if (e==null) { e=new Relation(memid,0,{},false,[]); setRelation(Relation(e),true); }
212 members.push(new RelationMember(e,role));
214 if (relation==null) {
215 relation = new Relation(id, version, tags, true, members);
217 relation.update(version,tags,true,members);
219 setRelation(relation,true);
220 gotRequest(id+"rel");
223 private function gotRequest(n:String):void {
224 for each (var c:AMFCounter in bboxrequests) {
225 if (c.removeRequest(n)) { break; }
227 while (bboxrequests.length>0 && bboxrequests[0].count==0) {
228 bboxrequests.shift();