001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
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: package org.geotools.data.crs;
017:
018: import java.io.IOException;
019: import java.util.NoSuchElementException;
020:
021: import org.geotools.data.DataSourceException;
022: import org.geotools.data.FeatureReader;
023: import org.geotools.feature.Feature;
024: import org.geotools.feature.FeatureType;
025: import org.geotools.feature.FeatureTypes;
026: import org.geotools.feature.IllegalAttributeException;
027: import org.geotools.feature.SchemaException;
028: import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
029: import org.geotools.referencing.CRS;
030: import org.geotools.referencing.ReferencingFactoryFinder;
031: import org.opengis.referencing.FactoryException;
032: import org.opengis.referencing.crs.CoordinateReferenceSystem;
033: import org.opengis.referencing.operation.MathTransform;
034: import org.opengis.referencing.operation.MathTransform2D;
035: import org.opengis.referencing.operation.OperationNotFoundException;
036: import org.opengis.referencing.operation.TransformException;
037:
038: import com.vividsolutions.jts.geom.Geometry;
039:
040: /**
041: * ReprojectFeatureReader provides a reprojection for FeatureTypes.
042: *
043: * <p>
044: * ReprojectFeatureReader is a wrapper used to reproject GeometryAttributes
045: * to a user supplied CoordinateReferenceSystem from the original
046: * CoordinateReferenceSystem supplied by the original FeatureReader.
047: * </p>
048: *
049: * <p>
050: * Example Use:
051: * <pre><code>
052: * ReprojectFeatureReader reader =
053: * new ReprojectFeatureReader( originalReader, reprojectCS );
054: *
055: * CoordinateReferenceSystem originalCS =
056: * originalReader.getFeatureType().getDefaultGeometry().getCoordinateSystem();
057: *
058: * CoordinateReferenceSystem newCS =
059: * reader.getFeatureType().getDefaultGeometry().getCoordinateSystem();
060: *
061: * assertEquals( reprojectCS, newCS );
062: * </code></pre>
063: * </p>
064: * TODO: handle the case where there is more than one geometry and the other
065: * geometries have a different CS than the default geometry
066: *
067: * @author jgarnett, Refractions Research, Inc.
068: * @author aaime
069: * @author $Author: jive $ (last modification)
070: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/crs/ReprojectFeatureReader.java $
071: * @version $Id: ReprojectFeatureReader.java 25050 2007-04-06 00:41:49Z jgarnett $
072: */
073: public class ReprojectFeatureReader implements FeatureReader {
074: FeatureReader reader;
075: FeatureType schema;
076: GeometryCoordinateSequenceTransformer transformer = new GeometryCoordinateSequenceTransformer();
077:
078: public ReprojectFeatureReader(FeatureReader reader,
079: FeatureType schema, MathTransform transform) {
080: this .reader = reader;
081: this .schema = schema;
082: transformer.setMathTransform((MathTransform2D) transform);
083: }
084:
085: public ReprojectFeatureReader(FeatureReader reader,
086: CoordinateReferenceSystem cs) throws SchemaException,
087: OperationNotFoundException, NoSuchElementException,
088: FactoryException {
089: if (cs == null) {
090: throw new NullPointerException("CoordinateSystem required");
091: }
092:
093: FeatureType type = reader.getFeatureType();
094: CoordinateReferenceSystem original = type.getDefaultGeometry()
095: .getCoordinateSystem();
096:
097: if (cs.equals(original)) {
098: throw new IllegalArgumentException("CoordinateSystem " + cs
099: + " already used (check before using wrapper)");
100: }
101:
102: this .schema = FeatureTypes.transform(type, cs);
103: this .reader = reader;
104: transformer.setMathTransform(CRS.findMathTransform(original,
105: cs, true));
106: }
107:
108: /**
109: * Implement getFeatureType.
110: *
111: * <p>
112: * Description ...
113: * </p>
114: *
115: *
116: * @throws IllegalStateException DOCUMENT ME!
117: *
118: * @see org.geotools.data.FeatureReader#getFeatureType()
119: */
120: public FeatureType getFeatureType() {
121: if (schema == null) {
122: throw new IllegalStateException(
123: "Reader has already been closed");
124: }
125:
126: return schema;
127: }
128:
129: /**
130: * Implement next.
131: *
132: * <p>
133: * Description ...
134: * </p>
135: *
136: *
137: * @throws IOException
138: * @throws IllegalAttributeException
139: * @throws NoSuchElementException
140: * @throws IllegalStateException DOCUMENT ME!
141: * @throws DataSourceException DOCUMENT ME!
142: *
143: * @see org.geotools.data.FeatureReader#next()
144: */
145: public Feature next() throws IOException,
146: IllegalAttributeException, NoSuchElementException {
147: if (reader == null) {
148: throw new IllegalStateException(
149: "Reader has already been closed");
150: }
151:
152: Feature next = reader.next();
153: Object[] attributes = next.getAttributes(null);
154:
155: try {
156: for (int i = 0; i < attributes.length; i++) {
157: if (attributes[i] instanceof Geometry) {
158: attributes[i] = transformer
159: .transform((Geometry) attributes[i]);
160: }
161: }
162: } catch (TransformException e) {
163: throw new DataSourceException(
164: "A transformation exception occurred while reprojecting data on the fly",
165: e);
166: }
167:
168: return schema.create(attributes, next.getID());
169: }
170:
171: /**
172: * Implement hasNext.
173: *
174: * <p>
175: * Description ...
176: * </p>
177: *
178: *
179: * @throws IOException
180: * @throws IllegalStateException DOCUMENT ME!
181: *
182: * @see org.geotools.data.FeatureReader#hasNext()
183: */
184: public boolean hasNext() throws IOException {
185: if (reader == null) {
186: throw new IllegalStateException(
187: "Reader has already been closed");
188: }
189:
190: return reader.hasNext();
191: }
192:
193: /**
194: * Implement close.
195: *
196: * <p>
197: * Description ...
198: * </p>
199: *
200: * @throws IOException
201: * @throws IllegalStateException DOCUMENT ME!
202: *
203: * @see org.geotools.data.FeatureReader#close()
204: */
205: public void close() throws IOException {
206: if (reader == null) {
207: throw new IllegalStateException(
208: "Reader has already been closed");
209: }
210:
211: reader.close();
212: reader = null;
213: schema = null;
214: }
215: }
|