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