1 9 package org.jscience.geography.coordinates.crs; 10 11 import javax.measure.quantities.*; 12 import javax.measure.units.SI; 13 14 43 public class ReferenceEllipsoid { 44 45 48 public static final ReferenceEllipsoid WGS84 49 = new ReferenceEllipsoid(6378137.0, 298.257223563); 50 53 public static final ReferenceEllipsoid GRS80 54 = new ReferenceEllipsoid(6378137.0, 298.257222101); 55 58 public static final ReferenceEllipsoid WGS72 59 = new ReferenceEllipsoid(6378135.0, 298.26); 60 64 public static final ReferenceEllipsoid INTERNATIONAL1924 65 = new ReferenceEllipsoid(6378388.0, 297.0); 66 67 private final double a; 68 69 private final double b; 70 71 private final double f; 72 73 private final double ea2; 74 75 private final double e; 76 77 private final double eb2; 78 79 private Quantity<Length> _semimajorAxis; 80 81 private Quantity<Length> _semiminorAxis; 82 83 91 public ReferenceEllipsoid(double semimajorAxis, double inverseFlattening) { 92 this.a = semimajorAxis; 93 f = 1.0 / inverseFlattening; 94 b = semimajorAxis * (1.0 - f); 95 ea2 = f * (2.0 - f); 96 e = Math.sqrt(ea2); 97 eb2 = ea2 / (1.0 - ea2); 98 } 99 100 private static double sqr(final double x) { 101 return x * x; 102 } 103 104 109 public Quantity<Length> getSemimajorAxis() { 110 if (_semimajorAxis == null) { 111 _semimajorAxis = new Scalar<Length>(a, SI.METER); 112 } 113 return _semimajorAxis; 114 } 115 116 121 public Quantity<Length> getsSemiminorAxis() { 122 if (_semiminorAxis == null) { 123 _semiminorAxis = new Scalar<Length>(b, SI.METER); 124 } 125 return _semiminorAxis; 126 } 127 128 133 public double getFlattening() { 134 return f; 135 } 136 137 142 public double getEccentricity() { 143 return e; 144 } 145 146 152 public double getEccentricitySquared() { 153 return ea2; 154 } 155 156 162 public double getSecondEccentricitySquared() { 163 return eb2; 164 } 165 166 173 public double verticalRadiusOfCurvature(final double phi) { 174 return a / Math.sqrt(1.0 - (ea2 * sqr(Math.sin(phi)))); 175 } 176 177 184 public Quantity<Length> verticalRadiusOfCurvature(final Quantity<Angle> latitude) { 185 return new Scalar<Length>(verticalRadiusOfCurvature(latitude.doubleValue(SI.RADIAN)), SI.METER); 186 } 187 188 195 public double meridionalRadiusOfCurvature(final double phi) { 196 return verticalRadiusOfCurvature(phi) 197 / (1.0 + eb2 * sqr(Math.cos(phi))); 198 } 199 200 207 public Quantity<Length> meridionalRadiusOfCurvature(final Quantity<Angle> latitude) { 208 return new Scalar<Length>(meridionalRadiusOfCurvature(latitude.doubleValue(SI.RADIAN)), SI.METER); 209 } 210 211 218 public double meridionalArc(final double phi) { 219 final double sin2Phi = Math.sin(2.0 * phi); 220 final double sin4Phi = Math.sin(4.0 * phi); 221 final double sin6Phi = Math.sin(6.0 * phi); 222 final double sin8Phi = Math.sin(8.0 * phi); 223 final double n = f / (2.0 - f); 224 final double n2 = n * n; 225 final double n3 = n2 * n; 226 final double n4 = n3 * n; 227 final double n5 = n4 * n; 228 final double n1n2 = n - n2; 229 final double n2n3 = n2 - n3; 230 final double n3n4 = n3 - n4; 231 final double n4n5 = n4 - n5; 232 final double ap = a * (1.0 - n + (5.0 / 4.0) * (n2n3) + (81.0 / 64.0) * (n4n5)); 233 final double bp = (3.0 / 2.0) * a * (n1n2 + (7.0 / 8.0) * (n3n4) + (55.0 / 64.0) * n5); 234 final double cp = (15.0 / 16.0) * a * (n2n3 + (3.0 / 4.0) * (n4n5)); 235 final double dp = (35.0 / 48.0) * a * (n3n4 + (11.0 / 16.0) * n5); 236 final double ep = (315.0 / 512.0) * a * (n4n5); 237 return ap * phi - bp * sin2Phi + cp * sin4Phi - dp * sin6Phi + ep * sin8Phi; 238 } 239 240 247 public Quantity<Length> meridionalArc(final Quantity<Angle> latitude) { 248 return new Scalar<Length>(meridionalArc(latitude.doubleValue(SI.RADIAN)), SI.METER); 249 } 250 251 } | Popular Tags |