001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/cs/CoordinateSystem.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.Map;
055
056 import org.deegree.model.csct.pt.Dimensioned;
057 import org.deegree.model.csct.pt.Envelope;
058 import org.deegree.model.csct.resources.Utilities;
059 import org.deegree.model.csct.resources.css.ResourceKeys;
060 import org.deegree.model.csct.resources.css.Resources;
061 import org.deegree.model.csct.units.Unit;
062
063 /**
064 * Base class for all coordinate systems. A coordinate system is a mathematical space, where the
065 * elements of the space are called positions. Each position is described by a list of numbers. The
066 * length of the list corresponds to the dimension of the coordinate system. So in a 2D coordinate
067 * system each position is described by a list containing 2 numbers. <br>
068 * <br>
069 * However, in a coordinate system, not all lists of numbers correspond to a position - some lists
070 * may be outside the domain of the coordinate system. For example, in a 2D Lat/Lon coordinate
071 * system, the list (91,91) does not correspond to a position. <br>
072 * <br>
073 * Some coordinate systems also have a mapping from the mathematical space into locations in the
074 * real world. So in a Lat/Lon coordinate system, the mathematical position (lat, long) corresponds
075 * to a location on the surface of the Earth. This mapping from the mathematical space into
076 * real-world locations is called a Datum.
077 *
078 * @version 1.00
079 * @author OpenGIS (www.opengis.org)
080 * @author Martin Desruisseaux
081 *
082 * @author last edited by: $Author: bezema $
083 *
084 * @version $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $
085 *
086 * @see "org.opengis.cs.CS_CoordinateSystem"
087 */
088 public abstract class CoordinateSystem extends Info implements Dimensioned {
089 /**
090 * Serial number for interoperability with different versions.
091 */
092 private static final long serialVersionUID = -4539963180028417479L;
093
094 /**
095 * Construct a coordinate system.
096 *
097 * @param name
098 * The coordinate system name.
099 */
100 public CoordinateSystem( final String name ) {
101 super( name );
102 }
103
104 /**
105 * Construct a coordinate system.
106 *
107 * @param properties
108 * The set of properties (see {@link Info}).
109 */
110 CoordinateSystem( final Map properties ) {
111 super( properties );
112 }
113
114 /**
115 * Make sure there is no axis among the same direction (e.g. two north axis, or a east and a
116 * west axis). This methods may be invoked from subclasses constructors.
117 *
118 * @param type
119 * The datum type, or <code>null</code> if unknow.
120 * @throws IllegalArgumentException
121 * if two axis have the same direction.
122 */
123 final void checkAxis( final DatumType type )
124 throws IllegalArgumentException {
125 final int dimension = getDimension();
126 for ( int i = 0; i < dimension; i++ ) {
127 AxisOrientation check = getAxis( i ).orientation;
128 if ( type != null && !type.isCompatibleOrientation( check ) ) {
129 throw new IllegalArgumentException(
130 Resources.format(
131 ResourceKeys.ERROR_ILLEGAL_AXIS_ORIENTATION_$2,
132 check.getName( null ),
133 Utilities.getShortClassName( this ) ) );
134 }
135 check = check.absolute();
136 if ( !check.equals( AxisOrientation.OTHER ) ) {
137 for ( int j = i + 1; j < dimension; j++ ) {
138 if ( check.equals( getAxis( j ).orientation.absolute() ) ) {
139 final String nameI = getAxis( i ).orientation.getName( null );
140 final String nameJ = getAxis( j ).orientation.getName( null );
141 throw new IllegalArgumentException(
142 Resources.format(
143 ResourceKeys.ERROR_COLINEAR_AXIS_$2,
144 nameI, nameJ ) );
145 }
146 }
147 }
148 }
149 }
150
151 /**
152 * Returns the dimension of the coordinate system.
153 *
154 * @return the dimension of the coordinate system.
155 *
156 * @see "org.opengis.cs.CS_CoordinateSystem#getDimension()"
157 */
158 public abstract int getDimension();
159
160 /**
161 * Gets axis details for dimension within coordinate system. Each dimension in the coordinate
162 * system has a corresponding axis.
163 *
164 * @param dimension
165 * Zero based index of axis.
166 * @return
167 *
168 * @see "org.opengis.cs.CS_CoordinateSystem#getAxis(int)"
169 */
170 public abstract AxisInfo getAxis( int dimension );
171
172 /**
173 * Gets units for dimension within coordinate system. Each dimension in the coordinate system
174 * has corresponding units.
175 *
176 * @param dimension
177 * Zero based index of axis.
178 * @return
179 *
180 * @see "org.opengis.cs.CS_CoordinateSystem#getUnits(int)"
181 */
182 public abstract Unit getUnits( int dimension );
183
184 /**
185 * If all dimensions use the same units, returns this units. Otherwise, returns
186 * <code>null</code>.
187 *
188 * @return this units, if all dimensions use the same units. Otherwise, returns
189 * <code>null</code>.
190 */
191 final Unit getUnits() {
192 Unit units = null;
193 for ( int i = getDimension(); --i >= 0; ) {
194 final Unit check = getUnits( i );
195 if ( units == null )
196 units = check;
197 else if ( !units.equals( check ) )
198 return null;
199 }
200 return units;
201 }
202
203 /**
204 * Returns the datum.
205 *
206 * @return the datum.
207 */
208 Datum getDatum() {
209 return null;
210 }
211
212 /**
213 * Gets default envelope of coordinate system. Coordinate systems which are bounded should
214 * return the minimum bounding box of their domain. Unbounded coordinate systems should return a
215 * box which is as large as is likely to be used. For example, a (lon,lat) geographic coordinate
216 * system in degrees should return a box from (-180,-90) to (180,90), and a geocentric
217 * coordinate system could return a box from (-r,-r,-r) to (+r,+r,+r) where r is the approximate
218 * radius of the Earth. <br>
219 * <br>
220 * The default implementation returns an envelope with infinite bounds.
221 *
222 * @return
223 *
224 * @see "org.opengis.cs.CS_CoordinateSystem#getDefaultEnvelope()"
225 */
226 public Envelope getDefaultEnvelope() {
227 final int dimension = getDimension();
228 final Envelope envelope = new Envelope( dimension );
229 for ( int i = dimension; --i >= 0; ) {
230 envelope.setRange( i, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY );
231 }
232 return envelope;
233 }
234
235 /**
236 * Returns <code>true</code> if this coordinate system is equivalents to the specified
237 * coordinate system. Two coordinate systems are considered equivalent if the
238 * {@link org.deegree.model.csct.ct.CoordinateTransformation} from <code>this</code> to
239 * <code>cs</code> would be the identity transform. The <code>equivalents</code> method is
240 * less strict than <code>equals</code> in that it doesn't compare names, alias, authority
241 * codes or others similar informations.
242 *
243 * @param cs
244 * The coordinate system (may be <code>null</code>).
245 * @return <code>true</code> if both coordinate systems are equivalent.
246 */
247 public boolean equivalents( final CoordinateSystem cs ) {
248 return ( cs != null ) && cs.getClass().equals( getClass() );
249 }
250
251 /**
252 * Compares the specified object with this coordinate system for equality.
253 *
254 * @param object
255 * @return
256 */
257 public boolean equals( final Object object ) {
258 if ( object == this )
259 return true; // Slight optimization
260 return super.equals( object ) && equivalents( (CoordinateSystem) object );
261 }
262
263 }