001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/cs/WGS84ConversionInfo.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/exse/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 It has been implemented within SEAGIS - An OpenSource implementation of OpenGIS specification
012 (C) 2001, Institut de Recherche pour le D�veloppement (http://sourceforge.net/projects/seagis/)
013 SEAGIS Contacts: Surveillance de l'Environnement Assist�e par Satellite
014 Institut de Recherche pour le D�veloppement / US-Espace
015 mailto:seasnet@teledetection.fr
016
017
018 This library is free software; you can redistribute it and/or
019 modify it under the terms of the GNU Lesser General Public
020 License as published by the Free Software Foundation; either
021 version 2.1 of the License, or (at your option) any later version.
022
023 This library is distributed in the hope that it will be useful,
024 but WITHOUT ANY WARRANTY; without even the implied warranty of
025 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
026 Lesser General Public License for more details.
027
028 You should have received a copy of the GNU Lesser General Public
029 License along with this library; if not, write to the Free Software
030 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031
032 Contact:
033
034 Andreas Poth
035 lat/lon GmbH
036 Aennchenstr. 19
037 53115 Bonn
038 Germany
039 E-Mail: poth@lat-lon.de
040
041 Klaus Greve
042 Department of Geography
043 University of Bonn
044 Meckenheimer Allee 166
045 53115 Bonn
046 Germany
047 E-Mail: klaus.greve@uni-bonn.de
048
049
050 ---------------------------------------------------------------------------*/
051 package org.deegree.model.csct.cs;
052
053 // Miscellaneous
054 import java.io.Serializable;
055
056 import org.deegree.model.csct.pt.Matrix;
057 import org.deegree.model.csct.resources.Utilities;
058
059 /**
060 * Parameters for a geographic transformation into WGS84. The Bursa Wolf parameters should be
061 * applied to geocentric coordinates, where the X axis points towards the Greenwich Prime Meridian,
062 * the Y axis points East, and the Z axis points North.
063 *
064 * @version 1.00
065 * @author OpenGIS (www.opengis.org)
066 * @author Martin Desruisseaux
067 *
068 * @author last edited by: $Author: bezema $
069 *
070 * @version $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $
071 *
072 * @see "org.opengis.cs.CS_WGS84ConversionInfo"
073 */
074 public class WGS84ConversionInfo implements Cloneable, Serializable {
075 /**
076 * Serial number for interoperability with different versions.
077 */
078 private static final long serialVersionUID = 3427461418504464735L;
079
080 /** Bursa Wolf shift in meters. */
081 public double dx;
082
083 /** Bursa Wolf shift in meters. */
084 public double dy;
085
086 /** Bursa Wolf shift in meters. */
087 public double dz;
088
089 /** Bursa Wolf rotation in arc seconds. */
090 public double ex;
091
092 /** Bursa Wolf rotation in arc seconds. */
093 public double ey;
094
095 /** Bursa Wolf rotation in arc seconds. */
096 public double ez;
097
098 /** Bursa Wolf scaling in parts per million. */
099 public double ppm;
100
101 /** Human readable text describing intended region of transformation. */
102 public String areaOfUse;
103
104 /**
105 * Construct a conversion info with all parameters set to 0.
106 */
107 public WGS84ConversionInfo() {
108 }
109
110 /**
111 * Returns an affine maps that can be used to define this Bursa Wolf transformation. The formula
112 * is as follows:
113 *
114 * <blockquote>
115 *
116 * <pre>
117 * S = 1 + {@link #ppm}/1000000
118 *
119 * [ X ] [ S -{@link #ez}*S +{@link #ey}*S {@link #dx} ] [ X ]
120 * [ Y ] = [ +{@link #ez}*S S -{@link #ex}*S {@link #dy} ] [ Y ]
121 * [ Z ] [ -{@link #ey}*S +{@link #ex}*S S {@link #dz} ] [ Z ]
122 * [ 1 ] [ 0 0 0 1 ] [ 1 ]
123 * </pre>
124 *
125 * </blockquote>
126 *
127 * This affine transform can be applied on <strong>geocentric</strong> coordinates.
128 *
129 * @return an affine maps that can be used to define this Bursa Wolf transformation.
130 */
131 public Matrix getAffineTransform() {
132 // Note: (ex, ey, ez) is a rotation in arc seconds.
133 // We need to convert it into radians (the R
134 // factor in RS).
135 final double S = 1 + ppm / 1E+6;
136 final double RS = ( Math.PI / ( 180 * 3600 ) ) * S;
137 return new Matrix( 4, 4, new double[] { S, -ez * RS, +ey * RS, dx, +ez * RS, S, -ex * RS,
138 dy, -ey * RS, +ex * RS, S, dz, 0, 0, 0, 1 } );
139 }
140
141 /**
142 * Returns a hash value for this object. This value need not remain consistent between different
143 * implementations of the same class.
144 *
145 * @return a hash value for this object. This value need not remain consistent between different
146 * implementations of the same class.
147 */
148 public int hashCode() {
149 long code = 14698129;
150 code = code * 37 + Double.doubleToLongBits( dx );
151 code = code * 37 + Double.doubleToLongBits( dy );
152 code = code * 37 + Double.doubleToLongBits( dz );
153 code = code * 37 + Double.doubleToLongBits( ex );
154 code = code * 37 + Double.doubleToLongBits( ey );
155 code = code * 37 + Double.doubleToLongBits( ez );
156 code = code * 37 + Double.doubleToLongBits( ppm );
157 return (int) ( code >>> 32 ) ^ (int) code;
158 }
159
160 /**
161 * Returns a copy of this object.
162 *
163 * @return a copy of this object.
164 */
165 public Object clone() {
166 try {
167 return super.clone();
168 } catch ( CloneNotSupportedException exception ) {
169 // Should not happen, since we are cloneable.
170 final InternalError error = new InternalError( exception.getMessage() );
171 throw error;
172 }
173 }
174
175 /**
176 * Compares the specified object with this object for equality.
177 *
178 * @param object
179 * @return
180 */
181 public boolean equals( final Object object ) {
182 if ( object instanceof WGS84ConversionInfo ) {
183 final WGS84ConversionInfo that = (WGS84ConversionInfo) object;
184 return Double.doubleToLongBits( this.dx ) == Double.doubleToLongBits( that.dx )
185 && Double.doubleToLongBits( this.dy ) == Double.doubleToLongBits( that.dy )
186 && Double.doubleToLongBits( this.dz ) == Double.doubleToLongBits( that.dz )
187 && Double.doubleToLongBits( this.ex ) == Double.doubleToLongBits( that.ex )
188 && Double.doubleToLongBits( this.ey ) == Double.doubleToLongBits( that.ey )
189 && Double.doubleToLongBits( this.ez ) == Double.doubleToLongBits( that.ez )
190 && Double.doubleToLongBits( this.ppm ) == Double.doubleToLongBits( that.ppm )
191 && Utilities.equals( this.areaOfUse, that.areaOfUse );
192 }
193 return false;
194 }
195
196 /**
197 * Returns the Well Know Text (WKT) for this object. The WKT is part of OpenGIS's specification
198 * and looks like <code>TOWGS84[dx, dy, dz, ex, ey, ez, ppm]</code>.
199 *
200 * @return the Well Know Text (WKT) for this object.
201 */
202 public String toString() {
203 final StringBuffer buffer = new StringBuffer( "TOWGS84[\"" );
204 buffer.append( areaOfUse );
205 buffer.append( "\", " );
206 buffer.append( dx );
207 buffer.append( ", " );
208 buffer.append( dy );
209 buffer.append( ", " );
210 buffer.append( dz );
211 buffer.append( ", " );
212 buffer.append( ex );
213 buffer.append( ", " );
214 buffer.append( ey );
215 buffer.append( ", " );
216 buffer.append( ez );
217 buffer.append( ", " );
218 buffer.append( ppm );
219 buffer.append( ']' );
220 return buffer.toString();
221 }
222 }