/* (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.map;
import static org.junit.Assert.*;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.xml.namespace.QName;
import org.custommonkey.xmlunit.NamespaceContext;
import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.PropertyStyleHandler;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.data.test.CiteTestData;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.data.test.SystemTestData.LayerProperty;
import org.geoserver.wms.WMSTestSupport;
import org.geotools.image.ImageWorker;
import org.geotools.image.test.ImageAssert;
import org.junit.Test;
import org.w3c.dom.Document;
import org.springframework.mock.web.MockHttpServletResponse;
public class GetMapIntegrationTest extends WMSTestSupport {
@Override
protected void setUpTestData(SystemTestData testData) throws Exception {
super.setUpTestData(testData);
testData.setUpWcs10RasterLayers();
}
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
Catalog catalog=getCatalog();
testData.addStyle("indexed","indexed.sld",getClass(),catalog);
testData.addStyle("crop_raster","CropTransform.sld",getClass(),catalog);
testData.addStyle("lakeScale", "lakeScale.sld", getClass(), catalog);
Map<LayerProperty, Object> props = new HashMap<>();
props.put(LayerProperty.STYLE, "indexed");
testData.addRasterLayer(new QName(MockData.SF_URI, "indexed", MockData.SF_PREFIX),
"indexed.tif", "tif", props,getClass(),catalog);
props.put(LayerProperty.STYLE, "raster");
testData.addRasterLayer(new QName(MockData.SF_URI, "paletted", MockData.SF_PREFIX),
"paletted.tif", "tif", props,getClass(),catalog);
testData.addRasterLayer(new QName(MockData.SF_URI, "mosaic", MockData.SF_PREFIX),
"raster-filter-test.zip",null, props,SystemTestData.class, catalog);
testData.addRasterLayer(new QName(MockData.SF_URI, "fourbits", MockData.SF_PREFIX),
"fourbits.zip", null, props,SystemTestData.class,catalog);
}
@Test
public void testIndexed() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wms?LAYERS=sf:indexed&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1"
+ "&REQUEST=GetMap&SRS=EPSG:4326&BBOX=100,78,104,80&WIDTH=300&HEIGHT=150");
assertEquals("image/png", response.getContentType());
RenderedImage image = ImageIO.read(getBinaryInputStream(response));
image = new ImageWorker(image).forceComponentColorModel().getRenderedImage();
ImageAssert.assertEquals(new File(
"src/test/resources/org/geoserver/wms/map/indexed-expected.png"), image, 0);
}
@Test
public void testIndexedBlackBG() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wms?bgcolor=0x000000&LAYERS=sf:indexed&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1"
+ "&REQUEST=GetMap&SRS=EPSG:4326&BBOX=100,78,104,80&WIDTH=300&HEIGHT=150&transparent=false");
assertEquals("image/png", response.getContentType());
RenderedImage image = ImageIO.read(getBinaryInputStream(response));
ImageAssert.assertEquals(new File(
"src/test/resources/org/geoserver/wms/map/indexed-bg-expected.png"), image, 0);
}
@Test
public void testRasterFilterRed() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
"&REQUEST=GetMap&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150&transparent=false&CQL_FILTER=location like 'red%25'");
assertEquals("image/png", response.getContentType());
// check we got the
RenderedImage image = ImageIO.read(getBinaryInputStream(response));
int[] pixel = new int[3];
image.getData().getPixel(0, 0, pixel);
assertEquals(255, pixel[0]);
assertEquals(0, pixel[1]);
assertEquals(0, pixel[2]);
}
@Test
public void testRasterFilterGreen() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
"&REQUEST=GetMap&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150&transparent=false&CQL_FILTER=location like 'green%25'");
assertEquals("image/png", response.getContentType());
RenderedImage image = ImageIO.read(getBinaryInputStream(response));
int[] pixel = new int[3];
image.getData().getPixel(0, 0, pixel);
assertEquals(0, pixel[0]);
assertEquals(255, pixel[1]);
assertEquals(0, pixel[2]);
}
@Test
public void testMosaicTwice() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
"&REQUEST=GetMap&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150&transparent=false");
assertEquals("image/png", response.getContentType());
response = getAsServletResponse("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
"&REQUEST=GetMap&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150&transparent=false");
assertEquals("image/png", response.getContentType());
}
@Test
public void testIndexedTransparency() throws Exception {
String request = "wms?LAYERS=sf:paletted&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS" +
"&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A3174" +
"&BBOX=-3256153.625,826440.25,-2756153.625,1326440.25" +
"&WIDTH=256&HEIGHT=256&transparent=true";
MockHttpServletResponse response = getAsServletResponse(request);
assertEquals("image/png", response.getContentType());
RenderedImage image = ImageIO.read(getBinaryInputStream(response));
assertTrue(image.getColorModel().hasAlpha());
int[] rgba = new int[4];
// transparent pixel in the top left corner
image.getData().getPixel(0, 0, rgba);
assertEquals(0, rgba[3]);
// solid pixel in the lower right corner
image.getData().getPixel(255, 255, rgba);
assertEquals(255, rgba[3]);
}
@Test
public void testFourBits() throws Exception {
String request = "wms?LAYERS=sf:fourbits&STYLES=&FORMAT=image/png" +
"&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A4269" +
"&BBOX=-118.58930224611,45.862378906251,-118.33030957033,45.974688476563" +
"&WIDTH=761&HEIGHT=330";
MockHttpServletResponse response = getAsServletResponse(request);
assertEquals("image/png", response.getContentType());
}
/**
* https://osgeo-org.atlassian.net/browse/GEOS-4893, make meta-tiler work
* with WMS 1.3 as well
* @throws Exception
*/
@Test
public void testMetaWMS13() throws Exception {
String wms11 = "wms?LAYERS=cite%3ALakes&STYLES=&FORMAT=image%2Fpng&TILED=true&TILESORIGIN=0.0006%2C-0.0018" +
"&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A4326&BBOX=0.0006,-0.0018,0.0031,0.0007&WIDTH=256&HEIGHT=256";
String wms13 = "wms?LAYERS=cite%3ALakes&STYLES=&FORMAT=image%2Fpng&TILED=true&TILESORIGIN=-0.0018%2C0.0006" +
"&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&CRS=EPSG%3A4326&BBOX=-0.0018,0.0006,0.0007,0.0031&WIDTH=256&HEIGHT=256";
BufferedImage image11 = getAsImage(wms11, "image/png");
BufferedImage image13 = getAsImage(wms13, "image/png");
// compare the general structure
assertEquals(image11.getWidth(), image13.getWidth());
assertEquals(image11.getHeight(), image13.getHeight());
assertEquals(image11.getColorModel(), image13.getColorModel());
assertEquals(image11.getSampleModel(), image13.getSampleModel());
// compare the actual data
DataBufferByte db11 = (DataBufferByte) image11.getData().getDataBuffer();
DataBufferByte db13 = (DataBufferByte) image13.getData().getDataBuffer();
byte[][] bankData11 = db11.getBankData();
byte[][] bankData13 = db13.getBankData();
for (int i = 0; i < bankData11.length; i++) {
assertTrue(Arrays.equals(bankData11[i], bankData13[i]));
}
}
@Test
public void testOpenLayersProxy() throws Exception {
NamespaceContext oldContext = XMLUnit.getXpathNamespaceContext();
try {
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("xhtml", "http://www.w3.org/1999/xhtml");
registerNamespaces(namespaces);
XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces));
// setup a proxy base url
GeoServerInfo global = getGeoServer().getGlobal();
global.getSettings().setProxyBaseUrl("http://www.geoserver.org:1234/gs");
getGeoServer().save(global);
Document dom = getAsDOM("wms?LAYERS=sf:indexed&STYLES=&FORMAT=application/openlayers&SERVICE=WMS&VERSION=1.1.1"
+ "&REQUEST=GetMap&SRS=EPSG:4326&BBOX=100,78,104,80&WIDTH=300&HEIGHT=150");
assertXpathEvaluatesTo("http://www.geoserver.org:1234/gs/openlayers/OpenLayers.js",
"//xhtml:script[contains(@src, 'OpenLayers.js')]/@src", dom);
} finally {
XMLUnit.setXpathNamespaceContext(oldContext);
}
}
@Test
public void testRasterRenderingTx() throws Exception {
System.out.println(getCatalog().getCoverages());
String layer = getLayerId(MockData.USA_WORLDIMG);
String url = "wms?service=WMS&VERSION=1.1.1&request=GetMap&styles="
+ "&format=image/png&layers=" + layer + "&WIDTH=100&HEIGHT=100"
+ "&srs=epsg:4326&BBOX=-130,49,-125,54";
BufferedImage image = getAsImage(url, "image/png");
Color color = getPixelColor(image, 25, 25);
// the color is not white, nor white-ish
assertTrue(color.getRed() + color.getGreen() + color.getBlue() < (250 * 3));
// now crop and check the image is cut
url = "wms?service=WMS&VERSION=1.1.1&request=GetMap&styles=crop_raster"
+ "&format=image/png&layers=" + layer + "&WIDTH=100&HEIGHT=100"
+ "&srs=epsg:4326&BBOX=-130,49,-125,54";
image = getAsImage(url, "image/png");
color = getPixelColor(image, 25, 25);
// the color is white, or white-ish
assertTrue(color.getRed() + color.getGreen() + color.getBlue() > (250 * 3));
}
@Test
public void testRasterRenderingTxOutOfBbox() throws Exception {
String layer = getLayerId(MockData.USA_WORLDIMG);
String url = "wms?service=WMS&VERSION=1.1.1&request=GetMap&styles=crop_raster"
+ "&format=image/png&layers=" + layer + "&WIDTH=100&HEIGHT=100"
+ "&srs=epsg:4326&BBOX=-120,40,-115,45";
BufferedImage image = getAsImage(url, "image/png");
Color color = getPixelColor(image, 25, 25);
// the color is white, or white-ish
assertTrue(color.getRed() + color.getGreen() + color.getBlue() > (250 * 3));
}
@Test
public void testGetMapWithPropertyStyle() throws Exception {
Properties props = new Properties();
props.put("type", "point");
props.put("color", "00ffff");
StringWriter w = new StringWriter();
props.store(w, null);
String bbox = "-180,-90,180,90";
String layer = getLayerId(CiteTestData.POINTS);
MockHttpServletResponse response = getAsServletResponse("wms?bbox=" + bbox +
"&layers=" + layer +
"&sld_body=" + w.toString() +
"&style_format=" + PropertyStyleHandler.FORMAT +
"&Format=image/png" + "&request=GetMap" +
"&width=550" + "&height=250" + "&srs=EPSG:4326");
checkImage(response);
}
@Test
public void testScaleMethod() throws Exception {
// first request, no scale method, scale is roughly 1:20k
String request = "wms?&LAYERS=" + getLayerId(MockData.LAKES)
+ "&STYLES=lakeScale&FORMAT=image%2Fpng"
+ "&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A4326"
+ "&BBOX=0,-0.002,0.00451,0&WIDTH=88&HEIGHT=44";
BufferedImage bi = getAsImage(request, "image/png");
assertNotBlank("Image should contain the polygon, scale denominator 20k", bi);
bi = getAsImage(request + "&scaleMethod=Accurate", "image/png");
assertBlank("Image should not contain the polygon, scale is just below 1:20", bi);
}
}