001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program 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
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.qa.diff;
034:
035: import java.util.*;
036: import com.vividsolutions.jts.geom.*;
037: import com.vividsolutions.jump.feature.*;
038: import com.vividsolutions.jts.index.SpatialIndex;
039: import com.vividsolutions.jts.index.strtree.STRtree;
040:
041: public class DiffGeometryIndex {
042:
043: public static Collection splitGeometry(Geometry geom,
044: boolean splitIntoComponents) {
045: Collection list = new ArrayList();
046: if (splitIntoComponents && geom instanceof GeometryCollection) {
047: GeometryCollection geomColl = (GeometryCollection) geom;
048: for (GeometryCollectionIterator gci = new GeometryCollectionIterator(
049: geomColl); gci.hasNext();) {
050: Geometry component = (Geometry) gci.next();
051: if (!(component instanceof GeometryCollection)) {
052: list.add(component);
053: }
054: }
055: } else {
056: // simply return input geometry in a list
057: list.add(geom);
058: }
059: return list;
060: }
061:
062: private SpatialIndex index;
063: private DiffGeometryMatcher diffMatcher;
064: private boolean splitIntoComponents;
065: private Collection featureList;
066:
067: public DiffGeometryIndex(FeatureCollection fc,
068: DiffGeometryMatcher diffMatcher, boolean splitIntoComponents) {
069: this .diffMatcher = diffMatcher;
070: this .splitIntoComponents = splitIntoComponents;
071: buildIndex(fc);
072: }
073:
074: public boolean hasMatch(Geometry testGeom) {
075: diffMatcher.setQueryGeometry(testGeom);
076:
077: List closeFeatList = index.query(diffMatcher.getQueryGeometry()
078: .getEnvelopeInternal());
079: for (Iterator j = closeFeatList.iterator(); j.hasNext();) {
080: FeatureGeometry closeFeat = (FeatureGeometry) j.next();
081:
082: if (diffMatcher.isMatch(closeFeat.getGeometry())) {
083: closeFeat.setMatched(true);
084: return true;
085: }
086: }
087: return false;
088: }
089:
090: private void buildIndex(FeatureCollection fc) {
091: featureList = new ArrayList();
092: index = new STRtree();
093: for (Iterator i = fc.iterator(); i.hasNext();) {
094: Feature feat = (Feature) i.next();
095: Geometry geom = feat.getGeometry();
096: Collection list = splitGeometry(geom, splitIntoComponents);
097: for (Iterator j = list.iterator(); j.hasNext();) {
098: Geometry g = (Geometry) j.next();
099: FeatureGeometry featGeom = new FeatureGeometry(feat, g);
100: index.insert(featGeom.getGeometry()
101: .getEnvelopeInternal(), featGeom);
102: featureList.add(featGeom);
103: }
104: }
105: }
106:
107: public Collection getUnmatchedFeatures() {
108: Set unmatchedFeatureSet = new TreeSet(
109: new FeatureUtil.IDComparator());
110: for (Iterator i = featureList.iterator(); i.hasNext();) {
111: FeatureGeometry fg = (FeatureGeometry) i.next();
112: if (!fg.isMatched()) {
113: unmatchedFeatureSet.add(fg.getFeature());
114: }
115: }
116: return unmatchedFeatureSet;
117: }
118:
119: public class FeatureGeometry {
120: private Feature feat;
121: private Geometry geom;
122: private boolean isMatched = false;
123:
124: public FeatureGeometry(Feature feat, Geometry geom) {
125: this .feat = feat;
126: this .geom = geom;
127: }
128:
129: public Feature getFeature() {
130: return feat;
131: }
132:
133: public Geometry getGeometry() {
134: return geom;
135: }
136:
137: public void setMatched(boolean isMatched) {
138: this .isMatched = isMatched;
139: }
140:
141: public boolean isMatched() {
142: return isMatched;
143: }
144: }
145:
146: }
|