load GPS tracks from server, needs a bit of refinement still but the basics are there
authorRichard Fairhurst <richard@systemed.net>
Sun, 8 Aug 2010 14:36:05 +0000 (14:36 +0000)
committerRichard Fairhurst <richard@systemed.net>
Sun, 8 Aug 2010 14:36:05 +0000 (14:36 +0000)
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/connection/Connection.as
net/systemeD/potlatch2/VectorSourceDialog.mxml
net/systemeD/potlatch2/utils/TrackLoader.as [new file with mode: 0644]
potlatch2.mxml

index c4c0420..833c656 100755 (executable)
@@ -289,6 +289,14 @@ package net.systemeD.halcyon {
                                
         }
 
+               // ------------------------------------------------------------------------------------------
+               // Add vector layer
+               
+               public function addVectorLayer(layer:VectorLayer):void {
+                       vectorlayers[layer.name]=layer;
+                       vectorbg.addChild(layer.paint);
+               }
+
                // ------------------------------------------------------------------------------------------
                // Redraw all items, zoom in and out
                
index 5875b7e..f036907 100755 (executable)
@@ -37,7 +37,7 @@ package net.systemeD.halcyon.connection {
             return params[name] == null ? defaultValue : params[name];
         }
 
-        public static function get apiBase():String {
+        public function get apiBase():String {
             return apiBaseURL;
         }
 
index f1affdd..d626b3b 100644 (file)
                var names:Array=url.split('/'); var name:String=names[names.length-1];
                var vectorlayer:VectorLayer=new VectorLayer(name,map,"potlatch.css");
                vectorlayer.url=url;
-               map.vectorlayers[name]=vectorlayer;
-               map.vectorbg.addChild(vectorlayer.paint);
+               map.addVectorLayer(vectorlayer);
 
                if (type=='gpx') {
                        var gpx:GpxImporter=new GpxImporter(vectorlayer, vectorlayer.paint, [url], filesLoaded, simplify);
diff --git a/net/systemeD/potlatch2/utils/TrackLoader.as b/net/systemeD/potlatch2/utils/TrackLoader.as
new file mode 100644 (file)
index 0000000..69bbb0b
--- /dev/null
@@ -0,0 +1,94 @@
+package net.systemeD.potlatch2.utils {
+
+       import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.VectorLayer;
+       import flash.net.*;
+       import flash.events.*;
+
+       public class TrackLoader {
+
+               private var left:Number=0;
+               private var right:Number=0;
+               private var top:Number=0;
+               private var bottom:Number=0;
+               private var page:uint=0;
+               private var _layer:VectorLayer;
+
+               private var map:Map;
+               private var apiBaseURL:String;
+
+               private static const STYLESHEET:String="wireframe.css";
+               
+               public function TrackLoader(map:Map, url:String) {
+                       this.map=map;
+                       apiBaseURL=url;
+               }
+               
+               public function load(keep:Boolean=false):void {
+                       if (map.edge_l==left && map.edge_r==right && map.edge_t==top && map.edge_b==bottom) {
+                               page++;
+                       } else {
+                               left  =map.edge_l;
+                               right =map.edge_r;
+                               top   =map.edge_t;
+                               bottom=map.edge_b;
+                               page=0;
+                               if (!keep) { } // ** TODO: blank the vector layer
+                       }
+
+                       var loader:URLLoader = new URLLoader();
+                       loader.load(new URLRequest(apiBaseURL+"trackpoints?bbox="+left+","+bottom+","+right+","+top+"&page="+page));
+                       loader.addEventListener(Event.COMPLETE, parseGPX);
+               }
+
+               public function parseGPX(event:Event):void {
+                       var xmlnsPattern:RegExp = new RegExp("xmlns[^\"]*\"[^\"]*\"", "gi");
+                       var xsiPattern:RegExp = new RegExp("xsi[^\"]*\"[^\"]*\"", "gi");
+                       var raw:String = String(event.target.data).replace(xmlnsPattern, "").replace(xsiPattern, "");
+                       var file:XML=new XML(raw);
+
+                       for each (var trk:XML in file.child("trk")) {
+                               for each (var trkseg:XML in trk.child("trkseg")) {
+                                       var nodestring:Array=[];
+                                       var lat:Number=NaN, lastlat:Number=NaN;
+                                       var lon:Number=NaN, lastlon:Number=NaN;
+                                       for each (var trkpt:XML in trkseg.child("trkpt")) {
+                                               lat=trkpt.@lat;
+                                               lon=trkpt.@lon;
+                                               if (lastlat && nodestring.length>0 && greatCircle(lat,lon,lastlat,lastlon)>30) {
+                                                       layer.createWay({}, nodestring);
+                                                       nodestring=[];
+                                               }
+                                               nodestring.push(layer.createNode({}, lat, lon));
+                                               lastlat=lat; lastlon=lon;
+                                       }
+                                       if (nodestring.length>0) { layer.createWay({}, nodestring); }
+                               }
+                       }
+                       layer.paint.updateEntityUIs(layer.getObjectsByBbox(left,right,top,bottom), false, false);
+               }
+
+               
+               private function get layer():VectorLayer {
+                       if (!_layer) {
+                               var n:String='GPS tracks';
+                               _layer=new VectorLayer(n,map,STYLESHEET);
+                               map.addVectorLayer(_layer);
+                       }
+                       return _layer;
+               }
+               
+               private function greatCircle(lat1:Number,lon1:Number,lat2:Number,lon2:Number):Number {
+                       var dlat:Number=(lat2-lat1)*Math.PI/180;
+                       var dlon:Number=(lon2-lon1)*Math.PI/180;
+                       var a:Number=Math.pow(Math.sin(dlat / 2),2) + 
+                                    Math.cos(lat1*Math.PI/180) * 
+                                    Math.cos(lat2*Math.PI/180) * 
+                                    Math.pow(Math.sin(dlon / 2),2);
+                       a=Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
+                       return a*3958.75*1609;
+               }
+               
+       }
+}
index d1ac89a..5866bb0 100755 (executable)
@@ -29,6 +29,7 @@
             creationComplete="bgButton.popUp = new BackgroundSelector();"/>
         <mx:PopUpButton id="styleButton" label="Map Style" openAlways="true"
             creationComplete="styleButton.popUp = new StyleSelector();"/>
+        <mx:Button label="GPS" click="trackLoader.load();"/>
         <mx:Spacer width="100%"/>
         <mx:Button label="Undo" click="MainUndoStack.getGlobalStack().undo();"
             enabled="{MainUndoStack.getGlobalStack().canUndo()}"/>
@@ -86,6 +87,7 @@
         public var theMap:Map;
         public var theController:EditController;
                public var yahoo:Yahoo;
+               public var trackLoader:TrackLoader;
                public var toolbox:Toolbox;
 
                private var savecount:uint=0;
             conn.addEventListener(Connection.SAVE_COMPLETED, onDataComplete);
             conn.addEventListener(Connection.DATA_DIRTY, onDataDirty);
             conn.addEventListener(Connection.DATA_CLEAN, onDataClean);
+
+                       // create GPS trackloader
+                       trackLoader=new TrackLoader(theMap,conn.apiBase);
                }
                
         public function onResizeMap():void {