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(name:String,api:String,policy:String,initparams:Object) {
30 super(name,api,policy,initparams);
31 if (Connection.policyURL!='')
32 Security.loadPolicyFile(Connection.policyURL);
34 readConnection=new NetConnection();
35 readConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
36 readConnection.connect(Connection.apiBaseURL+"amf/read");
38 writeConnection=new NetConnection();
39 writeConnection.objectEncoding = flash.net.ObjectEncoding.AMF0;
40 writeConnection.connect(Connection.apiBaseURL+"amf/write");
44 override public function getEnvironment(responder:Responder):void {
45 readConnection.call("getpresets",responder,null,"en");
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);
53 override public function sendEvent(e:*,queue:Boolean):void {
54 if (queue) { eventTarget.addEvent(e); }
55 else { dispatchEvent(e); }
58 private function gotBbox(r:Object):void {
59 var code:uint=r.shift();
61 error(new Array(r.shift()));
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);
75 for each (var a:Array in relationlist) {
79 var relation:Relation = getRelation(id);
80 if ( relation == null || !relation.loaded ) {
82 requests.addRelationRequest(id);
88 for each (var w:Array in waylist) {
92 var way:Way = getWay(id);
93 if ( way == null || !way.loaded ) {
95 requests.addWayRequest(id);
101 for each (var p:Array in pointlist) {
103 version = uint(p[4]);
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(id, version, tags, true, lat, lon);
116 bboxrequests.push(requests);
119 private function error(r:Object):void {}
121 private function loadWay(id:Number):void {
122 readConnection.call("getway",new Responder(gotWay, error),id);
125 private function gotWay(r:Object):void {
126 var code:uint = r.shift();
128 error(new Array(r.shift()));
132 var message:String=r.shift();
133 var id:Number = Number(r[0]);
134 var version:uint = uint(r[3]);
136 var way:Way = getWay(id);
137 if ( way != null && way.loaded ) {
138 gotRequest(id+"way");
142 var nodesAMF:Array = r[1];
143 var tags:Object = r[2];
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]);
152 var node:Node = getNode(nodeID);
153 if ( node == null ) {
154 var nodeTags:Object = p[3];
155 node = new Node(nodeID, nodeVersion, nodeTags, true, lat, lon);
156 } else if (!node.loaded) {
157 node.update(nodeVersion, nodeTags, true, false, lat, lon);
164 way = new Way(id, version, tags, true, nodes);
166 way.update(version, tags, true, true, nodes);
169 gotRequest(id+"way");
173 private function loadRelation(id:Number):void {
174 readConnection.call("getrelation",new Responder(gotRelation, error),id);
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();
182 var id:Number = Number(r[0]);
183 var version:uint = uint(r[3]);
185 var relation:Relation = getRelation(id);
186 if ( relation != null && relation.loaded ) {
187 gotRequest(id+"rel");
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];
202 if (e==null) { e=new Node(memid,0,{},false,0,0); setNode(Node(e),true); }
206 if (e==null) { e=new Way(memid,0,{},false,[]); setWay(Way(e),true); }
209 e=getRelation(memid);
210 if (e==null) { e=new Relation(memid,0,{},false,[]); setRelation(Relation(e),true); }
213 members.push(new RelationMember(e,role));
215 if (relation==null) {
216 relation = new Relation(id, version, tags, true, members);
218 relation.update(version,tags,true,false,members);
220 setRelation(relation,true);
221 gotRequest(id+"rel");
224 private function gotRequest(n:String):void {
225 for each (var c:AMFCounter in bboxrequests) {
226 if (c.removeRequest(n)) { break; }
228 while (bboxrequests.length>0 && bboxrequests[0].count==0) {
229 bboxrequests.shift();