Zip support, including for local shapefiles
authorRichard Fairhurst <richard@systemeD.net>
Sun, 25 Mar 2012 14:53:09 +0000 (15:53 +0100)
committerRichard Fairhurst <richard@systemeD.net>
Sun, 25 Mar 2012 14:53:09 +0000 (15:53 +0100)
net/systemeD/potlatch2/dialogs/VectorSourceDialog.mxml
net/systemeD/potlatch2/utils/Importer.as
net/systemeD/potlatch2/utils/ShpImporter.as

index d8a275a..8719c89 100644 (file)
                var connection:Connection = new Connection(name, url, null, null, CSSTransform.getInstance());
                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"]);
+               } else {
+                       importer.importFromRemoteFiles([url]);
                }
        }
        
        private function loadFileLocal():void {
                // note scoping issues - http://blog.wrench.com.au/2010/06/16/filereferenceload-keep-it-in-scope/
                localFileReference=new FileReference(); 
-               var fileTypes:FileFilter=new FileFilter("*."+selectedType, "*."+selectedType); 
-               localFileReference.browse([fileTypes]); 
+               var fileTypes:String=selectedType=='shp' ? "*.zip" : ("*.zip;*."+selectedType);
+               localFileReference.browse([new FileFilter(fileTypes,fileTypes)]); 
                localFileReference.addEventListener(Event.SELECT, selectFileLocal);
        }
        
index 709c36c..c3ff660 100644 (file)
@@ -7,6 +7,7 @@ package net.systemeD.potlatch2.utils {
        import flash.display.LoaderInfo;
        import flash.events.*;
        import flash.net.*;
+       import flash.utils.ByteArray;
        import nochump.util.zip.*;
 
        public class Importer {
@@ -51,29 +52,44 @@ package net.systemeD.potlatch2.utils {
                        file.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
                        file.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
                        file.load();
-                       // ** FIXME: if it's a zip (e.g. shapefiles), do something really amazingly clever
                }
                
                protected function fileLoaded(e:Event,filenum:uint=0):void {
                        var rawData:ByteArray=e.target.data;
-                       var firstFour:ByteArray;
+                       var firstFour:ByteArray=new ByteArray();
                        rawData.readBytes(firstFour,0,4);
                        rawData.position=0;
                        
                        if (firstFour.toString()=="PK"+String.fromCharCode(3)+String.fromCharCode(4)) {
-                               trace("looks like a zip file to me");
+                               // Zip file (we assume there'll only be one of these...)
+                               var zip:ZipFile = new ZipFile(rawData);
+                               for (var i:uint=0; i<zip.entries.length; i++) {
+                                       filenames[i]=zip.entries[i].name;
+                                       files[i]=zip.getInput(zip.entries[i]);
+                                       filesloaded++;
+                               }
+                               runImporter();
                        } else {
-                               trace("not a zip file");
+                               // Standard file
                                files[filenum]=rawData;
                                filesloaded++;
                                trace("loaded file "+filenum+" ("+filesloaded+"/"+filenames.length+")"); 
-                               if (filesloaded==filenames.length) {
-                       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(connection,options,true); }
-                               }
+                               if (filesloaded==filenames.length) { runImporter(); }
+                       }
+               }
+
+               private function runImporter():void {
+                       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(connection,options,true); }
+               }
+
+               protected function getFileByName(regex:RegExp):* {
+                       for (var i:uint=0; i<filenames.length; i++) {
+                               if (filenames[i].match(regex)) { return files[i]; }
                        }
+                       return null;
                }
                
                protected function doImport(push:Function):void {
index 7edcf55..115ce40 100644 (file)
@@ -8,6 +8,7 @@ package net.systemeD.potlatch2.utils {
        import net.systemeD.halcyon.connection.Node;
        import net.systemeD.halcyon.connection.Way;
        import net.systemeD.potlatch2.tools.Simplify;
+       import flash.utils.ByteArray;
 
        public class ShpImporter extends Importer {
 
@@ -20,8 +21,10 @@ package net.systemeD.potlatch2.utils {
 
                override protected function doImport(push:Function): void {
                        // we load .shp as files[0], .shx as files[1], .dbf as files[2]
-                       var shp:ShpHeader=new ShpHeader(files[0]);
-                       var dbf:DbfHeader=new DbfHeader(files[2]);
+                       var shpFile:ByteArray=getFileByName(/.shp$/);
+                       var dbfFile:ByteArray=getFileByName(/.dbf$/);
+                       var shp:ShpHeader=new ShpHeader(shpFile);
+                       var dbf:DbfHeader=new DbfHeader(dbfFile);
 
                        if (projection) {
                                var proj:Proj4as=new Proj4as();
@@ -35,12 +38,12 @@ package net.systemeD.potlatch2.utils {
                        if (shp.shapeType==ShpType.SHAPE_POLYGON || shp.shapeType==ShpType.SHAPE_POLYLINE) {
 
                                // Loop through all polylines in the shape
-                               var polyArray:Array = ShpTools.readRecords(files[0]);
+                               var polyArray:Array = ShpTools.readRecords(shpFile);
                                for (var i:uint=0; i<polyArray.length; i++) {
 
                                        // Get attributes and create a tags hash
                                        // (note that dr.values is a Dictionary)
-                                       var dr:DbfRecord = DbfTools.getRecord(files[2], dbf, i);
+                                       var dr:DbfRecord = DbfTools.getRecord(dbfFile, dbf, i);
                                        var tags:Object={};
                                        for (key in dr.values) {
                                                v=dr.values[key];