1 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 28 public class XYZ extends Coordinates<GeocentricCRS<XYZ>> { 29 30 33 public static final GeocentricCRS<XYZ> CRS = new GeocentricCRS<XYZ>() { 34 35 @Override 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 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 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 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 102 private double _xInMeter; 103 104 107 private double _yInMeter; 108 109 112 private double _zInMeter; 113 114 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 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 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 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 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 182 public GeocentricCRS<XYZ> getCoordinateReferenceSystem() { 183 return CRS; 184 } 185 186 public int getDimension() { 188 return 3; 189 } 190 191 public double getOrdinate(int dimension) throws IndexOutOfBoundsException { 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 (); 204 } 205 } 206 } | Popular Tags |