001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/cs/GeocentricCoordinateSystem.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 // OpenGIS dependencies
054 import java.util.Arrays;
055 import java.util.Map;
056
057 import org.deegree.model.csct.resources.Utilities;
058 import org.deegree.model.csct.resources.css.ResourceKeys;
059 import org.deegree.model.csct.resources.css.Resources;
060 import org.deegree.model.csct.units.Unit;
061
062 /**
063 * A 3D coordinate system, with its origin at the center of the Earth. The <var>X</var> axis points
064 * towards the prime meridian. The <var>Y</var> axis points East or West. The <var>Z</var> axis
065 * points North or South. By default the <var>Z</var> axis will point North, and the <var>Y</var>
066 * axis will point East (e.g. a right handed system), but you should check the axes for non-default
067 * values.
068 *
069 * @version 1.00
070 * @author OpenGIS (www.opengis.org)
071 * @author Martin Desruisseaux
072 *
073 * @author last edited by: $Author: bezema $
074 *
075 * @version $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $
076 *
077 * @see "org.opengis.cs.CS_GeocentricCoordinateSystem"
078 */
079 public class GeocentricCoordinateSystem extends CoordinateSystem {
080 /**
081 * Serial number for interoperability with different versions.
082 */
083 private static final long serialVersionUID = -6577810243397267703L;
084
085 /**
086 * The set of default axis orientation. The <var>X</var> axis points towards the prime
087 * meridian. The <var>Y</var> axis points East. The <var>Z</var> axis points North.
088 */
089 private static final AxisInfo[] DEFAULT_AXIS = new AxisInfo[] {
090 new AxisInfo(
091 "x",
092 AxisOrientation.OTHER ),
093 new AxisInfo(
094 "y",
095 AxisOrientation.EAST ),
096 new AxisInfo(
097 "z",
098 AxisOrientation.NORTH ) };
099
100 /**
101 * The default geocentric coordinate system. Prime meridian is Greenwich, horizontal datum in
102 * WGS84 and linear units are metre. The <var>X</var> axis points towards the prime meridian.
103 * The <var>Y</var> axis points East. The <var>Z</var> axis points North.
104 */
105 public static final GeocentricCoordinateSystem DEFAULT = (GeocentricCoordinateSystem) pool.intern( new GeocentricCoordinateSystem(
106 "WGS84",
107 Unit.METRE,
108 HorizontalDatum.WGS84,
109 PrimeMeridian.GREENWICH,
110 DEFAULT_AXIS ) );
111
112 /**
113 * The linear unit.
114 */
115 private final Unit unit;
116
117 /**
118 * The horizontal datum.
119 */
120 private final HorizontalDatum datum;
121
122 /**
123 * The prime meridian.
124 */
125 private final PrimeMeridian meridian;
126
127 /**
128 * The axis infos.
129 */
130 private final AxisInfo[] axis;
131
132 /**
133 * Construct a geocentric coordinate system with default axis. Unit are metres and prime
134 * meridian is greenwich.
135 *
136 * @param name
137 * The coordinate system name.
138 * @param datum
139 * The horizontal datum.
140 */
141 public GeocentricCoordinateSystem( final String name, final HorizontalDatum datum ) {
142 this( name, Unit.METRE, datum, PrimeMeridian.GREENWICH );
143 }
144
145 /**
146 * Construct a geocentric coordinate system with default axis. The <var>X</var> axis points
147 * towards the prime meridian. The <var>Y</var> axis points East. The <var>Z</var> axis points
148 * North.
149 *
150 * @param name
151 * The coordinate system name.
152 * @param unit
153 * The linear unit.
154 * @param datum
155 * The horizontal datum.
156 * @param meridian
157 * The prime meridian.
158 */
159 public GeocentricCoordinateSystem( final String name, final Unit unit,
160 final HorizontalDatum datum, final PrimeMeridian meridian ) {
161 this( name, unit, datum, meridian, DEFAULT_AXIS );
162 }
163
164 /**
165 * Construct a geocentric coordinate system.
166 *
167 * @param name
168 * The coordinate system name.
169 * @param unit
170 * The linear unit.
171 * @param datum
172 * The horizontal datum.
173 * @param meridian
174 * The prime meridian.
175 * @param axis
176 * The axis info. This is usually an array of lenght 3.
177 */
178 public GeocentricCoordinateSystem( final String name, final Unit unit,
179 final HorizontalDatum datum, final PrimeMeridian meridian,
180 final AxisInfo[] axis ) {
181 super( name );
182 this.unit = unit;
183 this.datum = datum;
184 this.meridian = meridian;
185 ensureNonNull( "axis", axis );
186 ensureNonNull( "unit", unit );
187 ensureNonNull( "datum", datum );
188 ensureNonNull( "meridian", meridian );
189 ensureLinearUnit( unit );
190 this.axis = clone( axis );
191 }
192
193 /**
194 * Construct a geocentric coordinate system.
195 *
196 * @param properties
197 * The set of properties (see {@link Info}).
198 * @param unit
199 * The linear unit.
200 * @param datum
201 * The horizontal datum.
202 * @param meridian
203 * The prime meridian.
204 * @param axis
205 * The axis info. This is usually an array of lenght 3.
206 */
207 GeocentricCoordinateSystem( final Map properties, final Unit unit, final HorizontalDatum datum,
208 final PrimeMeridian meridian, final AxisInfo[] axis ) {
209 super( properties );
210 this.unit = unit;
211 this.datum = datum;
212 this.meridian = meridian;
213 this.axis = clone( axis );
214 }
215
216 /**
217 * Clone the specified axis array.
218 */
219 private static AxisInfo[] clone( final AxisInfo[] axis ) {
220 return Arrays.equals( axis, DEFAULT_AXIS ) ? DEFAULT_AXIS : (AxisInfo[]) axis.clone();
221 }
222
223 /**
224 * Returns the dimension of this coordinate system, which is usually 3.
225 *
226 * @return the dimension of this coordinate system, which is usually 3.
227 *
228 * @see "org.opengis.cs.CS_GeocentricCoordinateSystem#getDimension()"
229 */
230 public int getDimension() {
231 return axis.length;
232 }
233
234 /**
235 * Override {@link CoordinateSystem#getDatum()}.
236 */
237 final Datum getDatum() {
238 return getHorizontalDatum();
239 }
240
241 /**
242 * Returns the horizontal datum. The horizontal datum is used to determine where the center of
243 * the Earth is considered to be. All coordinate points will be measured from the center of the
244 * Earth, and not the surface.
245 *
246 * @return the horizontal datum.
247 *
248 * @see "org.opengis.cs.CS_GeocentricCoordinateSystem#getHorizontalDatum()"
249 */
250 public HorizontalDatum getHorizontalDatum() {
251 return datum;
252 }
253
254 /**
255 * Gets units for dimension within coordinate system. For a
256 * <code>GeocentricCoordinateSystem</code>, the units is the same for all axis.
257 *
258 * @param dimension
259 * Zero based index of axis.
260 * @return
261 *
262 * @see "org.opengis.cs.CS_GeocentricCoordinateSystem#getUnits(int)"
263 */
264 public Unit getUnits( final int dimension ) {
265 if ( dimension >= 0 && dimension < getDimension() )
266 return unit;
267 throw new IndexOutOfBoundsException(
268 Resources.format(
269 ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1,
270 new Integer( dimension ) ) );
271 }
272
273 /**
274 * Gets axis details for dimension within coordinate system. Each dimension in the coordinate
275 * system has a corresponding axis.
276 *
277 * @param dimension
278 * Zero based index of axis.
279 * @return
280 *
281 * @see "org.opengis.cs.CS_CoordinateSystem#getAxis(int)"
282 */
283 public AxisInfo getAxis( final int dimension ) {
284 return axis[dimension];
285 }
286
287 /**
288 * Returns the prime meridian.
289 *
290 * @return the prime meridian.
291 *
292 * @see "org.opengis.cs.CS_GeocentricCoordinateSystem#getPrimeMeridian()"
293 */
294 public PrimeMeridian getPrimeMeridian() {
295 return meridian;
296 }
297
298 /**
299 * Returns <code>true</code> if this coordinate system is equivalents to the specified
300 * coordinate system. Two coordinate systems are considered equivalent if the
301 * {@link org.deegree.model.csct.ct.CoordinateTransformation} from <code>this</code> to
302 * <code>cs</code> would be the identity transform. The default implementation compare datum,
303 * units and axis, but ignore name, alias and other meta-data informations.
304 *
305 * @param cs
306 * The coordinate system (may be <code>null</code>).
307 * @return <code>true</code> if both coordinate systems are equivalent.
308 */
309 public boolean equivalents( final CoordinateSystem cs ) {
310 if ( cs == this )
311 return true;
312 if ( super.equivalents( cs ) ) {
313 final GeocentricCoordinateSystem that = (GeocentricCoordinateSystem) cs;
314 return Utilities.equals( this.unit, that.unit )
315 && Utilities.equals( this.datum, that.datum )
316 && Utilities.equals( this.meridian, that.meridian );
317 }
318 return false;
319 }
320
321 /**
322 * Fill the part inside "[...]". Used for formatting Well Know Text (WKT).
323 *
324 * @param buffer
325 * @return
326 */
327 String addString( final StringBuffer buffer ) {
328 buffer.append( ", " );
329 buffer.append( datum );
330 buffer.append( ", " );
331 buffer.append( meridian );
332 buffer.append( ", " );
333 addUnit( buffer, unit );
334 for ( int i = 0; i < axis.length; i++ ) {
335 buffer.append( ", " );
336 buffer.append( axis[i] );
337 }
338 return "GEOCCS";
339 }
340
341 }