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    }