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 }