/** * */ package nl.ipo.cds.etl.reporting.geom; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.Serializable; import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.geotools.data.DefaultTransaction; import org.geotools.data.Transaction; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.shapefile.ShapefileDataStoreFactory; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureSource; import org.geotools.data.simple.SimpleFeatureStore; import org.springframework.util.Assert; /** * @author eshuism * 16 mei 2012 */ public class ShapeFileGenerator { /** * Creates a set of files that together makes a shapefile in a temporay directory. * * @param collection * @param shapeFileZip * @return */ public void createShapeFile(SimpleFeatureCollection collection, File shapeFileZip){ Assert.notNull(collection); if(collection.size() == 0){ return; } ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory(); Map<String, Serializable> params = new HashMap<String, Serializable>(); try { params.put("url", shapeFileZip.toURI().toURL()); } catch (MalformedURLException e) { throw new RuntimeException(e); } params.put("create spatial index", Boolean.TRUE); ShapefileDataStore newDataStore = null; try { newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params); newDataStore.createSchema(collection.getSchema()); } catch (IOException e) { throw new RuntimeException(e); } /* * Write the features to the shapefile */ Transaction transaction = new DefaultTransaction("create"); String typeName = newDataStore.getTypeNames()[0]; SimpleFeatureSource featureSource; try { featureSource = newDataStore.getFeatureSource(typeName); if (featureSource instanceof SimpleFeatureStore) { SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource; featureStore.setTransaction(transaction); try { featureStore.addFeatures(collection); transaction.commit(); } catch (Exception problem) { problem.printStackTrace(); transaction.rollback(); } finally { transaction.close(); } } else { throw new RuntimeException(typeName + " does not support read/write access"); } } catch (IOException e) { throw new RuntimeException(e); } } /** * Creates a set of files that together makes a shapefile. Return the set of files as an archive * @param featureCollection with features to create the shapeFile from * @param shapeFile is the file that must be created. Extension must be ".shp" * @return archive of the generated files returned as zip */ public void createZippedShapeFile(SimpleFeatureCollection featureCollection, File shapeFileZip){ File parentDir = shapeFileZip.getParentFile(); String shapeFileName = shapeFileZip.getName().substring(0, shapeFileZip.getName().length()-4).concat(".shp"); File shapeDir = new File(parentDir, "shape"); shapeDir.deleteOnExit(); boolean createDirSuccess = shapeDir.mkdir(); Assert.notNull(createDirSuccess, "Not be able to create directory: " + shapeDir.getAbsolutePath()); this.createShapeFile(featureCollection, new File(shapeDir, shapeFileName)); // Remove generated files on Exit JVM File[] shapeFileFiles = shapeDir.listFiles(); for (int i = 0, n = shapeFileFiles.length; i < n; i++) { shapeFileFiles[i].deleteOnExit(); } try { this.zipDirectory(shapeDir, shapeFileZip); } catch (IOException e) { throw new RuntimeException(e); } } private final void zipDirectory( File directory, File zip ) throws IOException { ZipOutputStream zos = new ZipOutputStream( new FileOutputStream( zip ) ); zip( directory, directory, zos ); zos.close(); } private final void zip(File directory, File base, ZipOutputStream zos) throws IOException { File[] files = directory.listFiles(); byte[] buffer = new byte[8192]; int read = 0; for (int i = 0, n = files.length; i < n; i++) { if (files[i].isDirectory()) { zip(files[i], base, zos); } else { FileInputStream in = new FileInputStream(files[i]); ZipEntry entry = new ZipEntry(files[i].getPath().substring( base.getPath().length() + 1)); zos.putNextEntry(entry); while (-1 != (read = in.read(buffer))) { zos.write(buffer, 0, read); } in.close(); } } } }