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 static javax.measure.unit.SI.METRE;
012:
013: import javax.measure.quantity.Length;
014: import javax.measure.Measurable;
015: import javax.measure.unit.Unit;
016:
017: import javolution.context.ObjectFactory;
018: import javolution.xml.XMLFormat;
019: import javolution.xml.stream.XMLStreamException;
020:
021: import org.jscience.geography.coordinates.crs.VerticalCRS;
022: import org.opengis.referencing.cs.CoordinateSystem;
023:
024: /**
025: * This class represents the {@link VerticalCRS vertical} height above the
026: * WGS84 ellipsoid.
027: *
028: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
029: * @version 3.0, February 6, 2006
030: */
031: public final class Height extends Coordinates<VerticalCRS<?>> implements
032: Measurable<Length> {
033:
034: /**
035: * Holds the coordinate reference system for all instances of this class.
036: */
037: public static final VerticalCRS<Height> CRS = new VerticalCRS<Height>() {
038:
039: @Override
040: protected Height coordinatesOf(AbsolutePosition position) {
041: if (position.heightWGS84 instanceof Height)
042: return (Height) position.heightWGS84;
043: return Height.valueOf(position.heightWGS84
044: .doubleValue(METRE), METRE);
045: }
046:
047: @Override
048: protected AbsolutePosition positionOf(Height coordinates,
049: AbsolutePosition position) {
050: position.heightWGS84 = coordinates;
051: return position;
052: }
053:
054: @Override
055: public CoordinateSystem getCoordinateSystem() {
056: return VerticalCRS.HEIGHT_CS;
057: }
058: };
059:
060: /**
061: * Holds the height in meters.
062: */
063: private double _meters;
064:
065: /**
066: * Returns the vertical position corresponding to the specified coordinates.
067: *
068: * @param value the height above the WGS84 ellipsoid stated in the
069: * specified unit.
070: * @param unit the length unit in which the height is stated.
071: * @return the corresponding vertical position.
072: */
073: public static Height valueOf(double value, Unit<Length> unit) {
074: Height height = FACTORY.object();
075: height._meters = (unit == METRE) ? value : unit.getConverterTo(
076: METRE).convert(value);
077: return height;
078: }
079:
080: private static final ObjectFactory<Height> FACTORY = new ObjectFactory<Height>() {
081:
082: @Override
083: protected Height create() {
084: return new Height();
085: }
086: };
087:
088: private Height() {
089: }
090:
091: @Override
092: public VerticalCRS<?> getCoordinateReferenceSystem() {
093: return Height.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.equals(METRE) ? _meters : METRE
115: .getConverterTo(unit).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> arg0) {
125: double arg0InMeter = arg0.doubleValue(METRE);
126: return (_meters > arg0InMeter) ? 1
127: : (_meters < arg0InMeter) ? -1 : 0;
128: }
129:
130: @Override
131: public Height copy() {
132: return Height.valueOf(_meters, METRE);
133: }
134:
135: // Default serialization.
136: //
137:
138: static final XMLFormat<Height> XML = new XMLFormat<Height>(
139: Height.class) {
140:
141: @Override
142: public Height newInstance(Class<Height> cls, InputElement xml)
143: throws XMLStreamException {
144: return FACTORY.object();
145: }
146:
147: public void write(Height height, OutputElement xml)
148: throws XMLStreamException {
149: xml.setAttribute("meters", height._meters);
150: }
151:
152: public void read(InputElement xml, Height height)
153: throws XMLStreamException {
154: height._meters = xml.getAttribute("meters", 0.0);
155: }
156: };
157:
158: private static final long serialVersionUID = 1L;
159: }
|