KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jscience > geography > coordinates > XYZ


1 /*
2  * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
3  * Copyright (C) 2006 - JScience (http://jscience.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package org.jscience.geography.coordinates;
10
11 import javax.measure.converters.UnitConverter;
12 import javax.measure.quantities.*;
13 import javax.measure.units.SI;
14 import javax.measure.units.Unit;
15
16 import static org.jscience.geography.coordinates.crs.ReferenceEllipsoid.WGS84;
17
18 import org.jscience.geography.coordinates.crs.GeocentricCRS;
19 import org.opengis.referencing.cs.CoordinateSystem;
20
21 /**
22  * This class represents the {@link GeocentricCRS geocentric} Earth-Centered,
23  * Earth-Fixed (ECEF) cartesian coordinates used in GPS/GLONASS.
24  *
25  * @author Paul D. Anderson
26  * @version 3.0, February 18, 2006
27  */

28 public class XYZ extends Coordinates<GeocentricCRS<XYZ>> {
29
30     /**
31      * Holds the coordinate reference system for all instances of this class.
32      */

33     public static final GeocentricCRS<XYZ> CRS = new GeocentricCRS<XYZ>() {
34
35         @Override JavaDoc
36         protected XYZ coordinatesOf(AbsolutePosition position) {
37             double latitude = position.latitudeWGS84.doubleValue(SI.RADIAN);
38             double longitude = position.longitudeWGS84.doubleValue(SI.RADIAN);
39             double height = position.heightWGS84.doubleValue(SI.METER);
40
41             double cosLat = Math.cos(latitude);
42             double sinLat = Math.sin(latitude);
43             double cosLon = Math.cos(longitude);
44             double sinLon = Math.sin(longitude);
45
46             double roc = WGS84.verticalRadiusOfCurvature(latitude);
47             double x = (roc + height) * cosLat * cosLon;
48             double y = (roc + height) * cosLat * sinLon;
49             double z = ((1.0 - WGS84.getEccentricitySquared()) * roc + height)
50                     * sinLat;
51
52             return XYZ.valueOf(x, y, z, SI.METER);
53         }
54
55         @Override JavaDoc
56         protected AbsolutePosition positionOf(XYZ coordinates,
57                 AbsolutePosition position) {
58             final double x = coordinates._xInMeter;
59             final double y = coordinates._yInMeter;
60             final double z = coordinates._zInMeter;
61
62             final double longitude = Math.atan2(y, x);
63
64             final double latitude;
65             final double xy = Math.hypot(x, y);
66             // conventional result if xy == 0.0...
67
if (xy == 0.0) {
68                 latitude = (z >= 0.0) ? Math.PI / 2.0 : -Math.PI / 2.0;
69             } else {
70                 final double a = WGS84.getSemimajorAxis().doubleValue(SI.METER);
71                 final double b = WGS84.getsSemiminorAxis()
72                         .doubleValue(SI.METER);
73                 final double ea2 = WGS84.getEccentricitySquared();
74                 final double eb2 = WGS84.getSecondEccentricitySquared();
75                 final double beta = Math.atan2(a * z, b * xy);
76                 double numerator = z + b * eb2 * cube(Math.sin(beta));
77                 double denominator = xy - a * ea2 * cube(Math.cos(beta));
78                 latitude = Math.atan2(numerator, denominator);
79             }
80
81             final double height = xy / Math.cos(latitude)
82                     - WGS84.verticalRadiusOfCurvature(latitude);
83             position.latitudeWGS84 = new Scalar<Angle>(latitude, SI.RADIAN);
84             position.longitudeWGS84 = new Scalar<Angle>(longitude, SI.RADIAN);
85             position.heightWGS84 = new Scalar<Length>(height, SI.METER);
86             return position;
87         }
88
89         @Override JavaDoc
90         public CoordinateSystem getCoordinateSystem() {
91             return GeocentricCRS.XYZ_CS;
92         }
93     };
94
95     private static double cube(final double x) {
96         return x * x * x;
97     }
98
99     /**
100      * Holds the x position in meters.
101      */

102     private double _xInMeter;
103
104     /**
105      * Holds the y position in meters.
106      */

107     private double _yInMeter;
108
109     /**
110      * Holds the z position in meters.
111      */

112     private double _zInMeter;
113
114     /**
115      * Returns the spatial position corresponding to the specified coordinates.
116      *
117      * @param x the x value stated in the specified unit.
118      * @param y the y value stated in the specified unit.
119      * @param z the z value stated in the specified unit.
120      * @param unit the length unit in which the coordinates are stated.
121      * @return the corresponding 3D position.
122      */

123     public static XYZ valueOf(double x, double y, double z, Unit<Length> unit) {
124         return new XYZ(x, y, z, unit);
125     }
126
127     /**
128      * Creates a spatial position corresponding to the specified coordinates.
129      *
130      * @param x the x value stated in the specified unit.
131      * @param y the y value stated in the specified unit.
132      * @param z the z value stated in the specified unit.
133      * @param unit the length unit in which the coordinates are stated.
134      */

135     public XYZ(double x, double y, double z, Unit<Length> unit) {
136         if (unit == SI.METER) {
137             _xInMeter = x;
138             _yInMeter = y;
139             _zInMeter = z;
140         } else {
141             UnitConverter toMeter = unit.getConverterTo(SI.METER);
142             _xInMeter = toMeter.convert(x);
143             _yInMeter = toMeter.convert(y);
144             _zInMeter = toMeter.convert(z);
145         }
146     }
147
148     /**
149      * Returns the x coordinate value as <code>double</code>
150      *
151      * @param unit the length unit of the x coordinate value to return.
152      * @return the x coordinate stated in the specified unit.
153      */

154     public final double xValue(Unit<Length> unit) {
155         return unit.equals(SI.METER) ? _xInMeter : SI.METER
156                 .getConverterTo(unit).convert(_xInMeter);
157     }
158
159     /**
160      * Returns the y coordinate value as <code>double</code>
161      *
162      * @param unit the length unit of the x coordinate value to return.
163      * @return the z coordinate stated in the specified unit.
164      */

165     public final double yValue(Unit<Length> unit) {
166         return unit.equals(SI.METER) ? _yInMeter : SI.METER
167                 .getConverterTo(unit).convert(_yInMeter);
168     }
169
170     /**
171      * Returns the z coordinate value as <code>double</code>
172      *
173      * @param unit the length unit of the x coordinate value to return.
174      * @return the z coordinate stated in the specified unit.
175      */

176     public final double zValue(Unit<Length> unit) {
177         return unit.equals(SI.METER) ? _zInMeter : SI.METER
178                 .getConverterTo(unit).convert(_zInMeter);
179     }
180
181     @Override JavaDoc
182     public GeocentricCRS<XYZ> getCoordinateReferenceSystem() {
183         return CRS;
184     }
185
186     // OpenGIS Interface.
187
public int getDimension() {
188         return 3;
189     }
190
191     // OpenGIS Interface.
192
public double getOrdinate(int dimension) throws IndexOutOfBoundsException JavaDoc {
193         if (dimension == 0) {
194             Unit u = GeocentricCRS.XYZ_CS.getAxis(0).getUnit();
195             return SI.METER.getConverterTo(u).convert(_xInMeter);
196         } else if (dimension == 1) {
197             Unit u = GeocentricCRS.XYZ_CS.getAxis(1).getUnit();
198             return SI.METER.getConverterTo(u).convert(_yInMeter);
199         } else if (dimension == 2) {
200             Unit u = GeocentricCRS.XYZ_CS.getAxis(2).getUnit();
201             return SI.METER.getConverterTo(u).convert(_zInMeter);
202         } else {
203             throw new IndexOutOfBoundsException JavaDoc();
204         }
205     }
206 }
Popular Tags