Merge branch 'master' into icons2
[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     /**
10     * XMLBaseConnection is the common code between connecting to an OSM server
11     * (i.e. XMLConnection) and connecting to a standalone .osm file (i.e. OSMConnection)
12     * and so mainly concerns itself with /map -call-ish related matters
13     */
14         public class XMLBaseConnection extends Connection {
15
16                 public function XMLBaseConnection() {
17                 }
18                 
19         protected function loadedMap(event:Event):void {
20             var map:XML = new XML(URLLoader(event.target).data);
21             var id:Number;
22             var version:uint;
23             var uid:Number;
24             var timestamp:String;
25             var tags:Object;
26             var node:Node, newNode:Node;
27             var unusedNodes:Object={};
28
29                         var minlon:Number, maxlon:Number, minlat:Number, maxlat:Number;
30                         var singleEntityRequest:Boolean=true;
31                         if (map.bounds.@minlon.length()) {
32                                 minlon=map.bounds.@minlon;
33                                 maxlon=map.bounds.@maxlon;
34                                 minlat=map.bounds.@minlat;
35                                 maxlat=map.bounds.@maxlat;
36                                 singleEntityRequest=false;
37                         }
38
39             for each(var relData:XML in map.relation) {
40                 id = Number(relData.@id);
41                 version = uint(relData.@version);
42                 uid = Number(relData.@uid);
43                 timestamp = relData.@timestamp;
44                 
45                 var rel:Relation = getRelation(id);
46                 if ( rel == null || !rel.loaded ) {
47                     tags = parseTags(relData.tag);
48                     var members:Array = [];
49                     for each(var memberXML:XML in relData.member) {
50                         var type:String = memberXML.@type.toLowerCase();
51                         var role:String = memberXML.@role;
52                         var memberID:Number = Number(memberXML.@ref);
53                         var member:Entity = null;
54                         if ( type == "node" ) {
55                             member = getNode(memberID);
56                             if ( member == null ) {
57                                 member = new Node(memberID,0,{},false,0,0);
58                                 setNode(Node(member),true);
59                             } else if (member.isDeleted()) {
60                                 member.setDeletedState(false);
61                             }
62                         } else if ( type == "way" ) {
63                             member = getWay(memberID);
64                             if (member == null) {
65                                 member = new Way(memberID,0,{},false,[]);
66                                 setWay(Way(member),true);
67                             }
68                         } else if ( type == "relation" ) {
69                             member = getRelation(memberID);
70                             if (member == null) {
71                                 member = new Relation(memberID,0,{},false,[]);
72                                 setRelation(Relation(member),true);
73                             }
74                         }
75                         
76                         if ( member != null )
77                             members.push(new RelationMember(member, role));
78                     }
79                     
80                     if ( rel == null )
81                         setRelation(new Relation(id, version, tags, true, members, uid, timestamp), false);
82                     else {
83                         rel.update(version, tags, true, false, members, uid, timestamp);
84                         sendEvent(new EntityEvent(NEW_RELATION, rel), false);
85                     }
86                 }
87             }
88
89             for each(var nodeData:XML in map.node) {
90                                 id = Number(nodeData.@id);
91                                 node = getNode(id);
92                                 newNode = new Node(id, 
93                                                    uint(nodeData.@version), 
94                                                    parseTags(nodeData.tag),
95                                                    true, 
96                                                    Number(nodeData.@lat),
97                                                    Number(nodeData.@lon),
98                                                    Number(nodeData.@uid),
99                                                    nodeData.@timestamp);
100                                 
101                                 if ( singleEntityRequest ) {
102                                         // it's a revert request, so create/update the node
103                                         setOrUpdateNode(newNode, true);
104                                 } else if ( node == null || !node.loaded) {
105                                         // the node didn't exist before, so create/update it
106                                         newNode.parentsLoaded=newNode.within(minlon,maxlon,minlat,maxlat);
107                                         setOrUpdateNode(newNode, true);
108                                 } else {
109                                         // the node's already in memory, but store it in case one of the new ways needs it
110                                         if (newNode.within(minlon,maxlon,minlat,maxlat)) newNode.parentsLoaded=true;
111                                         unusedNodes[id]=newNode;
112                                 }
113                         }
114             
115             for each(var data:XML in map.way) {
116                 id = Number(data.@id);
117                 version = uint(data.@version);
118                 uid = Number(data.@uid);
119                 timestamp = data.@timestamp;
120
121                 var way:Way = getWay(id);
122                 if ( way == null || !way.loaded || singleEntityRequest) {
123                     var nodes:Array = [];
124                     for each(var nd:XML in data.nd) {
125                                                 var nodeid:Number=Number(nd.@ref)
126                                                 if (getNode(nodeid).isDeleted() && unusedNodes[nodeid]) { 
127                                                         setOrUpdateNode(unusedNodes[nodeid], true); 
128                                                 }
129                         nodes.push(getNode(nodeid));
130                                         }
131                     tags = parseTags(data.tag);
132                     if ( way == null ) {
133                         setWay(new Way(id, version, tags, true, nodes, uid, timestamp),false);
134                     } else {
135                                                 waycount++;
136                         way.update(version, tags, true, true, nodes, uid, timestamp);
137                         sendEvent(new EntityEvent(NEW_WAY, way), false);
138                     }
139                 }
140             }
141             
142             markBboxLoaded(minlon,maxlon,maxlat,minlat);
143             registerPOINodes();
144             dispatchEvent(new Event(LOAD_COMPLETED));
145         }
146         
147         protected function registerPOINodes():void {
148             for each (var nodeID:Number in getAllNodeIDs()) {
149                 var node:Node = getNode(nodeID);
150                 if (!node.hasParentWays)
151                     registerPOI(node);
152             }
153         }
154
155         private function parseTags(tagElements:XMLList):Object {
156             var tags:Object = {};
157             for each (var tagEl:XML in tagElements)
158                 tags[tagEl.@k] = tagEl.@v;
159             return tags;
160         }
161
162         }
163 }