Merge branch 'master' into history
[potlatch2.git] / net / systemeD / halcyon / connection / XMLBaseConnection.as
1 package net.systemeD.halcyon.connection {
2
3         import flash.events.*;
4
5         import flash.system.Security;
6         import flash.net.*;
7         import org.iotashan.oauth.*;
8
9         import net.systemeD.halcyon.MapEvent;
10     import net.systemeD.halcyon.connection.bboxes.*;
11
12         /**
13         * XMLBaseConnection is the common code between connecting to an OSM server
14         * (i.e. XMLConnection) and connecting to a standalone .osm file (i.e. OSMConnection)
15         * and so mainly concerns itself with /map -call-ish related matters
16         */
17         public class XMLBaseConnection extends Connection {
18
19                 public function XMLBaseConnection(name:String,api:String,policy:String,initparams:Object) {
20                         super(name,api,policy,initparams);
21                 }
22                 
23                 protected function loadedMap(event:Event):void {
24                         var map:XML = new XML(URLLoader(event.target).data);
25                         
26                         if (map.name().localName=="osmError") {
27                                 dispatchEvent(new MapEvent(MapEvent.ERROR, { message: "Couldn't load the map: " + map.message } ));
28                         } else {
29                                 var id:Number;
30                                 var version:uint;
31                                 var uid:Number;
32                                 var timestamp:String;
33                                 var user:String;
34                                 var tags:Object;
35                                 var node:Node, newNode:Node;
36                                 var unusedNodes:Object={};
37                                 var createdEntities:Array=[];
38
39                                 var minlon:Number, maxlon:Number, minlat:Number, maxlat:Number;
40                                 var singleEntityRequest:Boolean=true;
41                                 if (map.bounds.@minlon.length()) {
42                                         minlon=map.bounds.@minlon;
43                                         maxlon=map.bounds.@maxlon;
44                                         minlat=map.bounds.@minlat;
45                                         maxlat=map.bounds.@maxlat;
46                                         singleEntityRequest=false;
47                                         fetchSet.add(new Box().fromBbox(minlon,minlat,maxlon,maxlat));
48                                 }
49
50                                 for each(var relData:XML in map.relation) {
51                                         id = Number(relData.@id);
52                                         version = uint(relData.@version);
53                                         uid = Number(relData.@uid);
54                                         timestamp = relData.@timestamp;
55                                         user = relData.@user;
56                            
57                                         var rel:Relation = getRelation(id);
58                                         if ( rel == null || !rel.loaded || singleEntityRequest ) {
59                                                 tags = parseTags(relData.tag);
60                                                 var members:Array = [];
61                                                 for each(var memberXML:XML in relData.member) {
62                                                         var type:String = memberXML.@type.toLowerCase();
63                                                         var role:String = memberXML.@role;
64                                                         var memberID:Number = Number(memberXML.@ref);
65                                                         var member:Entity = null;
66                                                         if ( type == "node" ) {
67                                                                 member = getNode(memberID);
68                                                                 if ( member == null ) {
69                                                                         member = new Node(this,memberID,0,{},false,0,0);
70                                                                         setNode(Node(member),true);
71                                                                 } else if (member.isDeleted()) {
72                                                                         member.setDeletedState(false);
73                                                                 }
74                                                         } else if ( type == "way" ) {
75                                                                 member = getWay(memberID);
76                                                                 if (member == null) {
77                                                                         member = new Way(this,memberID,0,{},false,[]);
78                                                                         setWay(Way(member),true);
79                                                                 }
80                                                         } else if ( type == "relation" ) {
81                                                                 member = getRelation(memberID);
82                                                                 if (member == null) {
83                                                                         member = new Relation(this,memberID,0,{},false,[]);
84                                                                         setRelation(Relation(member),true);
85                                                                 }
86                                                         }
87                                                 
88                                                         if ( member != null )
89                                                                 members.push(new RelationMember(member, role));
90                                                 }
91                                         
92                                                 if ( rel == null ) {
93                                                         rel=new Relation(this, id, version, tags, true, members, uid, timestamp, user);
94                                                         setRelation(rel, false);
95                                                         createdEntities.push(rel);
96                                                 } else {
97                                                         rel.update(version, tags, true, false, members, uid, timestamp, user);
98                                                         sendEvent(new EntityEvent(NEW_RELATION, rel), false);
99                                                 }
100                                         }
101                                 }
102
103                                 for each(var nodeData:XML in map.node) {
104                                         id = Number(nodeData.@id);
105                                         node = getNode(id);
106                                         newNode = new Node(this,
107                                                                            id, 
108                                                                            uint(nodeData.@version), 
109                                                                            parseTags(nodeData.tag),
110                                                                            true, 
111                                                                            Number(nodeData.@lat),
112                                                                            Number(nodeData.@lon),
113                                                                            Number(nodeData.@uid),
114                                                                            nodeData.@timestamp,
115                                                                            nodeData.@user);
116
117                     if ( inlineStatus ) { newNode.status = nodeData.@status; }
118
119                                         if ( singleEntityRequest ) {
120                                                 // it's a revert request, so create/update the node
121                                                 setOrUpdateNode(newNode, true);
122                                         } else if ( node == null || !node.loaded) {
123                                                 // the node didn't exist before, so create/update it
124                                                 newNode.parentsLoaded=newNode.within(minlon,maxlon,minlat,maxlat);
125                                                 setOrUpdateNode(newNode, true);
126                                                 createdEntities.push(newNode);
127                                         } else {
128                                                 // the node's already in memory, but store it in case one of the new ways needs it
129                                                 if (newNode.within(minlon,maxlon,minlat,maxlat)) newNode.parentsLoaded=true;
130                                                 unusedNodes[id]=newNode;
131                                         }
132                                 }
133                         
134                                 for each(var data:XML in map.way) {
135                                         id = Number(data.@id);
136                                         version = uint(data.@version);
137                                         uid = Number(data.@uid);
138                                         timestamp = data.@timestamp;
139                                         user = data.@user;
140
141                                         var way:Way = getWay(id);
142                                         if ( way == null || !way.loaded || singleEntityRequest) {
143                                                 var nodelist:Array = [];
144                                                 for each(var nd:XML in data.nd) {
145                                                         var nodeid:Number=Number(nd.@ref)
146                                                         if (getNode(nodeid).isDeleted() && unusedNodes[nodeid]) { 
147                                                                 setOrUpdateNode(unusedNodes[nodeid], true); 
148                                                         }
149                                                         nodelist.push(getNode(nodeid));
150                                                 }
151                                                 tags = parseTags(data.tag);
152                                                 if ( way == null ) {
153                                                         way=new Way(this, id, version, tags, true, nodelist, uid, timestamp, user)
154                                                         if ( inlineStatus ) { way.status = data.@status; }
155                                                         setWay(way,false);
156                                                         createdEntities.push(way);
157                                                 } else {
158                                                         if (!way.loaded) createdEntities.push(way);
159                                                         waycount++;
160                                                         way.update(version, tags, true, true, nodelist, uid, timestamp, user);
161                                                         if ( inlineStatus ) { way.status = data.@status; }
162                                                         sendEvent(new EntityEvent(NEW_WAY, way), false);
163                                                 }
164                                         }
165                                 }
166                                 registerPOINodes();
167                         }
168
169                         dispatchEvent(new Event(LOAD_COMPLETED));
170
171                         if (statusFetcher) statusFetcher.fetch(createdEntities); 
172                 }
173                 
174                 protected function registerPOINodes():void {
175                         for each (var nodeID:Number in getAllNodeIDs()) {
176                                 var node:Node = getNode(nodeID);
177                                 if (!node.hasParentWays)
178                                         registerPOI(node);
179                         }
180                 }
181
182                 protected function parseTags(tagElements:XMLList):Object {
183                         var tags:Object = {};
184                         for each (var tagEl:XML in tagElements)
185                                 tags[tagEl.@k] = tagEl.@v;
186                         return tags;
187                 }
188
189         }
190 }