001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) Copyright IBM Corporation, 2005-2007. All rights reserved.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.data.db2;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.geotools.data.db2.filter.SQLEncoderDB2;
025: import org.geotools.data.jdbc.FilterToSQLException;
026: import org.geotools.factory.CommonFactoryFinder;
027:
028: import org.geotools.filter.FilterCapabilities;
029: import org.geotools.filter.IllegalFilterException;
030: import org.geotools.referencing.CRS;
031: import org.opengis.filter.FilterFactory2;
032: import org.opengis.filter.expression.Literal;
033: import org.opengis.filter.expression.PropertyName;
034: import org.opengis.filter.spatial.BBOX;
035: import org.opengis.filter.spatial.BinarySpatialOperator;
036: import org.opengis.filter.spatial.Contains;
037: import org.opengis.filter.spatial.Crosses;
038: import org.opengis.filter.spatial.Disjoint;
039: import org.opengis.filter.spatial.Equals;
040: import org.opengis.filter.spatial.Intersects;
041: import org.opengis.filter.spatial.Overlaps;
042: import org.opengis.filter.spatial.Touches;
043: import org.opengis.filter.spatial.Within;
044: import org.opengis.referencing.crs.CoordinateReferenceSystem;
045:
046: import com.vividsolutions.jts.geom.Envelope;
047: import com.vividsolutions.jts.geom.LineString;
048: import com.vividsolutions.jts.geom.Polygon;
049: import com.vividsolutions.jts.io.WKTReader;
050:
051: /**
052: * DOCUMENT ME!
053: *
054: * @author David Adler
055: * @source $URL:
056: * http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/db2/src/test/java/org/geotools/data/db2/SQLEncoderDB2Test.java $
057: */
058: public class SQLEncoderDB2Test extends DB2TestCase {
059: private static Map DB2_SPATIAL_PREDICATES = new HashMap();
060:
061: private SQLEncoderDB2 encoder;
062:
063: FilterFactory2 ff = null;
064:
065: Literal bboxLiteral = null;
066:
067: String sqlString = null;
068:
069: PropertyName spatialColumn = null;
070:
071: Literal doubleLiteral = null;
072:
073: Literal geometryLiteral = null;
074:
075: Literal polygonLiteral = null;
076: Envelope bboxEnv = null;
077:
078: /**
079: * Setup creates an encoder and an expression to encode
080: *
081: * @throws Exception
082: * DOCUMENT ME!
083: */
084: public void setUp() throws Exception {
085: super .setUp();
086: encoder = new SQLEncoderDB2();
087: encoder.setSqlNameEscape("\"");
088: ff = (FilterFactory2) CommonFactoryFinder
089: .getFilterFactory(null);
090: bboxLiteral = null;
091:
092: spatialColumn = ff.property("Geom");
093: doubleLiteral = ff.literal(1);
094:
095: WKTReader reader = new WKTReader();
096: LineString line = (LineString) reader
097: .read("LINESTRING (0 0, 300 300)");
098: bboxEnv = line.getEnvelopeInternal();
099: geometryLiteral = ff.literal(line);
100: polygonLiteral = ff
101: .literal((Polygon) reader
102: .read("POLYGON ((-76 41, -76 42, -74 42, -74 41, -76 41))"));
103:
104: // stuff below not currently used - was testing opengis geometries
105: CoordinateReferenceSystem crs = null;
106: crs = CRS.decode("EPSG:4269");
107: try {
108: // Geometry geom = JTSUtils.jtsToGo1(line,crs); // causes
109: // FactoryNotFoundException
110: Object obj = ff.contains(spatialColumn, geometryLiteral);
111: // Object obj2 = ff.contains("Geom", geom);
112: System.out.println(obj);
113: } catch (Exception e) {
114: System.out.println(e);
115: }
116: }
117:
118: /**
119: * Creates a geometry filter that uses the left and right geometries created
120: * by the setup method.
121: *
122: * @param opClass Class of the filter (Contains, Intersects, etc)
123: *
124: * @return a BinarySpatialOperator
125: *
126: * @throws IllegalFilterException
127: */
128: private BinarySpatialOperator createGeometryFilter(Class opClass)
129: throws IllegalFilterException {
130: BinarySpatialOperator gf = null;
131: gf = createGeometryFilter(opClass, spatialColumn,
132: polygonLiteral);
133: return gf;
134: }
135:
136: /**
137: * Creates a geometry filter with the specified filter type, left and right
138: * expressions.
139: *
140: * @param opClass Class of the filter (Contains, Intersects, etc)
141: * @param left
142: * @param right
143: *
144: * @return a BinarySpatialOperato
145: *
146: * @throws IllegalFilterException
147: */
148: private BinarySpatialOperator createGeometryFilter(Class opClass,
149: PropertyName left, Literal right)
150: throws IllegalFilterException {
151: BinarySpatialOperator gf = null;
152:
153: if (opClass == Contains.class) {
154: gf = ff.contains(left, right);
155: } else if (opClass == Crosses.class) {
156: gf = ff.crosses(left, right);
157: } else if (opClass == Disjoint.class) {
158: gf = ff.disjoint(left, right);
159: } else if (opClass == Equals.class) {
160: gf = ff.equal(left, right);
161: } else if (opClass == Intersects.class) {
162: gf = ff.intersects(left, right);
163: } else if (opClass == Overlaps.class) {
164: gf = ff.overlaps(left, right);
165: } else if (opClass == Touches.class) {
166: gf = ff.touches(left, right);
167: } else if (opClass == Within.class) {
168: gf = ff.within(left, right);
169: } else {
170: // This shouldn't happen since we will have pulled out
171: // the unsupported parts before invoking this method
172: String msg = "unsupported filter type" + opClass.toString();
173: System.out.println(msg);
174: }
175: return gf;
176: }
177:
178: /**
179: * Creates a distance filter with the specified left and right
180: * expressions and distance.
181: *
182: * @param left
183: * @param right
184: * @param distance
185: *
186: * @return
187: *
188: * @throws IllegalFilterException
189: */
190: private BinarySpatialOperator createDistanceFilter(
191: PropertyName left, Literal right, double distance)
192: throws IllegalFilterException {
193:
194: BinarySpatialOperator gf = ff
195: .dwithin(left, right, distance, "");
196: return gf;
197: }
198:
199: private BinarySpatialOperator createBeyondFilter(PropertyName left,
200: Literal right, double distance)
201: throws IllegalFilterException {
202:
203: BinarySpatialOperator gf = ff.beyond(left, right, distance, "");
204: return gf;
205: }
206:
207: private BBOX createBBOXFilter(PropertyName left, Envelope env)
208: throws IllegalFilterException {
209:
210: double xmin = env.getMinX();
211: double ymin = env.getMinY();
212: double xmax = env.getMaxX();
213: double ymax = env.getMaxY();
214: BBOX bbox = ff.bbox(left, xmin, ymin, xmax, ymax, "");
215: return bbox;
216: }
217:
218: public void testDistance() throws IllegalFilterException,
219: FilterToSQLException {
220: BinarySpatialOperator gf = null;
221: encoder.setSelectivityClause(null);
222: gf = createBeyondFilter(spatialColumn, geometryLiteral, 10.0);
223: encoder.setSelectivityClause(null);
224: sqlString = this .encoder.encodeToString(gf);
225:
226: assertEquals(
227: "Beyond",
228: "WHERE db2gse.ST_Distance(\"Geom\", db2gse.ST_LINESTRING('LINESTRING (0 0, 300 300)', 1)) > 10.0",
229: sqlString);
230: gf = createDistanceFilter(spatialColumn, geometryLiteral, 10.0);
231: encoder.setSelectivityClause(null);
232: sqlString = this .encoder.encodeToString(gf);
233: assertEquals(
234: "DWithin",
235: "WHERE db2gse.ST_Distance(\"Geom\", db2gse.ST_LINESTRING('LINESTRING (0 0, 300 300)', 1)) < 10.0",
236: sqlString);
237:
238: encoder.setSelectivityClause("SELECTIVITY 0.01");
239: sqlString = this .encoder.encodeToString(gf);
240: assertEquals(
241: "DWithin",
242: "WHERE db2gse.ST_Distance(\"Geom\", db2gse.ST_LINESTRING('LINESTRING (0 0, 300 300)', 1)) < 10.0 SELECTIVITY 0.01",
243: sqlString);
244: }
245:
246: public void testBBOX() throws IllegalFilterException,
247: FilterToSQLException {
248:
249: encoder.setSelectivityClause(null);
250:
251: BBOX bbox = createBBOXFilter(spatialColumn, bboxEnv);
252: encoder.setSelectivityClause(null);
253: sqlString = this .encoder.encodeToString(bbox);
254: assertEquals(
255: "geometry literal",
256: "WHERE db2gse.EnvelopesIntersect(\"Geom\", 0.0, 0.0, 300.0, 300.0, 1) = 1",
257: sqlString);
258:
259: encoder.setSelectivityClause("SELECTIVITY 0.001");
260: sqlString = this .encoder.encodeToString(bbox);
261: assertEquals(
262: "geometry literal",
263: "WHERE db2gse.EnvelopesIntersect(\"Geom\", 0.0, 0.0, 300.0, 300.0, 1) = 1 SELECTIVITY 0.001",
264: sqlString);
265:
266: }
267:
268: public void testCommonPredicates() throws IllegalFilterException,
269: FilterToSQLException {
270:
271: BinarySpatialOperator gf = null;
272: Set keys = encoder.getPredicateMap().keySet();
273: Iterator it = keys.iterator();
274: while (it.hasNext()) {
275: Class filterType = (Class) it.next();
276: String predicateName = (String) encoder.getPredicateMap()
277: .get(filterType);
278:
279: if (predicateName.equals("EnvelopesIntersect")
280: || predicateName.equals("ST_Distance")) { // skip - tested separately
281: continue;
282: }
283:
284: System.out.println("Testing predicate '" + predicateName
285: + "' type = " + filterType);
286: gf = createGeometryFilter(filterType);
287: encoder.setSelectivityClause(null);
288: sqlString = this .encoder.encodeToString(gf);
289: String expected = "WHERE db2gse."
290: + predicateName
291: + "(\"Geom\", db2gse.ST_POLYGON('POLYGON ((-76 41, -76 42, -74 42, -74 41, -76 41))', 1)) = 1";
292: assertEquals("Testing predicate: " + predicateName,
293: expected, sqlString);
294: }
295: }
296:
297: public void testGetCapabilities() throws IllegalFilterException {
298: FilterCapabilities fc = encoder.getCapabilities();
299:
300: assertTrue("Check if filter supported", fc
301: .fullySupports(createGeometryFilter(Contains.class)));
302: }
303: }
|