001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2004 TOPP - www.openplans.org
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * Created on Apr 27, 2004
018: */
019: package org.geotools.validation.relate;
020:
021: import java.io.IOException;
022: import java.util.Map;
023: import java.util.logging.Logger;
024:
025: import org.geotools.feature.FeatureIterator;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.data.FeatureSource;
028: import org.geotools.feature.Feature;
029: import org.geotools.filter.Filter;
030: import org.geotools.filter.FilterFactory;
031: import org.geotools.filter.FilterFactoryFinder;
032: import org.geotools.validation.ValidationResults;
033:
034: import com.vividsolutions.jts.geom.Envelope;
035: import com.vividsolutions.jts.geom.Geometry;
036:
037: /**
038: * @author Pati
039: * <b>Purpose:</b><br>
040: * <p>
041: * Tests to see if a Geometry lies within another Geometry.
042: *
043: * <b>Description:</b><br>
044: * <p>
045: * If only one Geometry is given, then this test checks to see if part of it lies within itself.
046: * </p>
047: *
048: * <b>Usage:</b><br>
049: * <p>
050: *
051: * </p>
052: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/validation/src/main/java/org/geotools/validation/relate/WithinIntegrity.java $
053: */
054: public class WithinIntegrity extends RelationIntegrity {
055: private static final Logger LOGGER = org.geotools.util.logging.Logging
056: .getLogger("org.geotools.validation");
057:
058: /**
059: * OverlapsIntegrity Constructor
060: *
061: */
062: public WithinIntegrity() {
063: super ();
064: }
065:
066: /* (non-Javadoc)
067: * @see org.geotools.validation.IntegrityValidation#validate(java.util.Map, com.vividsolutions.jts.geom.Envelope, org.geotools.validation.ValidationResults)
068: */
069: public boolean validate(Map layers, Envelope envelope,
070: ValidationResults results) throws Exception {
071: LOGGER.finer("Starting test " + getName() + " ("
072: + getClass().getName() + ")");
073: String typeRef1 = getGeomTypeRefA();
074: LOGGER.finer(typeRef1 + ": looking up FeatureSource ");
075: FeatureSource geomSource1 = (FeatureSource) layers
076: .get(typeRef1);
077: LOGGER.finer(typeRef1 + ": found "
078: + geomSource1.getSchema().getTypeName());
079:
080: String typeRef2 = getGeomTypeRefB();
081: if (typeRef2 == EMPTY || typeRef1.equals(typeRef2))
082: return validateSingleLayer(geomSource1, isExpected(),
083: results, envelope);
084: else {
085: LOGGER.finer(typeRef2 + ": looking up FeatureSource ");
086: FeatureSource geomSource2 = (FeatureSource) layers
087: .get(typeRef2);
088: LOGGER.finer(typeRef2 + ": found "
089: + geomSource2.getSchema().getTypeName());
090: return validateMultipleLayers(geomSource1, geomSource2,
091: isExpected(), results, envelope);
092: }
093:
094: }
095:
096: /**
097: * <b>validateMultipleLayers Purpose:</b> <br>
098: * <p>
099: * This validation tests for a geometry lies within another geometry.
100: * Uses JTS' Geometry.within(Geometry) method.
101: * Returns true if the DE-9IM intersection matrix for the two Geometrys is T*F**F***.
102: * </p>
103: *
104: * <b>Description:</b><br>
105: * <p>
106: * The function filters the FeatureSources using the given bounding box.
107: * It creates iterators over both filtered FeatureSources. It calls within() using the
108: * geometries in the FeatureSource layers. Tests the results of the method call against
109: * the given expected results. Returns true if the returned results and the expected results
110: * are true, false otherwise.
111: *
112: * </p>
113: *
114: * Author: bowens<br>
115: * Created on: Apr 27, 2004<br>
116: * @param featureSourceA - the FeatureSource to pull the original geometries from.
117: * @param featureSourceB - the FeatureSource to pull the other geometries from.
118: * @param expected - boolean value representing the user's expected outcome of the test
119: * @param results - ValidationResults
120: * @param bBox - Envelope - the bounding box within which to perform the within()
121: * @return boolean result of the test
122: * @throws Exception - IOException if iterators improperly closed
123:
124: */
125: private boolean validateMultipleLayers(
126: FeatureSource featureSourceA, FeatureSource featureSourceB,
127: boolean expected, ValidationResults results, Envelope bBox)
128: throws Exception {
129: boolean success = true;
130:
131: FilterFactory ff = FilterFactoryFinder.createFilterFactory();
132: Filter filter = null;
133:
134: //JD: fix this !!
135: //filter = (Filter) ff.createBBoxExpression(bBox);
136:
137: FeatureCollection collectionA = featureSourceA
138: .getFeatures(filter);
139: FeatureCollection collectionB = featureSourceB
140: .getFeatures(filter);
141:
142: FeatureIterator fr1 = null;
143: FeatureIterator fr2 = null;
144: try {
145: fr1 = collectionA.features();
146:
147: if (fr1 == null)
148: return false;
149:
150: while (fr1.hasNext()) {
151: Feature f1 = fr1.next();
152: Geometry g1 = f1.getDefaultGeometry();
153: fr2 = collectionB.features();
154: try {
155: while (fr2 != null && fr2.hasNext()) {
156: Feature f2 = fr2.next();
157: Geometry g2 = f2.getDefaultGeometry();
158: if (g1.within(g2) != expected) {
159: results.error(f1, f1.getDefaultGeometry()
160: .getGeometryType()
161: + " "
162: + getGeomTypeRefA()
163: + " within "
164: + getGeomTypeRefB()
165: + "("
166: + f2.getID()
167: + "), Result was not " + expected);
168: success = false;
169: }
170: }
171: } finally {
172: collectionB.close(fr2);
173: }
174: }
175: } finally {
176: collectionA.close(fr1);
177: }
178:
179: return success;
180: }
181:
182: /**
183: * <b>validateSingleLayer Purpose:</b> <br>
184: * <p>
185: * This validation tests for a geometry that lies within itself.
186: * Uses JTS' Geometry.within(Geometry) method.
187: * Returns true if the DE-9IM intersection matrix for the two Geometrys is T*F**F***.
188: * </p>
189: *
190: * <b>Description:</b><br>
191: * <p>
192: * The function filters the FeatureSource using the given bounding box.
193: * It creates iterators over the filtered FeatureSource. It calls within() using the
194: * geometries in the FeatureSource layer. Tests the results of the method call against
195: * the given expected results. Returns true if the returned results and the expected results
196: * are true, false otherwise.
197: *
198: * </p>
199: *
200: * Author: bowens<br>
201: * Created on: Apr 27, 2004<br>
202: * @param featureSourceA - the FeatureSource to pull the original geometries from.
203: * @param expected - boolean value representing the user's expected outcome of the test
204: * @param results - ValidationResults
205: * @param bBox - Envelope - the bounding box within which to perform the within()
206: * @return boolean result of the test
207: * @throws Exception - IOException if iterators improperly closed
208: */
209: private boolean validateSingleLayer(FeatureSource featureSourceA,
210: boolean expected, ValidationResults results, Envelope bBox)
211: throws Exception {
212: boolean success = true;
213:
214: FilterFactory ff = FilterFactoryFinder.createFilterFactory();
215: Filter filter = null;
216:
217: //JD: fix this !!
218: //filter = (Filter) ff.createBBoxExpression(bBox);
219:
220: FeatureCollection collection = featureSourceA
221: .getFeatures(filter);
222:
223: FeatureIterator fr1 = null;
224: FeatureIterator fr2 = null;
225: try {
226: fr1 = collection.features();
227:
228: if (fr1 == null)
229: return false;
230:
231: while (fr1.hasNext()) {
232: Feature f1 = fr1.next();
233: Geometry g1 = f1.getDefaultGeometry();
234: fr2 = collection.features();
235: try {
236: while (fr2 != null && fr2.hasNext()) {
237: Feature f2 = fr2.next();
238: Geometry g2 = f2.getDefaultGeometry();
239: if (!f1.getID().equals(f2.getID())) // if they are the same feature, move onto the next one
240: {
241: if (g1.within(g2) != expected) {
242: results.error(f1, f1
243: .getDefaultGeometry()
244: .getGeometryType()
245: + " "
246: + getGeomTypeRefA()
247: + " within "
248: + getGeomTypeRefA()
249: + "("
250: + f2.getID()
251: + "), Result was not "
252: + expected);
253: success = false;
254: }
255: }
256: }
257: } finally {
258: collection.close(fr2);
259: }
260: }
261: } finally {
262: collection.close(fr1);
263: }
264:
265: return success;
266: }
267: }
|