Skip to content

Commit

Permalink
GEOS-8599: WPS download at granule's resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
dromagnoli committed Mar 6, 2018
1 parent eaea17c commit 67c6e93
Show file tree
Hide file tree
Showing 8 changed files with 1,029 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public Boolean execute(
LOGGER.log(Level.FINE, "Working with Raster dataset");
}
final CoverageInfo coverage = (CoverageInfo) resourceInfo;
return new RasterEstimator(limits).execute(progressListener, coverage, roi, targetCRS,
return new RasterEstimator(limits, catalog).execute(progressListener, coverage, roi, targetCRS,
clip, filter, targetSizeX, targetSizeY, bandIndices);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public File execute(
//
CoverageInfo cInfo = (CoverageInfo) resourceInfo;
// convert/reproject/crop if needed the coverage
internalOutput = new RasterDownload(limits, resourceManager, context).execute(
internalOutput = new RasterDownload(limits, resourceManager, context, catalog).execute(
mimeType, progressListener, cInfo, roi, targetCRS, clip, filter,
interpolation, targetSizeX, targetSizeY, bandIndices, writeParameters);
} else {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ public CoordinateReferenceSystem getTargetCRS() {
return targetCRS;
}

public CoordinateReferenceSystem getNativeCRS() {
return nativeCRS;
}

public boolean isRoiCrsEqualsTargetCrs() {
return roiCrsEqualsTargetCrs;
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageDimensionInfo;
import org.geoserver.catalog.CoverageInfo;
import org.geotools.coverage.TypeMap;
Expand Down Expand Up @@ -39,14 +40,18 @@ class RasterEstimator {
/** The downloadServiceConfiguration object containing the limits to check */
private DownloadServiceConfiguration downloadServiceConfiguration;

private Catalog catalog;

/**
* Constructor
*
* @param limits the parent {@link DownloadEstimatorProcess} that contains the download limits to be enforced.
* @param catalog
*
*/
public RasterEstimator(DownloadServiceConfiguration limits) {
public RasterEstimator(DownloadServiceConfiguration limits, Catalog catalog) {
this.downloadServiceConfiguration = limits;
this.catalog = catalog;
if (limits == null) {
throw new NullPointerException("The provided DownloadEstimatorProcess is null!");
}
Expand Down Expand Up @@ -98,6 +103,9 @@ public boolean execute(final ProgressListener progressListener, CoverageInfo cov
roiManager = new ROIManager(roi, roiCRS);
// set use nativeCRS
roiManager.useNativeCRS(nativeCRS);
if (targetCRS != null) {
roiManager.useTargetCRS(targetCRS);
}
}

// get a reader for this CoverageInfo
Expand Down Expand Up @@ -139,7 +147,16 @@ public boolean execute(final ProgressListener progressListener, CoverageInfo cov
scaling = new ScaleToTarget(reader);
}
scaling.setTargetSize(targetSizeX, targetSizeY);
GridGeometry2D gg = scaling.getGridGeometry();

GridGeometry2D gg = null;

if (targetSizeX == null && targetSizeY == null) {
// Ask to the GridGeometryProvider
GridGeometryProvider provider = new GridGeometryProvider(reader, roiManager, filter, catalog);
gg = provider.getGridGeometry();
} else {
gg = scaling.getGridGeometry();
}

areaRead = (long) gg.getGridRange2D().width * gg.getGridRange2D().height;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
Expand All @@ -23,15 +24,16 @@
import java.util.zip.ZipInputStream;

import javax.imageio.metadata.IIOMetadataNode;
import javax.xml.namespace.QName;

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.util.IOUtils;
import org.geoserver.wcs.CoverageCleanerCallback;
import org.geoserver.wps.ProcessEvent;
import org.geoserver.wps.WPSTestSupport;
Expand All @@ -55,7 +57,9 @@
import org.geotools.process.ProcessException;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.geotools.resources.coverage.CoverageUtilities;
import org.geotools.resources.coverage.FeatureUtilities;
import org.geotools.util.DefaultProgressListener;
import org.geotools.util.NullProgressListener;
import org.geotools.util.URLs;
Expand All @@ -64,6 +68,12 @@
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.PropertyName;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.util.InternationalString;
import org.opengis.util.ProgressListener;
import org.w3c.dom.NamedNodeMap;
Expand All @@ -83,6 +93,10 @@
*/
public class DownloadProcessTest extends WPSTestSupport {

private static final FilterFactory2 FF = FeatureUtilities.DEFAULT_FILTER_FACTORY;

private static QName MIXED_RES = new QName(WCS_URI, "mixedres", WCS_PREFIX);

/**
* This method is used for decoding an input file.
*
Expand Down Expand Up @@ -134,11 +148,20 @@ public static File decode(InputStream input, File tempDirectory) throws Exceptio

/** Test ROI used */
final static Polygon roi;

final static Polygon ROI2;

final static Polygon ROI3;

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 ))");

ROI2 = (Polygon) new WKTReader2()
.read("POLYGON (( -125 30, -116 30, -116 45, -125 45, -125 30))");

ROI3 = (Polygon) new WKTReader2().read("POLYGON (( 356050 5520000, 791716 5520000, 791716 5655096, 356050 5655096, 356050 5520000))");
} catch (ParseException e) {
throw new RuntimeException(e);
}
Expand All @@ -148,6 +171,8 @@ public static File decode(InputStream input, File tempDirectory) throws Exceptio
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
testData.addRasterLayer(MockData.USA_WORLDIMG, "usa.zip", MockData.PNG, getCatalog());
testData.addRasterLayer(MIXED_RES, "mixedres.zip", null, getCatalog());

}

@Override
Expand Down Expand Up @@ -939,11 +964,11 @@ public void testDownloadRasterSelectedBandsScaledWithROI() throws Exception {
// check envelope
Assert.assertEquals(-130.88669845369998,
gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6);
Assert.assertEquals(48.611129008700004, gc.getEnvelope().getLowerCorner()
Assert.assertEquals(48.5552612829, gc.getEnvelope().getLowerCorner()
.getOrdinate(1), 1E-6);
Assert.assertEquals(-123.95304462109999,
Assert.assertEquals(-124.05382943906582,
gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6);
Assert.assertEquals(54.0861661371, gc.getEnvelope().getUpperCorner().getOrdinate(1),
Assert.assertEquals(54.00577111704634, gc.getEnvelope().getUpperCorner().getOrdinate(1),
1E-6);

} finally {
Expand Down Expand Up @@ -1125,7 +1150,7 @@ public void testDownloadScaledRaster() throws Exception {
// check envelope
Assert.assertEquals(-130.88669845369998,
gc.getEnvelope().getLowerCorner().getOrdinate(0), 1E-6);
Assert.assertEquals(48.611129008700004, gc.getEnvelope().getLowerCorner()
Assert.assertEquals(48.623544058877776, gc.getEnvelope().getLowerCorner()
.getOrdinate(1), 1E-6);
Assert.assertEquals(-123.95304462109999,
gc.getEnvelope().getUpperCorner().getOrdinate(0), 1E-6);
Expand Down Expand Up @@ -1674,6 +1699,146 @@ public void testWrongOutputFormat() throws Exception {
}
}

/**
* Test download of raster data using underlying granules resolution.
* The sample mosaic is composed of:
*
* 18km_32610.tif with resolution = 17550.948453185396000 meters
* 9km_32610.tif with resolution = 8712.564801039759900 meters
*
*/
@Test
public void testDownloadGranuleHeterogeneousResolution() throws Exception {

DownloadEstimatorProcess limits = new DownloadEstimatorProcess(
new StaticDownloadServiceConfiguration(), getGeoServer());
final WPSResourceManager resourceManager = getResourceManager();
DownloadProcess downloadProcess = new DownloadProcess(getGeoServer(), limits,
resourceManager);


// Setting filter to get the granule with resolution
final PropertyName property = FF.property("resolution");
Filter filter = (Filter) FF.greaterOrEqual(property, FF.literal(16000));

testExpectedResolution(downloadProcess, filter, CRS.decode("EPSG:4326", true),
ROI2, resourceManager, 17550.94845318, -17550.94845318);

// Download native resolution 2
filter = FF.and(FF.lessOrEqual(property, FF.literal(10000)),
FF.greaterOrEqual(property, FF.literal(1000)));

testExpectedResolution(downloadProcess, filter, null, null, resourceManager,
8712.564801039759900, -8712.564801039759900);

// Download native resolution 3
filter = (Filter) FF.lessOrEqual(property, FF.literal(1000));

// Final checks on the result
testExpectedResolution(downloadProcess, filter, null, null, resourceManager,
7818.453242658203, -10139.712928934865);


filter = FF.and(FF.lessOrEqual(property, FF.literal(10000)),
FF.greaterOrEqual(property, FF.literal(1000)));

File rasterZip = downloadProcess.execute(getLayerId(MIXED_RES), // layerName
filter, // filter
"image/tiff", // outputFormat
null, // targetCRS
CRS.decode("EPSG:32610", true),
ROI3, // roi
false, // cropToGeometry
null, // interpolation
512, // targetSizeX
128, // targetSizeY
null, // bandSelectIndices
null, // Writing params
new NullProgressListener() // progressListener
);

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);
// check coverage size
RenderedImage ri = gc.getRenderedImage();
Assert.assertEquals(512, ri.getWidth());
Assert.assertEquals(128, ri.getHeight());

} finally {
if (gc != null) {
CoverageCleanerCallback.disposeCoverage(gc);
}
if (reader != null) {
reader.dispose();
}

// clean up process
resourceManager.finished(resourceManager.getExecutionId(true));
}
}

private void testExpectedResolution(DownloadProcess downloadProcess, Filter filter,
CoordinateReferenceSystem roiCrs, Polygon roi, WPSResourceManager resourceManager,
double expectedX, double expectedY) throws IOException {

File rasterZip = downloadProcess.execute(getLayerId(MIXED_RES), // layerName
filter, // filter
"image/tiff", // outputFormat
null, // targetCRS
roiCrs, // roiCRS
roi, // roi
false, // cropToGeometry
null, // interpolation
null, // targetSizeX
null, // targetSizeY
null, // bandSelectIndices
null, // Writing params
new NullProgressListener() // progressListener
);

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);
Assert.assertEquals("32610", gc.getCoordinateReferenceSystem().getIdentifiers().iterator().next().getCode());

// check coverage size
MathTransform mt = reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER);
AffineTransform2D transform2D = (AffineTransform2D) mt;
double resX = transform2D.getScaleX();
double resY = transform2D.getScaleY();

Assert.assertEquals(expectedX, resX, 1E-6);
Assert.assertEquals(expectedY, resY, 1E-6);

} finally {
if (gc != null) {
CoverageCleanerCallback.disposeCoverage(gc);
}
if (reader != null) {
reader.dispose();
}

// clean up process
resourceManager.finished(resourceManager.getExecutionId(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
Expand Down
Binary file not shown.

0 comments on commit 67c6e93

Please sign in to comment.