support GPX 1.1 too
[potlatch2.git] / net / systemeD / halcyon / connection / Trace.as
1 package net.systemeD.halcyon.connection {
2
3     import flash.events.EventDispatcher;
4     import flash.utils.Dictionary;
5     import flash.events.*;
6     import flash.net.URLLoader;
7
8     import net.systemeD.halcyon.connection.*;
9     import net.systemeD.halcyon.Map;
10     import net.systemeD.halcyon.Globals;
11     import net.systemeD.halcyon.VectorLayer;
12
13     /**
14     * Implements trace objects loaded from the OSM API.
15     * See also potlatch2's utils GpxImporter.as and Importer.as classes, which can handle
16     * loading GPX files (and other formats) from arbitrary urls.
17     */
18     public class Trace extends EventDispatcher {
19         private var _id:Number;
20         private var _description:String;
21         private var tags:Array = []; // N.B. trace tags are NOT k/v pairs
22         private var _isLoaded:Boolean;
23         private var _filename:String;
24         private var _traceData:String;
25         private var map:Map;
26         private var _layer:VectorLayer;
27         private var simplify:Boolean = false;
28
29         private static const STYLESHEET:String="gpx.css";
30
31         public function Trace() {
32             map = Globals.vars.root;
33         }
34
35         /* Create a new trace, from the XML description given by the user/traces call */
36         public function fromXML(xml:XML):Trace {
37             _id = Number(xml.@id);
38             _filename = xml.@name;
39             _description = xml.description;
40             for each(var tag:XML in xml.tag) {
41               tags.push(String(tag));
42             }
43             return this;
44         }
45
46         public function get id():Number {
47             return _id;
48         }
49
50         public function get description():String {
51             return _description;
52         }
53
54         public function get filename():String {
55             return _filename;
56         }
57
58         public function get tagsText():String {
59             return tags.join(", ");
60         }
61
62         private function fetchFromServer():void {
63             // todo - needs proper error handling
64             Connection.getConnectionInstance().fetchTrace(id, saveTraceData);
65             dispatchEvent(new Event("loading_data"));
66         }
67
68         private function saveTraceData(event:Event):void {
69             _traceData = String(URLLoader(event.target).data);
70             dispatchEvent(new Event("loaded_data"));
71         }
72
73         private function get layer():VectorLayer {
74             if (!_layer) {
75                 _layer=new VectorLayer(filename,map,STYLESHEET);
76                 map.addVectorLayer(_layer);
77             }
78             return _layer;
79         }
80
81         public function addToMap():void {
82             // this allows adding and removing traces from the map, without re-downloading
83             // the data from the server repeatedly.
84             if (!_isLoaded) {
85               addEventListener("loaded_data", processEvent);
86               fetchFromServer();
87               return;
88             } else {
89               process();
90             }
91         }
92
93         public function removeFromMap():void {
94             //todo
95         }
96
97         private function processEvent(e:Event):void {
98             process();
99         }
100
101         private function process():void {
102             var file:XML = new XML(_traceData);
103                         for each (var ns:Namespace in file.namespaceDeclarations()) {
104                                 if (ns.uri.match(/^http:\/\/www\.topografix\.com\/GPX\/1\/[01]$/)) {
105                                         default xml namespace = ns;
106                                 }
107                         }
108
109             for each (var trkseg:XML in file..trkseg) {
110                 var way:Way;
111                 var nodestring:Array = [];
112                 for each (var trkpt:XML in trkseg.trkpt) {
113                     nodestring.push(layer.createNode({}, trkpt.@lat, trkpt.@lon));
114                 }
115                 if (nodestring.length > 0) {
116                     way = layer.createWay({}, nodestring);
117                     //if (simplify) { Simplify.simplify(way, paint.map, false); }
118                 }
119             }
120
121             for each (var wpt:XML in file.wpt) {
122                 var tags:Object = {};
123                 for each (var tag:XML in wpt.children()) {
124                     tags[tag.name().localName]=tag.toString();
125                 }
126                 var node:Node = layer.createNode(tags, wpt.@lat, wpt.@lon);
127                                 layer.registerPOI(node);
128             }
129
130             layer.paint.updateEntityUIs(layer.getObjectsByBbox(map.edge_l,map.edge_r,map.edge_t,map.edge_b), true, false);
131         }
132     }
133 }