/*---------------- 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.Locale;
import javax.media.jai.EnumeratedParameter;
import org.deegree.model.csct.resources.WeakHashSet;
import org.deegree.model.csct.resources.css.ResourceKeys;
import org.deegree.model.csct.resources.css.Resources;
/**
* Type of the datum expressed as an enumerated value.
* The enumeration is split into ranges which indicate the datum's type.
* The value should be one of the predefined values, or within the range
* for local types. This will allow OpenGIS Consortium to coordinate the
* addition of new interoperable codes.
*
* @version 1.00
* @author OpenGIS (www.opengis.org)
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_DatumType
*/
public abstract class DatumType extends EnumeratedParameter {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 4829955972189625202L;
/**
* Lowest possible value for horizontal datum types.
*/
public static final int CS_HD_Min=1000;
/**
* Unspecified horizontal datum type.
* Horizontal datums with this type should never supply
* a conversion to WGS84 using Bursa Wolf parameters.
*/
public static final int CS_HD_Other=1000;
/**
* These datums, such as ED50, NAD27 and NAD83, have been designed to
* support horizontal positions on the ellipsoid as opposed to positions
* in 3-D space. These datums were designed mainly to support a horizontal
* component of a position in a domain of limited extent, such as a country,
* a region or a continent.
*/
public static final int CS_HD_Classic=1001;
/**
* A geocentric datum is a "satellite age" modern geodetic datum mainly of
* global extent, such as WGS84 (used in GPS), PZ90 (used in GLONASS) and
* ITRF. These datums were designed to support both a horizontal
* component of position and a vertical component of position (through
* ellipsoidal heights). The regional realizations of ITRF, such as
* ETRF, are also included in this category.
*/
public static final int CS_HD_Geocentric=1002;
/**
* Highest possible value for horizontal datum types.
*/
public static final int CS_HD_Max=1999;
/**
* Lowest possible value for vertical datum types.
*/
public static final int CS_VD_Min=2000;
/**
* Unspecified vertical datum type.
*/
public static final int CS_VD_Other=2000;
/**
* A vertical datum for orthometric heights that are measured along the
* plumb line.
*/
public static final int CS_VD_Orthometric=2001;
/**
* A vertical datum for ellipsoidal heights that are measured along the
* normal to the ellipsoid used in the definition of horizontal datum.
*/
public static final int CS_VD_Ellipsoidal=2002;
/**
* The vertical datum of altitudes or heights in the atmosphere. These
* are approximations of orthometric heights obtained with the help of
* a barometer or a barometric altimeter. These values are usually
* expressed in one of the following units: meters, feet, millibars
* (used to measure pressure levels), or theta value (units used to
* measure geopotential height).
*/
public static final int CS_VD_AltitudeBarometric=2003;
/**
* A normal height system.
*/
public static final int CS_VD_Normal=2004;
/**
* A vertical datum of geoid model derived heights, also called
* GPS-derived heights. These heights are approximations of
* orthometric heights (<var>H</var>), constructed from the
* ellipsoidal heights (<var>h</var>) by the use of the given
* geoid undulation model (<var>N</var>) through the equation:
* <var>H</var>=<var>h</var>-<var>N</var>.
*/
public static final int CS_VD_GeoidModelDerived=2005;
/**
* This attribute is used to support the set of datums generated
* for hydrographic engineering projects where depth measurements below
* sea level are needed. It is often called a hydrographic or a marine
* datum. Depths are measured in the direction perpendicular
* (approximately) to the actual equipotential surfaces of the earth's
* gravity field, using such procedures as echo-sounding.
*/
public static final int CS_VD_Depth=2006;
/**
* Highest possible value for vertical datum types.
*/
public static final int CS_VD_Max=2999;
/**
* Lowest possible value for local datum types.
*/
public static final int CS_LD_Min=10000;
/**
* Highest possible value for local datum types.
*/
public static final int CS_LD_Max=32767;
/**
* The pool of local datum. This pool
* will be created only when needed.
*/
private static WeakHashSet pool;
/**
* These datums, such as ED50, NAD27 and NAD83, have been designed
* to support horizontal positions on the ellipsoid as opposed to positions
* in 3-D space. These datums were designed mainly to support a horizontal
* component of a position in a domain of limited extent, such as a country,
* a region or a continent.
*
* @see org.opengis.cs.CS_DatumType#CS_HD_Classic
*/
public static final Horizontal CLASSIC = new Horizontal( "CLASSIC", CS_HD_Classic,
ResourceKeys.CLASSIC );
/**
* A geocentric datum is a "satellite age" modern geodetic datum
* mainly of global extent, such as WGS84 (used in GPS), PZ90 (used in GLONASS) and
* ITRF. These datums were designed to support both a horizontal
* component of position and a vertical component of position (through
* ellipsoidal heights). The regional realizations of ITRF, such as
* ETRF, are also included in this category.
*
* @see org.opengis.cs.CS_DatumType#CS_HD_Geocentric
*/
public static final Horizontal GEOCENTRIC = new Horizontal( "GEOCENTRIC",
CS_HD_Geocentric,
ResourceKeys.GEOCENTRIC );
/**
* A vertical datum for orthometric heights
* that are measured along the plumb line.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Orthometric
*/
public static final Vertical ORTHOMETRIC = new Vertical( "ORTHOMETRIC",
CS_VD_Orthometric,
ResourceKeys.ORTHOMETRIC );
/**
* A vertical datum for ellipsoidal heights that are measured along the
* normal to the ellipsoid used in the definition of horizontal datum.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Ellipsoidal
*/
public static final Vertical ELLIPSOIDAL = new Vertical( "ELLIPSOIDAL",
CS_VD_Ellipsoidal,
ResourceKeys.ELLIPSOIDAL );
/**
* The vertical datum of altitudes or heights in the atmosphere.
* These are approximations of orthometric heights obtained with
* the help of a barometer or a barometric altimeter. These values
* are usually expressed in one of the following units: meters, feet,
* millibars (used to measure pressure levels), or theta value (units
* used to measure geopotential height).
*
* @see org.opengis.cs.CS_DatumType#CS_VD_AltitudeBarometric
*/
public static final Vertical ALTITUDE_BAROMETRIC = new Vertical(
"ALTITUDE_BAROMETRIC",
CS_VD_AltitudeBarometric,
ResourceKeys.BAROMETRIC_ALTITUDE );
/**
* A normal height system.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Normal
*/
public static final Vertical NORMAL = new Vertical( "NORMAL", CS_VD_Normal,
ResourceKeys.NORMAL );
/**
* A vertical datum of geoid model derived heights,
* also called GPS-derived heights. These heights are approximations
* of orthometric heights (<var>H</var>), constructed from the
* ellipsoidal heights (<var>h</var>) by the use of the given
* geoid undulation model (<var>N</var>) through the equation:
* <var>H</var>=<var>h</var>-<var>N</var>.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_GeoidModelDerived
*/
public static final Vertical GEOID_MODEL_DERIVED = new Vertical(
"GEOID_MODEL_DERIVED",
CS_VD_GeoidModelDerived,
ResourceKeys.GEOID_MODEL_DERIVED );
/**
* This attribute is used to support the set of datums generated
* for hydrographic engineering projects where depth measurements below
* sea level are needed. It is often called a hydrographic or a marine
* datum. Depths are measured in the direction perpendicular
* (approximately) to the actual equipotential surfaces of the earth's
* gravity field, using such procedures as echo-sounding.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Depth
*/
public static final Vertical DEPTH = new Vertical( "DEPTH", CS_VD_Depth,
ResourceKeys.DEPTH );
/**
* A temporal datum for Universal Time (UTC).
* UTC is based on an atomic clock, while GMT is based on astronomical observations.
* <br><br>
* <strong>Note: This enum is not part of OpenGIS specification. It may change
* in incompatible way if OpenGIS define an equivalent enum.</strong>
*/
public static final Temporal UTC = new Temporal( "UTC", 3001, ResourceKeys.UTC );
/**
* A temporal datum for Greenwich Mean Time (GMT).
* GMT is based on astronomical observations, while UTC is based on an atomic clock.
* <br><br>
* <strong>Note: This enum is not part of OpenGIS specification. It may change
* in incompatible way if OpenGIS define an equivalent enum.</strong>
*/
public static final Temporal GMT = new Temporal( "GMT", 3002, ResourceKeys.GMT );
/**
* List of predefined enum types.
*/
private static final DatumType[] ENUMS = { Horizontal.OTHER, CLASSIC, GEOCENTRIC,
Vertical.OTHER, ORTHOMETRIC, ELLIPSOIDAL,
ALTITUDE_BAROMETRIC, NORMAL, GEOID_MODEL_DERIVED,
DEPTH, UTC, GMT };
/**
* Resource key, used for building localized name. This key doesn't need to
* be serialized, since {@link #readResolve} canonicalize enums according their
* {@link #value}. Furthermore, its value is implementation-dependent (which is
* an other raison why it should not be serialized).
*/
private transient int key = 0;
/**
* Construct a new enum with the specified value.
*/
public DatumType( final String name, final int value, final int key ) {
super( name, value );
this.key = key;
if ( !( value >= getMinimum() && value <= getMaximum() ) )
throw new IllegalArgumentException( String.valueOf( value ) );
}
/**
* Return the enum for the specified value.
*
* @param value The enum value.
* @return The enum for the specified value.
*/
public static DatumType getEnum( final int value ) {
for ( int i = 0; i < ENUMS.length; i++ )
if ( ENUMS[i].getValue() == value )
return ENUMS[i];
final DatumType datum;
if ( value >= Horizontal.MINIMUM && value <= Horizontal.MAXIMUM ) {
datum = new Horizontal( "Custom", value, -1 );
} else if ( value >= Vertical.MINIMUM && value <= Vertical.MAXIMUM ) {
datum = new Vertical( "Custom", value, -1 );
} else if ( value >= Temporal.MINIMUM && value <= Temporal.MAXIMUM ) {
datum = new Temporal( "Custom", value, -1 );
} else if ( value >= Local.MINIMUM && value <= Local.MAXIMUM ) {
datum = new Local( "Custom", value, -1 );
} else {
throw new IllegalArgumentException( String.valueOf( value ) );
}
synchronized ( DatumType.class ) {
if ( pool == null ) {
pool = new Pool();
}
return (DatumType) pool.intern( datum );
}
}
/**
* Returns <code>true</code> if the specified orientation is compatible
* with this datum type. For example, a vertical datum is compatible only
* with orientations UP and DOWN.
*/
abstract boolean isCompatibleOrientation( final AxisOrientation orientation );
/**
* Get the minimum value.
*/
abstract int getMinimum();
/**
* Get the maximum value.
*/
abstract int getMaximum();
/**
* Return the type key.
*/
abstract int getTypeKey();
/**
* Return the type name in the specified locale.
* Type may be "Horizontal", "Vertical", "Temporal" or "Local".
*/
public String getType( final Locale locale ) {
return Resources.getResources( locale ).getString( getTypeKey() );
}
/**
* Returns this enum's name in the specified locale.
* If no name is available for the specified locale, a default one will be used.
*
* @param locale The locale, or <code>null</code> for the default locale.
* @return Enum's name in the specified locale.
*/
public String getName( final Locale locale ) {
return ( key >= 0 ) ? Resources.getResources( locale ).getString( key ) : getName();
}
/**
* Use a single instance of {@link DatumType} after deserialization.
* It allow client code to test <code>enum1==enum2</code> instead of
* <code>enum1.equals(enum2)</code>.
*
* @return A single instance of this enum.
*/
private Object readResolve() {
return getEnum( getValue() );
}
/**
* Horizontal datum type.
*
* @version 1.00
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_DatumType
*/
public static final class Horizontal extends DatumType {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = -9026322423891329754L;
/**
* Lowest possible value for horizontal datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_HD_Min
*/
public static final int MINIMUM = CS_HD_Min;
/**
* Highest possible value for horizontal datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_HD_Max
*/
public static final int MAXIMUM = CS_HD_Max;
/**
* Unspecified horizontal datum type.
* Horizontal datums with this type should never supply
* a conversion to WGS84 using Bursa Wolf parameters.
*
* @see org.opengis.cs.CS_DatumType#CS_HD_Other
*/
public static final Horizontal OTHER = new Horizontal( "OTHER", CS_HD_Other,
ResourceKeys.OTHER );
/**
* Construct a new enum with the specified value.
*/
private Horizontal( final String name, final int value, final int key ) {
super( name, value, key );
}
/**
* Returns <code>true</code> if the specified orientation is compatible
* with this datum type. Compatible orientations are NORTH, SOUTH, EAST
* and WEST.
*/
boolean isCompatibleOrientation( final AxisOrientation orientation ) {
return AxisOrientation.NORTH.equals( orientation )
|| AxisOrientation.SOUTH.equals( orientation )
|| AxisOrientation.EAST.equals( orientation )
|| AxisOrientation.WEST.equals( orientation );
}
/** Get the minimum value. */
final int getMinimum() {
return MINIMUM;
}
/** Get the maximum value. */
final int getMaximum() {
return MAXIMUM;
}
/** Return the type key. */
final int getTypeKey() {
return ResourceKeys.HORIZONTAL;
}
}
/**
* Vertical datum type.
*
* @version 1.00
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_DatumType
*/
public static final class Vertical extends DatumType {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = -916273252180448822L;
/**
* Lowest possible value for vertical datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Min
*/
public static final int MINIMUM = CS_VD_Min;
/**
* Highest possible value for vertical datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Max
*/
public static final int MAXIMUM = CS_VD_Max;
/**
* Unspecified vertical datum type.
*
* @see org.opengis.cs.CS_DatumType#CS_VD_Other
*/
public static final Vertical OTHER = new Vertical( "OTHER", CS_VD_Other,
ResourceKeys.OTHER );
/**
* Construct a new enum with the specified value.
*/
private Vertical( final String name, final int value, final int key ) {
super( name, value, key );
}
/**
* Returns <code>true</code> if the specified orientation is compatible
* with this datum type. Compatible orientations are UP and DOWN.
*/
boolean isCompatibleOrientation( final AxisOrientation orientation ) {
return AxisOrientation.UP.equals( orientation )
|| AxisOrientation.DOWN.equals( orientation );
}
/** Get the minimum value. */
final int getMinimum() {
return MINIMUM;
}
/** Get the maximum value. */
final int getMaximum() {
return MAXIMUM;
}
/** Return the type key. */
final int getTypeKey() {
return ResourceKeys.VERTICAL;
}
}
/**
* Temporal datum type.
*
* @version 1.00
* @author Martin Desruisseaux
*/
public static final class Temporal extends DatumType {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 731901694455984836L;
/**
* Lowest possible value for temporal datum types.
* <br><br>
* <strong>Note: Temporal enums are not part of OpenGIS specification. The
* <code>MINIMUM</code> "constant" may change in the future
* if OpenGIS defines an equivalent datum type. If this value
* change, developpers will have to recompile their code.</strong>
*/
public static final int MINIMUM = 3000;
/**
* Highest possible value for temporal datum types.
* <br><br>
* <strong>Note: Temporal enums are not part of OpenGIS specification. The
* <code>MAXIMUM</code> "constant" may change in the future
* if OpenGIS defines an equivalent datum type. If this value
* change, developpers will have to recompile their code.</strong>
*/
public static final int MAXIMUM = 3999;
/**
* Construct a new enum with the specified value.
*/
private Temporal( final String name, final int value, final int key ) {
super( name, value, key );
}
/**
* Returns <code>true</code> if the specified orientation is compatible
* with this datum type. Compatible orientations are FUTURE and PAST.
*/
boolean isCompatibleOrientation( final AxisOrientation orientation ) {
return AxisOrientation.FUTURE.equals( orientation )
|| AxisOrientation.PAST.equals( orientation );
}
/** Get the minimum value. */
final int getMinimum() {
return MINIMUM;
}
/** Get the maximum value. */
final int getMaximum() {
return MAXIMUM;
}
/** Return the type key. */
final int getTypeKey() {
return ResourceKeys.TEMPORAL;
}
}
/**
* Local datum type.
*
* @version 1.00
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_DatumType
*/
public static final class Local extends DatumType {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 412409825333947716L;
/**
* Lowest possible value for local datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_LD_Min
*/
public static final int MINIMUM = CS_LD_Min;
/**
* Highest possible value for local datum types.
*
* @see org.opengis.cs.CS_DatumType#CS_LD_Max
*/
public static final int MAXIMUM = CS_LD_Max;
/**
* Construct a new enum with the specified value.
*/
private Local( final String name, final int value, final int key ) {
super( name, value, key );
}
/**
* Returns <code>true</code> if the specified orientation is compatible
* with this datum type. Local datum accept all orientations.
*/
boolean isCompatibleOrientation( final AxisOrientation orientation ) {
return true;
}
/** Get the minimum value. */
final int getMinimum() {
return MINIMUM;
}
/** Get the maximum value. */
final int getMaximum() {
return MAXIMUM;
}
/** Return the type key. */
final int getTypeKey() {
return ResourceKeys.LOCAL;
}
}
/**
* Pool of custom {@link DatumType}.
*
* @version 1.00
* @author Martin Desruisseaux
*/
private static final class Pool extends WeakHashSet {
/**
* Override in order to get hash code computed from the enum value.
*/
protected int hashCode( final Object object ) {
return ( (DatumType) object ).getValue();
}
/**
* Override in order to compare hash code values only (not the name).
*/
protected boolean equals( final Object object1, final Object object2 ) {
return ( (DatumType) object1 ).getValue() == ( (DatumType) object2 ).getValue();
}
}
}