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.Measure;
012: import javax.measure.converter.UnitConverter;
013: import javax.measure.quantity.Angle;
014: import static javax.measure.unit.NonSI.DEGREE_ANGLE;
015: import static javax.measure.unit.SI.RADIAN;
016: import javax.measure.unit.Unit;
017:
018: import javolution.context.ObjectFactory;
019: import javolution.xml.XMLFormat;
020: import javolution.xml.stream.XMLStreamException;
021:
022: import org.jscience.geography.coordinates.crs.GeographicCRS;
023: import org.opengis.referencing.cs.CoordinateSystem;
024:
025: /**
026: * This class represents the {@link GeographicCRS geographic} latitude/longitude
027: * coordinates onto the WGS84 ellipsoid.
028: *
029: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
030: * @version 3.0, February 13, 2006
031: */
032: public final class LatLong extends Coordinates<GeographicCRS<?>> {
033:
034: /**
035: * Holds the coordinate reference system for all instances of this class.
036: */
037: public static final GeographicCRS<LatLong> CRS = new GeographicCRS<LatLong>() {
038:
039: @Override
040: protected LatLong coordinatesOf(AbsolutePosition position) {
041: return LatLong.valueOf(position.latitudeWGS84
042: .doubleValue(DEGREE_ANGLE), position.longitudeWGS84
043: .doubleValue(DEGREE_ANGLE), DEGREE_ANGLE);
044: }
045:
046: @Override
047: protected AbsolutePosition positionOf(LatLong coordinates,
048: AbsolutePosition position) {
049: position.latitudeWGS84 = Measure.valueOf(
050: coordinates._latitude, DEGREE_ANGLE);
051: position.longitudeWGS84 = Measure.valueOf(
052: coordinates._longitude, DEGREE_ANGLE);
053: return position;
054: }
055:
056: @Override
057: public CoordinateSystem getCoordinateSystem() {
058: return GeographicCRS.LATITUDE_LONGITUDE_CS;
059: }
060:
061: };
062:
063: /**
064: * Holds converter from degree to radian.
065: */
066: private static final UnitConverter DEGREE_TO_RADIAN = DEGREE_ANGLE
067: .getConverterTo(RADIAN);
068:
069: /**
070: * Holds converter from radian to degree.
071: */
072: private static final UnitConverter RADIAN_TO_DEGREE = DEGREE_TO_RADIAN
073: .inverse();
074:
075: /**
076: * Holds the latitude in degrees.
077: */
078: private double _latitude;
079:
080: /**
081: * Holds the longitude in degrees.
082: */
083: private double _longitude;
084:
085: /**
086: * Returns the surface position corresponding to the specified coordinates.
087: *
088: * @param latitude the latitude value stated in the specified unit.
089: * @param longitude the longitude value stated in the specified unit.
090: * @param unit the angle unit in which the coordinates are stated
091: * ({@link javax.measure.unit.NonSI#DEGREE_ANGLE Degree} typically).
092: * @return the corresponding surface position.
093: */
094: public static LatLong valueOf(double latitude, double longitude,
095: Unit<Angle> unit) {
096: LatLong latLong = FACTORY.object();
097: if (unit == DEGREE_ANGLE) {
098: latLong._latitude = latitude;
099: latLong._longitude = longitude;
100: } else if (unit == RADIAN) {
101: latLong._latitude = RADIAN_TO_DEGREE.convert(latitude);
102: latLong._longitude = RADIAN_TO_DEGREE.convert(longitude);
103: } else { // Other angle unit.
104: UnitConverter toDegree = unit.getConverterTo(DEGREE_ANGLE);
105: latLong._latitude = toDegree.convert(latitude);
106: latLong._longitude = toDegree.convert(longitude);
107: }
108: return latLong;
109: }
110:
111: private static final ObjectFactory<LatLong> FACTORY = new ObjectFactory<LatLong>() {
112:
113: @Override
114: protected LatLong create() {
115: return new LatLong();
116: }
117: };
118:
119: private LatLong() {
120: }
121:
122: /**
123: * Returns the latitude value as <code>double</code>
124: *
125: * @param unit the angle unit of the latitude to return.
126: * @return the latitude stated in the specified unit.
127: */
128: public final double latitudeValue(Unit<Angle> unit) {
129: return (unit == DEGREE_ANGLE) ? _latitude
130: : (unit == RADIAN) ? DEGREE_TO_RADIAN
131: .convert(_latitude) : DEGREE_ANGLE
132: .getConverterTo(unit).convert(_latitude);
133: }
134:
135: /**
136: * Returns the longitude value as <code>double</code>
137: *
138: * @param unit the angle unit of the longitude to return.
139: * @return the longitude stated in the specified unit.
140: */
141: public final double longitudeValue(Unit<Angle> unit) {
142: return (unit == DEGREE_ANGLE) ? _longitude
143: : (unit == RADIAN) ? DEGREE_TO_RADIAN
144: .convert(_longitude) : DEGREE_ANGLE
145: .getConverterTo(unit).convert(_longitude);
146: }
147:
148: @Override
149: public GeographicCRS<LatLong> getCoordinateReferenceSystem() {
150: return CRS;
151: }
152:
153: // OpenGIS Interface.
154: public int getDimension() {
155: return 2;
156: }
157:
158: // OpenGIS Interface.
159: public double getOrdinate(int dimension)
160: throws IndexOutOfBoundsException {
161: if (dimension == 0) {
162: Unit<?> u = GeographicCRS.LATITUDE_LONGITUDE_CS.getAxis(0)
163: .getUnit();
164: return DEGREE_ANGLE.getConverterTo(u).convert(_latitude);
165: } else if (dimension == 1) {
166: Unit<?> u = GeographicCRS.LATITUDE_LONGITUDE_CS.getAxis(1)
167: .getUnit();
168: return DEGREE_ANGLE.getConverterTo(u).convert(_longitude);
169: } else {
170: throw new IndexOutOfBoundsException();
171: }
172: }
173:
174: // Implements Realtime.
175: public LatLong copy() {
176: return LatLong.valueOf(_latitude, _longitude, DEGREE_ANGLE);
177: }
178:
179: // Default serialization.
180: //
181:
182: static final XMLFormat<LatLong> XML = new XMLFormat<LatLong>(
183: LatLong.class) {
184:
185: @Override
186: public LatLong newInstance(Class<LatLong> cls, InputElement xml)
187: throws XMLStreamException {
188: return FACTORY.object();
189: }
190:
191: public void write(LatLong latLong, OutputElement xml)
192: throws XMLStreamException {
193: xml.setAttribute("latitude", latLong._latitude);
194: xml.setAttribute("longitude", latLong._longitude);
195: }
196:
197: public void read(InputElement xml, LatLong latLong)
198: throws XMLStreamException {
199: latLong._latitude = xml.getAttribute("latitude", 0.0);
200: latLong._longitude = xml.getAttribute("longitude", 0.0);
201: }
202: };
203:
204: private static final long serialVersionUID = 1L;
205: }
|