001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-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.geometry.jts;
017:
018: import com.vividsolutions.jts.geom.CoordinateSequence;
019: import com.vividsolutions.jts.geom.Geometry;
020: import com.vividsolutions.jts.geom.GeometryCollection;
021: import com.vividsolutions.jts.geom.GeometryFactory;
022: import com.vividsolutions.jts.geom.LineString;
023: import com.vividsolutions.jts.geom.LinearRing;
024: import com.vividsolutions.jts.geom.MultiLineString;
025: import com.vividsolutions.jts.geom.MultiPoint;
026: import com.vividsolutions.jts.geom.MultiPolygon;
027: import com.vividsolutions.jts.geom.Point;
028: import com.vividsolutions.jts.geom.Polygon;
029: import org.opengis.referencing.crs.CoordinateReferenceSystem;
030: import org.opengis.referencing.operation.MathTransform;
031: import org.opengis.referencing.operation.TransformException;
032:
033: /**
034: * Service object that takes a geometry an applies a MathTransform on top
035: * of it.
036: * @author Andrea Aime
037: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/geometry/jts/GeometryCoordinateSequenceTransformer.java $
038: */
039: public class GeometryCoordinateSequenceTransformer {
040: private MathTransform transform;
041: private CoordinateSequenceTransformer csTransformer;
042: private CoordinateReferenceSystem crs;
043:
044: public GeometryCoordinateSequenceTransformer() {
045: csTransformer = new DefaultCoordinateSequenceTransformer();
046: }
047:
048: public GeometryCoordinateSequenceTransformer(
049: CoordinateSequenceTransformer transformer) {
050: csTransformer = transformer;
051: }
052:
053: /**
054: * Sets the math transform to be used for transformation
055: * @param transform
056: */
057: public void setMathTransform(MathTransform transform) {
058: this .transform = transform;
059: }
060:
061: /**
062: * Sets the target coordinate reference system.
063: * <p>
064: * This value is used to set the coordinate reference system of geometries
065: * after they have been transformed.
066: * </p>
067: * @param crs The target coordinate reference system.
068: */
069: public void setCoordinateReferenceSystem(
070: CoordinateReferenceSystem crs) {
071: this .crs = crs;
072: }
073:
074: /**
075: * Applies the transform to the provided geometry, given
076: * @param g
077: * @throws TransformException
078: */
079: public Geometry transform(Geometry g) throws TransformException {
080: GeometryFactory factory = g.getFactory();
081:
082: Geometry transformed = null;
083:
084: if (g instanceof Point) {
085: transformed = transformPoint((Point) g, factory);
086: } else if (g instanceof MultiPoint) {
087: MultiPoint mp = (MultiPoint) g;
088: Point[] points = new Point[mp.getNumGeometries()];
089:
090: for (int i = 0; i < points.length; i++) {
091: points[i] = transformPoint((Point) mp.getGeometryN(i),
092: factory);
093: }
094:
095: transformed = factory.createMultiPoint(points);
096: } else if (g instanceof LineString) {
097: transformed = transformLineString((LineString) g, factory);
098: } else if (g instanceof MultiLineString) {
099: MultiLineString mls = (MultiLineString) g;
100: LineString[] lines = new LineString[mls.getNumGeometries()];
101:
102: for (int i = 0; i < lines.length; i++) {
103: lines[i] = transformLineString((LineString) mls
104: .getGeometryN(i), factory);
105: }
106:
107: transformed = factory.createMultiLineString(lines);
108: } else if (g instanceof Polygon) {
109: transformed = transformPolygon((Polygon) g, factory);
110: } else if (g instanceof MultiPolygon) {
111: MultiPolygon mp = (MultiPolygon) g;
112: Polygon[] polygons = new Polygon[mp.getNumGeometries()];
113:
114: for (int i = 0; i < polygons.length; i++) {
115: polygons[i] = transformPolygon((Polygon) mp
116: .getGeometryN(i), factory);
117: }
118:
119: transformed = factory.createMultiPolygon(polygons);
120: } else if (g instanceof GeometryCollection) {
121: GeometryCollection gc = (GeometryCollection) g;
122: Geometry[] geoms = new Geometry[gc.getNumGeometries()];
123:
124: for (int i = 0; i < geoms.length; i++) {
125: geoms[i] = transform(gc.getGeometryN(i));
126: }
127:
128: transformed = factory.createGeometryCollection(geoms);
129: } else {
130: throw new IllegalArgumentException(
131: "Unsupported geometry type " + g.getClass());
132: }
133:
134: //copy over user data, do a special check for coordinate reference
135: // systme
136: transformed.setUserData(g.getUserData());
137:
138: if ((g.getUserData() == null)
139: || g.getUserData() instanceof CoordinateReferenceSystem) {
140: //set the new one to be the target crs
141: if (crs != null) {
142: transformed.setUserData(crs);
143: }
144: }
145:
146: return transformed;
147: }
148:
149: /**
150: *
151: * @throws TransformException
152: */
153: public LineString transformLineString(LineString ls,
154: GeometryFactory gf) throws TransformException {
155: CoordinateSequence cs = projectCoordinateSequence(ls
156: .getCoordinateSequence());
157:
158: if (ls instanceof LinearRing) {
159: return gf.createLinearRing(cs);
160: } else {
161: return gf.createLineString(cs);
162: }
163: }
164:
165: /**
166: * @param point
167: *
168: * @throws TransformException
169: */
170: public Point transformPoint(Point point, GeometryFactory gf)
171: throws TransformException {
172: CoordinateSequence cs = projectCoordinateSequence(point
173: .getCoordinateSequence());
174:
175: return gf.createPoint(cs);
176: }
177:
178: /**
179: * @param cs a CoordinateSequence
180: *
181: * @throws TransformException
182: */
183: public CoordinateSequence projectCoordinateSequence(
184: CoordinateSequence cs) throws TransformException {
185: return csTransformer.transform(cs, transform);
186: }
187:
188: /**
189: * @param polygon
190: * @throws TransformException
191: */
192: public Polygon transformPolygon(Polygon polygon, GeometryFactory gf)
193: throws TransformException {
194: LinearRing exterior = (LinearRing) transformLineString(polygon
195: .getExteriorRing(), gf);
196: LinearRing[] interiors = new LinearRing[polygon
197: .getNumInteriorRing()];
198:
199: for (int i = 0; i < interiors.length; i++) {
200: interiors[i] = (LinearRing) transformLineString(polygon
201: .getInteriorRingN(i), gf);
202: }
203:
204: return gf.createPolygon(exterior, interiors);
205: }
206: }
|