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 }