/*---------------- 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.Dimensioned; 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; /** * Base class for all coordinate systems. * A coordinate system is a mathematical space, where the elements of * the space are called positions. Each position is described by a list * of numbers. The length of the list corresponds to the dimension of * the coordinate system. So in a 2D coordinate system each position is * described by a list containing 2 numbers. * <br><br> * However, in a coordinate system, not all lists of numbers correspond * to a position - some lists may be outside the domain of the coordinate * system. For example, in a 2D Lat/Lon coordinate system, the list (91,91) * does not correspond to a position. * <br><br> * Some coordinate systems also have a mapping from the mathematical space * into locations in the real world. So in a Lat/Lon coordinate system, the * mathematical position (lat, long) corresponds to a location on the surface * of the Earth. This mapping from the mathematical space into real-world * locations is called a Datum. * * @version 1.00 * @author OpenGIS (www.opengis.org) * @author Martin Desruisseaux * * @see org.opengis.cs.CS_CoordinateSystem */ public abstract class CoordinateSystem extends Info implements Dimensioned { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = -4539963180028417479L; /** * Construct a coordinate system. * * @param name The coordinate system name. */ public CoordinateSystem( final String name ) { super( name ); } /** * Construct a coordinate system. * * @param properties The set of properties (see {@link Info}). */ CoordinateSystem( final Map properties ) { super( properties ); } /** * Make sure there is no axis among the same direction * (e.g. two north axis, or a east and a west axis). * This methods may be invoked from subclasses constructors. * * @param type The datum type, or <code>null</code> if unknow. * @throws IllegalArgumentException if two axis have the same direction. */ final void checkAxis( final DatumType type ) throws IllegalArgumentException { final int dimension = getDimension(); for ( int i = 0; i < dimension; i++ ) { AxisOrientation check = getAxis( i ).orientation; if ( type != null && !type.isCompatibleOrientation( check ) ) { throw new IllegalArgumentException( Resources.format( ResourceKeys.ERROR_ILLEGAL_AXIS_ORIENTATION_$2, check.getName( null ), Utilities.getShortClassName( this ) ) ); } check = check.absolute(); if ( !check.equals( AxisOrientation.OTHER ) ) { for ( int j = i + 1; j < dimension; j++ ) { if ( check.equals( getAxis( j ).orientation.absolute() ) ) { final String nameI = getAxis( i ).orientation.getName( null ); final String nameJ = getAxis( j ).orientation.getName( null ); throw new IllegalArgumentException( Resources.format( ResourceKeys.ERROR_COLINEAR_AXIS_$2, nameI, nameJ ) ); } } } } } /** * Returns the dimension of the coordinate system. * * @see org.opengis.cs.CS_CoordinateSystem#getDimension() */ public abstract int getDimension(); /** * Gets axis details for dimension within coordinate system. * Each dimension in the coordinate system has a corresponding axis. * * @param dimension Zero based index of axis. * * @see org.opengis.cs.CS_CoordinateSystem#getAxis(int) */ public abstract AxisInfo getAxis( int dimension ); /** * Gets units for dimension within coordinate system. * Each dimension in the coordinate system has corresponding units. * * @param dimension Zero based index of axis. * * @see org.opengis.cs.CS_CoordinateSystem#getUnits(int) */ public abstract Unit getUnits( int dimension ); /** * If all dimensions use the same units, returns this * units. Otherwise, returns <code>null</code>. */ final Unit getUnits() { Unit units = null; for ( int i = getDimension(); --i >= 0; ) { final Unit check = getUnits( i ); if ( units == null ) units = check; else if ( !units.equals( check ) ) return null; } return units; } /** * Returns the datum. */ Datum getDatum() { return null; } /** * Gets default envelope of coordinate system. * Coordinate systems which are bounded should return the minimum bounding * box of their domain. Unbounded coordinate systems should return a box * which is as large as is likely to be used. For example, a (lon,lat) * geographic coordinate system in degrees should return a box from * (-180,-90) to (180,90), and a geocentric coordinate system could return * a box from (-r,-r,-r) to (+r,+r,+r) where r is the approximate radius * of the Earth. * <br><br> * The default implementation returns an envelope with infinite bounds. * * @see org.opengis.cs.CS_CoordinateSystem#getDefaultEnvelope() */ public Envelope getDefaultEnvelope() { final int dimension = getDimension(); final Envelope envelope = new Envelope( dimension ); for ( int i = dimension; --i >= 0; ) { envelope.setRange( i, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY ); } return envelope; } /** * 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. * The <code>equivalents</code> method is less strict than <code>equals</code> * in that it doesn't compare names, alias, authority codes or others similar * informations. * * @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 ) { return ( cs != null ) && cs.getClass().equals( getClass() ); } /** * Compares the specified object with * this coordinate system for equality. */ public boolean equals( final Object object ) { if ( object == this ) return true; // Slight optimization return super.equals( object ) && equivalents( (CoordinateSystem) object ); } }