001 //$HeadURL: $
002 /*---------------- FILE HEADER ------------------------------------------
003 This file is part of deegree.
004 Copyright (C) 2001-2008 by:
005 Department of Geography, University of Bonn
006 http://www.giub.uni-bonn.de/deegree/
007 lat/lon GmbH
008 http://www.lat-lon.de
009
010 This library is free software; you can redistribute it and/or
011 modify it under the terms of the GNU Lesser General Public
012 License as published by the Free Software Foundation; either
013 version 2.1 of the License, or (at your option) any later version.
014 This library is distributed in the hope that it will be useful,
015 but WITHOUT ANY WARRANTY; without even the implied warranty of
016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 Lesser General Public License for more details.
018 You should have received a copy of the GNU Lesser General Public
019 License along with this library; if not, write to the Free Software
020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021 Contact:
022
023 Andreas Poth
024 lat/lon GmbH
025 Aennchenstr. 19
026 53177 Bonn
027 Germany
028 E-Mail: poth@lat-lon.de
029
030 Prof. Dr. Klaus Greve
031 Department of Geography
032 University of Bonn
033 Meckenheimer Allee 166
034 53115 Bonn
035 Germany
036 E-Mail: greve@giub.uni-bonn.de
037 ---------------------------------------------------------------------------*/
038
039 package org.deegree.crs.components;
040
041 import org.deegree.crs.Identifiable;
042 import org.deegree.crs.projections.ProjectionUtils;
043
044 /**
045 * The <code>PrimeMeridian</code> class saves the longitude to the greenwich meridian.
046 *
047 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
048 *
049 * @author last edited by: $Author:$
050 *
051 * @version $Revision:$, $Date:$
052 *
053 */
054
055 public class PrimeMeridian extends Identifiable {
056
057 private double longitude;
058
059 private Unit units;
060
061 /**
062 * The PrimeMeridian of greenwich with epsg:8901 code and radian units.
063 */
064 public static final PrimeMeridian GREENWICH = new PrimeMeridian( Unit.RADIAN, 0, new String[]{"EPSG:8901", "http://www.opengis.net/gml/srs/epsg.xml#8901","URN:OPENGIS:DEF:CRS:EPSG::8901", "URN:OGC:DEF:CRS:EPSG::"}, new String[]{"Greenwich"}, new String[]{"1995-06-02"}, null, null );
065
066 /**
067 * @param units
068 * Angular units of longitude, normally radians.
069 * @param longitude (in given units) normally radians.
070 * @param identifiers
071 * @param names
072 * @param versions
073 * @param descriptions
074 * @param areasOfUse
075 */
076 public PrimeMeridian( Unit units, double longitude, String[] identifiers, String[] names, String[] versions,
077 String[] descriptions, String[] areasOfUse ) {
078 super( identifiers, names, versions, descriptions, areasOfUse );
079 this.units = units;
080 this.longitude = longitude;
081 }
082
083 /**
084 * @param units
085 * Angular units of longitude.
086 * @param longitude
087 * @param identifier
088 * @param name
089 * @param version
090 * @param description
091 * @param areaOfUse
092 */
093 public PrimeMeridian( Unit units, double longitude, String identifier, String name, String version,
094 String description, String areaOfUse ) {
095 this( units,
096 longitude,
097 new String[] { identifier },
098 new String[] { name },
099 new String[] { version },
100 new String[] { description },
101 new String[] { areaOfUse } );
102 }
103
104 /**
105 * @param units
106 * Angular units of longitude.
107 * @param longitude
108 * @param identifiers
109 */
110 public PrimeMeridian( Unit units, double longitude, String[] identifiers ) {
111 this( units, longitude, identifiers, null,null,null,null );
112 }
113
114 /**
115 * @param units
116 * Angular units of longitude.
117 * @param longitude
118 * @param identifier
119 */
120 public PrimeMeridian( Unit units, double longitude, String identifier ) {
121 this( units, longitude, new String[]{identifier} );
122 }
123
124 /**
125 * A Prime meredian with 0 degrees longitude from the greenwich meridian.
126 *
127 * @param units
128 * Angular units of longitude.
129 * @param identifiers
130 */
131 public PrimeMeridian( Unit units, String[] identifiers ) {
132 this( units, 0, identifiers );
133 }
134
135 /**
136 * A Prime meredian with 0 degrees longitude from the greenwich meridian.
137 *
138 * @param units
139 * Angular units of longitude.
140 * @param identifier
141 * @param name human readable name
142 */
143 public PrimeMeridian( Unit units, String identifier, String name ) {
144 this( units, 0, new String[]{identifier}, new String[]{name}, null,null,null );
145 }
146
147 /**
148 * @return the longitude value relative to the Greenwich Meridian. The longitude is expressed in this objects
149 * angular units.
150 */
151 public double getLongitude() {
152 return longitude;
153 }
154
155 /**
156 * @param targetUnit
157 * The unit in which to express longitude.
158 * @return the longitude value relative to the Greenwich Meridian, expressed in the specified units. This
159 * convenience method make easier to obtains longitude in degrees (<code>getLongitude(Unit.DEGREE)</code>),
160 * no matter the underlying angular unit of this prime meridian.
161 */
162 public double getLongitude( final Unit targetUnit ) {
163 return targetUnit.convert( getLongitude(), getAngularUnit() );
164 }
165
166 /**
167 * @return the angular unit.
168 */
169 public Unit getAngularUnit() {
170 return units;
171 }
172
173 @Override
174 public boolean equals( Object other ) {
175 if ( other != null && other instanceof PrimeMeridian ) {
176 PrimeMeridian that = (PrimeMeridian) other;
177 return ( Math.abs( this.longitude - that.longitude ) < ProjectionUtils.EPS11 ) && ( ( this.units != null ) ? this.units.equals( that.units )
178 : ( that.units == null ) );
179 }
180 return false;
181 }
182
183 @Override
184 public String toString() {
185 StringBuilder sb = new StringBuilder( super.toString() );
186 sb.append( ", Units: " ).append( units );
187 sb.append( ", longitude: " ).append( longitude );
188 return sb.toString();
189 }
190
191 /**
192 * Implementation as proposed by Joshua Block in Effective Java (Addison-Wesley 2001), which supplies an even
193 * distribution and is relatively fast. It is created from field <b>f</b> as follows:
194 * <ul>
195 * <li>boolean -- code = (f ? 0 : 1)</li>
196 * <li>byte, char, short, int -- code = (int)f </li>
197 * <li>long -- code = (int)(f ^ (f >>>32))</li>
198 * <li>float -- code = Float.floatToIntBits(f);</li>
199 * <li>double -- long l = Double.doubleToLongBits(f); code = (int)(l ^ (l >>> 32))</li>
200 * <li>all Objects, (where equals( ) calls equals( ) for this field) -- code = f.hashCode( )</li>
201 * <li>Array -- Apply above rules to each element</li>
202 * </ul>
203 * <p>
204 * Combining the hash code(s) computed above: result = 37 * result + code;
205 * </p>
206 *
207 * @return (int) ( result >>> 32 ) ^ (int) result;
208 *
209 * @see java.lang.Object#hashCode()
210 */
211 @Override
212 public int hashCode() {
213 // the 2.nd million th. prime, :-)
214 long code = 32452843;
215 long ll = Double.doubleToLongBits( longitude);
216 code = code * 37 + (int)( ll ^ (ll >>> 32 ));
217 if( units != null ){
218 code = code * 37 + units.hashCode();
219 }
220 return (int) ( code >>> 32 ) ^ (int) code;
221 }
222
223 }