Package org.geoserver.wms.wms_1_1_1

Source Code of org.geoserver.wms.wms_1_1_1.GetFeatureInfoTest

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2014 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wms.wms_1_1_1;

import static org.junit.Assert.*;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

import javax.xml.namespace.QName;

import org.custommonkey.xmlunit.XMLAssert;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ProjectionPolicy;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WMSLayerInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.data.test.SystemTestData.LayerProperty;
import org.geoserver.test.RemoteOWSTestSupport;
import org.geoserver.wfs.WFSInfo;
import org.geoserver.wms.WMSInfo;
import org.geoserver.wms.WMSTestSupport;
import org.geoserver.wms.featureinfo.*;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope3D;
import org.geotools.referencing.CRS;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Rule;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.util.logging.Logging;
import org.junit.Test;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.w3c.dom.Document;

import com.mockrunner.mock.web.MockHttpServletResponse;

public class GetFeatureInfoTest extends WMSTestSupport {
   
    public static String WCS_PREFIX = "wcs";
    public static String WCS_URI = "http://www.opengis.net/wcs/1.1.1";
    public static QName TASMANIA_BM = new QName(WCS_URI, "BlueMarble", WCS_PREFIX);
    public static QName SQUARES = new QName(MockData.CITE_URI, "squares", MockData.CITE_PREFIX);
    public static QName CUSTOM = new QName(MockData.CITE_URI, "custom", MockData.CITE_PREFIX);
   
    public static QName POINT_TEST_2D = new QName(MockData.CITE_URI, "point_test_2d", MockData.CITE_PREFIX);
    public static QName POINT_TEST_3D = new QName(MockData.CITE_URI, "point_test_3d", MockData.CITE_PREFIX);

    @Override
    protected void onSetUp(SystemTestData testData) throws Exception {
        super.onSetUp(testData);
        Logging.getLogger("org.geoserver.ows").setLevel(Level.OFF);
       
        // setup buffer
        WMSInfo wmsInfo = getGeoServer().getService(WMSInfo.class);
        wmsInfo.setMaxBuffer(50);
        getGeoServer().save(wmsInfo);
       
        // force feature bounding in WFS
        WFSInfo wfsInfo = getGeoServer().getService(WFSInfo.class);
        wfsInfo.setFeatureBounding(true);
        getGeoServer().save(wfsInfo);
       
        // add a wms store too, if possible
        if (RemoteOWSTestSupport.isRemoteWMSStatesAvailable(LOGGER)) {
            // setup the wms store, resource and layer
            CatalogBuilder cb = new CatalogBuilder(getCatalog());
            WMSStoreInfo wms = cb.buildWMSStore("demo");
            wms.setCapabilitiesURL(RemoteOWSTestSupport.WMS_SERVER_URL
                    + "service=WMS&request=GetCapabilities");
            getCatalog().save(wms);
            cb.setStore(wms);
            WMSLayerInfo states = cb.buildWMSLayer("topp:states");
            states.setName("rstates");
            getCatalog().add(states);
            LayerInfo layer = cb.buildLayer(states);
            getCatalog().add(layer);
        }
        Catalog catalog = getCatalog();
        testData.addStyle("thickStroke","thickStroke.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("paramStroke","paramStroke.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("raster","raster.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("rasterScales","rasterScales.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("squares","squares.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("point_test","point_test.sld",GetFeatureInfoTest.class,catalog);
        testData.addStyle("scaleBased","scaleBased.sld",GetFeatureInfoTest.class,catalog);
        testData.addVectorLayer(SQUARES,Collections.EMPTY_MAP,"squares.properties",
                GetFeatureInfoTest.class,catalog);
        Map propertyMap = new HashMap<SystemTestData.LayerProperty, Object>();
        propertyMap.put(LayerProperty.STYLE,"raster");
        testData.addRasterLayer(TASMANIA_BM, "tazbm.tiff","tiff",propertyMap,
                SystemTestData.class,catalog);
        testData.addRasterLayer(new QName(MockData.SF_URI, "mosaic", MockData.SF_PREFIX),
                "raster-filter-test.zip",null, propertyMap,SystemTestData.class, catalog);
        testData.addRasterLayer(CUSTOM,
                "custom.zip", null,propertyMap,GetFeatureInfoTest.class, catalog);
       
        Map<LayerProperty, Object> properties = new HashMap<SystemTestData.LayerProperty, Object>();
        properties.put(LayerProperty.LATLON_ENVELOPE, new ReferencedEnvelope(130.875825803896,
                130.898939990319, -16.4491956225999, -16.4338185791628, CRS.decode("EPSG:4326")));
        properties.put(LayerProperty.ENVELOPE, new ReferencedEnvelope(130.875825803896,
                130.898939990319, -16.4491956225999, -16.4338185791628, CRS.decode("EPSG:4326")));
        properties.put(LayerProperty.SRS, 4326);

        testData.addVectorLayer(POINT_TEST_2D, properties, "point_test_2d.properties",
                GetFeatureInfoTest.class, catalog);

        properties = new HashMap<SystemTestData.LayerProperty, Object>();
        properties.put(LayerProperty.LATLON_ENVELOPE, new ReferencedEnvelope(130.875825803896,
                130.898939990319, -16.4491956225999, -16.4338185791628, CRS.decode("EPSG:4326")));
        properties.put(LayerProperty.ENVELOPE, new ReferencedEnvelope3D(130.875825803896,
                130.898939990319, -16.4491956225999, -16.4338185791628, 95.1442741322517,
                98.1069524121285, CRS.decode("EPSG:4326")));
        properties.put(LayerProperty.SRS, 4939);
        testData.addVectorLayer(POINT_TEST_3D, properties, "point_test_3d.properties",
                GetFeatureInfoTest.class, catalog);
    }
   
   

   
    /**
     * Test GetFeatureInfo with 3D content, and the result returns the expected point.
     */
    @Test
    public void testPoint3d() throws Exception {

        FeatureTypeInfo info = getCatalog()
                .getFeatureTypeByName(MockData.CITE_URI, "point_test_3d");

        ReferencedEnvelope b = info.getLatLonBoundingBox();
        String bbox = b.minX() + "," + b.minY() + "," + b.maxX() + "," + b.maxY()
                + "&srs=EPSG:4326";

        // first request against 2D dataset
        String layer2d = getLayerId(POINT_TEST_2D);
        String base2d = "wms?version=1.1.1&format=png&info_format=text/html&request=GetFeatureInfo&layers="
                + layer2d
                + "&query_layers="
                + layer2d
                + "&styles=point_test&bbox="
                + bbox
                + "&feature_count=10";

        Document dom2d = getAsDOM(base2d + "&width=" + 10 + "&height=" + 10 + "&x=" + 5 + "&y=" + 5);
        // print(dom2d);
        XMLAssert.assertXpathEvaluatesTo("11", "count(/html/body/table/tr)", dom2d);

        // second request against 3D dataset
        String layer3d = getLayerId(POINT_TEST_3D);
        String base3d = "wms?version=1.1.1&format=png&info_format=text/html&request=GetFeatureInfo&layers="
                + layer3d
                + "&query_layers="
                + layer3d
                + "&styles=point_test&bbox="
                + bbox
                + "&feature_count=10";

        Document dom3d = getAsDOM(base3d + "&width=" + 10 + "&height=" + 10 + "&x=" + 5 + "&y=" + 5);
        // print(dom3d);
        XMLAssert.assertXpathEvaluatesTo("11", "count(/html/body/table/tr)", dom3d);

    }


  /**
     * Tests GML output does not break when asking for an area that has no data with
     * GML feature bounding enabled
     *
     * @param contentType Content-type (MIME-type) to test on.
     * @throws Exception When an XPath Exception occurs.
     */
    private void testGMLNoData(String contentType) throws Exception {
        String layer = getLayerId(MockData.PONDS);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=" + contentType +"&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=20&y=20";
        Document dom = getAsDOM(request);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//wfs:FeatureCollection)", dom);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//gml:featureMember)", dom);
    }

    /**
     * Tests GML output does not break when asking for an area that has no data with
     * GML feature bounding enabled. This method tests GML 2 with Content-Type:
     * <code>application/vnd.ogc.gml</code>.
     *
     * @throws Exception
     */
    @Test
    public void testGMLNoData() throws Exception {
        this.testGMLNoData(GML2FeatureInfoOutputFormat.FORMAT);
    }

    /**
     * Tests GML output does not break when asking for an area that has no data with
     * GML feature bounding enabled. This method tests GML 2 with Content-Type:
     * <code>text/xml</code>.
     *
     * @throws Exception
     */
    @Test
    public void testXMLNoData() throws Exception {
        this.testGMLNoData(XML2FeatureInfoOutputFormat.FORMAT);
    }

    /**
     * Tests GML output does not break when asking for an area that has no data with
     * GML feature bounding enabled. This method tests GML 3.1.1 with Content-Type:
     * <code>text/xml; subtype=gml/3.1.1</code>.
     *
     * @throws Exception
     */
    @Test
    public void testXML311NoData() throws Exception {
        this.testGMLNoData(XML311FeatureInfoOutputFormat.FORMAT);
    }
   
    /**
     * Tests GML outside of
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testSimple() throws Exception {
        String layer = getLayerId(MockData.FORESTS);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        String result = getAsString(request);
        //System.out.println(result);
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
    }
   
    @Test
    public void testAllowedMimeTypes() throws Exception {
       
        WMSInfo wms = getWMS().getServiceInfo();
        GetFeatureInfoOutputFormat format = new TextFeatureInfoOutputFormat(getWMS());       
        wms.getGetFeatureInfoMimeTypes().add(format.getContentType());
        wms.setGetFeatureInfoMimeTypeCheckingEnabled(true);
        getGeoServer().save(wms);

        // check mime type allowed
        String layer = getLayerId(MockData.FORESTS);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        String result = getAsString(request);
        // System.out.println(result);
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
       
        // check mime type not allowed
        request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format="+GML3FeatureInfoOutputFormat.FORMAT+"&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";

        result = getAsString(request);
        assertTrue(result.indexOf("ForbiddenFormat") > 0);       
       
        wms.getGetFeatureInfoMimeTypes().clear();
        wms.setGetFeatureInfoMimeTypeCheckingEnabled(false);
        getGeoServer().save(wms);
        request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format="+GML3FeatureInfoOutputFormat.FORMAT+"&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";

        result = getAsString(request);
        assertTrue(result.indexOf("Green Forest") > 0);
    }

   
   
    /**
     * Tests property selection
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testSelectPropertiesVector() throws Exception {
        String layer = getLayerId(MockData.FORESTS);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg&service=wms" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10&propertyName=NAME,FID";
        String result = getAsString(request);
        System.out.println(result);
        assertNotNull(result);
        int idxGeom = result.indexOf("the_geom");
        int idxFid = result.indexOf("FID");
        int idxName = result.indexOf("NAME");
        assertEquals(-1, idxGeom); // geometry filtered out
        assertTrue(idxFid > 0);
        assertTrue(idxName > 0);
        assertTrue(idxName < idxFid); // properties got reordered as expected
    }
   
    /**
     * Tests a simple GetFeatureInfo works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testSimpleHtml() throws Exception {
        String layer = getLayerId(MockData.FORESTS);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/html&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        Document dom = getAsDOM(request);
     
        // count lines that do contain a forest reference
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'Forests.')])", dom);
       
        MockHttpServletResponse response = getAsServletResponse(request,"");
        // Check if the character encoding is the one expected
        assertTrue("UTF-8".equals(response.getCharacterEncoding()));
    }
   
    /**
     * Tests GetFeatureInfo with a buffer specified works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testBuffer() throws Exception {
        // to setup the request and the buffer I rendered BASIC_POLYGONS using GeoServer, then played
        // against the image coordinates
        String layer = getLayerId(MockData.BASIC_POLYGONS);
        String base = "wms?version=1.1.1&bbox=-4.5,-2.,4.5,7&styles=&format=jpeg&info_format=text/html" +
                "&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=300&height=300";
        Document dom = getAsDOM(base + "&x=85&y=230");
        // make sure the document is empty, as we chose an area with no features inside
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr)", dom);

        // another request that will catch one feature due to the extended buffer, make sure it's in
        dom = getAsDOM(base + "&x=85&y=230&buffer=40");
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'BasicPolygons.')])", dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[. = 'BasicPolygons.1107531493630'])", dom);
       
        // this one would end up catching everything (3 features) if it wasn't that we say the max buffer at 50
        // in the WMS configuration
        dom = getAsDOM(base + "&x=85&y=230&buffer=300");
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'BasicPolygons.')])", dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[. = 'BasicPolygons.1107531493630'])", dom);
    }
   
    /**
     * Tests GetFeatureInfo with a buffer specified works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testAutoBuffer() throws Exception {
        String layer = getLayerId(MockData.BASIC_POLYGONS);
        String base = "wms?version=1.1.1&bbox=-4.5,-2.,4.5,7&format=jpeg&info_format=text/html" +
                "&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=300&height=300&x=111&y=229";
        String url = base + "&styles=";
        Document dom = getAsDOM(url);
        print(dom);
        // make sure the document is empty, the style we chose has thin lines
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr)", dom);

        // another request that will catch one feature due to the style with a thick stroke, make sure it's in
        dom = getAsDOM(base + "&styles=thickStroke");
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'BasicPolygons.')])", dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[. = 'BasicPolygons.1107531493630'])", dom);
    }
   
    /**
     * Tests GetFeatureInfo uses the env params
     *
     * @throws Exception
     */
    @Test
    public void testParameterizedStyle() throws Exception {
        String layer = getLayerId(MockData.BASIC_POLYGONS);
        String base = "wms?version=1.1.1&bbox=-4.5,-2.,4.5,7&format=jpeg&info_format=text/html" +
                "&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=300&height=300&x=111&y=229&styles=paramStroke";
        Document dom = getAsDOM(base);
        // make sure the document is empty, the style we chose has thin lines
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr)", dom);

        // another request that will catch one feature due to the style with a thick stroke, make sure it's in
        dom = getAsDOM(base + "&env=thickness:12");
        // print(dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'BasicPolygons.')])", dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[. = 'BasicPolygons.1107531493630'])", dom);
    }
   
    /**
     * Tests GetFeatureInfo with a buffer specified works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testBufferScales() throws Exception {
        String layer = getLayerId(SQUARES);
        String base = "wms?version=1.1.1&format=png&info_format=text/html&request=GetFeatureInfo&layers="
                + layer
                + "&query_layers="
                + layer
                + "&styles=squares&bbox=0,0,10000,10000&feature_count=10&srs=EPSG:32632";
       
        // first request, should provide no result, scale is 1:100
        int w = (int) (100.0 / 0.28 * 1000); // dpi compensation
        Document dom = getAsDOM(base + "&width=" + w + "&height=" + w + "&x=20&y=" + (w - 20));
        // print(dom);
        // make sure the document is empty, the style we chose has thin lines
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr)", dom);
       
        // second request, should provide oe result, scale is 1:50
        w = (int) (200.0 / 0.28 * 1000); // dpi compensation
        dom = getAsDOM(base + "&width=" + w + "&height=" + w + "&x=20&y=" + (w - 20));
        print(dom);
        XMLAssert.assertXpathEvaluatesTo("1",
                "count(/html/body/table/tr/td[starts-with(.,'squares.')])", dom);
        XMLAssert
                .assertXpathEvaluatesTo("1", "count(/html/body/table/tr/td[. = 'squares.1'])", dom);

        // third request, should provide two result, scale is 1:10
        w = (int) (1000.0 / 0.28 * 1000); // dpi compensation
        dom = getAsDOM(base + "&width=" + w + "&height=" + w + "&x=20&y=" + (w - 20));
        // print(dom);
        XMLAssert.assertXpathEvaluatesTo("2",
                "count(/html/body/table/tr/td[starts-with(.,'squares.')])", dom);
        XMLAssert
                .assertXpathEvaluatesTo("1", "count(/html/body/table/tr/td[. = 'squares.1'])", dom);
        XMLAssert
                .assertXpathEvaluatesTo("1", "count(/html/body/table/tr/td[. = 'squares.2'])", dom);
       
    }
   
    /**
     * Tests a GetFeatureInfo again works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testTwoLayers() throws Exception {
        String layer = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.LAKES);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/html&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        String result = getAsString(request);
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
        // GEOS-2603 GetFeatureInfo returns html tables without css style if more than one layer is selected
        assertTrue(result.indexOf("<style type=\"text/css\">") > 0);
    }
   
    /**
     * Tests a GetFeatureInfo again works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testSelectPropertiesTwoVectorLayers() throws Exception {
        String layer = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.LAKES);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10&buffer=10&service=wms"
                + "&feature_count=2&propertyName=(FID)(NAME)";
        String result = getAsString(request);
        assertNotNull(result);
        int idxGeom = result.indexOf("the_geom");
        int idxLakes= result.indexOf("Lakes");
        int idxFid = result.indexOf("FID");
        int idxName = result.indexOf("NAME");
        assertEquals(-1, idxGeom); // geometry filtered out
        assertTrue(idxFid > 0);
        assertTrue(idxName > 0);
        assertTrue(idxLakes > 0);
        assertTrue(idxFid < idxLakes); // fid only for the first features
        assertTrue(idxName > idxLakes); // name only for the second features
    }
   
    /**
     * Tests a GetFeatureInfo again works, and that the result contains the
     * expected polygon
     *
     * @throws Exception
     */
    @Test
    public void testSelectPropertiesTwoVectorLayersOneList() throws Exception {
        String layer = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.LAKES);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10&buffer=10&service=wms"
                + "&feature_count=2&propertyName=NAME";
        String result = getAsString(request);
        // System.out.println(result);
        assertNotNull(result);
        int idxGeom = result.indexOf("the_geom");
        int idxLakes= result.indexOf("Lakes");
        int idxName1 = result.indexOf("NAME");
        int idxName2 = result.indexOf("NAME", idxLakes);
        assertEquals(-1, idxGeom); // geometry filtered out

        assertTrue(idxName1 > 0);
        assertTrue(idxName2 > 0);
        assertTrue(idxLakes > 0);
        // name in both features
        assertTrue(idxName1 < idxLakes);
        assertTrue(idxName2 > idxLakes);
    }
   
    /**
     * Tests that FEATURE_COUNT is respected globally, not just per layer
     *
     * @throws Exception
     */
    @Test
    public void testTwoLayersFeatureCount() throws Exception {
        // this request hits on two overlapping features, a lake and a forest
        String layer = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.LAKES);
        String request = "wms?REQUEST=GetFeatureInfo&EXCEPTIONS=application%2Fvnd.ogc.se_xml&" +
            "BBOX=-0.002356%2C-0.004819%2C0.005631%2C0.004781&SERVICE=WMS&VERSION=1.1.0&X=267&Y=325" +
            "&INFO_FORMAT=application/vnd.ogc.gml" +
            "&QUERY_LAYERS=" + layer + "&Layers=" + layer + " &Styles=&WIDTH=426&HEIGHT=512" +
              "&format=image%2Fpng&srs=EPSG%3A4326";
        // no feature count, just one should be returned
        Document dom = getAsDOM(request);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//gml:featureMember)", dom);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//cite:Forests)", dom);
       
        // feature count set to 2, both features should be there
        dom = getAsDOM(request + "&FEATURE_COUNT=2");
        // print(dom);
        XMLAssert.assertXpathEvaluatesTo("2", "count(//gml:featureMember)", dom);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//cite:Forests)", dom);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//cite:Lakes)", dom);
    }


    /**
     * Check GetFeatureInfo returns an error if the format is not known, instead
     * of returning the text format as in
     * http://jira.codehaus.org/browse/GEOS-1924
     *
     * @throws Exception
     */
    @Test
    public void testUknownFormat() throws Exception {
        String layer = MockData.FORESTS.getPrefix() + ":" + MockData.FORESTS.getLocalPart();
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg&info_format=unknown/format&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        Document doc = dom(get(request), true);
        // print(doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//ServiceExceptionReport/ServiceException)",
                doc);
        XMLAssert.assertXpathEvaluatesTo("InvalidFormat",
                "/ServiceExceptionReport/ServiceException/@code", doc);
        XMLAssert.assertXpathEvaluatesTo("info_format",
                "/ServiceExceptionReport/ServiceException/@locator", doc);
    }
   
    @Test
    public void testCoverage() throws Exception {
        // http://jira.codehaus.org/browse/GEOS-2574
        String layer = getLayerId(TASMANIA_BM);
        String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
            "&layers=" + layer + "&styles=&bbox=146.5,-44.5,148,-43&width=600&height=600" +
            "&info_format=text/html&query_layers=" + layer + "&x=300&y=300&srs=EPSG:4326";
        Document dom = getAsDOM(request);
        // we also have the charset which may be platf. dep.
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'RED_BAND'])", dom);
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'GREEN_BAND'])",
                dom);
        XMLAssert
                .assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'BLUE_BAND'])", dom);
    }
   
    @Test
    public void testCoveragePropertySelection() throws Exception {
        // http://jira.codehaus.org/browse/GEOS-2574
        String layer = getLayerId(TASMANIA_BM);
        String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
                "&layers=" + layer + "&styles=&bbox=146.5,-44.5,148,-43&width=600&height=600" +
                "&info_format=text/html&query_layers=" + layer + "&x=300&y=300&srs=EPSG:4326&propertyName=RED_BAND";
        Document dom = getAsDOM(request);
        // we also have the charset which may be platf. dep.
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'RED_BAND'])", dom);
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr/th[. = 'GREEN_BAND'])",
                dom);
        XMLAssert
                .assertXpathEvaluatesTo("0", "count(/html/body/table/tr/th[. = 'BLUE_BAND'])", dom);
    }
   
    @Test
    public void testCoverageGML() throws Exception {
        // http://jira.codehaus.org/browse/GEOS-3996
        String layer = getLayerId(TASMANIA_BM);
        String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
                        "&layers=" + layer + "&styles=&bbox=146.5,-44.5,148,-43&width=600&height=600" +
                        "&info_format=application/vnd.ogc.gml&query_layers=" + layer + "&x=300&y=300&srs=EPSG:4326";
        Document dom = getAsDOM(request);
        //print(dom);
       
        XMLAssert.assertXpathEvaluatesTo("26.0",
                "//wfs:FeatureCollection/gml:featureMember/wcs:BlueMarble/wcs:RED_BAND", dom);
        XMLAssert.assertXpathEvaluatesTo("70.0",
                "//wfs:FeatureCollection/gml:featureMember/wcs:BlueMarble/wcs:GREEN_BAND", dom);
        XMLAssert.assertXpathEvaluatesTo("126.0",
                "//wfs:FeatureCollection/gml:featureMember/wcs:BlueMarble/wcs:BLUE_BAND", dom);
    }
   
    @Test
    public void testCoverageScales() throws Exception {
        String layer = getLayerId(TASMANIA_BM);
        String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
                "&layers=" + layer + "&styles=rasterScales&bbox=146.5,-44.5,148,-43" +
                "&info_format=text/html&query_layers=" + layer + "&x=300&y=300&srs=EPSG:4326";
       
        // this one should be blank
        Document dom = getAsDOM(request + "&width=300&height=300");
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr/th)", dom);
       
        // this one should draw the coverage
        dom = getAsDOM(request + "&width=600&height=600");
        // we also have the charset which may be platf. dep.
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'RED_BAND'])", dom);
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'GREEN_BAND'])",
                dom);
        XMLAssert
                .assertXpathEvaluatesTo("1", "count(/html/body/table/tr/th[. = 'BLUE_BAND'])", dom);
    }
   
    @Test
    public void testOutsideCoverage() throws Exception {
        // a request which is way large on the west side, lots of blank space
        String layer = getLayerId(TASMANIA_BM);
        String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
                "&layers=" + layer + "&styles=raster&bbox=0,-90,148,-43" +
                "&info_format=text/html&query_layers=" + layer + "&width=300&height=300&x=10&y=150&srs=EPSG:4326";
       
        // this one should be blank, but not be a service exception
        Document dom = getAsDOM(request + "");
        XMLAssert.assertXpathEvaluatesTo("1", "count(/html)", dom);
        XMLAssert.assertXpathEvaluatesTo("0", "count(/html/body/table/tr/th)", dom);
    }
   
    /**
     * Check we report back an exception when query_layer contains layers not part of LAYERS
     * @throws Exception
     */
    @Test
    public void testUnkonwnQueryLayer() throws Exception {
        String layers1 = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.LAKES);
        String layers2 = getLayerId(MockData.FORESTS) + "," + getLayerId(MockData.BRIDGES);
        String request = "wms?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg&info_format=text/html&request=GetFeatureInfo&layers="
                + layers1 + "&query_layers=" + layers2 + "&width=20&height=20&x=10&y=10&info";
       
        Document dom = getAsDOM(request + "");
        XMLAssert.assertXpathEvaluatesTo("1", "count(/ServiceExceptionReport)", dom);
    }
   
    @Test
    public void testLayerQualified() throws Exception {
        String layer = "Forests";
        String q = "?version=1.1.1&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        String request = "cite/Ponds/wms" + q;
        Document dom = getAsDOM(request);
        assertEquals("ServiceExceptionReport", dom.getDocumentElement().getNodeName());
       
        request = "cite/Forests/wms" + q;
        String result = getAsString(request);
        //System.out.println(result);
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
    }
   
    @Test
    public void testGroupWorkspaceQualified() throws Exception {
        // check the group works without workspace qualification
        String url = "wms?service=wms&version=1.1.1"
                + "&layers=nature&width=100&height=100&format=image/png"
                + "&srs=epsg:4326&bbox=-0.002,-0.003,0.005,0.002&info_format=text/plain" +
                    "&request=GetFeatureInfo&query_layers=nature&x=50&y=50&feature_count=2";
        String result = getAsString(url);
        assertTrue(result.indexOf("Blue Lake") > 0);
        assertTrue(result.indexOf("Green Forest") > 0);

        // check that it still works when workspace qualified
        result = getAsString("cite/" + url);
        assertTrue(result.indexOf("Blue Lake") > 0);
        assertTrue(result.indexOf("Green Forest") > 0);
       
        // but we have nothing if the workspace
        Document dom = getAsDOM("cdf/" + url);
        assertEquals("ServiceExceptionReport", dom.getDocumentElement().getNodeName());
    }
   
    @Test
    public void testNonExactVersion() throws Exception {
        String layer = getLayerId(MockData.FORESTS);
        String request = "wms?version=1.0.0&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
                "&info_format=text/plain&request=GetFeatureInfo&layers="
                + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        String result = getAsString(request);
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
       
        request = "wms?version=1.1.0&bbox=-0.002,-0.002,0.002,0.002&styles=&format=jpeg" +
        "&info_format=text/plain&request=GetFeatureInfo&layers="
        + layer + "&query_layers=" + layer + "&width=20&height=20&x=10&y=10";
        result = getAsString(request);
       
        assertNotNull(result);
        assertTrue(result.indexOf("Green Forest") > 0);
    }
   
    @Test
    public void testRasterFilterRed() throws Exception {
        String response = getAsString("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=" +
            "&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
                "&REQUEST=GetFeatureInfo&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150" +
                "&transparent=false&CQL_FILTER=location like 'red%25' + " +
                "&query_layers=sf:mosaic&x=10&y=10");
       
        assertTrue(response.indexOf("RED_BAND = 255.0") > 0);
        assertTrue(response.indexOf("GREEN_BAND = 0.0") > 0);
        assertTrue(response.indexOf("BLUE_BAND = 0.0") > 0);
    }
   
    @Test
    public void testRasterFilterGreen() throws Exception {
        String response = getAsString("wms?bgcolor=0x000000&LAYERS=sf:mosaic&STYLES=" +
                "&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1" +
                "&REQUEST=GetFeatureInfo&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=150&HEIGHT=150" +
                "&transparent=false&CQL_FILTER=location like 'green%25' + " +
                "&query_layers=sf:mosaic&x=10&y=10");
       
        assertTrue(response.indexOf("RED_BAND = 0.0") > 0);
        assertTrue(response.indexOf("GREEN_BAND = 255.0") > 0);
        assertTrue(response.indexOf("BLUE_BAND = 0.0") > 0);
    }
   
   @Test
   public void testPropertySelectionWmsCascade() throws Exception {
       if (!RemoteOWSTestSupport.isRemoteWMSStatesAvailable(LOGGER)) {
           LOGGER.log(Level.WARNING, "Skipping testPropertySelectionWmsCascade");
           return;
       }
      
       String result = getAsString("wms?REQUEST=GetFeatureInfo" +
           "&BBOX=-132.835937%2C21.132813%2C-64.867187%2C55.117188" +
           "&SERVICE=WMS&INFO_FORMAT=text/plain" +
           "&QUERY_LAYERS=rstates&FEATURE_COUNT=50&Layers=rstates&WIDTH=300&HEIGHT=150" +
           "&format=image%2Fpng&styles=&srs=EPSG%3A4326&version=1.1.1&x=149&y=70&propertyName=STATE_ABBR,STATE_NAME");
      
       // System.out.println(result);
      
       int idxGeom = result.indexOf("the_geom");
       int idxName = result.indexOf("STATE_NAME");
       int idxFips = result.indexOf("STATE_FIPS");
       int idxAbbr = result.indexOf("STATE_ABBR");
       assertEquals(-1, idxGeom);
       assertEquals(-1, idxFips);
       assertTrue(idxAbbr > 0);
       assertTrue(idxName > 0);
       assertTrue(idxAbbr < idxName);
   }
   
  
   @Test
   public void testRasterKeepNative() throws Exception {
       // force it to "keep native"
       CoverageInfo ci = getCatalog().getCoverageByName(getLayerId(CUSTOM));
       ci.setProjectionPolicy(ProjectionPolicy.NONE);
       getCatalog().save(ci);
      
       // make a first reprojected request on a pixel that's black (0)
       String result = getAsString("wms?REQUEST=GetFeatureInfo&EXCEPTIONS=application%2Fvnd.ogc.se_xml" +
           "&BBOX=-887430.34934%2C4467316.30601%2C-885862.361705%2C4468893.535223&SERVICE=WMS" +
           "&INFO_FORMAT=text%2Fplain&QUERY_LAYERS=cite%3Acustom&FEATURE_COUNT=50&Layers=custom" +
           "&WIDTH=509&HEIGHT=512&format=image%2Fjpeg&styles=&srs=epsg%3A900913&version=1.1.1&x=177&y=225");
       assertTrue(result.contains("0.0"));
      
       // and now one with actual data, 2
       result = getAsString("wms?REQUEST=GetFeatureInfo&EXCEPTIONS=application%2Fvnd.ogc.se_xml" +
               "&BBOX=-887430.34934%2C4467316.30601%2C-885862.361705%2C4468893.535223&SERVICE=WMS" +
               "&INFO_FORMAT=text%2Fplain&QUERY_LAYERS=cite%3Acustom&FEATURE_COUNT=50&Layers=custom" +
               "&WIDTH=509&HEIGHT=512&format=image%2Fjpeg&styles=&srs=epsg%3A900913&version=1.1.1&x=135&y=223");
       assertTrue(result.contains("2.0"));
   }

   @Test
   public void testGMLWithPostFilter() throws Exception {
       //we need to create a situation where a post filter is setup, simple way is to change the
       // style so that its filter is an or with more than 20 children
       Catalog cat = getCatalog();
       LayerInfo l = cat.getLayerByName(getLayerId(MockData.NAMED_PLACES));

       StyleInfo style = l.getDefaultStyle();
       Style s = style.getStyle();

       FeatureTypeStyle fts = s.featureTypeStyles().get(0);
       FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
       StyleFactory sf = CommonFactoryFinder.getStyleFactory();
       for (int i = 0; i < 21; i++) {
           Filter f = ff.equals(ff.literal(1), ff.literal(1));
           Rule r = sf.createRule();
           r.setFilter(f);
           r.symbolizers().add(sf.createPolygonSymbolizer());
           fts.rules().add(r);
       }

       cat.getResourcePool().writeStyle(style, s);
       cat.save(style);

       String layer = getLayerId(MockData.NAMED_PLACES);
      
       String request = "wms?service=wms&request=GetFeatureInfo&version=1.1.1" +
                       "&layers=" + layer + "&styles=&bbox=0.000004,-0.00285,0.005596,0.00415&width=409&height=512" +
                       "&info_format=application/vnd.ogc.gml&query_layers=" + layer + "&x=194&y=229&srs=EPSG:4326";
       Document dom = getAsDOM(request);
       assertEquals("wfs:FeatureCollection", dom.getDocumentElement().getNodeName());
   }
  
   /**
    * The rendering engine has a 10-6 tolerance when evaluating rule scale activation, GetFeatureInfo did not
    * @throws Exception
    */
   @Test
   public void testScaleTolerance() throws Exception {
       String layer = getLayerId(MockData.BASIC_POLYGONS);
       String getMap = "wms?version=1.1.1&bbox=-10000,20000,10000,40000&srs=EPSG:900913&styles=scaleBased&format=image/png&info_format=text/html" +
               "&request=GetMap&layers="
               + layer + "&query_layers=" + layer + "&width=2041&height=2041";
      
       BufferedImage image = getAsImage(getMap, "image/png");
       // ImageIO.write(image, "png", new File("/tmp/test.png"));
       assertPixel(image, 150, 150, Color.BLUE);
   }
  
}
TOP

Related Classes of org.geoserver.wms.wms_1_1_1.GetFeatureInfoTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.