Refactoring importers
authorRichard Fairhurst <richard@systemeD.net>
Sun, 25 Mar 2012 12:53:31 +0000 (13:53 +0100)
committerRichard Fairhurst <richard@systemeD.net>
Sun, 25 Mar 2012 12:53:31 +0000 (13:53 +0100)
net/systemeD/potlatch2/collections/VectorBackgrounds.as
net/systemeD/potlatch2/dialogs/VectorSourceDialog.mxml
net/systemeD/potlatch2/utils/GpxImporter.as
net/systemeD/potlatch2/utils/Importer.as
net/systemeD/potlatch2/utils/KmlImporter.as
net/systemeD/potlatch2/utils/OsmImporter.as
net/systemeD/potlatch2/utils/ShpImporter.as
potlatch2.mxml

index 34a4fcc..9b64e3a 100644 (file)
@@ -75,13 +75,14 @@ package net.systemeD.potlatch2.collections {
                                                                                var gpx_url:String = String(set.url);
 
                                                                                var connection:Connection = new Connection(name, gpx_url, null, null);
-                                                                               var gpx:GpxImporter=new GpxImporter(connection, _map, [gpx_url],
+                                                                               var gpx:GpxImporter=new GpxImporter(connection, _map, 
                                                                                function(success:Boolean,message:String=null):void {
                                                                                        if (!success) return;
                                                                                        var paint:MapPaint = _map.addLayer(connection, "stylesheets/gpx.css");
                                                                                        paint.updateEntityUIs(false, false);
                                                                                        dispatchEvent(new Event("layers_changed"));
                                                                                }, false);
+                                                                               gpx.importFromRemoteFiles([gpx_url]);
                                                                        } else {
                                                                        trace("VectorBackgrounds: configured but not loaded isn't supported yet");
                                                                        }
index fd049da..6ba72e0 100644 (file)
@@ -5,7 +5,7 @@
                xmlns:s="library://ns.adobe.com/flex/spark"
         layout="vertical" showCloseButton="true"
         horizontalAlign="center" title="Load vector file"
-        width="600" height="450" verticalGap="0">
+        width="630" height="450" verticalGap="0">
 
        <mx:DataGrid editable="true" width="100%" height="100%" id="dataGrid" 
                dataProvider="{vectorLayers}" itemEditEnd="dataEdited(event)">
 
         <s:FormItem label="File:">
                        <s:HGroup>
+                               <s:Button label="Open..." click="loadFileLocal()" />
+                               <s:Rect width="20" height="1" />
                    <s:TextInput id="src" text="" change="selectByExtension()" />
-                               <s:Button label="Fetch" click="loadFiles(src.text, filetype.selectedValue.toString(), simplify.selected, projection.selectedItem.data);" enabled="{src.text == '' ? false : true}"/>
+                               <s:Button label="Fetch" click="loadFiles(src.text);" enabled="{src.text == '' ? false : true}"/>
                        </s:HGroup>
             <s:helpContent><s:Label text="URL of file to load" /></s:helpContent>
         </s:FormItem>
 
         <s:FormItem label="Tag transform:">
                        <s:HGroup>
+                               <s:Button label="Open..." />
+                               <s:Rect width="20" height="1" />
                                <s:TextInput id="transformsrc" text="{CSSTransform.getInstance().url}"/>
                                <s:Button label="Fetch" click="loadTransform(transformsrc.text);" enabled="{transformsrc.text == '' ? false : true}"/>
                                <s:Button label="Clear" click="clearTransform();"                 enabled="{transformsrc.text == '' ? false : true}"/>
                return v;
        }
        
+       private function get selectedType():String {
+               return filetype.selectedValue.toString();
+       }
+       
        private function toggleVisibility(event:Event):void {
                map.findLayer(dataGrid.selectedItem.name).visible = !map.findLayer(dataGrid.selectedItem.name).visible;
        }
         PopUpManager.removePopUp(this);
     }
 
-       private function loadFiles(url:String,type:String,simplify:Boolean,projection:String=""):void {
+       /** Launch importer for remotely hosted files. */
+       private function loadFiles(url:String):void {
                var names:Array=url.split('/'); var name:String=names[names.length-1];
-               var stylesheet:String="stylesheets/potlatch.css";
-               if (type=='gpx') { stylesheet="stylesheets/gpx.css"; }
-
                var connection:Connection = new Connection(name, url, null, null, CSSTransform.getInstance());
-
-               var filesLoaded:Function = function(success:Boolean,message:String=null):void {
-                       if (success) {
-                               var paint:MapPaint = map.addLayer(connection, stylesheet);
-                               paint.updateEntityUIs(false, false);
-                               dispatchEvent(new Event("layers_changed"));
-                       } else {
-                               Alert.show(message, 'Error', mx.controls.Alert.OK);
-                       }
+               var importer:Importer = findImporter(connection);
+               if (selectedType=='shp') {
+                       importer.importFromRemoteFiles([url]);
+               } else {
+                       var re:RegExp=/.shp$/i; url=url.replace(re,'');
+                       importer.importFromRemoteFiles([url+".shp",url+".shx",url+".dbf"]);
                }
+       }
+       
+       /** Present an 'Open File' dialogue. */
+       private function loadFileLocal():void {
+               var file:FileReference=new FileReference(); 
+               var fileTypes:FileFilter=new FileFilter("*."+selectedType, "*."+selectedType); 
+               file.browse([fileTypes]); 
+               file.addEventListener(Event.SELECT, selectFileLocal);
+       }
+       
+       /** The user has chosen a file in the local 'Open File' dialogue. */
+       private function selectFileLocal(event:Event):void {
+               var connection:Connection = new Connection(name, url, null, null, CSSTransform.getInstance());
+               var importer:Importer = findImporter(connection);
+               importer.importFromLocalFile();
+       }
+       
+       /** Create an Importer object of the type selected by the user. */
+       private function findImporter(connection:Connection):Importer {
+               var simplifyPath:Boolean=simplify.selected;
+               var reproject:String=projection.selectedItem.data;
+               var stylesheet:String="stylesheets/potlatch.css"; if (selectedType=='gpx') { stylesheet="stylesheets/gpx.css"; }
 
-               if (type=='gpx') {
-                       var gpx:GpxImporter=new GpxImporter(connection, map, [url], filesLoaded, simplify);
-               } else if (type=='kml') {
-                       var kml:KmlImporter=new KmlImporter(connection, map, [url], filesLoaded, simplify);
-               } else if (type=='osm') {
-                       var osm:OsmImporter=new OsmImporter(connection, map, [url], filesLoaded, simplify);
+               switch (selectedType) {
+                       case 'gpx':     return new GpxImporter(connection, map, filesLoaded, simplifyPath, { stylesheet: stylesheet });
+                       case 'kml':     return new KmlImporter(connection, map, filesLoaded, simplifyPath, { stylesheet: stylesheet });
+                       case 'osm': return new OsmImporter(connection, map, filesLoaded, simplifyPath, { stylesheet: stylesheet });
+                       case 'shp': return new ShpImporter(connection, map, filesLoaded, simplifyPath, { stylesheet: stylesheet, projection: reproject });
+               }
+               return null;
+       }
+       
+       /** Callback routine when import has completed. */
+       private function filesLoaded(connection:Connection,options:Object,success:Boolean,message:String=null):void {
+               if (success) {
+                       var paint:MapPaint = map.addLayer(connection, options['stylesheet']);
+                       paint.updateEntityUIs(false, false);
+                       dispatchEvent(new Event("layers_changed"));
                } else {
-                       /* FIXME: 
-                          we're currently hardcoding the projection values. We could populate this directly from 
-                          proj4as, or better still, parse the WKT in the .PRJ file:
-                                       http://trac.osgeo.org/proj4js/ticket/47
-                                       http://trac.osgeo.org/proj4js/changeset/1873
-                       */
-                       var re:RegExp=/.shp$/i; url=url.replace(re,'');
-                       var shp:ShpImporter=new ShpImporter(connection,
-                                                           map,
-                                                           [url+".shp",url+".shx",url+".dbf"], filesLoaded, simplify, projection);
+                       Alert.show(message, 'Error', mx.controls.Alert.OK);
                }
        }
        
index 5f0816c..88dba75 100644 (file)
@@ -12,8 +12,8 @@ package net.systemeD.potlatch2.utils {
     */
        public class GpxImporter extends Importer {
 
-               public function GpxImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false) {
-                       super(connection,map,filenames,callback,simplify);
+               public function GpxImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
+                       super(connection,map,callback,simplify,options);
                }
 
                override protected function doImport(push:Function): void {
index 665e627..4068072 100644 (file)
@@ -14,22 +14,25 @@ package net.systemeD.potlatch2.utils {
         protected var map:Map;                  // map being used - used only in Simplify calls
 
                public var files:Array=[];
-               protected var filenames:Array;
+               protected var filenames:Array;                  // array of filenames _or_ FileReference objects
                protected var filesloaded:uint=0;
                protected var callback:Function;
                protected var simplify:Boolean;
+               protected var options:Object;
 
-               public function Importer(connection:Connection, map:Map, filenames:Array, callback:Function, simplify:Boolean) {
+               public function Importer(connection:Connection, map:Map, callback:Function, simplify:Boolean, options:Object) {
                        this.connection = connection;
                        this.map = map;
-                       this.filenames=filenames;
                        this.callback=callback;
                        this.simplify=simplify;
-
+                       this.options=options;
+               }
+               
+               public function importFromRemoteFiles(filenames:Array):void {
+                       this.filenames=filenames;
                        // Use forEach to avoid closure problem (http://stackoverflow.com/questions/422784/how-to-fix-closure-problem-in-actionscript-3-as3#3971784)
-                       filenames.forEach(function(fn:String, index:int, array:Array):void {
+                       filenames.forEach(function(file:*, index:int, array:Array):void {
                                trace("requesting file "+index);
-                               var request:URLRequest = new URLRequest(fn);
                                var loader:URLLoader = new URLLoader();
                                loader.dataFormat=URLLoaderDataFormat.BINARY;
                                loader.addEventListener(Event.COMPLETE,function(e:Event):void { fileLoaded(e,index); });
@@ -37,10 +40,14 @@ package net.systemeD.potlatch2.utils {
                                        loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler);
                                        loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler);
                                }
-                               loader.load(request);
+                               loader.load(new URLRequest(file));
                        });
                }
                
+               public function importFromLocalFiles():void {
+                       // ** FIXME: if it's a zip, do something clever
+               }
+               
                protected function fileLoaded(e:Event,filenum:uint):void {
                        files[filenum]=e.target.data;
                        filesloaded++;
@@ -49,15 +56,15 @@ package net.systemeD.potlatch2.utils {
                 var action:CompositeUndoableAction = new CompositeUndoableAction("Import layer "+connection.name);
                                doImport(action.push);
                                action.doAction(); // just do it, don't add to undo stack
-                               if (callback!=null) { callback(true); }
+                               if (callback!=null) { callback(connection,options,true); }
                        }
                }
                
                protected function doImport(push:Function):void {
                }
 
-               protected function securityErrorHandler( event:SecurityErrorEvent ):void { callback(false,"You don't have permission to open that file."); }
-               protected function ioErrorHandler( event:IOErrorEvent ):void { callback(false,"The file could not be loaded."); }
+               protected function securityErrorHandler( event:SecurityErrorEvent ):void { callback(connection,options,false,"You don't have permission to open that file."); }
+               protected function ioErrorHandler( event:IOErrorEvent ):void { callback(connection,options,false,"The file could not be loaded."); }
 
        }
 }
index 302fa8f..f5ebe5c 100644 (file)
@@ -13,8 +13,8 @@ package net.systemeD.potlatch2.utils {
      */
     public class KmlImporter extends Importer {
 
-        public function KmlImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false) {
-            super(connection, map, filenames, callback, simplify);
+        public function KmlImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
+            super(connection, map, callback, simplify, options);
         }
 
         override protected function doImport(push:Function): void {
index 3e7b0c1..550024f 100644 (file)
@@ -6,8 +6,8 @@ package net.systemeD.potlatch2.utils {
 
        public class OsmImporter extends Importer {
 
-               public function OsmImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false) {
-                       super(connection,map,filenames,callback,simplify);
+               public function OsmImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
+                       super(connection,map,callback,simplify,options);
                }
 
                override protected function doImport(push:Function):void {
index dd0cf6c..7edcf55 100644 (file)
@@ -13,9 +13,9 @@ package net.systemeD.potlatch2.utils {
 
                private var projection:String;
 
-               public function ShpImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false, projection:String="") {
-                       if (projection!='') this.projection=projection;
-                       super(connection,map,filenames,callback,simplify);
+               public function ShpImporter(connection:Connection, map:Map, callback:Function=null, simplify:Boolean=false, options:Object=null) {
+                       if (options[projection]) this.projection=options[projection];
+                       super(connection,map,callback,simplify,options);
                }
 
                override protected function doImport(push:Function): void {
index b234f47..c6e29f8 100644 (file)
                 var gpx_url:String = loaderInfo.parameters['gpx_url'];
 
                 var connection:Connection = new Connection(name, gpx_url, null, null);
-                var gpx:GpxImporter=new GpxImporter(connection, theMap, [gpx_url],
+                var gpx:GpxImporter=new GpxImporter(connection, theMap,
                                                 function(success:Boolean,message:String=null):void {
                                                     if (!success) return;
                                                     var paint:MapPaint = theMap.addLayer(connection, "stylesheets/gpx.css");
                                                     paint.updateEntityUIs(false, false);
                                                     dispatchEvent(new Event("layers_changed"));
                                                 }, false);
+                               gpx.importFromRemoteFiles([gpx_url]);
                        }
 
                        // create GPS trackloader