package org.geoserver.wcs2_0.kvp;
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import java.awt.image.Raster;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;
import javax.xml.namespace.QName;
import org.eclipse.emf.common.util.EList;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.wcs2_0.WCS20Const;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.data.DataSourceException;
import org.geotools.gce.geotiff.GeoTiffReader;
import org.geotools.wcs.v2_0.RangeSubset;
import org.geotools.wcs.v2_0.Scaling;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;
import net.opengis.wcs20.GetCoverageType;
import net.opengis.wcs20.InterpolationType;
import net.opengis.wcs20.RangeItemType;
import net.opengis.wcs20.RangeSubsetType;
import net.opengis.wcs20.ScaleAxisByFactorType;
import net.opengis.wcs20.ScaleAxisType;
import net.opengis.wcs20.ScaleByFactorType;
import net.opengis.wcs20.ScaleToExtentType;
import net.opengis.wcs20.ScaleToSizeType;
import net.opengis.wcs20.ScalingType;
import net.opengis.wcs20.TargetAxisExtentType;
import net.opengis.wcs20.TargetAxisSizeType;
public class GetCoverageKvpTest extends WCSKVPTestSupport {
private static final QName RAIN = new QName(MockData.SF_URI, "rain", MockData.SF_PREFIX);
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
testData.addRasterLayer(RAIN, "rain.zip", "asc", getCatalog());
testData.addRasterLayer(new QName(MockData.SF_URI, "mosaic", MockData.SF_PREFIX),
"raster-filter-test.zip",null, null ,SystemTestData.class, getCatalog());
}
@Test
public void testParseBasic() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1&coverageId=theCoverage");
assertEquals("theCoverage", gc.getCoverageId());
}
@Test
public void testGetCoverageNoWs() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=BlueMarble&Format=image/tiff");
assertEquals("image/tiff", response.getContentType());
}
@Test
public void testGetCoverageNativeFormat() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=sf__rain");
// we got back an ArcGrid response
assertEquals("text/plain", response.getContentType());
}
@Test
public void testNotExistent() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=NotThere&&Format=image/tiff");
checkOws20Exception(response, 404, "NoSuchCoverage", "coverageId");
}
@Test
public void testGetCoverageLocalWs() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs/wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=BlueMarble&&Format=image/tiff");
assertEquals("image/tiff", response.getContentType());
}
@Test
public void testExtensionScaleFactor() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&scaleFactor=2");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
ScalingType scaling = (ScalingType) extensions.get(Scaling.NAMESPACE + ":Scaling");
ScaleByFactorType sbf = scaling.getScaleByFactor();
assertEquals(2.0, sbf.getScaleFactor(), 0d);
}
@Test
public void testExtensionScaleAxes() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&scaleaxes=http://www.opengis.net/def/axis/OGC/1/i(3.5)," +
"http://www.opengis.net/def/axis/OGC/1/j(5.0),http://www.opengis.net/def/axis/OGC/1/k(2.0)");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
ScalingType scaling = (ScalingType) extensions.get(Scaling.NAMESPACE + ":Scaling");
ScaleAxisByFactorType sax = scaling.getScaleAxesByFactor();
EList<ScaleAxisType> saxes = sax.getScaleAxis();
assertEquals(3, saxes.size());
assertEquals("http://www.opengis.net/def/axis/OGC/1/i", saxes.get(0).getAxis());
assertEquals(3.5d, saxes.get(0).getScaleFactor(), 0d);
assertEquals("http://www.opengis.net/def/axis/OGC/1/j", saxes.get(1).getAxis());
assertEquals(5.0d, saxes.get(1).getScaleFactor(), 0d);
assertEquals("http://www.opengis.net/def/axis/OGC/1/k", saxes.get(2).getAxis());
assertEquals(2.0d, saxes.get(2).getScaleFactor(), 0d);
}
@Test
public void testExtensionScaleSize() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&scalesize=http://www.opengis.net/def/axis/OGC/1/i(1000)," +
"http://www.opengis.net/def/axis/OGC/1/j(1000),http://www.opengis.net/def/axis/OGC/1/k(10)");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
ScalingType scaling = (ScalingType) extensions.get(Scaling.NAMESPACE + ":Scaling");
ScaleToSizeType sts = scaling.getScaleToSize();
EList<TargetAxisSizeType> scaleAxes = sts.getTargetAxisSize();
assertEquals(3, scaleAxes.size());
assertEquals("http://www.opengis.net/def/axis/OGC/1/i", scaleAxes.get(0).getAxis());
assertEquals(1000d, scaleAxes.get(0).getTargetSize(), 0d);
assertEquals("http://www.opengis.net/def/axis/OGC/1/j", scaleAxes.get(1).getAxis());
assertEquals(1000d, scaleAxes.get(1).getTargetSize(), 0d);
assertEquals("http://www.opengis.net/def/axis/OGC/1/k", scaleAxes.get(2).getAxis());
assertEquals(10d, scaleAxes.get(2).getTargetSize(), 0d);
}
@Test
public void testExtensionScaleExtent() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&scaleextent=http://www.opengis.net/def/axis/OGC/1/i(10,20),http://www.opengis.net/def/axis/OGC/1/j(20,30)");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
ScalingType scaling = (ScalingType) extensions.get(Scaling.NAMESPACE + ":Scaling");
ScaleToExtentType ste = scaling.getScaleToExtent();
assertEquals(2, ste.getTargetAxisExtent().size());
TargetAxisExtentType tax = ste.getTargetAxisExtent().get(0);
assertEquals("http://www.opengis.net/def/axis/OGC/1/i", tax.getAxis());
assertEquals(10.0, tax.getLow(), 0d);
assertEquals(20.0, tax.getHigh(), 0d);
tax = ste.getTargetAxisExtent().get(1);
assertEquals("http://www.opengis.net/def/axis/OGC/1/j", tax.getAxis());
assertEquals(20.0, tax.getLow(), 0d);
assertEquals(30.0, tax.getHigh(), 0d);
}
@Test
public void testExtensionRangeSubset() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&rangesubset=band01,band03:band05,band10,band19:band21");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
RangeSubsetType rangeSubset = (RangeSubsetType) extensions.get(RangeSubset.NAMESPACE + ":RangeSubset");
EList<RangeItemType> items = rangeSubset.getRangeItems();
assertEquals(4, items.size());
RangeItemType i1 = items.get(0);
assertEquals("band01", i1.getRangeComponent());
RangeItemType i2 = items.get(1);
assertEquals("band03", i2.getRangeInterval().getStartComponent());
assertEquals("band05", i2.getRangeInterval().getEndComponent());
RangeItemType i3 = items.get(2);
assertEquals("band10", i3.getRangeComponent());
RangeItemType i4 = items.get(3);
assertEquals("band19", i4.getRangeInterval().getStartComponent());
assertEquals("band21", i4.getRangeInterval().getEndComponent());
}
@Test
public void testExtensionCRS() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&SUBSETTINGCRS=http://www.opengis.net/def/crs/EPSG/0/4326&outputcrs=http://www.opengis.net/def/crs/EPSG/0/32632");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(2, extensions.size());
assertEquals("http://www.opengis.net/def/crs/EPSG/0/4326", extensions.get("http://www.opengis.net/wcs/service-extension/crs/1.0:subsettingCrs"));
assertEquals("http://www.opengis.net/def/crs/EPSG/0/32632", extensions.get("http://www.opengis.net/wcs/service-extension/crs/1.0:outputCrs"));
}
@Test
public void testExtensionInterpolationLinear() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&interpolation=http://www.opengis.net/def/interpolation/OGC/1/linear");
Map<String, Object> extensions = getExtensionsMap(gc);
InterpolationType interp = (InterpolationType) extensions.get("http://www.opengis.net/WCS_service-extension_interpolation/1.0:Interpolation");
assertEquals("http://www.opengis.net/def/interpolation/OGC/1/linear", interp.getInterpolationMethod().getInterpolationMethod());
}
@Test
public void testExtensionInterpolationMixed() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1" +
"&coverageId=theCoverage&interpolation=http://www.opengis.net/def/interpolation/OGC/1/linear");
Map<String, Object> extensions = getExtensionsMap(gc);
InterpolationType interp = (InterpolationType) extensions.get("http://www.opengis.net/WCS_service-extension_interpolation/1.0:Interpolation");
assertEquals("http://www.opengis.net/def/interpolation/OGC/1/linear", interp.getInterpolationMethod().getInterpolationMethod());
}
@Test
public void testExtensionOverview() throws Exception {
GetCoverageType gc = parse("wcs?request=GetCoverage&service=WCS&version=2.0.1"
+ "&coverageId=theCoverage&overviewPolicy=QUALITY");
Map<String, Object> extensions = getExtensionsMap(gc);
assertEquals(1, extensions.size());
String overviewPolicy = (String) extensions
.get(WCS20Const.OVERVIEW_POLICY_EXTENSION_NAMESPACE + ":"
+ WCS20Const.OVERVIEW_POLICY_EXTENSION);
assertEquals(overviewPolicy, "QUALITY");
}
@Test
public void testGetMissingCoverage() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1&coverageId=notThereBaby");
checkOws20Exception(response, 404, "NoSuchCoverage", "coverageId");
}
@Test
public void testCqlFilterRed() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1&coverageId=sf__mosaic&CQL_FILTER=location like 'red%25'");
assertOriginPixelColor(response, new int[] {255, 0, 0});
}
@Test
public void testCqlFilterGreen() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=GetCoverage&service=WCS&version=2.0.1&coverageId=sf__mosaic&CQL_FILTER=location like 'green%25'");
assertOriginPixelColor(response, new int[] {0, 255, 0});
}
private void assertOriginPixelColor(MockHttpServletResponse response, int[] expected)
throws DataSourceException, IOException {
assertEquals("image/tiff", response.getContentType());
byte[] bytes = response.getContentAsByteArray();
GeoTiffReader reader = new GeoTiffReader(new ByteArrayInputStream(bytes));
GridCoverage2D coverage = reader.read(null);
Raster raster = coverage.getRenderedImage().getData();
int[] pixel = new int[3];
raster.getPixel(0, 0, pixel);
assertThat(pixel, equalTo(expected));
}
}