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 */ 009package org.jscience.geography.coordinates; 010 011import javax.measure.quantity.Length; 012import javax.measure.Measurable; 013import static javax.measure.unit.SI.METRE; 014import javax.measure.unit.Unit; 015 016import javolution.context.ObjectFactory; 017import javolution.xml.XMLFormat; 018import javolution.xml.stream.XMLStreamException; 019 020import org.jscience.geography.coordinates.crs.VerticalCRS; 021import 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 */ 034public final class Altitude extends Coordinates<VerticalCRS<?>> implements 035 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.doubleValue(METRE), 045 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 : 076 unit.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 private Altitude() { 088 } 089 090 @Override 091 public VerticalCRS<?> getCoordinateReferenceSystem() { 092 return Altitude.CRS; 093 } 094 095 // OpenGIS Interface. 096 public int getDimension() { 097 return 1; 098 } 099 100 // OpenGIS Interface. 101 public double getOrdinate(int dimension) throws IndexOutOfBoundsException { 102 if (dimension == 0) { 103 Unit<?> u = VerticalCRS.HEIGHT_CS.getAxis(0).getUnit(); 104 return METRE.getConverterTo(u).convert(_meters); 105 } else { 106 throw new IndexOutOfBoundsException(); 107 } 108 } 109 110 // Implements Scalar<Length> 111 public final double doubleValue(Unit<Length> unit) { 112 return (unit == METRE) ? _meters : 113 METRE.getConverterTo(unit).convert(_meters); 114 } 115 116 // Implements Scalar<Length> 117 public final long longValue(Unit<Length> unit) { 118 return Math.round(doubleValue(unit)); 119 } 120 121 // Implements Scalar<Length> 122 public int compareTo(Measurable<Length> measure) { 123 double meters = measure.doubleValue(METRE); 124 return (_meters > meters) ? 1 125 : (_meters < meters) ? -1 : 0; 126 } 127 128 @Override 129 public Altitude copy() { 130 return Altitude.valueOf(_meters, METRE); 131 } 132 133 // Default serialization. 134 // 135 136 static final XMLFormat<Altitude> XML = new XMLFormat<Altitude>(Altitude.class) { 137 138 @Override 139 public Altitude newInstance(Class<Altitude> cls, InputElement xml) throws XMLStreamException { 140 return FACTORY.object(); 141 } 142 143 public void write(Altitude altitude, OutputElement xml) throws XMLStreamException { 144 xml.setAttribute("meters", altitude._meters); 145 } 146 147 public void read(InputElement xml, Altitude altitude) throws XMLStreamException { 148 altitude._meters = xml.getAttribute("meters", 0.0); 149 } 150 }; 151 152 private static final long serialVersionUID = 1L; 153 154}