001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2001, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * This package contains documentation from OpenGIS specifications.
018: * OpenGIS consortium's work is fully acknowledged here.
019: */
020: package org.geotools.referencing.datum;
021:
022: // J2SE direct dependencies
023: import java.util.Collections;
024: import java.util.Map;
025:
026: // OpenGIS dependencies
027: import org.opengis.referencing.crs.VerticalCRS;
028: import org.opengis.referencing.cs.CoordinateSystemAxis;
029: import org.opengis.referencing.datum.VerticalDatum;
030: import org.opengis.referencing.datum.VerticalDatumType;
031:
032: // Geotools dependencies
033: import org.geotools.referencing.AbstractIdentifiedObject;
034: import org.geotools.referencing.wkt.Formatter;
035: import org.geotools.resources.Utilities;
036:
037: /**
038: * A textual description and/or a set of parameters identifying a particular reference level
039: * surface used as a zero-height surface. The description includes its position with respect
040: * to the Earth for any of the height types recognized by this standard. There are several
041: * types of vertical datums, and each may place constraints on the
042: * {@linkplain CoordinateSystemAxis coordinate system axis} with which it is combined to
043: * create a {@linkplain VerticalCRS vertical CRS}.
044: *
045: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultVerticalDatum.java $
046: * @version $Id: DefaultVerticalDatum.java 20874 2006-08-07 10:00:01Z jgarnett $
047: * @author Martin Desruisseaux
048: *
049: * @since 2.1
050: */
051: public class DefaultVerticalDatum extends AbstractDatum implements
052: VerticalDatum {
053: /**
054: * Serial number for interoperability with different versions.
055: */
056: private static final long serialVersionUID = 380347456670516572L;
057:
058: /**
059: * A copy of the list of vertical types.
060: */
061: private static final VerticalDatumType[] TYPES = VerticalDatumType
062: .values();
063:
064: /**
065: * Mapping between {@linkplain VerticalDatumType vertical datum type} and the numeric
066: * values used in legacy specification (OGC 01-009).
067: */
068: private static final short[] LEGACY_CODES = new short[TYPES.length];
069: static {
070: LEGACY_CODES[VerticalDatumType.GEOIDAL.ordinal()] = 2005; // CS_VD_GeoidModelDerived
071: LEGACY_CODES[VerticalDatumType.ELLIPSOIDAL.ordinal()] = 2002; // CS_VD_Ellipsoidal
072: LEGACY_CODES[VerticalDatumType.DEPTH.ordinal()] = 2006; // CS_VD_Depth
073: LEGACY_CODES[VerticalDatumType.BAROMETRIC.ordinal()] = 2003; // CS_VD_AltitudeBarometric
074: LEGACY_CODES[VerticalDatumType.ORTHOMETRIC.ordinal()] = 2001; // CS_VD_Orthometric
075: LEGACY_CODES[VerticalDatumType.OTHER_SURFACE.ordinal()] = 2000; // CS_VD_Other
076: }
077:
078: /**
079: * The type of this vertical datum. Default is “geoidal”.
080: */
081: private final VerticalDatumType type;
082:
083: /**
084: * Default vertical datum for {@linkplain VerticalDatumType#GEOIDAL geoidal heights}.
085: */
086: public static final DefaultVerticalDatum GEOIDAL = new DefaultVerticalDatum(
087: "Geoidal", VerticalDatumType.GEOIDAL);
088:
089: /**
090: * Default vertical datum for ellipsoidal heights. Ellipsoidal heights
091: * are measured along the normal to the ellipsoid used in the definition
092: * of horizontal datum.
093: */
094: public static final DefaultVerticalDatum ELLIPSOIDAL = new DefaultVerticalDatum(
095: "Ellipsoidal", VerticalDatumType.ELLIPSOIDAL);
096:
097: /**
098: * Constructs a vertical datum from a name.
099: *
100: * @param name The datum name.
101: * @param type The type of this vertical datum.
102: */
103: public DefaultVerticalDatum(final String name,
104: final VerticalDatumType type) {
105: this (Collections.singletonMap(NAME_KEY, name), type);
106: }
107:
108: /**
109: * Constructs a new datum with the same values than the specified one.
110: * This copy constructor provides a way to wrap an arbitrary implementation into a
111: * Geotools one or a user-defined one (as a subclass), usually in order to leverage
112: * some implementation-specific API. This constructor performs a shallow copy,
113: * i.e. the properties are not cloned.
114: *
115: * @since 2.2
116: */
117: public DefaultVerticalDatum(final VerticalDatum datum) {
118: super (datum);
119: type = datum.getVerticalDatumType();
120: }
121:
122: /**
123: * Constructs a vertical datum from a set of properties. The properties map is given
124: * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
125: *
126: * @param properties Set of properties. Should contains at least <code>"name"</code>.
127: * @param type The type of this vertical datum.
128: */
129: public DefaultVerticalDatum(final Map properties,
130: final VerticalDatumType type) {
131: super (properties);
132: this .type = type;
133: ensureNonNull("type", type);
134: }
135:
136: /**
137: * The type of this vertical datum. Default is “geoidal”.
138: *
139: * @return The type of this vertical datum.
140: */
141: public VerticalDatumType getVerticalDatumType() {
142: return type;
143: }
144:
145: /**
146: * Returns the legacy code for the datum type.
147: */
148: final int getLegacyDatumType() {
149: final int ordinal = type.ordinal();
150: if (ordinal >= 0 && ordinal < LEGACY_CODES.length) {
151: assert type.equals(TYPES[ordinal]) : type;
152: return LEGACY_CODES[ordinal];
153: }
154: return 0;
155: }
156:
157: /**
158: * Returns the vertical datum type from a legacy code. The legacy codes were defined in
159: * <A HREF="http://www.opengis.org/docs/01-009.pdf">Coordinate Transformation Services</A>
160: * (OGC 01-009), which also defined the
161: * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
162: * Known Text</cite> (WKT)</A> format. This method is used for WKT parsing.
163: *
164: * @param code The legacy vertical datum code.
165: * @return The vertical datum type, or {@code null} if the code is unrecognized.
166: */
167: public static VerticalDatumType getVerticalDatumTypeFromLegacyCode(
168: final int code) {
169: for (int i = 0; i < LEGACY_CODES.length; i++) {
170: if (LEGACY_CODES[i] == code) {
171: return TYPES[i];
172: }
173: }
174: return null;
175: }
176:
177: /**
178: * Compare this vertical datum with the specified object for equality.
179: *
180: * @param object The object to compare to {@code this}.
181: * @param compareMetadata {@code true} for performing a strict comparaison, or
182: * {@code false} for comparing only properties relevant to transformations.
183: * @return {@code true} if both objects are equal.
184: */
185: public boolean equals(final AbstractIdentifiedObject object,
186: final boolean compareMetadata) {
187: if (object == this ) {
188: return true; // Slight optimization.
189: }
190: if (super .equals(object, compareMetadata)) {
191: final DefaultVerticalDatum that = (DefaultVerticalDatum) object;
192: return Utilities.equals(this .type, that.type);
193: }
194: return false;
195: }
196:
197: /**
198: * Returns a hash value for this vertical datum. {@linkplain #getName Name},
199: * {@linkplain #getRemarks remarks} and the like are not taken in account. In
200: * other words, two vertical datums will return the same hash value if they
201: * are equal in the sense of
202: * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
203: *
204: * @return The hash code value. This value doesn't need to be the same
205: * in past or future versions of this class.
206: */
207: public int hashCode() {
208: return super .hashCode() ^ type.hashCode();
209: }
210:
211: /**
212: * Format the inner part of a
213: * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
214: * Known Text</cite> (WKT)</A> element.
215: *
216: * @param formatter The formatter to use.
217: * @return The WKT element name, which is "VERT_DATUM"
218: */
219: protected String formatWKT(final Formatter formatter) {
220: super .formatWKT(formatter);
221: return "VERT_DATUM";
222: }
223: }
|