package org.geotools.map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.util.ParameterParser; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.data.ows.HTTPResponse; import org.geotools.data.ows.Layer; import org.geotools.data.ows.MockHttpClient; import org.geotools.data.ows.MockHttpResponse; import org.geotools.data.wms.WebMapServer; import org.geotools.factory.Hints; import org.geotools.geometry.GeneralEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.ows.ServiceException; import org.geotools.parameter.Parameter; import org.geotools.referencing.CRS; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.crs.CoordinateReferenceSystem; public class WMSCoverageReaderTest { Map<String, String> parseParams(String query) { ParameterParser pp = new ParameterParser(); List params = pp.parse(query, '&'); Map<String, String> result = new HashMap<String, String>(); for (Iterator it = params.iterator(); it.hasNext();) { NameValuePair pair = (NameValuePair) it.next(); result.put(pair.getName().toUpperCase(), pair.getValue()); } return result; }; @Before public void setup() { System.setProperty("org.geotools.referencing.forceXY", "true"); Hints.putSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING, "http"); CRS.reset("all"); } @After public void teardown() { System.clearProperty("org.geotools.referencing.forceXY"); Hints.putSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING, ""); CRS.reset("all"); } @Test public void test4326wms13() throws Exception { WMSCoverageReader reader = getReader4326wms13(); // build a getmap request and check it CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-180, 180, -90, 90, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] { ggParam }); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); } @Test public void test4326wms13RequestFlipped() throws Exception { WMSCoverageReader reader = getReader4326wms13(); // build a getmap request and check it CoordinateReferenceSystem wgs84 = CRS.decode("urn:ogc:def:crs:EPSG::4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-90, 90, -180, 180, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] { ggParam }); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); } @Test public void test4326wms13RequestFlippedStandardEPSG() throws Exception { // reset the CRS system to its defaults System.clearProperty("org.geotools.referencing.forceXY"); Hints.putSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING, ""); CRS.reset("all"); WMSCoverageReader reader = getReader4326wms13(); // build a getmap request and check it CoordinateReferenceSystem wgs84 = CRS.decode("urn:ogc:def:crs:EPSG::4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-90, 90, -180, 180, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] { ggParam }); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); } private WMSCoverageReader getReader4326wms13() throws IOException, ServiceException, MalformedURLException { // prepare the responses MockHttpClient client = new MockHttpClient() { public HTTPResponse get(URL url) throws IOException { if (url.getQuery().contains("GetCapabilities")) { URL caps130 = WMSCoverageReaderTest.class.getResource("caps130.xml"); return new MockHttpResponse(caps130, "text/xml"); } else if (url.getQuery().contains("GetMap") && url.getQuery().contains("world4326")) { Map<String, String> params = parseParams(url.getQuery()); assertEquals("1.3.0", params.get("VERSION")); assertEquals("-90.0,-180.0,90.0,180.0", params.get("BBOX")); assertEquals("EPSG:4326", params.get("CRS")); URL world = WMSCoverageReaderTest.class.getResource("world.png"); return new MockHttpResponse(world, "image/png"); } else { throw new IllegalArgumentException( "Don't know how to handle a get request over " + url.toExternalForm()); } } }; // setup the reader WebMapServer server = new WebMapServer(new URL("http://geoserver.org/geoserver/wms"), client); WMSCoverageReader reader = new WMSCoverageReader(server, getLayer(server, "world4326")); return reader; } @Test public void testGetMapNoContentType() throws Exception { // reset the CRS system to its defaults System.clearProperty("org.geotools.referencing.forceXY"); Hints.putSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING, ""); CRS.reset("all"); // prepare the responses final AtomicBoolean disposeCalled = new AtomicBoolean(false); MockHttpClient client = new MockHttpClient() { public HTTPResponse get(URL url) throws IOException { if (url.getQuery().contains("GetCapabilities")) { URL caps130 = WMSCoverageReaderTest.class.getResource("caps130.xml"); return new MockHttpResponse(caps130, "text/xml"); } else if (url.getQuery().contains("GetMap") && url.getQuery().contains("world4326")) { Map<String, String> params = parseParams(url.getQuery()); assertEquals("1.3.0", params.get("VERSION")); assertEquals("-90.0,-180.0,90.0,180.0", params.get("BBOX")); assertEquals("EPSG:4326", params.get("CRS")); URL world = WMSCoverageReaderTest.class.getResource("world.png"); return new MockHttpResponse(world, null) { public void dispose() { disposeCalled.set(true); super.dispose(); }; }; } else { throw new IllegalArgumentException( "Don't know how to handle a get request over " + url.toExternalForm()); } } }; // setup the reader WebMapServer server = new WebMapServer(new URL("http://geoserver.org/geoserver/wms"), client); WMSCoverageReader reader = new WMSCoverageReader(server, getLayer(server, "world4326")); // build a getmap request and check it CoordinateReferenceSystem wgs84 = CRS.decode("urn:ogc:def:crs:EPSG::4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-90, 90, -180, 180, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); try { reader.read(new GeneralParameterValue[] { ggParam }); fail("Should have thrown an exception, the GetMap content type was null"); } catch (Exception e) { // it's fine } assertTrue(disposeCalled.get()); } @Test public void test4326wms11() throws Exception { WMSCoverageReader reader = getReader4326wms11(); GeneralEnvelope original = reader.getOriginalEnvelope(); CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true); assertTrue(CRS.equalsIgnoreMetadata(wgs84, original.getCoordinateReferenceSystem())); // build a getmap request and check it ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-180, 180, -90, 90, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] { ggParam }); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); } private WMSCoverageReader getReader4326wms11() throws IOException, ServiceException, MalformedURLException { // prepare the responses MockHttpClient client = new MockHttpClient() { public HTTPResponse get(URL url) throws IOException { if (url.getQuery().contains("GetCapabilities")) { URL caps130 = WMSCoverageReaderTest.class.getResource("caps110.xml"); return new MockHttpResponse(caps130, "text/xml"); } else if (url.getQuery().contains("GetMap") && url.getQuery().contains("world4326")) { Map<String, String> params = parseParams(url.getQuery()); assertEquals("1.1.0", params.get("VERSION")); assertEquals("-180.0,-90.0,180.0,90.0", params.get("BBOX")); assertEquals("EPSG:4326", params.get("SRS")); URL world = WMSCoverageReaderTest.class.getResource("world.png"); return new MockHttpResponse(world, "image/png"); } else { throw new IllegalArgumentException( "Don't know how to handle a get request over " + url.toExternalForm()); } } }; // setup the reader WebMapServer server = new WebMapServer(new URL("http://geoserver.org/geoserver/wms"), client); WMSCoverageReader reader = new WMSCoverageReader(server, getLayer(server, "world4326")); return reader; } @Test public void testCrs84wms13() throws Exception { // prepare the responses MockHttpClient client = new MockHttpClient() { public HTTPResponse get(URL url) throws IOException { if (url.getQuery().contains("GetCapabilities")) { URL caps130 = WMSCoverageReaderTest.class.getResource("caps130_crs84.xml"); return new MockHttpResponse(caps130, "text/xml"); } else if (url.getQuery().contains("GetMap") && url.getQuery().contains("world84")) { Map<String, String> params = parseParams(url.getQuery()); assertEquals("1.3.0", params.get("VERSION")); assertEquals("CRS:84", params.get("CRS")); assertEquals("-180.0,-90.0,180.0,90.0", params.get("BBOX")); URL world = WMSCoverageReaderTest.class.getResource("world.png"); return new MockHttpResponse(world, "image/png"); } else { throw new IllegalArgumentException( "Don't know how to handle a get request over " + url.toExternalForm()); } } }; WebMapServer server = new WebMapServer(new URL("http://geoserver.org/geoserver/wms"), client); WMSCoverageReader reader = new WMSCoverageReader(server, getLayer(server, "world84")); // setup the request and check it CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-180, 180, -90, 90, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] { ggParam }); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); } private Layer getLayer(WebMapServer server, String layerName) { for (Layer layer : server.getCapabilities().getLayerList()) { if (layerName.equals(layer.getName())) { return layer; } } throw new IllegalArgumentException("Could not find layer " + layerName); } }