/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wps.gs.download; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.data.test.MockData; import org.geoserver.data.test.SystemTestData; import org.geoserver.data.util.IOUtils; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.wcs.CoverageCleanerCallback; import org.geoserver.wps.ProcessEvent; import org.geoserver.wps.WPSTestSupport; import org.geoserver.wps.executor.ExecutionStatus; import org.geoserver.wps.executor.ProcessState; import org.geoserver.wps.ppio.WFSPPIO; import org.geoserver.wps.ppio.ZipArchivePPIO; import org.geoserver.wps.resource.WPSResourceManager; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.data.DataUtilities; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.filter.text.cql2.CQL; import org.geotools.gce.geotiff.GeoTiffReader; import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geometry.jts.JTS; import org.geotools.geometry.jts.WKTReader2; import org.geotools.process.ProcessException; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.resources.coverage.CoverageUtilities; import org.geotools.util.DefaultProgressListener; import org.geotools.util.NullProgressListener; import org.geotools.util.logging.Logging; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.opengis.feature.simple.SimpleFeature; import org.opengis.util.InternationalString; import org.opengis.util.ProgressListener; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.io.ParseException; /** * This class tests checks if the DownloadProcess class behaves correctly. * * @author "Alessio Fabiani - alessio.fabiani@geo-solutions.it" */ public class DownloadProcessTest extends WPSTestSupport { /** * This method is used for decoding an input file. * * @param input the input stream to decode * @param tempDirectory temporary directory on where the file is decoded. * @return the object the decoded file * @throws Exception the exception TODO review */ public static File decode(InputStream input, File tempDirectory) throws Exception { // unzip to the temporary directory ZipInputStream zis = null; try { zis = new ZipInputStream(input); ZipEntry entry = null; // Copy the whole file in the new position while ((entry = zis.getNextEntry()) != null) { File file = new File(tempDirectory, entry.getName()); if (entry.isDirectory()) { file.mkdir(); } else { int count; byte data[] = new byte[4096]; // write the files to the disk FileOutputStream fos = null; try { fos = new FileOutputStream(file); while ((count = zis.read(data)) != -1) { fos.write(data, 0, count); } fos.flush(); } finally { if (fos != null) { org.apache.commons.io.IOUtils.closeQuietly(fos); } } } zis.closeEntry(); } } finally { if (zis != null) { org.apache.commons.io.IOUtils.closeQuietly(zis); } } return tempDirectory; } /** Test ROI used */ final static Polygon roi; static { try { roi = (Polygon) new WKTReader2() .read("POLYGON (( 500116.08576537756 499994.25579707103, 500116.08576537756 500110.1012210889, 500286.2657688021 500110.1012210889, 500286.2657688021 499994.25579707103, 500116.08576537756 499994.25579707103 ))"); } catch (ParseException e) { throw new RuntimeException(e); } } @Override protected void onSetUp(SystemTestData testData) throws Exception { super.onSetUp(testData); testData.addRasterLayer(MockData.USA_WORLDIMG, "usa.zip", MockData.PNG, getCatalog()); } @Override protected void setUpTestData(SystemTestData testData) throws Exception { super.setUpTestData(testData); // add limits properties file testData.copyTo( DownloadProcessTest.class.getClassLoader().getResourceAsStream( "download-process/download.properties"), "download.properties"); } @Before public void clearPolygons() throws IOException { revertLayer(MockData.POLYGONS); } /** * Test get features as shapefile. * * @throws Exception the exception */ @Test public void testGetFeaturesAsShapefile() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); FeatureTypeInfo ti = getCatalog().getFeatureTypeByName(getLayerId(MockData.POLYGONS)); SimpleFeatureCollection rawSource = (SimpleFeatureCollection) ti.getFeatureSource(null, null).getFeatures(); // Download File shpeZip = downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // mail "application/zip", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(shpeZip); SimpleFeatureCollection rawTarget = (SimpleFeatureCollection) decodeShape(new FileInputStream( shpeZip)); Assert.assertNotNull(rawTarget); Assert.assertEquals(rawSource.size(), rawTarget.size()); } /** * Test downloading with a duplicate style * * @throws Exception the exception */ @Test public void testDownloadWithDuplicateStyle() throws Exception { String polygonsName = getLayerId(MockData.POLYGONS); LayerInfo li = getCatalog().getLayerByName(polygonsName); // setup an alternative equal to the main style li.getStyles().add(li.getDefaultStyle()); getCatalog().save(li); testGetFeaturesAsShapefile(); } /** * Test filtered clipped features. * * @throws Exception the exception */ @Test public void testFilteredClippedFeatures() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI object Polygon roi = (Polygon) new WKTReader2() .read("POLYGON ((0.0008993124415341 0.0006854377923293, 0.0008437876520112 0.0006283489242283, 0.0008566913002806 0.0005341131898971, 0.0009642217025257 0.0005188634237605, 0.0011198475210477 0.000574779232928, 0.0010932581852198 0.0006572843779233, 0.0008993124415341 0.0006854377923293))"); FeatureTypeInfo ti = getCatalog().getFeatureTypeByName(getLayerId(MockData.BUILDINGS)); SimpleFeatureCollection rawSource = (SimpleFeatureCollection) ti.getFeatureSource(null, null).getFeatures(); // Download File shpeZip = downloadProcess.execute(getLayerId(MockData.BUILDINGS), // layerName CQL.toFilter("ADDRESS = '123 Main Street'"), // filter "application/zip", // outputFormat null, // targetCRS DefaultGeographicCRS.WGS84, // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(shpeZip); SimpleFeatureCollection rawTarget = (SimpleFeatureCollection) decodeShape(new FileInputStream( shpeZip)); Assert.assertNotNull(rawTarget); Assert.assertEquals(1, rawTarget.size()); SimpleFeature srcFeature = rawSource.features().next(); SimpleFeature trgFeature = rawTarget.features().next(); Assert.assertEquals(srcFeature.getAttribute("ADDRESS"), trgFeature.getAttribute("ADDRESS")); // Final checks on the ROI Geometry srcGeometry = (Geometry) srcFeature.getDefaultGeometry(); Geometry trgGeometry = (Geometry) trgFeature.getDefaultGeometry(); Assert.assertTrue("Target geometry clipped and included into the source one", srcGeometry.contains(trgGeometry)); } /** * Test get features as gml. * * @throws Exception the exception */ @Test public void testGetFeaturesAsGML() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); FeatureTypeInfo ti = getCatalog().getFeatureTypeByName(getLayerId(MockData.POLYGONS)); SimpleFeatureCollection rawSource = (SimpleFeatureCollection) ti.getFeatureSource(null, null).getFeatures(); // Download as GML 2 File gml2Zip = downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "application/wfs-collection-1.0", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(gml2Zip); File[] files = exctractGMLFile(gml2Zip); SimpleFeatureCollection rawTarget = (SimpleFeatureCollection) new WFSPPIO.WFS10() .decode(new FileInputStream(files[0])); Assert.assertNotNull(rawTarget); Assert.assertEquals(rawSource.size(), rawTarget.size()); // Download as GML 3 File gml3Zip = downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "application/wfs-collection-1.1", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(gml3Zip); files = exctractGMLFile(gml2Zip); rawTarget = (SimpleFeatureCollection) new WFSPPIO.WFS11().decode(new FileInputStream( files[0])); Assert.assertNotNull(rawTarget); Assert.assertEquals(rawSource.size(), rawTarget.size()); } /** * This method is used for extracting only the xml file from a GML output file * * @param gml2Zip * * @throws IOException */ private File[] exctractGMLFile(File gml2Zip) throws IOException { IOUtils.decompress(gml2Zip, gml2Zip.getParentFile()); File[] files = gml2Zip.getParentFile().listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return FilenameUtils.getExtension(name).equalsIgnoreCase("xml"); } }); return files; } /** * This method is used for extracting only the json file from a JSON output file * * @param jsonZip * * @throws IOException */ private File[] exctractJSONFile(File jsonZip) throws IOException { IOUtils.decompress(jsonZip, jsonZip.getParentFile()); File[] files = jsonZip.getParentFile().listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return FilenameUtils.getExtension(name).equalsIgnoreCase("json"); } }); return files; } /** * This method is used for extracting only the tiff file from a Tiff/GeoTiff output file * * @param gtiffZip * * @throws IOException */ private File[] extractTIFFFile(final File gtiffZip) throws IOException { IOUtils.decompress(gtiffZip, gtiffZip.getParentFile()); File[] files = gtiffZip.getParentFile().listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return (FilenameUtils.getExtension(name).equalsIgnoreCase("tif") || FilenameUtils.getExtension(name).equalsIgnoreCase("tiff") || FilenameUtils .getExtension(name).equalsIgnoreCase("geotiff")); } }); return files; } /** * Test get features as geo json. * * @throws Exception the exception */ @Test public void testGetFeaturesAsGeoJSON() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); FeatureTypeInfo ti = getCatalog().getFeatureTypeByName(getLayerId(MockData.POLYGONS)); SimpleFeatureCollection rawSource = (SimpleFeatureCollection) ti.getFeatureSource(null, null).getFeatures(); // Download the file as Json File jsonZip = downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "application/json", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(jsonZip); File[] files = exctractJSONFile(jsonZip); SimpleFeatureCollection rawTarget = (SimpleFeatureCollection) new FeatureJSON() .readFeatureCollection(new FileInputStream(files[0])); Assert.assertNotNull(rawTarget); Assert.assertEquals(rawSource.size(), rawTarget.size()); } /** * Test download of raster data. * * @throws Exception the exception */ @Test public void testDownloadRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // test ROI Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.88669845369998 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); // ROI reprojection Polygon roiResampled = (Polygon) JTS.transform( roi, CRS.findMathTransform(CRS.decode("EPSG:4326", true), CRS.decode("EPSG:900913", true))); // Download the coverage as tiff (Not reprojected) File rasterZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(rasterZip); GeoTiffReader reader = null; GridCoverage2D gc = null, gcResampled = null; try { final File[] tiffFiles = extractTIFFFile(rasterZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); Assert.assertEquals(-130.88669845369998, gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6); Assert.assertEquals(48.611129008700004, gc.getEnvelope().getLowerCorner() .getOrdinate(1), 1E-6); Assert.assertEquals(-123.95304462109999, gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6); Assert.assertEquals(54.0861661371, gc.getEnvelope().getUpperCorner().getOrdinate(1), 1E-6); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } // Download the coverage as tiff (Reprojected) File resampledZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat CRS.decode("EPSG:900913", true), // targetCRS CRS.decode("EPSG:900913", true), // roiCRS roiResampled, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(resampledZip); try { File[] files = extractTIFFFile(resampledZip); reader = new GeoTiffReader(files[files.length - 1]); gcResampled = reader.read(null); Assert.assertNotNull(gcResampled); Assert.assertEquals(-1.457024062347863E7, gcResampled.getEnvelope().getLowerCorner() .getOrdinate(0), 1E-6); Assert.assertEquals(6209706.404894806, gcResampled.getEnvelope().getLowerCorner() .getOrdinate(1), 1E-6); Assert.assertEquals(-1.379838980949677E7, gcResampled.getEnvelope().getUpperCorner() .getOrdinate(0), 1E-6); Assert.assertEquals(7187128.139081598, gcResampled.getEnvelope().getUpperCorner() .getOrdinate(1), 1E-6); } finally { if (gcResampled != null) { CoverageCleanerCallback.disposeCoverage(gcResampled); } if (reader != null) reader.dispose(); // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } } /** * Test download of selected bands of raster data. Result contains only bands 0 and 2. * * @throws Exception the exception */ @Test public void testDownloadRasterSelectedBands() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); /////////////////////////////////////// // test full coverage // /////////////////////////////////////// // Download the coverage as tiff File rasterZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY new int[]{0,2}, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(rasterZip); GeoTiffReader reader = null; GridCoverage2D gc = null; try { final File[] tiffFiles = extractTIFFFile(rasterZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // check bands Assert.assertEquals(2, gc.getNumSampleDimensions()); // check visible band index for new coverage Assert.assertEquals(0, CoverageUtilities.getVisibleBand(gc)); // check non existing band index Assert.assertNotEquals(3, gc.getNumSampleDimensions()); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } } /** * Test download of selected bands of raster data, scald and using a ROI area. * Result contains only band 1. * * @throws Exception the exception */ @Test public void testDownloadRasterSelectedBandsScaledWithROI() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); /////////////////////////////////////// // test full coverage // /////////////////////////////////////// Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( " + "-127.57473954542964 54.06575021619523, " + "-130.88669845369998 52.00807146727025, " + "-129.50812897394974 49.85372324691927, " + "-130.5300633861675 49.20465679591609, " + "-129.25955033314003 48.60392508062591, " + "-128.00975216684665 50.986137055052474, " + "-125.8623089087404 48.63154492960477, " + "-123.984159178178 50.68231871628503, " + "-126.91186316993704 52.15307567440926, " + "-125.3444367403868 53.54787804784162, " + "-127.57473954542964 54.06575021619523 " + "))"); roi.setSRID(4326); // Download the coverage as tiff File rasterZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation 40, // targetSizeX 40, // targetSizeY new int[]{1}, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(rasterZip); GeoTiffReader reader = null; GridCoverage2D gc = null; try { final File[] tiffFiles = extractTIFFFile(rasterZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // check bands Assert.assertEquals(1, gc.getNumSampleDimensions()); Rectangle2D originalGridRange = (GridEnvelope2D) reader.getOriginalGridRange(); Assert.assertEquals(40, Math.round(originalGridRange.getWidth())); Assert.assertEquals(40, Math.round(originalGridRange.getHeight())); // check envelope Assert.assertEquals(-130.88669845369998, gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6); Assert.assertEquals(48.611129008700004, gc.getEnvelope().getLowerCorner() .getOrdinate(1), 1E-6); Assert.assertEquals(-123.95304462109999, gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6); Assert.assertEquals(54.0861661371, gc.getEnvelope().getUpperCorner().getOrdinate(1), 1E-6); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } } /** * Test download of raster data. The output is scaled to fit exactly the provided size. * * @throws Exception the exception */ @Test public void testDownloadScaledRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); /////////////////////////////////////// // test full coverage // /////////////////////////////////////// // Download the coverage as tiff File rasterZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation 80, // targetSizeX 80, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(rasterZip); GeoTiffReader reader = null; GridCoverage2D gc = null; try { final File[] tiffFiles = extractTIFFFile(rasterZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // check coverage size Rectangle2D originalGridRange = (GridEnvelope2D) reader.getOriginalGridRange(); Assert.assertEquals(80, Math.round(originalGridRange.getWidth())); Assert.assertEquals(80, Math.round(originalGridRange.getHeight())); // check envelope Assert.assertEquals(-130.8866985, gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6); Assert.assertEquals(48.5552613, gc.getEnvelope().getLowerCorner() .getOrdinate(1), 1E-6); Assert.assertEquals(-123.8830077, gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6); Assert.assertEquals(54.1420339, gc.getEnvelope().getUpperCorner().getOrdinate(1), 1E-6); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } /////////////////////////////////////// // test partial input // /////////////////////////////////////// // Download the coverage as tiff File largerZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation 160, // targetSizeX null, // targetSizeY not specified, will be calculated based on targetSizeX and aspect ratio of the original image null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(largerZip); try { final File[] tiffFiles = extractTIFFFile(largerZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // check coverage size Rectangle2D originalGridRange = (GridEnvelope2D) reader.getOriginalGridRange(); Assert.assertEquals(160, Math.round(originalGridRange.getWidth())); Assert.assertEquals(160, Math.round(originalGridRange.getHeight())); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } ////////////////////////////////// // test with ROI // ////////////////////////////////// Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.88669845369998 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); // Download the coverage as tiff File resampledZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation 80, // targetSizeX 80, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(resampledZip); try { final File[] tiffFiles = extractTIFFFile(resampledZip); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // check coverage size Rectangle2D originalGridRange = (GridEnvelope2D) reader.getOriginalGridRange(); Assert.assertEquals(80, Math.round(originalGridRange.getWidth())); Assert.assertEquals(80, Math.round(originalGridRange.getHeight())); // check envelope Assert.assertEquals(-130.88669845369998, gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6); Assert.assertEquals(48.611129008700004, gc.getEnvelope().getLowerCorner() .getOrdinate(1), 1E-6); Assert.assertEquals(-123.95304462109999, gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6); Assert.assertEquals(54.0861661371, gc.getEnvelope().getUpperCorner().getOrdinate(1), 1E-6); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } } /** * PPIO Test. * * @throws Exception the exception */ @Test public void testZipGeoTiffPPIO() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); ZipArchivePPIO ppio = new ZipArchivePPIO( DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI as a BBOX Envelope env = new Envelope(-125.074006936869, -123.88300771369998, 48.5552612829, 49.03872); Polygon roi = JTS.toGeometry(env); // Download the data with ROI File rasterZip = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326"), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // Final checks on the result Assert.assertNotNull(rasterZip); // make sure we create files locally so that we don't clog the sytem temp final File currentDirectory = new File(DownloadProcessTest.class.getResource(".").toURI()); File tempZipFile = File.createTempFile("zipppiotemp", ".zip", currentDirectory); ppio.encode(rasterZip, new FileOutputStream(tempZipFile)); Assert.assertTrue(tempZipFile.length() > 0); final File tempDir = new File(currentDirectory, Long.toString(System.nanoTime())); Assert.assertTrue(tempDir.mkdir()); File tempFile = decode(new FileInputStream(tempZipFile), tempDir); Assert.assertNotNull(tempFile); IOUtils.delete(tempFile); } /** * Test download estimator for raster data. The result should exceed the limits * * @throws Exception the exception */ @Test public void testDownloadEstimatorReadLimitsRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, 10, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI as polygon Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.8545966116691 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); try { // Download the data with ROI. It should throw an exception downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); Assert.assertFalse(true); } catch (ProcessException e) { Assert.assertEquals( "java.lang.IllegalArgumentException: Download Limits Exceeded. Unable to proceed!: Download Limits Exceeded. Unable to proceed!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } } /** * Test download estimator write limits raster. The result should exceed the limits * * @throws Exception the exception */ @Test public void testDownloadEstimatorWriteLimitsRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, 10, 10, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.88669845369998 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); try { // Download the data with ROI. It should throw an exception downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); Assert.assertFalse(true); } catch (ProcessException e) { Assert.assertEquals( "org.geotools.process.ProcessException: java.io.IOException: Download Exceeded the maximum HARD allowed size!: java.io.IOException: Download Exceeded the maximum HARD allowed size!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } } /** * Test download estimator write limits raster for scaled output. Scaled image should exceed the limits, whereas the original raster should not. * * @throws Exception the exception */ @Test public void testDownloadEstimatorWriteLimitsScaledRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, 921600, // 900KB DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); File nonScaled = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); Assert.assertNotNull(nonScaled); GeoTiffReader reader = null; GridCoverage2D gc = null; try { final File[] tiffFiles = extractTIFFFile(nonScaled); Assert.assertNotNull(tiffFiles); Assert.assertTrue(tiffFiles.length > 0); reader = new GeoTiffReader(tiffFiles[0]); gc = reader.read(null); Assert.assertNotNull(gc); // ten times the size of the original coverage int targetSizeX = (int) (gc.getGridGeometry().getGridRange2D().getWidth() * 10); int targetSizeY = (int) (gc.getGridGeometry().getGridRange2D().getHeight() * 10); downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation targetSizeX, // targetSizeX targetSizeY, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); // exception should have been thrown at this stage Assert.assertFalse(true); } catch (ProcessException e) { Assert.assertEquals( "org.geotools.process.ProcessException: java.io.IOException: Download Exceeded the maximum HARD allowed size!: java.io.IOException: Download Exceeded the maximum HARD allowed size!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } finally { if (gc != null) { CoverageCleanerCallback.disposeCoverage(gc); } if (reader != null) { reader.dispose(); } // clean up process resourceManager.finished(resourceManager.getExecutionId(true)); } // Test same process for checking write output limits, using selected band indices limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, 30000, //= 100x100 pixels x 3 bands x 1 byte (8 bits) per band DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); try { // create a scaled 100x100 raster, with 4 bands int targetSizeX = 100; int targetSizeY = 100; int[] bandIndices = new int[]{0,2,2,2}; File scaled = downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS null, // roi false, // cropToGeometry null, // interpolation targetSizeX, // targetSizeX targetSizeY, // targetSizeY bandIndices, // bandSelectIndices new NullProgressListener() // progressListener ); // exception should have been thrown at this stage Assert.assertFalse(true); } catch (ProcessException e) { Assert.assertEquals( "java.lang.IllegalArgumentException: Download Limits Exceeded. " + "Unable to proceed!: Download Limits Exceeded. Unable to proceed!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } } /** * Test download estimator for raster data. The result should exceed the integer limits * * @throws Exception the exception */ @Test public void testDownloadEstimatorIntegerMaxValueLimitRaster() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, (long) 1E12, // huge number, way above integer limits DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI as polygon Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.8545966116691 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); try { // Download the data with ROI. It should throw an exception downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation 100000, // targetSizeX 60000, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); Assert.fail(); } catch (ProcessException e) { Assert.assertEquals( "java.lang.IllegalArgumentException: Download Limits Exceeded. Unable to proceed!", e.getMessage()); } } /** * Test download estimator for vectorial data. The result should be exceed the hard output limits * * @throws Exception the exception */ @Test public void testDownloadEstimatorHardOutputLimit() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, 10, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); try { // Download the features. It should throw an exception downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "application/zip", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices new NullProgressListener() // progressListener ); Assert.assertFalse(true); } catch (ProcessException e) { Assert.assertEquals( "java.io.IOException: Download Exceeded the maximum HARD allowed size!: Download Exceeded the maximum HARD allowed size!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } } private WPSResourceManager getResourceManager() { return GeoServerExtensions.bean(WPSResourceManager.class); } /** * Test download physical limit for raster data. It should throw an exception * * @throws Exception the exception */ @Test public void testDownloadPhysicalLimitsRaster() throws Exception { final WPSResourceManager resourceManager = getResourceManager(); ProcessListener listener = new ProcessListener(new ExecutionStatus(new NameImpl("gs", "DownloadEstimator"), resourceManager.getExecutionId(false), false)); // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); // ROI data Polygon roi = (Polygon) new WKTReader2() .read("POLYGON (( -127.57473954542964 54.06575021619523, -130.88669845369998 52.00807146727025, -129.50812897394974 49.85372324691927, -130.5300633861675 49.20465679591609, -129.25955033314003 48.60392508062591, -128.00975216684665 50.986137055052474, -125.8623089087404 48.63154492960477, -123.984159178178 50.68231871628503, -126.91186316993704 52.15307567440926, -125.3444367403868 53.54787804784162, -127.57473954542964 54.06575021619523 ))"); roi.setSRID(4326); try { // Download the data. It should throw an exception downloadProcess.execute(getLayerId(MockData.USA_WORLDIMG), // layerName null, // filter "image/tiff", // outputFormat null, // targetCRS CRS.decode("EPSG:4326", true), // roiCRS roi, // roi true, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices listener // progressListener ); } catch (Exception e) { Throwable e1 = listener.exception; Assert.assertNotNull(e1); Assert.assertEquals( "org.geotools.process.ProcessException: java.io.IOException: Download Exceeded the maximum HARD allowed size!: java.io.IOException: Download Exceeded the maximum HARD allowed size!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); } } /** * Test download physical limit for vectorial data. It should throw an exception * * @throws Exception the exception */ @Test public void testDownloadPhysicalLimitsVector() throws Exception { final WPSResourceManager resourceManager = getResourceManager(); ProcessListener listener = new ProcessListener(new ExecutionStatus(new NameImpl("gs", "DownloadEstimator"), resourceManager.getExecutionId(false), false)); // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(new DownloadServiceConfiguration( DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, DownloadServiceConfiguration.NO_LIMIT, 1, DownloadServiceConfiguration.DEFAULT_COMPRESSION_LEVEL)), getGeoServer()); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); try { // Download the features. It should throw an exception downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "application/zip", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices listener // progressListener ); } catch (ProcessException e) { Assert.assertEquals( "java.io.IOException: Download Exceeded the maximum HARD allowed size!: Download Exceeded the maximum HARD allowed size!", e.getMessage() + (e.getCause() != null ? ": " + e.getCause().getMessage() : "")); Throwable le = listener.exception; Assert.assertEquals( "java.io.IOException: Download Exceeded the maximum HARD allowed size!: Download Exceeded the maximum HARD allowed size!", le.getMessage() + (le.getCause() != null ? ": " + le.getCause().getMessage() : "")); return; } Assert.assertFalse(true); } /** * Test with a wrong output format. It should thrown an exception. * * @throws Exception the exception */ @Test public void testWrongOutputFormat() throws Exception { // Estimator process for checking limits DownloadEstimatorProcess limits = new DownloadEstimatorProcess( new StaticDownloadServiceConfiguration(), getGeoServer()); final WPSResourceManager resourceManager = getResourceManager(); // Creates the new process for the download DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits, resourceManager); FeatureTypeInfo ti = getCatalog().getFeatureTypeByName(getLayerId(MockData.POLYGONS)); SimpleFeatureCollection rawSource = (SimpleFeatureCollection) ti.getFeatureSource(null, null).getFeatures(); final DefaultProgressListener progressListener = new DefaultProgressListener(); try { // Download the features. It should throw an exception. downloadProcess.execute(getLayerId(MockData.POLYGONS), // layerName null, // filter "IAmWrong!!!", // outputFormat null, // targetCRS CRS.decode("EPSG:32615"), // roiCRS roi, // roi false, // cropToGeometry null, // interpolation null, // targetSizeX null, // targetSizeY null, // bandSelectIndices progressListener // progressListener ); Assert.assertTrue("We did not get an exception", false); } catch (Exception e) { Assert.assertTrue("Everything as expected", true); } } /** * The listener interface for receiving process events. The class that is interested in processing a process event implements this interface, and * the object created with that class is registered with a component using the component's <code>addProcessListener<code> method. When * the process event occurs, that object's appropriate * method is invoked. * * @see ProcessEvent */ static class ProcessListener implements ProgressListener { /** The Constant LOGGER. */ static final Logger LOGGER = Logging.getLogger(ProcessListener.class); /** The status. */ ExecutionStatus status; /** The task. */ InternationalString task; /** The description. */ String description; /** The exception. */ Throwable exception; /** * Instantiates a new process listener. * * @param status the status */ public ProcessListener(ExecutionStatus status) { this.status = status; } /** * Gets the task. * * @return the task */ public InternationalString getTask() { return task; } /** * Sets the task. * * @param task the new task */ public void setTask(InternationalString task) { this.task = task; } /** * Gets the description. * * @return the description */ public String getDescription() { return this.description; } /** * Sets the description. * * @param description the new description */ public void setDescription(String description) { this.description = description; } /** * Started. */ public void started() { status.setPhase(ProcessState.RUNNING); } /** * Progress. * * @param percent the percent */ public void progress(float percent) { status.setProgress(percent); } /** * Gets the progress. * * @return the progress */ public float getProgress() { return status.getProgress(); } /** * Complete. */ public void complete() { // nothing to do } /** * Dispose. */ public void dispose() { // nothing to do } /** * Checks if is canceled. * * @return true, if is canceled */ public boolean isCanceled() { return status.getPhase() == ProcessState.DISMISSING; } /** * Sets the canceled. * * @param cancel the new canceled */ public void setCanceled(boolean cancel) { if (cancel == true) { status.setPhase(ProcessState.DISMISSING); } } /** * Warning occurred. * * @param source the source * @param location the location * @param warning the warning */ public void warningOccurred(String source, String location, String warning) { LOGGER.log(Level.WARNING, "Got a warning during process execution " + status.getExecutionId() + ": " + warning); } /** * Exception occurred. * * @param exception the exception */ public void exceptionOccurred(Throwable exception) { this.exception = exception; } } /** * Private method for decoding a Shapefile * * @param input the input shp * @return the object a {@link SimpleFeatureCollection} object related to the shp file. * @throws Exception the exception */ private Object decodeShape(InputStream input) throws Exception { // create the temp directory and register it as a temporary resource File tempDir = IOUtils.createRandomDirectory(IOUtils.createTempDirectory("shpziptemp") .getAbsolutePath(), "download-process", "download-services"); // unzip to the temporary directory ZipInputStream zis = null; File shapeFile = null; File zipFile = null; // extract shp-zip file try { zis = new ZipInputStream(input); ZipEntry entry = null; // Cycle on all the entries and copies the input shape in the target directory while ((entry = zis.getNextEntry()) != null) { String name = entry.getName(); File file = new File(tempDir, entry.getName()); if (entry.isDirectory()) { file.mkdir(); } else { if (file.getName().toLowerCase().endsWith(".shp")) { shapeFile = file; } else if (file.getName().toLowerCase().endsWith(".zip")) { zipFile = file; } int count; byte data[] = new byte[4096]; // write the files to the disk FileOutputStream fos = null; try { fos = new FileOutputStream(file); while ((count = zis.read(data)) != -1) { fos.write(data, 0, count); } fos.flush(); } finally { if (fos != null) { fos.close(); } } } zis.closeEntry(); } } finally { if (zis != null) { zis.close(); } } // Read the shapefile if (shapeFile == null) { if (zipFile != null) return decodeShape(new FileInputStream(zipFile)); else { FileUtils.deleteDirectory(tempDir); throw new IOException("Could not find any file with .shp extension in the zip file"); } } else { ShapefileDataStore store = new ShapefileDataStore(DataUtilities.fileToURL(shapeFile)); return store.getFeatureSource().getFeatures(); } } }