001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/cs/CompoundCoordinateSystem.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.CoordinatePoint; 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 * An aggregate of two coordinate systems. One of these is usually a two dimensional coordinate 065 * system such as a geographic or a projected coordinate system with a horizontal datum. The other 066 * is one-dimensional coordinate system with a vertical datum. 067 * 068 * @version 1.00 069 * @author OpenGIS (www.opengis.org) 070 * @author Martin Desruisseaux 071 * 072 * @author last edited by: $Author: bezema $ 073 * 074 * @version $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $ 075 * 076 * @see "org.opengis.cs.CS_CompoundCoordinateSystem" 077 */ 078 public class CompoundCoordinateSystem extends CoordinateSystem { 079 /** 080 * Serial number for interoperability with different versions. 081 */ 082 private static final long serialVersionUID = -488997059924367289L; 083 084 /** 085 * A default three-dimensional coordinate system for use with geographic coordinates with 086 * heights above the ellipsoid. The head coordinate system is 087 * {@link GeographicCoordinateSystem#WGS84} and the tail coordinate system is 088 * {@link VerticalCoordinateSystem#ELLIPSOIDAL}. 089 */ 090 public static final CompoundCoordinateSystem WGS84 = (CompoundCoordinateSystem) pool.intern( new CompoundCoordinateSystem( 091 "WGS84", 092 GeographicCoordinateSystem.WGS84, 093 VerticalCoordinateSystem.ELLIPSOIDAL ) ); 094 095 /** 096 * First sub-coordinate system. 097 */ 098 private final CoordinateSystem head; 099 100 /** 101 * Second sub-coordinate system. 102 */ 103 private final CoordinateSystem tail; 104 105 /** 106 * Creates a compound coordinate system. 107 * 108 * @param name 109 * Name to give new object. 110 * @param head 111 * Coordinate system to use for earlier ordinates. 112 * @param tail 113 * Coordinate system to use for later ordinates. 114 * 115 */ 116 public CompoundCoordinateSystem( final String name, final CoordinateSystem head, 117 final CoordinateSystem tail ) { 118 super( name ); 119 this.head = head; 120 this.tail = tail; 121 ensureNonNull( "head", head ); 122 ensureNonNull( "tail", tail ); 123 checkAxis( null ); 124 } 125 126 /** 127 * Creates a compound coordinate system. 128 * 129 * @param properties 130 * The set of properties (see {@link Info}). 131 * @param head 132 * Coordinate system to use for earlier ordinates. 133 * @param tail 134 * Coordinate system to use for later ordinates. 135 */ 136 CompoundCoordinateSystem( final Map properties, final CoordinateSystem head, 137 final CoordinateSystem tail ) { 138 super( properties ); 139 this.head = head; 140 this.tail = tail; 141 // Accept null values. 142 } 143 144 /** 145 * Returns the first sub-coordinate system. 146 * 147 * @return the first sub-coordinate system. 148 * 149 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getHeadCS()" 150 */ 151 public CoordinateSystem getHeadCS() { 152 return head; 153 } 154 155 /** 156 * Returns the second sub-coordinate system. 157 * 158 * @return the second sub-coordinate system. 159 * 160 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getTailCS()" 161 */ 162 public CoordinateSystem getTailCS() { 163 return tail; 164 } 165 166 /** 167 * Returns the dimension of the coordinate system. 168 * 169 * @return the dimension of the coordinate system. 170 * 171 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getDimension()" 172 */ 173 public int getDimension() { 174 return head.getDimension() + tail.getDimension(); 175 } 176 177 /** 178 * Gets axis details for dimension within coordinate system. Each dimension in the coordinate 179 * system has a corresponding axis. 180 * 181 * @param dimension 182 * @return 183 * 184 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getAxis(int)" 185 */ 186 public AxisInfo getAxis( final int dimension ) { 187 if ( dimension >= 0 ) { 188 final int headDim = head.getDimension(); 189 if ( dimension < headDim ) { 190 return head.getAxis( dimension ); 191 } 192 final int dim = dimension - headDim; 193 if ( dim < tail.getDimension() ) { 194 return tail.getAxis( dim ); 195 } 196 } 197 throw new IndexOutOfBoundsException( 198 Resources.format( 199 ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1, 200 new Integer( dimension ) ) ); 201 } 202 203 /** 204 * Gets units for dimension within coordinate system. Each dimension in the coordinate system 205 * has corresponding units. 206 * 207 * @param dimension 208 * @return 209 * 210 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getUnits(int)" 211 */ 212 public Unit getUnits( final int dimension ) { 213 if ( dimension >= 0 ) { 214 final int headDim = head.getDimension(); 215 if ( dimension < headDim ) { 216 return head.getUnits( dimension ); 217 } 218 final int dim = dimension - headDim; 219 if ( dim < tail.getDimension() ) { 220 return head.getUnits( dim ); 221 } 222 } 223 throw new IndexOutOfBoundsException( 224 Resources.format( 225 ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1, 226 new Integer( dimension ) ) ); 227 } 228 229 /** 230 * Gets default envelope of coordinate system. 231 * 232 * @return 233 * 234 * @see "org.opengis.cs.CS_CompoundCoordinateSystem#getDefaultEnvelope()" 235 */ 236 public Envelope getDefaultEnvelope() { 237 final Envelope headEnv = head.getDefaultEnvelope(); 238 final Envelope tailEnv = tail.getDefaultEnvelope(); 239 final int headDim = headEnv.getDimension(); 240 final int tailDim = tailEnv.getDimension(); 241 final CoordinatePoint min = new CoordinatePoint( headDim + tailDim ); 242 final CoordinatePoint max = new CoordinatePoint( headDim + tailDim ); 243 for ( int i = 0; i < headDim; i++ ) { 244 min.ord[i] = headEnv.getMinimum( i ); 245 max.ord[i] = headEnv.getMaximum( i ); 246 } 247 for ( int i = 0; i < tailDim; i++ ) { 248 min.ord[headDim + i] = tailEnv.getMinimum( i ); 249 max.ord[headDim + i] = tailEnv.getMaximum( i ); 250 } 251 return new Envelope( min, max ); 252 } 253 254 /** 255 * Returns <code>true</code> if this coordinate system is equivalents to the specified 256 * coordinate system. Two coordinate systems are considered equivalent if the 257 * {@link org.deegree.model.csct.ct.CoordinateTransformation} from <code>this</code> to 258 * <code>cs</code> would be the identity transform. 259 * 260 * @param cs 261 * The coordinate system (may be <code>null</code>). 262 * @return <code>true</code> if both coordinate systems are equivalent. 263 */ 264 public boolean equivalents( final CoordinateSystem cs ) { 265 if ( cs == this ) 266 return true; 267 if ( super.equivalents( cs ) ) { 268 final CompoundCoordinateSystem that = (CompoundCoordinateSystem) cs; 269 return head.equivalents( that.head ) && tail.equivalents( that.tail ); 270 } 271 return false; 272 } 273 274 /** 275 * Compares the specified object with this coordinate system for equality. 276 * 277 * @param object 278 * @return 279 */ 280 public boolean equals( final Object object ) { 281 if ( object == this ) 282 return true; 283 if ( super.equals( object ) ) { 284 final CompoundCoordinateSystem that = (CompoundCoordinateSystem) object; 285 return Utilities.equals( this.head, that.head ) 286 && Utilities.equals( this.tail, that.tail ); 287 } 288 return false; 289 } 290 291 /** 292 * Fill the part inside "[...]". Used for formatting Well Know Text (WKT). 293 * 294 * @param buffer 295 * @return 296 */ 297 String addString( final StringBuffer buffer ) { 298 buffer.append( ", " ); 299 buffer.append( head ); 300 buffer.append( ", " ); 301 buffer.append( tail ); 302 return "COMPD_CS"; 303 } 304 305 }