/* (c) 2014 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.test; import org.geotools.geometry.jts.JTS; import org.geotools.referencing.CRS; import org.junit.Test; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import org.w3c.dom.Document; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; /** * This is to test spatial (bbox) queries for complex features * * @author Derrick Wong, Curtin University of Technology */ public class BBoxFilterTest extends AbstractAppSchemaTestSupport { private final String WFS_GET_FEATURE = "wfs?request=GetFeature&version=1.1.0&typename=ex:geomContainer"; private final String WFS_GET_FEATURE_LOG = "WFS GetFeature&typename=ex:geomContainerresponse:\n"; private final String LONGLAT = "&BBOX=130,-29,134,-24"; private final String LATLONG = "&BBOX=-29,130,-24,134"; private final String EPSG_4326 = "EPSG:4326"; private final String EPSG_4283 = "urn:x-ogc:def:crs:EPSG:4283"; protected BBoxMockData createTestData() { return new BBoxMockData(); } /** * The following performs a WFS request and obtains all features specified in * BBoxTestPropertyfile.properties */ @Test public void testQuery() { Document doc = getAsDOM(WFS_GET_FEATURE); LOGGER.info(WFS_GET_FEATURE_LOG + prettyString(doc)); assertXpathEvaluatesTo("3", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(3, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering longitude * latitude. */ @Test public void testQueryBboxLongLat() { Document doc = getAsDOM(WFS_GET_FEATURE + LONGLAT); LOGGER.info(WFS_GET_FEATURE_LOG + LONGLAT + prettyString(doc)); assertXpathEvaluatesTo("0", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(0, "//ex:geomContainer", doc); } /** * This uses long lat bbox, with srsName specified in long lat format (EPSG code). This should return the results. */ @Test public void testQueryBboxLongLatEPSGCode() { Document doc = getAsDOM(WFS_GET_FEATURE + LONGLAT + ",EPSG:4326"); LOGGER.info(WFS_GET_FEATURE_LOG + LONGLAT + prettyString(doc)); assertXpathEvaluatesTo("2", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(2, "//ex:geomContainer", doc); } /** * This uses long lat bbox, with srsName specified in lat long format (URN). This should not return the results. */ @Test public void testQueryBboxLongLatURN() { Document doc = getAsDOM(WFS_GET_FEATURE + LONGLAT + ",urn:x-ogc:def:crs:EPSG:4326"); LOGGER.info(WFS_GET_FEATURE_LOG + LONGLAT + prettyString(doc)); assertXpathEvaluatesTo("0", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(0, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering latitude * longitude. This test should return features since WFS 1.1.0 defaults to lat long if unspecified. */ @Test public void testQueryBboxLatLong() { Document doc = getAsDOM(WFS_GET_FEATURE + LATLONG); LOGGER.info(WFS_GET_FEATURE_LOG + LATLONG + prettyString(doc)); assertXpathEvaluatesTo("2", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(2, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering latitude * longitude and srsName in EPSG code format. This test should not return features if the axis ordering behaves similar to queries * to Simple features. */ @Test public void testQueryBboxLatLongEPSGCode() { Document doc = getAsDOM(WFS_GET_FEATURE + LATLONG + ",EPSG:4326"); LOGGER.info(WFS_GET_FEATURE_LOG + LATLONG + prettyString(doc)); assertXpathEvaluatesTo("0", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(0, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering latitude * longitude and srsName in URN format. This test should return features if the axis ordering behaves similar to queries * to Simple features. */ @Test public void testQueryBboxLatLongURN() { Document doc = getAsDOM(WFS_GET_FEATURE + LATLONG + ",urn:x-ogc:def:crs:EPSG:4326"); LOGGER.info(WFS_GET_FEATURE_LOG + LATLONG + prettyString(doc)); assertXpathEvaluatesTo("2", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(2, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering latitude * longitude and srsName in URN format using POST request (GEOS-6216). * This test should return features if the axis ordering behaves similar to queries * to Simple features. */ @Test public void testQueryBboxLatLongPost() { String xml = "<wfs:GetFeature service=\"WFS\" version=\"1.1.0\" " // + "xmlns:ogc=\"http://www.opengis.net/ogc\" " // + "xmlns:wfs=\"http://www.opengis.net/wfs\" " // + "xmlns:gml=\"http://www.opengis.net/gml\" " // + "xmlns:ex=\"http://example.com\" " // + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " // + "xsi:schemaLocation=\"" // + "http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd \">" // + "<wfs:Query typeName=\"ex:geomContainer\">" // + " <ogc:Filter>" // + " <ogc:BBOX>" // + " <ogc:PropertyName>ex:geom</ogc:PropertyName>" // + " <gml:Envelope srsName=\"urn:x-ogc:def:crs:EPSG:4326\">" // + " <gml:lowerCorner>-29 130</gml:lowerCorner>" // + " <gml:upperCorner>-24 134</gml:upperCorner>" // + " </gml:Envelope>" // + " </ogc:BBOX>" // + " </ogc:Filter>" // + "</wfs:Query>" // + "</wfs:GetFeature>"; // validate(xml); Document doc = postAsDOM("wfs", xml); LOGGER.info(WFS_GET_FEATURE_LOG + " with POST filter " + prettyString(doc)); assertXpathEvaluatesTo("2", "/wfs:FeatureCollection/@numberOfFeatures", doc); assertXpathCount(2, "//ex:geomContainer", doc); } /** * The following performs a WFS request specifying a BBOX parameter of axis ordering longitude * latitude along with srs reprojection. */ @Test public void testQueryBboxLatLongSrs4283() throws NoSuchAuthorityCodeException, FactoryException, MismatchedDimensionException, TransformException { Document doc = getAsDOM(WFS_GET_FEATURE + LATLONG + "&srsName=urn:x-ogc:def:crs:EPSG:4283"); LOGGER.info(WFS_GET_FEATURE_LOG + LONGLAT + prettyString(doc)); CoordinateReferenceSystem sourceCRS = (CoordinateReferenceSystem) CRS.decode(EPSG_4326); CoordinateReferenceSystem targetCRS = (CoordinateReferenceSystem) CRS.decode(EPSG_4283); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS); GeometryFactory factory = new GeometryFactory(); Point targetPoint = (Point) JTS.transform(factory .createPoint(new Coordinate(132.61, -26.98)), transform); String targetPointCoord1 = targetPoint.getCoordinate().x + " " + targetPoint.getCoordinate().y; targetPoint = (Point) JTS.transform(factory.createPoint(new Coordinate(132.71, -26.46)), transform); String targetPointCoord2 = targetPoint.getCoordinate().x + " " + targetPoint.getCoordinate().y; assertXpathEvaluatesTo("urn:x-ogc:def:crs:EPSG:4283", "//ex:geomContainer[@gml:id='1']/ex:geom/gml:Point/@srsName", doc); assertXpathEvaluatesTo("2", "//ex:geomContainer[@gml:id='1']/ex:geom/gml:Point/@srsDimension", doc); assertXpathEvaluatesTo(targetPointCoord1, "//ex:geomContainer[@gml:id='1']/ex:geom/gml:Point/gml:pos", doc); assertXpathEvaluatesTo( "urn:x-ogc:def:crs:EPSG:4283", "//ex:geomContainer[@gml:id='1']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.1']/ex:geom/gml:Point/@srsName", doc); assertXpathEvaluatesTo( "2", "//ex:geomContainer[@gml:id='1']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.1']/ex:geom/gml:Point/@srsDimension", doc); assertXpathEvaluatesTo( targetPointCoord1, "//ex:geomContainer[@gml:id='1']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.1']/ex:geom/gml:Point/gml:pos", doc); assertXpathEvaluatesTo("urn:x-ogc:def:crs:EPSG:4283", "//ex:geomContainer[@gml:id='2']/ex:geom/gml:Point/@srsName", doc); assertXpathEvaluatesTo("2", "//ex:geomContainer[@gml:id='2']/ex:geom/gml:Point/@srsDimension", doc); assertXpathEvaluatesTo(targetPointCoord2, "//ex:geomContainer[@gml:id='2']/ex:geom/gml:Point/gml:pos", doc); assertXpathEvaluatesTo( "urn:x-ogc:def:crs:EPSG:4283", "//ex:geomContainer[@gml:id='2']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.2']/ex:geom/gml:Point/@srsName", doc); assertXpathEvaluatesTo( "2", "//ex:geomContainer[@gml:id='2']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.2']/ex:geom/gml:Point/@srsDimension", doc); assertXpathEvaluatesTo( targetPointCoord2, "//ex:geomContainer[@gml:id='2']/ex:nestedFeature/ex:nestedGeom[@gml:id='nested.2']/ex:geom/gml:Point/gml:pos", doc); } }