001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/crs/transformations/coordinate/ProjectionTransform.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036
037 package org.deegree.crs.transformations.coordinate;
038
039 import java.util.List;
040
041 import javax.vecmath.Point2d;
042 import javax.vecmath.Point3d;
043
044 import org.deegree.crs.Identifiable;
045 import org.deegree.crs.components.Axis;
046 import org.deegree.crs.coordinatesystems.ProjectedCRS;
047 import org.deegree.crs.exceptions.ProjectionException;
048 import org.deegree.crs.exceptions.TransformationException;
049 import org.deegree.crs.projections.Projection;
050 import org.deegree.framework.log.ILogger;
051 import org.deegree.framework.log.LoggerFactory;
052
053 /**
054 * The <code>ProjectionTransform</code> class wraps the access to a projection, by calling it's doProjection.
055 *
056 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
057 *
058 * @author last edited by: $Author: mschneider $
059 *
060 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
061 *
062 */
063
064 public class ProjectionTransform extends CRSTransformation {
065
066 private static final long serialVersionUID = -3330650918439492823L;
067
068 private static ILogger LOG = LoggerFactory.getLogger( ProjectionTransform.class );
069
070 private Projection projection;
071
072 private boolean swapAxis = false;
073
074 /**
075 * @param projectedCRS
076 * The crs containing a projection.
077 * @param id
078 * an identifiable instance containing information about this transformation
079 */
080 public ProjectionTransform( ProjectedCRS projectedCRS, Identifiable id ) {
081 super( projectedCRS.getGeographicCRS(), projectedCRS, id );
082 this.projection = projectedCRS.getProjection();
083 swapAxis = checkAxisOrientation( projectedCRS.getAxis() );
084 }
085
086 /**
087 * @param axis
088 * @return
089 */
090 private boolean checkAxisOrientation( Axis[] axis ) {
091 boolean result = false;
092 if ( axis == null || axis.length != 2 ) {
093 result = false;
094 } else {
095 Axis first = axis[0];
096 Axis second = axis[1];
097 LOG.logDebug( "First projected crs Axis: " + first );
098 LOG.logDebug( "Second projected crs Axis: " + second );
099 if ( first != null && second != null ) {
100 if ( Axis.AO_WEST == Math.abs( second.getOrientation() ) ) {
101 result = true;
102 if ( Axis.AO_NORTH != Math.abs( first.getOrientation() ) ) {
103 LOG.logWarning( "The given projection uses a second axis which is not mappable ( " + second
104 + ") please check your configuration, assuming y, x axis-order." );
105 }
106 }
107 }
108 }
109 LOG.logDebug( "Incoming ordinates will" + ( ( result ) ? " " : " not " ) + "be swapped." );
110 return result;
111 }
112
113 /**
114 * @param projectedCRS
115 * The crs containing a projection.
116 */
117 public ProjectionTransform( ProjectedCRS projectedCRS ) {
118 this( projectedCRS, new Identifiable( createFromTo( projectedCRS.getGeographicCRS().getIdentifier(),
119 projectedCRS.getIdentifier() ) ) );
120 }
121
122 @Override
123 public List<Point3d> doTransform( List<Point3d> srcPts )
124 throws TransformationException {
125 // List<Point3d> result = new ArrayList<Point3d>( srcPts.size() );
126 if ( ILogger.LOG_DEBUG == LOG.getLevel() ) {
127 StringBuilder sb = new StringBuilder( isInverseTransform() ? "An inverse" : "A" );
128 sb.append( " projection transform with incoming points: " );
129 sb.append( srcPts );
130 sb.append( " and following projection: " );
131 sb.append( projection.getImplementationName() );
132 LOG.logDebug( sb.toString() );
133 }
134 TransformationException trans = new TransformationException( srcPts.size() );
135 if ( isInverseTransform() ) {
136 doInverseTransform( srcPts, trans );
137 } else {
138 doForwardTransform( srcPts, trans );
139 }
140 if ( !trans.getTransformErrors().isEmpty() ) {
141 trans.setTransformedPoints( srcPts );
142 throw trans;
143 }
144 return srcPts;
145 }
146
147 /**
148 * @param srcPts
149 * @param trans
150 */
151 private void doForwardTransform( List<Point3d> srcPts, TransformationException trans ) {
152 int i = 0;
153 if ( swapAxis ) {
154 for ( Point3d p : srcPts ) {
155 try {
156 Point2d tmp = projection.doProjection( p.y, p.x );
157 p.x = tmp.y;
158 p.y = tmp.x;
159 } catch ( ProjectionException e ) {
160 trans.setTransformError( i, e.getMessage() );
161 }
162 ++i;
163 }
164 } else {
165 for ( Point3d p : srcPts ) {
166 try {
167 Point2d tmp = projection.doProjection( p.x, p.y );
168 p.x = tmp.x;
169 p.y = tmp.y;
170 } catch ( ProjectionException e ) {
171 trans.setTransformError( i, e.getMessage() );
172 }
173 ++i;
174 }
175 }
176
177 }
178
179 /**
180 * @param srcPts
181 */
182 private void doInverseTransform( List<Point3d> srcPts, TransformationException trans ) {
183
184 int i = 0;
185 if ( swapAxis ) {
186 for ( Point3d p : srcPts ) {
187 try {
188 Point2d tmp = projection.doInverseProjection( p.y, p.x );
189 p.x = tmp.y;
190 p.y = tmp.x;
191 } catch ( ProjectionException e ) {
192 trans.setTransformError( i, e.getMessage() );
193 }
194 ++i;
195 }
196 } else {
197 for ( Point3d p : srcPts ) {
198 try {
199 Point2d tmp = projection.doInverseProjection( p.x, p.y );
200 p.x = tmp.x;
201 p.y = tmp.y;
202 } catch ( ProjectionException e ) {
203 trans.setTransformError( i, e.getMessage() );
204 }
205 ++i;
206 }
207 }
208 }
209
210 @Override
211 public boolean isIdentity() {
212 // a projection cannot be an identity it doesn't make a lot of sense.
213 return false;
214 }
215
216 @Override
217 public String toString() {
218 return super.toString() + " - Projection: " + projection.getImplementationName();
219 }
220
221 @Override
222 public String getImplementationName() {
223 return "Projection-Transform";
224 }
225
226 }