/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2010, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.geometry.jts.transform; import com.vividsolutions.jts.geom.*; import org.geotoolkit.geometry.jts.JTS; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.TransformException; /** * Service object that takes a geometry use the cs tranformer on it. * * @author Andrea Aime * @author Johann Sorel (Geomatys) * @module */ public class GeometryCSTransformer implements GeometryTransformer{ private final CoordinateSequenceTransformer csTransformer; private CoordinateReferenceSystem crs; public GeometryCSTransformer(final CoordinateSequenceTransformer transformer) { csTransformer = transformer; } public CoordinateSequenceTransformer getCSTransformer() { return csTransformer; } /** * Sets the target coordinate reference system. * <p> * This value is used to set the coordinate reference system of geometries * after they have been transformed. * </p> * @param crs The target coordinate reference system. */ public void setCoordinateReferenceSystem(final CoordinateReferenceSystem crs) { this.crs = crs; } /** * Applies the transform to the provided geometry, given * @param g * @throws TransformException */ @Override public Geometry transform(final Geometry g) throws TransformException { final GeometryFactory factory = g.getFactory(); final Geometry transformed; if (g instanceof Point) { transformed = transformPoint((Point) g, factory); } else if (g instanceof MultiPoint) { MultiPoint mp = (MultiPoint) g; Point[] points = new Point[mp.getNumGeometries()]; for (int i = 0; i < points.length; i++) { points[i] = transformPoint((Point) mp.getGeometryN(i), factory); } transformed = factory.createMultiPoint(points); } else if (g instanceof LineString) { transformed = transformLineString((LineString) g, factory); } else if (g instanceof MultiLineString) { MultiLineString mls = (MultiLineString) g; LineString[] lines = new LineString[mls.getNumGeometries()]; for (int i = 0; i < lines.length; i++) { lines[i] = transformLineString((LineString) mls.getGeometryN(i), factory); } transformed = factory.createMultiLineString(lines); } else if (g instanceof Polygon) { transformed = transformPolygon((Polygon) g, factory); } else if (g instanceof MultiPolygon) { MultiPolygon mp = (MultiPolygon) g; Polygon[] polygons = new Polygon[mp.getNumGeometries()]; for (int i = 0; i < polygons.length; i++) { polygons[i] = transformPolygon((Polygon) mp.getGeometryN(i), factory); } transformed = factory.createMultiPolygon(polygons); } else if (g instanceof GeometryCollection) { GeometryCollection gc = (GeometryCollection) g; Geometry[] geoms = new Geometry[gc.getNumGeometries()]; for (int i = 0; i < geoms.length; i++) { geoms[i] = transform(gc.getGeometryN(i)); } transformed = factory.createGeometryCollection(geoms); } else { throw new IllegalArgumentException("Unsupported geometry type " + g.getClass()); } //copy over user data, do a special check for coordinate reference systeme transformed.setUserData(g.getUserData()); //set the new one to be the target crs if (crs != null) { JTS.setCRS(transformed, crs); } return transformed; } /** * * @throws TransformException */ public LineString transformLineString(final LineString ls, final GeometryFactory gf) throws TransformException { CoordinateSequence cs = projectCoordinateSequence(ls.getCoordinateSequence()); final LineString transformed; if (ls instanceof LinearRing) { cs = ensureClosed(cs); transformed = gf.createLinearRing(cs); } else { transformed = gf.createLineString(cs); } transformed.setUserData( ls.getUserData() ); return transformed; } /** * @param point * * @throws TransformException */ public Point transformPoint(final Point point, final GeometryFactory gf) throws TransformException { final CoordinateSequence cs = projectCoordinateSequence(point.getCoordinateSequence()); final Point transformed = gf.createPoint(cs); transformed.setUserData( point.getUserData() ); return transformed; } /** * @param cs a CoordinateSequence * * @throws TransformException */ public CoordinateSequence projectCoordinateSequence(final CoordinateSequence cs) throws TransformException { return csTransformer.transform(cs,1); } /** * @param polygon * @throws TransformException */ public Polygon transformPolygon(final Polygon polygon, final GeometryFactory gf) throws TransformException { final LinearRing exterior = (LinearRing) transformLineString(polygon.getExteriorRing(), gf); final LinearRing[] interiors = new LinearRing[polygon.getNumInteriorRing()]; for (int i = 0; i < interiors.length; i++) { interiors[i] = (LinearRing) transformLineString(polygon.getInteriorRingN(i), gf); } final Polygon transformed = gf.createPolygon(exterior, interiors); transformed.setUserData( polygon.getUserData() ); return transformed; } @Override public CoordinateSequence transform(final CoordinateSequence sequence, final int minpoints) throws TransformException { return csTransformer.transform(sequence,minpoints); } public static CoordinateSequence ensureClosed(final CoordinateSequence sequence){ final Coordinate first = sequence.getCoordinate(0); final int lastIndex = sequence.size()-1; if(!first.equals2D(sequence.getCoordinate(lastIndex))){ sequence.setOrdinate(lastIndex, 0, first.x); sequence.setOrdinate(lastIndex, 1, first.y); if(sequence.getDimension()>2){ sequence.setOrdinate(lastIndex, 2, first.z); } } return sequence; } }