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.feature;
034:
035: import java.util.*;
036:
037: import com.vividsolutions.jts.geom.Envelope;
038: import com.vividsolutions.jts.geom.Geometry;
039: import com.vividsolutions.jts.index.SpatialIndex;
040: import com.vividsolutions.jts.index.strtree.STRtree;
041: import com.vividsolutions.jump.I18N;
042:
043: /**
044: * An IndexedFeatureCollection creates a new collection which is backed by a
045: * FeatureCollection, but which is indexed for query purposes. In this
046: * implementation, Features cannot be added or removed (an Exception is thrown)
047: * and Features' Geometries should not be modified (otherwise they will be out
048: * of sync with the spatial index).
049: */
050: public class IndexedFeatureCollection extends FeatureCollectionWrapper {
051: private SpatialIndex spatialIndex;
052:
053: /**
054: * Constructs an IndexedFeatureCollection wrapping the given FeatureCollection
055: * and using the default spatial index.
056: */
057: public IndexedFeatureCollection(FeatureCollection fc) {
058: //Based on tests on Victoria ICI data, 10 is an optimum node-capacity for
059: //fast queries. [Jon Aquino]
060: this (fc, new STRtree(10));
061: }
062:
063: /**
064: * Constructs an IndexedFeatureCollection wrapping the given FeatureCollection
065: * and using the given empty spatial index.
066: */
067: public IndexedFeatureCollection(FeatureCollection fc,
068: SpatialIndex spatialIndex) {
069: super (fc);
070: this .spatialIndex = spatialIndex;
071: createIndex();
072: }
073:
074: public void add(Feature feature) {
075: throw new UnsupportedOperationException(
076: I18N
077: .get("feature.IndexedFeatureCollection.index-cannot-be-modified"));
078: }
079:
080: public void remove(Feature feature) {
081: throw new UnsupportedOperationException(
082: I18N
083: .get("feature.IndexedFeatureCollection.index-cannot-be-modified"));
084: }
085:
086: public List query(Envelope env) {
087: //System.out.println("FC size = " + base.size());
088: //System.out.println("Quadtree size = " + quadtreeIndex.size());
089: // index query returns list of *potential* overlaps (e.g. it is a primary filter)
090: List candidate = spatialIndex.query(env);
091:
092: // filter out only Features where envelope actually intersects
093: List result = new ArrayList();
094:
095: for (Iterator i = candidate.iterator(); i.hasNext();) {
096: Feature f = (Feature) i.next();
097: Geometry g = f.getGeometry();
098:
099: if (env.intersects(g.getEnvelopeInternal())) {
100: result.add(f);
101: }
102: }
103:
104: return result;
105: }
106:
107: private void createIndex() {
108: int count = 0; // debugging
109:
110: for (Iterator i = iterator(); i.hasNext();) {
111: Feature f = (Feature) i.next();
112: spatialIndex.insert(f.getGeometry().getEnvelopeInternal(),
113: f);
114: count++;
115: }
116: }
117:
118: public void addAll(Collection features) {
119: throw new UnsupportedOperationException(
120: I18N
121: .get("feature.IndexedFeatureCollection.index-cannot-be-modified"));
122: }
123:
124: public Collection remove(Envelope env) {
125: throw new UnsupportedOperationException(
126: I18N
127: .get("feature.IndexedFeatureCollection.index-cannot-be-modified"));
128: }
129:
130: public void removeAll(Collection features) {
131: throw new UnsupportedOperationException(
132: I18N
133: .get("feature.IndexedFeatureCollection.index-cannot-be-modified"));
134: }
135: }
|