All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opengis.cite.iso19142.joins.SpatialJoinTests Maven / Gradle / Ivy

There is a newer version: 2.0-r18
Show newest version
package org.opengis.cite.iso19142.joins;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;

import javax.xml.namespace.QName;
import javax.xml.xpath.XPathExpressionException;

import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSTypeDefinition;
import org.opengis.cite.geomatics.SpatialOperator;
import org.opengis.cite.iso19142.ConformanceClass;
import org.opengis.cite.iso19142.ErrorMessage;
import org.opengis.cite.iso19142.ErrorMessageKeys;
import org.opengis.cite.iso19142.Namespaces;
import org.opengis.cite.iso19142.ProtocolBinding;
import org.opengis.cite.iso19142.SuiteAttribute;
import org.opengis.cite.iso19142.basic.filter.QueryFilterFixture;
import org.opengis.cite.iso19142.util.AppSchemaUtils;
import org.opengis.cite.iso19142.util.FeatureProperty;
import org.opengis.cite.iso19142.util.ServiceMetadataUtils;
import org.opengis.cite.iso19142.util.XMLUtils;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.SkipException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.sun.jersey.api.client.ClientResponse;

/**
 * A spatial join includes a spatial predicate. One or more of the following
 * spatial predicates must be supported:
 * 
    *
  • Equals
  • *
  • Disjoint
  • *
  • Intersects
  • *
  • Touches
  • *
  • Crosses
  • *
  • Within
  • *
  • Contains
  • *
  • Overlaps
  • *
  • Beyond
  • *
  • DWithin
  • *
* *

* A sample GetFeature request entity is shown below, where the "Intersects" * predicate refers to the geometry properties of two different feature types. *

* *
 * <wfs:GetFeature version="2.0.0" service="WFS" 
 *   xmlns:tns="http://example.org/ns1" 
 *   xmlns:wfs="http://www.opengis.net/wfs/2.0"
 *   xmlns:fes="http://www.opengis.net/fes/2.0">
 *   <wfs:Query typeNames="tns:Parks tns:Lakes">
 *     <fes:Filter>
 *       <fes:Intersects>
 *         <fes:ValueReference>tns:Parks/tns:geometry</fes:ValueReference>
 *         <fes:ValueReference>tns:Lakes/tns:geometry</fes:ValueReference>
 *       </fes:Intersects>
 *     </fes:Filter>
 *   </wfs:Query>
 * </wfs:GetFeature>
 * 
* *

* Sources *

*
    *
  • OGC 09-025r2, 7.9.2.5.3: Join processing
  • *
  • OGC 09-025r2, A.1.12: Spatial joins
  • *
  • OGC 09-026r2, A.8: Test cases for spatial filter
  • *
*/ public class SpatialJoinTests extends QueryFilterFixture { public final static String IMPL_SPATIAL_JOINS = "ImplementsSpatialJoins"; private static final Logger LOGR = Logger.getLogger(SpatialJoinTests.class.getPackage().getName()); private Map> surfaceProps; private Map> curveProps; private Map> pointProps; private Map> spatialCapabilities; /** * Searches the application schema for geometry properties where the value * is an instance of the given type. * * @param gmlTypeName * The name of a GML geometry type (may be abstract). * @return A Map containing, for each feature type name (key), a list of * matching geometry properties (value). */ Map> findGeometryProperties(String gmlTypeName) { Map> geomProps = new HashMap>(); XSTypeDefinition gmlGeomBaseType = getModel().getTypeDefinition(gmlTypeName, Namespaces.GML); for (QName featureType : this.featureTypes) { List geomPropsList = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType, gmlGeomBaseType); if (!geomPropsList.isEmpty()) { geomProps.put(featureType, geomPropsList); } } return geomProps; } /** * Checks the value of the service constraint {@value #IMPL_SPATIAL_JOINS} * in the capabilities document. All tests are skipped if this is not * "TRUE". * * @param testContext * Information about the test run environment. */ @BeforeTest public void implementsSpatialJoins(ITestContext testContext) { this.wfsMetadata = (Document) testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJECT.getName()); String xpath = String.format("//ows:Constraint[@name='%s' and (ows:DefaultValue = 'TRUE')]", IMPL_SPATIAL_JOINS); NodeList result; try { result = XMLUtils.evaluateXPath(this.wfsMetadata, xpath, null); } catch (XPathExpressionException e) { throw new AssertionError(e.getMessage()); } if (result.getLength() == 0) { throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, ConformanceClass.SPATIAL_JOINS.getConstraintName())); } } /** * Initializes the test class fixture. Finds surface, curve, and point * properties defined in the application schema. Properties that use * primitive types are preferred, but if none are defined then aggregate * geometry types (Multi*) will be used instead. */ @BeforeClass public void initFixture() { this.spatialCapabilities = ServiceMetadataUtils.getSpatialCapabilities(this.wfsMetadata); this.surfaceProps = findGeometryProperties("AbstractSurfaceType"); if (this.surfaceProps.isEmpty()) { this.surfaceProps = findGeometryProperties("MultiSurfaceType"); } LOGR.info(this.surfaceProps.toString()); this.curveProps = findGeometryProperties("AbstractCurveType"); if (this.curveProps.isEmpty()) { this.curveProps = findGeometryProperties("MultiCurveType"); } LOGR.info(this.curveProps.toString()); this.pointProps = findGeometryProperties("PointType"); if (this.pointProps.isEmpty()) { this.pointProps = findGeometryProperties("MultiPointType"); } LOGR.info(this.pointProps.toString()); } /** * [{@code Test}] Submits a basic join query that includes the * Intersects operator. A projection clause (wfs:PropertyName) * is omitted, so the response entity is expected to contain instances of * both feature types. */ @Test(description = "See OGC 09-025r2: 7.9.2.5.3, A.1.12") public void joinWithIntersects() { if (!this.spatialCapabilities.keySet().contains(SpatialOperator.INTERSECTS)) { throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, SpatialOperator.INTERSECTS)); } List joinProperties = new ArrayList(); if (this.surfaceProps.size() > 1) { Iterator>> itr = this.surfaceProps.entrySet().iterator(); Entry> entry = itr.next(); joinProperties.add(new FeatureProperty(entry.getKey(), entry.getValue().get(0))); entry = itr.next(); joinProperties.add(new FeatureProperty(entry.getKey(), entry.getValue().get(0))); } else if (!this.surfaceProps.isEmpty() && !this.curveProps.isEmpty()) { // surface property Iterator>> itrSurfaceProps = this.surfaceProps.entrySet().iterator(); Entry> entrySurfaceProps = itrSurfaceProps.next(); joinProperties.add(new FeatureProperty(entrySurfaceProps.getKey(), entrySurfaceProps.getValue().get(0))); // curve property Iterator>> itrCurveProps = this.curveProps.entrySet().iterator(); Entry> entryCurveProps = itrCurveProps.next(); joinProperties.add(new FeatureProperty(entryCurveProps.getKey(), entryCurveProps.getValue().get(0))); } else if (!this.surfaceProps.isEmpty() && !this.pointProps.isEmpty()) { // surface property Iterator>> itrSurfaceProps = this.surfaceProps.entrySet().iterator(); Entry> entrySurfaceProps = itrSurfaceProps.next(); joinProperties.add(new FeatureProperty(entrySurfaceProps.getKey(), entrySurfaceProps.getValue().get(0))); // point property Iterator>> itrPointProps = this.pointProps.entrySet().iterator(); Entry> entryPointProps = itrPointProps.next(); joinProperties.add(new FeatureProperty(entryPointProps.getKey(), entryPointProps.getValue().get(0))); } else if (!this.curveProps.isEmpty() && !this.pointProps.isEmpty()) { // curve property Iterator>> itrCurveProps = this.curveProps.entrySet().iterator(); Entry> entryCurveProps = itrCurveProps.next(); joinProperties.add(new FeatureProperty(entryCurveProps.getKey(), entryCurveProps.getValue().get(0))); // point property Iterator>> itrPointProps = this.pointProps.entrySet().iterator(); Entry> entryPointProps = itrPointProps.next(); joinProperties.add(new FeatureProperty(entryPointProps.getKey(), entryPointProps.getValue().get(0))); } else{ throw new SkipException("This test has triggered an unexpected Spatial Join condition. The Spatial Join test will need to be applied manually."); } JoinQueryUtils.appendSpatialJoinQuery(this.reqEntity, "Intersects", joinProperties); ClientResponse rsp = wfsClient.submitRequest(this.reqEntity, ProtocolBinding.ANY); this.rspEntity = extractBodyAsDocument(rsp); Assert.assertEquals(rsp.getStatus(), ClientResponse.Status.OK.getStatusCode(), ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS)); // TODO check entity body: F1 intersects F2 } // self-join T1 BBOX T1 (gml:boundedBy)?? // self-join T1 INTERSECTS T1 // self-join T1 BEFORE T1 // join T1 BBOX T2 (gml;boundedBy) ?? // join T1 AFTER T2 // join T1 BEFORE T2 public void selfJoinWithIntersects() { if (!ServiceMetadataUtils.implementsSpatialOperator(this.wfsMetadata, "Intersects")) { throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, "Intersects operator")); } if (!this.surfaceProps.isEmpty()) { // TODO } if (!this.curveProps.isEmpty()) { // TODO } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy