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.coordinatesystems;
040
041 import org.deegree.crs.Identifiable;
042 import org.deegree.crs.components.Axis;
043 import org.deegree.crs.projections.Projection;
044
045 /**
046 * A <code>ProjectedCRS</code> is a coordinatesystem defined with a projection and a geographic crs. It allows for
047 * transformation between projected coordinates (mostly in meters) and the lat/lon coordinates of the geographic crs and
048 * vice versa.
049 *
050 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
051 *
052 * @author last edited by: $Author:$
053 *
054 * @version $Revision:$, $Date:$
055 *
056 */
057
058 public class ProjectedCRS extends CoordinateSystem {
059
060 private final GeographicCRS underlyingCRS;
061
062 private Projection projection;
063
064 /**
065 * @param projection
066 * the projection which converts coordinates from this ProjectedCRS into the underlying GeographicCRS and
067 * vice versa.
068 * @param axisOrder
069 * of this projection.
070 * @param identity
071 */
072 public ProjectedCRS( Projection projection, Axis[] axisOrder, Identifiable identity ) {
073 super( projection.getGeographicCRS().getGeodeticDatum(), axisOrder, identity );
074 this.underlyingCRS = projection.getGeographicCRS();
075 this.projection = projection;
076 }
077
078 /**
079 * @param projection
080 * the projection which converts coordinates from this ProjectedCRS into the underlying GeographicCRS and
081 * vice versa.
082 * @param axisOrder
083 * of this projection.
084 * @param identifiers
085 * @param names
086 * @param versions
087 * @param descriptions
088 * @param areasOfUse
089 */
090 public ProjectedCRS( Projection projection, Axis[] axisOrder, String[] identifiers, String[] names,
091 String[] versions, String[] descriptions, String[] areasOfUse ) {
092 super( projection.getGeographicCRS().getGeodeticDatum(),
093 axisOrder,
094 identifiers,
095 names,
096 versions,
097 descriptions,
098 areasOfUse );
099 this.underlyingCRS = projection.getGeographicCRS();
100 this.projection = projection;
101 }
102
103 /**
104 *
105 * @param projection
106 * the projection which converts coordinates from this ProjectedCRS into the underlying GeographicCRS and
107 * vice versa.
108 * @param axisOrder
109 * of this projection.
110 * @param identifiers
111 */
112 public ProjectedCRS( Projection projection, Axis[] axisOrder, String[] identifiers ) {
113 this( projection, axisOrder, identifiers, null, null, null, null );
114 }
115
116 /**
117 * @param projection
118 * the projection which converts coordinates from this ProjectedCRS into the underlying GeographicCRS and
119 * vice versa.
120 * @param axisOrder
121 * of this projection.
122 * @param identifier
123 * @param name
124 * @param version
125 * @param description
126 * @param areaOfUse
127 */
128 public ProjectedCRS( Projection projection, Axis[] axisOrder, String identifier, String name, String version,
129 String description, String areaOfUse ) {
130 this( projection,
131 axisOrder,
132 new String[] { identifier },
133 new String[] { name },
134 new String[] { version },
135 new String[] { description },
136 new String[] { areaOfUse } );
137 }
138
139 /**
140 *
141 * @param projection
142 * the projection which converts coordinates from this ProjectedCRS into the underlying GeographicCRS and
143 * vice versa.
144 * @param axisOrder
145 * of this projection.
146 * @param identifier
147 */
148 public ProjectedCRS( Projection projection, Axis[] axisOrder, String identifier ) {
149 this( projection, axisOrder, identifier, null, null, null, null );
150 }
151
152 /*
153 * (non-Javadoc)
154 *
155 * @see org.deegree.crs.coordinatesystems.CoordinateSystem#getDimension()
156 */
157 @Override
158 public int getDimension() {
159 return getAxis().length;
160 }
161
162 /**
163 * @return the underlyingCRS.
164 */
165 public final GeographicCRS getGeographicCRS() {
166 return underlyingCRS;
167 }
168
169 @Override
170 public final int getType() {
171 return PROJECTED_CRS;
172 }
173
174 /**
175 * @return the projection.
176 */
177 public final Projection getProjection() {
178 return projection;
179 }
180
181 @Override
182 public boolean equals( Object other ) {
183 if ( other != null && other instanceof ProjectedCRS ) {
184 final ProjectedCRS that = (ProjectedCRS) other;
185 return super.equals( that ) && this.projection.equals( that.projection );
186 }
187 return false;
188 }
189
190 @Override
191 public String toString() {
192 StringBuilder sb = new StringBuilder( super.toString() );
193 sb.append( "\n - Projection: " ).append( projection );
194 return sb.toString();
195 }
196
197 /**
198 * Implementation as proposed by Joshua Block in Effective Java (Addison-Wesley 2001), which supplies an even
199 * distribution and is relatively fast. It is created from field <b>f</b> as follows:
200 * <ul>
201 * <li>boolean -- code = (f ? 0 : 1)</li>
202 * <li>byte, char, short, int -- code = (int)f </li>
203 * <li>long -- code = (int)(f ^ (f >>>32))</li>
204 * <li>float -- code = Float.floatToIntBits(f);</li>
205 * <li>double -- long l = Double.doubleToLongBits(f); code = (int)(l ^ (l >>> 32))</li>
206 * <li>all Objects, (where equals( ) calls equals( ) for this field) -- code = f.hashCode( )</li>
207 * <li>Array -- Apply above rules to each element</li>
208 * </ul>
209 * <p>
210 * Combining the hash code(s) computed above: result = 37 * result + code;
211 * </p>
212 *
213 * @return (int) ( result >>> 32 ) ^ (int) result;
214 *
215 * @see java.lang.Object#hashCode()
216 */
217 @Override
218 public int hashCode() {
219 // the 2nd millionth prime, :-)
220 long code = 32452843;
221 code = code * 37 + super.hashCode();
222 if( projection != null ){
223 code = code * 37 + projection.hashCode();
224 }
225
226 return (int) ( code >>> 32 ) ^ (int) code;
227 }
228 }