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 /**
042 * The <code>Axis</code> class describe the orientation, unit and the name of a crs-axis.
043 *
044 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
045 *
046 * @author last edited by: $Author:$
047 *
048 * @version $Revision:$, $Date:$
049 *
050 */
051
052 public class Axis {
053
054 /**
055 * Axis is pointing NORTH ( == -SOUTH) e.g Polar axis positive northwards.
056 */
057 public static final int AO_NORTH = 1;
058
059 /**
060 * Axis is pointing SOUTH ( == -NORTH )
061 */
062 public static final int AO_SOUTH = -AO_NORTH;
063
064 /**
065 * Axis is pointing WEST( == -EAST)
066 */
067 public static final int AO_WEST = 2;
068
069 /**
070 * Axis is pointing EAST( == -WEST) the intersection of the equator with longitude 90°E.
071 */
072 public static final int AO_EAST = -AO_WEST;
073
074 /**
075 * Axis is pointing UP ( == -DOWN ),
076 */
077 public static final int AO_UP = 3;
078
079 /**
080 * Axis is pointing DOWN ( == -UP)
081 */
082 public static final int AO_DOWN = -AO_UP;
083
084 /**
085 * Axis is pointing FRONT( == -BACK), e.g. the Axis through the intersection of the Greenwich meridian and equator.
086 */
087 public static final int AO_FRONT = 4;
088
089 /**
090 * Axis is pointing BACK ( == -FRONT) e.g. the Axis through the intersection of the opposite of the Greenwich
091 * meridian and equator.
092 */
093 public static final int AO_BACK = -AO_FRONT;
094
095 /**
096 * Axis is pointing in an OTHER direction, which is not specified.
097 */
098 public static final int AO_OTHER = Integer.MAX_VALUE;
099
100 private Unit units;
101
102 private String name;
103
104 private int orientation;
105
106 /**
107 * @param units
108 * of this axis
109 * @param name
110 * of this axis (e.g. longitude...)
111 * @param orientation
112 * of the positive scale direction, one of Axis.AO*. If an unknown value is supplied AO_OTHER is assumed.
113 */
114 public Axis( Unit units, String name, final int orientation ) {
115 this.units = units;
116 this.name = name;
117 this.orientation = orientation;
118 if ( orientation != AO_NORTH && orientation != AO_SOUTH
119 && orientation != AO_WEST
120 && orientation != AO_EAST
121 && orientation != AO_UP
122 && orientation != AO_DOWN
123 && orientation != AO_FRONT
124 && orientation != AO_BACK ) {
125 this.orientation = AO_OTHER;
126 }
127
128 }
129
130 /**
131 * Parses the given orientation and creates a valid orientation of it's non-case-sensitive version. If no conversion
132 * was found, {@link #AO_OTHER} will be used.
133 *
134 * @param units
135 * of the axis.
136 * @param name
137 * of the axis.
138 * @param orientation
139 * of the axis as a string for example north
140 */
141 public Axis( Unit units, String name, String orientation ) {
142 this.units = units;
143 this.name = name;
144 this.orientation = AO_OTHER;
145 if ( orientation != null ) {
146 orientation = orientation.trim().toLowerCase();
147 if ( "north".equals( orientation ) ) {
148 this.orientation = AO_NORTH;
149 } else if ( "south".equals( orientation ) ) {
150 this.orientation = AO_SOUTH;
151 } else if ( "east".equals( orientation ) ) {
152 this.orientation = AO_EAST;
153 } else if ( "west".equals( orientation ) ) {
154 this.orientation = AO_WEST;
155 } else if ( "front".equals( orientation ) ) {
156 this.orientation = AO_FRONT;
157 } else if ( "back".equals( orientation ) ) {
158 this.orientation = AO_BACK;
159 } else if ( "up".equals( orientation ) ) {
160 this.orientation = AO_UP;
161 } else if ( "down".equals( orientation ) ) {
162 this.orientation = AO_DOWN;
163 }
164 }
165 }
166
167 /**
168 * An Axis with unit set to metre.
169 *
170 * @param name
171 * of this axis (e.g. longitude...)
172 * @param orientation
173 * of the positive scale direction, one of Axis.AO*. If an unknown value is supplied AO_OTHER is assumed.
174 */
175 public Axis( String name, final int orientation ) {
176 this( Unit.METRE, name, orientation );
177 }
178
179 /**
180 * Parses the given orientation and creates a valid orientation of it's non-case-sensitive version. If no conversion
181 * was found, {@link #AO_OTHER} will be used. This axis will have metres as it's unit.
182 *
183 * @param name
184 * of the axis
185 * @param orientation
186 * of the axis as a string for example north
187 */
188 public Axis( String name, final String orientation ) {
189 this( Unit.METRE, name, orientation );
190 }
191
192 /**
193 * @return the name.
194 */
195 public final String getName() {
196 return name;
197 }
198
199 /**
200 * @return the orientation.
201 */
202 public final int getOrientation() {
203 return orientation;
204 }
205
206 /**
207 * @return the units.
208 */
209 public final Unit getUnits() {
210 return units;
211 }
212
213 @Override
214 public String toString() {
215 return new StringBuilder( "name: " ).append( name )
216 .append( " orientation: " )
217 .append( getOrientationAsString() )
218 .append( " units: " )
219 .append( units )
220 .toString();
221 }
222
223 @Override
224 public boolean equals( Object otherAxis ) {
225 if ( otherAxis == null || !( otherAxis instanceof Axis ) ) {
226 return false;
227 }
228 Axis other = (Axis) otherAxis;
229 return this.units.equals( other.units ) && this.orientation == other.orientation;
230 }
231
232 /**
233 * Implementation as proposed by Joshua Block in Effective Java (Addison-Wesley 2001), which supplies an even
234 * distribution and is relatively fast. It is created from field <b>f</b> as follows:
235 * <ul>
236 * <li>boolean -- code = (f ? 0 : 1)</li>
237 * <li>byte, char, short, int -- code = (int)f </li>
238 * <li>long -- code = (int)(f ^ (f >>>32))</li>
239 * <li>float -- code = Float.floatToIntBits(f);</li>
240 * <li>double -- long l = Double.doubleToLongBits(f); code = (int)(l ^ (l >>> 32))</li>
241 * <li>all Objects, (where equals( ) calls equals( ) for this field) -- code = f.hashCode( )</li>
242 * <li>Array -- Apply above rules to each element</li>
243 * </ul>
244 * <p>
245 * Combining the hash code(s) computed above: result = 37 * result + code;
246 * </p>
247 *
248 * @return (int) ( result >>> 32 ) ^ (int) result;
249 *
250 * @see java.lang.Object#hashCode()
251 */
252 @Override
253 public int hashCode() {
254 // the 2nd millionth prime, :-)
255 long code = 32452843;
256 if( units != null ){
257 code = code * 37 + units.hashCode();
258 }
259 long tmp = Double.doubleToLongBits( orientation );
260 code = code * 37 + (int)( tmp ^ (tmp >>> 32 ));
261 return (int) ( code >>> 32 ) ^ (int) code;
262 }
263
264 /**
265 * @return an 'English' representation for the Axis Orientation, or Unknown if the given direction is not known.
266 */
267 public String getOrientationAsString() {
268 switch ( orientation ) {
269 case AO_NORTH:
270 return "north";
271 case AO_SOUTH:
272 return "south";
273 case AO_EAST:
274 return "east";
275 case AO_WEST:
276 return "west";
277 case AO_FRONT:
278 return "front";
279 case AO_BACK:
280 return "back";
281 case AO_UP:
282 return "up";
283 case AO_DOWN:
284 return "down";
285 case AO_OTHER:
286 return "Other";
287 }
288 return "Unknown";
289 }
290
291 }