2835030a4f18679bb943217d5619c0c1e0dc4a3f
[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.VectorLayer;
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         public class TrackLoader {
14
15                 private var left:Number=0;
16                 private var right:Number=0;
17                 private var top:Number=0;
18                 private var bottom:Number=0;
19                 private var page:uint=0;
20
21                 private var map:Map;
22                 private var apiBaseURL:String;
23
24                 private static const STYLESHEET:String="stylesheets/gpx.css";
25                 
26                 public function TrackLoader(map:Map, url:String) {
27                         this.map=map;
28                         apiBaseURL=url;
29                 }
30                 
31                 public function load(keep:Boolean=false):void {
32                         if (map.edge_l==left && map.edge_r==right && map.edge_t==top && map.edge_b==bottom) {
33                                 page++;
34                         } else {
35                                 left  =map.edge_l;
36                                 right =map.edge_r;
37                                 top   =map.edge_t;
38                                 bottom=map.edge_b;
39                                 page=0;
40                                 if (!keep) { } // ** TODO: blank the vector layer
41                         }
42
43                         var loader:URLLoader = new URLLoader();
44                         loader.load(new URLRequest(apiBaseURL+"trackpoints?bbox="+left+","+bottom+","+right+","+top+"&page="+page));
45                         loader.addEventListener(Event.COMPLETE, parseGPX);
46                 }
47
48                 public function parseGPX(event:Event):void {
49                         var file:XML = new XML(event.target.data);
50                         for each (var ns:Namespace in file.namespaceDeclarations()) {
51                                 if (ns.uri.match(/^http:\/\/www\.topografix\.com\/GPX\/1\/[01]$/)) {
52                                         default xml namespace = ns;
53                                 }
54                         }
55
56                         for each (var trkseg:XML in file..trkseg) {
57                                 var nodestring:Array = [];
58                                 var lat:Number = NaN, lastlat:Number = NaN;
59                                 var lon:Number = NaN, lastlon:Number = NaN;
60                 for each (var trkpt:XML in trkseg.trkpt) {
61                                         lat = trkpt.@lat;
62                     lon = trkpt.@lon;
63                     if (lastlat && nodestring.length > 0 && greatCircle(lat, lon, lastlat, lastlon) > 30) {
64                         layer.createWay({}, nodestring);
65                         nodestring = [];
66                     }
67                     nodestring.push(layer.createNode({}, lat, lon));
68                     lastlat = lat; lastlon = lon;
69                                 }
70                 if (nodestring.length > 0) { layer.createWay({}, nodestring); }
71                         }
72             
73                         default xml namespace = new Namespace("");
74                         layer.paint.updateEntityUIs(false, false);
75                 }
76
77                 private function get layer():VectorLayer {
78                         // >>>> REFACTOR: VectorLayer commented out
79                         // var vl:VectorLayer=map.findVectorLayer('GPS tracks');
80                         // if (!vl) {
81                         //      vl=new VectorLayer('GPS tracks',map,STYLESHEET);
82                         //      map.addVectorLayer(vl);
83                         // }
84                         // return vl;
85                         return null;
86                 }
87                 
88                 private function greatCircle(lat1:Number,lon1:Number,lat2:Number,lon2:Number):Number {
89                         var dlat:Number=(lat2-lat1)*Math.PI/180;
90                         var dlon:Number=(lon2-lon1)*Math.PI/180;
91                         var a:Number=Math.pow(Math.sin(dlat / 2),2) + 
92                                      Math.cos(lat1*Math.PI/180) * 
93                                      Math.cos(lat2*Math.PI/180) * 
94                                      Math.pow(Math.sin(dlon / 2),2);
95                         a=Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
96                         return a*3958.75*1609;
97                 }
98                 
99         }
100 }