001: /*
002: * Geotools 2 - OpenSource mapping toolkit
003: * (C) 2006, Geotools Project Managment Committee (PMC)
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package org.geotools.gce.imagemosaic;
020:
021: import java.util.List;
022: import java.util.logging.Level;
023: import java.util.logging.Logger;
024:
025: import org.geotools.feature.Feature;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.feature.FeatureIterator;
028:
029: import com.vividsolutions.jts.geom.Envelope;
030: import com.vividsolutions.jts.geom.Geometry;
031: import com.vividsolutions.jts.index.strtree.STRtree;
032:
033: /**
034: * This class simply builds an SRTREE spatial index in memory for fast indexed
035: * geometric queries.
036: *
037: * <p>
038: * Since the {@link ImageMosaicReader} heavily uses spatial queries to find out
039: * which are the involved tiles during mosaic creation, it is better to do some
040: * caching and keep the index in memory as much as possible, hence we came up
041: * with this index.
042: *
043: * @author Simone Giannecchini
044: * @since 2.3
045: */
046: public final class MemorySpatialIndex {
047:
048: /** Logger. */
049: private final static Logger LOGGER = org.geotools.util.logging.Logging
050: .getLogger("org.geotools.gce.imagemosaic");
051:
052: /** The {@link STRtree} index. */
053: private final STRtree index;
054:
055: /**
056: * Constructs a {@link MemorySpatialIndex} out of a
057: * {@link FeatureCollection}.
058: *
059: * @param features
060: */
061: public MemorySpatialIndex(FeatureCollection features) {
062: if (features == null) {
063: if (LOGGER.isLoggable(Level.WARNING))
064: LOGGER
065: .warning("The provided FeatureCollection is null, it's impossible to create an index!");
066: throw new IllegalArgumentException(
067: "The provided FeatureCollection is null, it's impossible to create an index!");
068:
069: }
070: final FeatureIterator it = features.features();
071: if (!it.hasNext()) {
072: if (LOGGER.isLoggable(Level.WARNING))
073: LOGGER
074: .warning("The provided FeatureCollection or empty, it's impossible to create an index!");
075: throw new IllegalArgumentException(
076: "The provided FeatureCollection or empty, it's impossible to create an index!");
077: }
078: index = new com.vividsolutions.jts.index.strtree.STRtree();
079: while (it.hasNext()) {
080: final Feature f = it.next();
081: final Geometry g = f.getDefaultGeometry();
082: index.insert(g.getEnvelopeInternal(), f);
083: }
084: // closing he iterator to free some resources.
085: features.close(it);
086: // force index construction --> STRTrees are build on first call to
087: // query
088: index.build();
089:
090: }
091:
092: /**
093: * Finds the features that intersects the provided {@link Envelope}:
094: *
095: * @param envelope
096: * The {@link Envelope} to test for intersection.
097: * @return List of {@link Feature} that intersect the providede
098: * {@link Envelope}.
099: */
100: public List findFeatures(Envelope envelope) {
101: return index.query(envelope);
102:
103: }
104:
105: }
|