/* (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.wms.worldwind; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import javax.xml.namespace.QName; import org.apache.commons.io.FileUtils; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CoverageInfo; import org.geoserver.data.test.MockData; import org.geoserver.data.test.SystemTestData; import org.geoserver.wms.WMSInfo; import org.geoserver.wms.WMSTestSupport; import org.junit.Test; import org.springframework.mock.web.MockHttpServletResponse; /** * Test case for producing Raw bil images out of an elevation model. * * @author Tishampati Dhar * @since 2.0.x * */ public class BilTest extends WMSTestSupport { /** * This is a READ ONLY TEST so we can use one time setup */ public static String WCS_PREFIX = "wcs"; public static String WCS_URI = "http://www.opengis.net/wcs/1.1.1"; public static QName AUS_DEM = new QName(WCS_URI, "Ausdem", WCS_PREFIX); public static QName SF_DEM = new QName(MockData.SF_URI, "sfdem", MockData.SF_PREFIX); private final int width = 64; private final int height = 64; @Override protected void onSetUp(SystemTestData testData) throws Exception { super.onSetUp(testData); Catalog catalog = getCatalog(); testData.addStyle("raster", "raster.sld", BilTest.class, catalog); testData.addRasterLayer(AUS_DEM, "aus_dem.tiff", "tiff", null, BilTest.class, catalog); testData.addRasterLayer(SF_DEM, "sfdem.tiff", "tiff", null, BilTest.class, catalog); WMSInfo wmsInfo = getGeoServer().getService(WMSInfo.class); wmsInfo.setMaxBuffer(50); getGeoServer().save(wmsInfo); } @Test public void testBil() throws Exception { byte[] response = getStandardRequest("application/bil"); int expected = width * height * 2; // Native encoding, 2 bytes/pixel assertEquals("testStandardRequest", expected, response.length); } @Test public void testBil8() throws Exception { byte[] response = getStandardRequest("application/bil8"); int expected = width * height; // 1 byte/pixel assertEquals("testStandardRequest", expected, response.length); } @Test public void testBil16() throws Exception { byte[] response = getStandardRequest("application/bil16"); int expected = width * height * 2; // 2 bytes/pixel assertEquals("testStandardRequest", expected, response.length); } @Test public void testBil32() throws Exception { byte[] response = getStandardRequest("application/bil32"); int expected = width * height * 4; // 4 bytes/pixel assertEquals("testStandardRequest", expected, response.length); } private byte[] getStandardRequest(String mimeType) throws Exception { String layer = getLayerId(AUS_DEM); String request = "wms?service=wms&request=GetMap&version=1.1.1" + "&layers=" + layer + "&styles=&bbox=108.3,-46.3,160.3,-4.2" + "&width=" + width + "&height=" + height + "&format=" + mimeType + "&srs=EPSG:4326"; MockHttpServletResponse servletResponse = getAsServletResponse(request); return getBinary(servletResponse); } @Test public void testLargeRequest() throws Exception { String layer = getLayerId(AUS_DEM); String request = "wms?service=wms&request=GetMap&version=1.1.1" + "&layers=" + layer + "&styles=&bbox=108.3,-46.3,160.3,-4.2&width=600&height=600" + "&format=image/bil&srs=EPSG:4326"; String exceptstr = getAsString(request); assertTrue("testLargeRequest",exceptstr.contains("512x512")); } @Test public void testWms13Request() throws Exception { String layer = getLayerId(AUS_DEM); String request = "wms?service=wms&request=GetMap&version=1.3.0" + "&layers=" + layer + "&styles=&bbox=-46.3,108.3,-4.2,160.3" + "&width=" + width + "&height=" + height + "&format=application/bil&crs=EPSG:4326"; MockHttpServletResponse servletResponse = getAsServletResponse(request); byte[] bytes1_3_0 = getBinary(servletResponse); // Check response length in bytes int expected = width * height * 2; // 2 bytes/pixel assertEquals("testStandardRequest", expected, bytes1_3_0.length); // Check that the WMS 1.3.0 response is equivalent to the WMS 1.1.1 response. byte[] bytes1_1_1 = getStandardRequest("application/bil16"); assertArrayEquals("WMS 1.3.0 response different from WMS 1.1.1", bytes1_1_1, bytes1_3_0); } @Test public void testDefaultDataType() throws Exception { // Int8 default type setConfiguration(AUS_DEM, BilConfig.DEFAULT_DATA_TYPE, "application/bil8"); byte[] bytes = getStandardRequest("application/bil"); int expected = width * height * 1; // 1 bytes/pixel assertEquals("testStandardRequest", expected, bytes.length); // Int16 default type setConfiguration(AUS_DEM, BilConfig.DEFAULT_DATA_TYPE, "application/bil16"); bytes = getStandardRequest("application/bil"); expected = width * height * 2; // 2 bytes/pixel assertEquals("testStandardRequest", expected, bytes.length); // Int32 default type setConfiguration(AUS_DEM, BilConfig.DEFAULT_DATA_TYPE, "application/bil32"); bytes = getStandardRequest("application/bil"); expected = width * height * 4; // 4 bytes/pixel assertEquals("testStandardRequest", expected, bytes.length); } @Test public void testByteOrder() throws Exception { byte[] bytesDefault = getStandardRequest("application/bil16"); setConfiguration(AUS_DEM, BilConfig.BYTE_ORDER, ByteOrder.BIG_ENDIAN.toString()); byte[] bytesBigEndian = getStandardRequest("application/bil16"); assertArrayEquals("Big endian byte order should return same result as default", bytesDefault, bytesBigEndian); // Change byte order of big endian response to get expected little endian response. ShortBuffer expected = ByteBuffer.wrap(bytesBigEndian).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); setConfiguration(AUS_DEM, BilConfig.BYTE_ORDER, ByteOrder.LITTLE_ENDIAN.toString()); byte[] bytesLittleEndian = getStandardRequest("application/bil16"); ShortBuffer actual = ByteBuffer.wrap(bytesLittleEndian).asShortBuffer(); assertEquals("Little endian byte order should return reverse of big endian byte order", expected, actual); } @Test public void testNoDataTranslation() throws Exception { final float inNoData = -9.99999993381581251e+36f; final float outNoData = -9999; String layer = getLayerId(SF_DEM); String request = "wms?service=wms&request=GetMap&version=1.1.0" + "&layers=" + layer + "&bbox=-103.871,44.370,-103.629,44.501" + "&width=" + width + "&height=" + width + "&format=application/bil32&crs=EPSG:4326"; // Issue request without no-data translation. MockHttpServletResponse servletResponse = getAsServletResponse(request); byte[] bytes = getBinary(servletResponse); FloatBuffer orig = ByteBuffer.wrap(bytes).asFloatBuffer(); // Issue request again, recoding no-data values. setConfiguration(SF_DEM, BilConfig.NO_DATA_OUTPUT, String.valueOf(outNoData)); servletResponse = getAsServletResponse(request); bytes = getBinary(servletResponse); FloatBuffer translated = ByteBuffer.wrap(bytes).asFloatBuffer(); // Content length should be the same, though content will be different. assertEquals("Unexpected content length after translating no-data values", orig.limit(), translated.limit()); // Assert that each no-data value was recoded properly. int noDataCount = 0; for (int i = 0; i < orig.limit(); i++) { if (orig.get(i) == inNoData) { assertEquals(outNoData, translated.get(i), 1e-6); noDataCount += 1; } } // Make sure that the test actually did something. assertTrue("Did not find any no-data values", noDataCount > 0); } @Test public void testNonIntersectiongBbox() throws Exception { String layer = getLayerId(AUS_DEM); String bbox = "0,0,10,10"; // Does not intersection coverage area String request = "wms?service=wms&request=GetMap&version=1.1.1" + "&layers=" + layer + "&styles=&bbox=" + bbox + "&width=" + width + "&height=" + height + "&format=application/bil16&srs=EPSG:4326"; MockHttpServletResponse servletResponse = getAsServletResponse(request); byte[] response = getBinary(servletResponse); int expected = width * height * 2; // 2 bytes/pixel assertEquals("testStandardRequest", expected, response.length); } private void setConfiguration(QName layerQname, String key, String value) { String layer = getLayerId(layerQname); Catalog catalog = getCatalog(); CoverageInfo coverage = catalog.getCoverageByName(layer); coverage.getMetadata().put(key, value); catalog.save(coverage); } /** * Need to override since we are in the community folder */ protected void copySchemaFile(String file) throws IOException { File f = new File("../../web/app/src/main/webapp/schemas/" + file); FileUtils.copyFile(f, getResourceLoader().createFile("WEB-INF/schemas/"+file)); } }