Merge branch 'master' of github.com:systemed/potlatch2
[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 csData:XML in map.changeset) {
51                                         var cs:Changeset = new Changeset(this, csData.@id, parseTags(csData.tag) );
52                                         setChangeset(cs);
53                                 }
54
55                                 for each(var relData:XML in map.relation) {
56                                         id = Number(relData.@id);
57                                         version = uint(relData.@version);
58                                         uid = Number(relData.@uid);
59                                         timestamp = relData.@timestamp;
60                                         user = relData.@user;
61                            
62                                         var rel:Relation = getRelation(id);
63                                         if ( rel == null || !rel.loaded || singleEntityRequest ) {
64                                                 tags = parseTags(relData.tag);
65                                                 var members:Array = [];
66                                                 for each(var memberXML:XML in relData.member) {
67                                                         var type:String = memberXML.@type.toLowerCase();
68                                                         var role:String = memberXML.@role;
69                                                         var memberID:Number = Number(memberXML.@ref);
70                                                         var member:Entity = null;
71                                                         if ( type == "node" ) {
72                                                                 member = getNode(memberID);
73                                                                 if ( member == null ) {
74                                                                         member = new Node(this,memberID,0,{},false,0,0);
75                                                                         setNode(Node(member),true);
76                                                                 } else if (member.isDeleted()) {
77                                                                         member.setDeletedState(false);
78                                                                 }
79                                                         } else if ( type == "way" ) {
80                                                                 member = getWay(memberID);
81                                                                 if (member == null) {
82                                                                         member = new Way(this,memberID,0,{},false,[]);
83                                                                         setWay(Way(member),true);
84                                                                 }
85                                                         } else if ( type == "relation" ) {
86                                                                 member = getRelation(memberID);
87                                                                 if (member == null) {
88                                                                         member = new Relation(this,memberID,0,{},false,[]);
89                                                                         setRelation(Relation(member),true);
90                                                                 }
91                                                         }
92                                                 
93                                                         if ( member != null )
94                                                                 members.push(new RelationMember(member, role));
95                                                 }
96                                         
97                                                 if ( rel == null ) {
98                                                         rel=new Relation(this, id, version, tags, true, members, uid, timestamp, user);
99                                                         setRelation(rel, false);
100                                                         createdEntities.push(rel);
101                                                 } else {
102                                                         rel.update(version, tags, true, false, members, uid, timestamp, user);
103                                                         sendEvent(new EntityEvent(NEW_RELATION, rel), false);
104                                                 }
105                                         }
106                                 }
107
108                                 for each(var nodeData:XML in map.node) {
109                                         id = Number(nodeData.@id);
110                                         node = getNode(id);
111                                         newNode = new Node(this,
112                                                                            id, 
113                                                                            uint(nodeData.@version), 
114                                                                            parseTags(nodeData.tag),
115                                                                            true, 
116                                                                            Number(nodeData.@lat),
117                                                                            Number(nodeData.@lon),
118                                                                            Number(nodeData.@uid),
119                                                                            nodeData.@timestamp,
120                                                                            nodeData.@user);
121
122                     if ( inlineStatus ) { newNode.status = nodeData.@status; }
123
124                                         if ( singleEntityRequest ) {
125                                                 // it's a revert request, so create/update the node
126                                                 setOrUpdateNode(newNode, true);
127                                         } else if ( node == null || !node.loaded) {
128                                                 // the node didn't exist before, so create/update it
129                                                 newNode.parentsLoaded=newNode.within(minlon,maxlon,minlat,maxlat);
130                                                 setOrUpdateNode(newNode, true);
131                                                 createdEntities.push(newNode);
132                                         } else {
133                                                 // the node's already in memory, but store it in case one of the new ways needs it
134                                                 if (newNode.within(minlon,maxlon,minlat,maxlat)) newNode.parentsLoaded=true;
135                                                 unusedNodes[id]=newNode;
136                                         }
137                                 }
138                         
139                                 for each(var data:XML in map.way) {
140                                         id = Number(data.@id);
141                                         version = uint(data.@version);
142                                         uid = Number(data.@uid);
143                                         timestamp = data.@timestamp;
144                                         user = data.@user;
145
146                                         var way:Way = getWay(id);
147                                         if ( way == null || !way.loaded || singleEntityRequest) {
148                                                 var nodelist:Array = [];
149                                                 for each(var nd:XML in data.nd) {
150                                                         var nodeid:Number=Number(nd.@ref)
151                                                         if (getNode(nodeid).isDeleted() && unusedNodes[nodeid]) { 
152                                                                 setOrUpdateNode(unusedNodes[nodeid], true); 
153                                                         }
154                                                         nodelist.push(getNode(nodeid));
155                                                 }
156                                                 tags = parseTags(data.tag);
157                                                 if ( way == null ) {
158                                                         way=new Way(this, id, version, tags, true, nodelist, uid, timestamp, user)
159                                                         if ( inlineStatus ) { way.status = data.@status; }
160                                                         setWay(way,false);
161                                                         createdEntities.push(way);
162                                                 } else {
163                                                         if (!way.loaded) createdEntities.push(way);
164                                                         waycount++;
165                                                         way.update(version, tags, true, true, nodelist, uid, timestamp, user);
166                                                         if ( inlineStatus ) { way.status = data.@status; }
167                                                         sendEvent(new EntityEvent(NEW_WAY, way), false);
168                                                 }
169                                         }
170                                 }
171                                 registerPOINodes();
172                         }
173
174                         dispatchEvent(new Event(LOAD_COMPLETED));
175
176                         if (statusFetcher) statusFetcher.fetch(createdEntities); 
177                 }
178                 
179                 protected function parseTags(tagElements:XMLList):Object {
180                         var tags:Object = {};
181                         for each (var tagEl:XML in tagElements)
182                                 tags[tagEl.@k] = tagEl.@v;
183                         return tags;
184                 }
185
186         }
187 }