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 }