001: /*
002: * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003: * Copyright (C) 2006 - JScience (http://jscience.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package org.jscience.geography.coordinates;
010:
011: import javax.measure.quantity.Length;
012: import javax.measure.Measurable;
013: import static javax.measure.unit.SI.METRE;
014: import javax.measure.unit.Unit;
015:
016: import javolution.context.ObjectFactory;
017: import javolution.xml.XMLFormat;
018: import javolution.xml.stream.XMLStreamException;
019:
020: import org.jscience.geography.coordinates.crs.VerticalCRS;
021: import org.opengis.referencing.cs.CoordinateSystem;
022:
023: /**
024: * This class represents the Mean-Sea-Level {@link VerticalCRS vertical}
025: * altitude (MSL).
026: *
027: * <p> Note: The current implementation approximates the MSL altitude to
028: * the WGS-86 Ellipsoid Height. Future implementations will use
029: * lookup tables in order to correct for regional discrepencies.</p>
030: *
031: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
032: * @version 3.0, February 26, 2006
033: */
034: public final class Altitude extends Coordinates<VerticalCRS<?>>
035: implements Measurable<Length> {
036:
037: /**
038: * Holds the coordinate reference system for all instances of this class.
039: */
040: public static final VerticalCRS<Altitude> CRS = new VerticalCRS<Altitude>() {
041:
042: @Override
043: protected Altitude coordinatesOf(AbsolutePosition position) {
044: return Altitude.valueOf(position.heightWGS84
045: .doubleValue(METRE), METRE);
046: }
047:
048: @Override
049: protected AbsolutePosition positionOf(Altitude coordinates,
050: AbsolutePosition position) {
051: position.heightWGS84 = coordinates;
052: return position;
053: }
054:
055: @Override
056: public CoordinateSystem getCoordinateSystem() {
057: return VerticalCRS.HEIGHT_CS;
058: }
059: };
060:
061: /**
062: * Holds the altitude value in meters.
063: */
064: private double _meters;
065:
066: /**
067: * Returns the vertical position corresponding to the specified coordinates.
068: *
069: * @param value the mean sea level altitude stated in the specified unit.
070: * @param unit the length unit in which the altitude is stated.
071: * @return the corresponding vertical position.
072: */
073: public static Altitude valueOf(double value, Unit<Length> unit) {
074: Altitude altitude = FACTORY.object();
075: altitude._meters = (unit == METRE) ? value : unit
076: .getConverterTo(METRE).convert(value);
077: return altitude;
078: }
079:
080: private static final ObjectFactory<Altitude> FACTORY = new ObjectFactory<Altitude>() {
081:
082: @Override
083: protected Altitude create() {
084: return new Altitude();
085: }
086: };
087:
088: private Altitude() {
089: }
090:
091: @Override
092: public VerticalCRS<?> getCoordinateReferenceSystem() {
093: return Altitude.CRS;
094: }
095:
096: // OpenGIS Interface.
097: public int getDimension() {
098: return 1;
099: }
100:
101: // OpenGIS Interface.
102: public double getOrdinate(int dimension)
103: throws IndexOutOfBoundsException {
104: if (dimension == 0) {
105: Unit<?> u = VerticalCRS.HEIGHT_CS.getAxis(0).getUnit();
106: return METRE.getConverterTo(u).convert(_meters);
107: } else {
108: throw new IndexOutOfBoundsException();
109: }
110: }
111:
112: // Implements Scalar<Length>
113: public final double doubleValue(Unit<Length> unit) {
114: return (unit == METRE) ? _meters : METRE.getConverterTo(unit)
115: .convert(_meters);
116: }
117:
118: // Implements Scalar<Length>
119: public final long longValue(Unit<Length> unit) {
120: return Math.round(doubleValue(unit));
121: }
122:
123: // Implements Scalar<Length>
124: public int compareTo(Measurable<Length> measure) {
125: double meters = measure.doubleValue(METRE);
126: return (_meters > meters) ? 1 : (_meters < meters) ? -1 : 0;
127: }
128:
129: @Override
130: public Altitude copy() {
131: return Altitude.valueOf(_meters, METRE);
132: }
133:
134: // Default serialization.
135: //
136:
137: static final XMLFormat<Altitude> XML = new XMLFormat<Altitude>(
138: Altitude.class) {
139:
140: @Override
141: public Altitude newInstance(Class<Altitude> cls,
142: InputElement xml) throws XMLStreamException {
143: return FACTORY.object();
144: }
145:
146: public void write(Altitude altitude, OutputElement xml)
147: throws XMLStreamException {
148: xml.setAttribute("meters", altitude._meters);
149: }
150:
151: public void read(InputElement xml, Altitude altitude)
152: throws XMLStreamException {
153: altitude._meters = xml.getAttribute("meters", 0.0);
154: }
155: };
156:
157: private static final long serialVersionUID = 1L;
158:
159: }
|