/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/exse/
lat/lon GmbH
http://www.lat-lon.de
It has been implemented within SEAGIS - An OpenSource implementation of OpenGIS specification
(C) 2001, Institut de Recherche pour le D�veloppement (http://sourceforge.net/projects/seagis/)
SEAGIS Contacts: Surveillance de l'Environnement Assist�e par Satellite
Institut de Recherche pour le D�veloppement / US-Espace
mailto:seasnet@teledetection.fr
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: klaus.greve@uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.model.csct.cs;
// OpenGIS dependencies
import java.util.Map;
import org.deegree.model.csct.pt.CoordinatePoint;
import org.deegree.model.csct.pt.Envelope;
import org.deegree.model.csct.resources.Utilities;
import org.deegree.model.csct.resources.css.ResourceKeys;
import org.deegree.model.csct.resources.css.Resources;
import org.deegree.model.csct.units.Unit;
/**
* An aggregate of two coordinate systems.
* One of these is usually a two dimensional coordinate system such as a
* geographic or a projected coordinate system with a horizontal datum.
* The other is one-dimensional coordinate system with a vertical datum.
*
* @version 1.00
* @author OpenGIS (www.opengis.org)
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem
*/
public class CompoundCoordinateSystem extends CoordinateSystem {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = -488997059924367289L;
/**
* A default three-dimensional coordinate system for use with geographic
* coordinates with heights above the ellipsoid. The head coordinate
* system is {@link GeographicCoordinateSystem#WGS84} and the tail
* coordinate system is {@link VerticalCoordinateSystem#ELLIPSOIDAL}.
*/
public static final CompoundCoordinateSystem WGS84 = (CompoundCoordinateSystem) pool.intern( new CompoundCoordinateSystem(
"WGS84",
GeographicCoordinateSystem.WGS84,
VerticalCoordinateSystem.ELLIPSOIDAL ) );
/**
* First sub-coordinate system.
*/
private final CoordinateSystem head;
/**
* Second sub-coordinate system.
*/
private final CoordinateSystem tail;
/**
* Creates a compound coordinate system.
*
* @param name Name to give new object.
* @param head Coordinate system to use for earlier ordinates.
* @param tail Coordinate system to use for later ordinates.
*
*/
public CompoundCoordinateSystem( final String name, final CoordinateSystem head,
final CoordinateSystem tail ) {
super( name );
this.head = head;
this.tail = tail;
ensureNonNull( "head", head );
ensureNonNull( "tail", tail );
checkAxis( null );
}
/**
* Creates a compound coordinate system.
*
* @param properties The set of properties (see {@link Info}).
* @param head Coordinate system to use for earlier ordinates.
* @param tail Coordinate system to use for later ordinates.
*/
CompoundCoordinateSystem( final Map properties, final CoordinateSystem head,
final CoordinateSystem tail ) {
super( properties );
this.head = head;
this.tail = tail;
// Accept null values.
}
/**
* Returns the first sub-coordinate system.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getHeadCS()
*/
public CoordinateSystem getHeadCS() {
return head;
}
/**
* Returns the second sub-coordinate system.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getTailCS()
*/
public CoordinateSystem getTailCS() {
return tail;
}
/**
* Returns the dimension of the coordinate system.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getDimension()
*/
public int getDimension() {
return head.getDimension() + tail.getDimension();
}
/**
* Gets axis details for dimension within coordinate system.
* Each dimension in the coordinate system has a corresponding axis.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getAxis(int)
*/
public AxisInfo getAxis( final int dimension ) {
if ( dimension >= 0 ) {
final int headDim = head.getDimension();
if ( dimension < headDim ) {
return head.getAxis( dimension );
}
final int dim = dimension - headDim;
if ( dim < tail.getDimension() ) {
return tail.getAxis( dim );
}
}
throw new IndexOutOfBoundsException(
Resources.format(
ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1,
new Integer( dimension ) ) );
}
/**
* Gets units for dimension within coordinate system.
* Each dimension in the coordinate system has corresponding units.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getUnits(int)
*/
public Unit getUnits( final int dimension ) {
if ( dimension >= 0 ) {
final int headDim = head.getDimension();
if ( dimension < headDim ) {
return head.getUnits( dimension );
}
final int dim = dimension - headDim;
if ( dim < tail.getDimension() ) {
return head.getUnits( dim );
}
}
throw new IndexOutOfBoundsException(
Resources.format(
ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1,
new Integer( dimension ) ) );
}
/**
* Gets default envelope of coordinate system.
*
* @see org.opengis.cs.CS_CompoundCoordinateSystem#getDefaultEnvelope()
*/
public Envelope getDefaultEnvelope() {
final Envelope headEnv = head.getDefaultEnvelope();
final Envelope tailEnv = tail.getDefaultEnvelope();
final int headDim = headEnv.getDimension();
final int tailDim = tailEnv.getDimension();
final CoordinatePoint min = new CoordinatePoint( headDim + tailDim );
final CoordinatePoint max = new CoordinatePoint( headDim + tailDim );
for ( int i = 0; i < headDim; i++ ) {
min.ord[i] = headEnv.getMinimum( i );
max.ord[i] = headEnv.getMaximum( i );
}
for ( int i = 0; i < tailDim; i++ ) {
min.ord[headDim + i] = tailEnv.getMinimum( i );
max.ord[headDim + i] = tailEnv.getMaximum( i );
}
return new Envelope( min, max );
}
/**
* Returns <code>true</code> if this coordinate system is equivalents to
* the specified coordinate system. Two coordinate systems are considered
* equivalent if the {@link org.deegree.model.csct.ct.CoordinateTransformation} from
* <code>this</code> to <code>cs</code> would be the identity transform.
*
* @param cs The coordinate system (may be <code>null</code>).
* @return <code>true</code> if both coordinate systems are equivalent.
*/
public boolean equivalents( final CoordinateSystem cs ) {
if ( cs == this )
return true;
if ( super.equivalents( cs ) ) {
final CompoundCoordinateSystem that = (CompoundCoordinateSystem) cs;
return head.equivalents( that.head ) && tail.equivalents( that.tail );
}
return false;
}
/**
* Compares the specified object with
* this coordinate system for equality.
*/
public boolean equals( final Object object ) {
if ( object == this )
return true;
if ( super.equals( object ) ) {
final CompoundCoordinateSystem that = (CompoundCoordinateSystem) object;
return Utilities.equals( this.head, that.head )
&& Utilities.equals( this.tail, that.tail );
}
return false;
}
/**
* Fill the part inside "[...]".
* Used for formatting Well Know Text (WKT).
*/
String addString( final StringBuffer buffer ) {
buffer.append( ", " );
buffer.append( head );
buffer.append( ", " );
buffer.append( tail );
return "COMPD_CS";
}
}