Remove trace statement
[potlatch2.git] / net / systemeD / potlatch2 / utils / TrackLoader.as
1 package net.systemeD.potlatch2.utils {
2
3         import net.systemeD.halcyon.connection.*;
4         import net.systemeD.halcyon.Map;
5         import net.systemeD.halcyon.MapPaint;
6         import flash.net.*;
7         import flash.events.*;
8
9         /* still to do:
10         - empty layer on reload
11         - cope with tracks with timestamps */
12
13     /** A TrackLoader will load the public GPX traces for the current map bounding box into a separate layer */
14         public class TrackLoader {
15
16                 private var left:Number=0;
17                 private var right:Number=0;
18                 private var top:Number=0;
19                 private var bottom:Number=0;
20                 private var page:uint=0;
21
22                 private var map:Map;
23                 private var apiBaseURL:String;
24                 private var connection:Connection; /* to store the nodes/ways that are faked up for GPX tracks */
25
26                 private static const STYLESHEET:String="stylesheets/gpx.css";
27                 private static const LAYER:String="GPS tracks";
28
29                 /** Create a new TrackLoader
30                 *   @param map The map object you want to the GPS tracks layer to be added to
31                 *   @param url The url of the server api base
32                 */
33                 public function TrackLoader(map:Map, url:String) {
34                         this.map=map;
35                         apiBaseURL=url;
36                         connection = new Connection(LAYER,apiBaseURL,null, null);
37                 }
38
39                 /** Load the public traces for the current map extent
40                 *   @param keep not implemented
41                 */
42                 public function load(keep:Boolean=false):void {
43                         if (map.edge_l==left && map.edge_r==right && map.edge_t==top && map.edge_b==bottom) {
44                                 page++;
45                         } else {
46                                 left  =map.edge_l;
47                                 right =map.edge_r;
48                                 top   =map.edge_t;
49                                 bottom=map.edge_b;
50                                 page=0;
51                                 if (!keep) { } // ** TODO: blank the connection objects
52                         }
53
54             /* This isn't great - conceptially it would be nicer for the connection to do the request */
55                         var loader:URLLoader = new URLLoader();
56                         loader.load(new URLRequest(apiBaseURL+"trackpoints?bbox="+left+","+bottom+","+right+","+top+"&page="+page));
57                         loader.addEventListener(Event.COMPLETE, parseGPX);
58                 }
59
60                 private function parseGPX(event:Event):void {
61                         var file:XML = new XML(event.target.data);
62                         var action:CompositeUndoableAction = new CompositeUndoableAction("add track objects");
63                         for each (var ns:Namespace in file.namespaceDeclarations()) {
64                                 if (ns.uri.match(/^http:\/\/www\.topografix\.com\/GPX\/1\/[01]$/)) {
65                                         default xml namespace = ns;
66                                 }
67                         }
68
69                         for each (var trkseg:XML in file..trkseg) {
70                                 var nodestring:Array = [];
71                                 var lat:Number = NaN, lastlat:Number = NaN;
72                                 var lon:Number = NaN, lastlon:Number = NaN;
73                 for each (var trkpt:XML in trkseg.trkpt) {
74                                         lat = trkpt.@lat;
75                     lon = trkpt.@lon;
76                     if (lastlat && nodestring.length > 0 && greatCircle(lat, lon, lastlat, lastlon) > 30) {
77                         connection.createWay({}, nodestring, action.push);
78                         nodestring = [];
79                     }
80                     nodestring.push(connection.createNode({}, lat, lon, action.push));
81                     lastlat = lat; lastlon = lon;
82                                 }
83                 if (nodestring.length > 0) { connection.createWay({}, nodestring, action.push); trace("create way");}
84                         }
85
86             action.doAction(); /* just do it, don't add to undo stack */
87                         default xml namespace = new Namespace("");
88                         layer.updateEntityUIs(false, false);
89                 }
90
91                 private function get layer():MapPaint {
92             var mp:MapPaint = map.findLayer(LAYER);
93             if (!mp) {
94                 mp = map.addLayer(connection, STYLESHEET);
95             }
96             return mp;
97                 }
98                 
99                 private function greatCircle(lat1:Number,lon1:Number,lat2:Number,lon2:Number):Number {
100                         var dlat:Number=(lat2-lat1)*Math.PI/180;
101                         var dlon:Number=(lon2-lon1)*Math.PI/180;
102                         var a:Number=Math.pow(Math.sin(dlat / 2),2) + 
103                                      Math.cos(lat1*Math.PI/180) * 
104                                      Math.cos(lat2*Math.PI/180) * 
105                                      Math.pow(Math.sin(dlon / 2),2);
106                         a=Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
107                         return a*3958.75*1609;
108                 }
109                 
110         }
111 }