source: josm/trunk/src/org/openstreetmap/josm/data/projection/Ellipsoid.java@ 2676

Last change on this file since 2676 was 2507, checked in by stoecker, 14 years ago

apply #2989 - patch by pieren - improve lambert projection

File size: 5.3 KB
Line 
1/*
2 * Import from fr.geo.convert package, a geographic coordinates converter.
3 * (http://www.i3s.unice.fr/~johan/gps/)
4 * License: GPL. For details, see LICENSE file.
5 * Copyright (C) 2002 Johan Montagnat (johan@creatis.insa-lyon.fr)
6 */
7
8package org.openstreetmap.josm.data.projection;
9
10/**
11 * the reference ellipsoids
12 */
13public class Ellipsoid {
14 /**
15 * Clarke's ellipsoid (NTF system)
16 */
17 public static final Ellipsoid clarke = new Ellipsoid(6378249.2, 6356515.0);
18 /**
19 * Hayford's ellipsoid (ED50 system)
20 */
21 public static final Ellipsoid hayford =
22 new Ellipsoid(6378388.0, 6356911.9461);
23 /**
24 * GRS80 ellipsoid
25 */
26 public static final Ellipsoid GRS80 = new Ellipsoid(6378137.0, 6356752.3141);
27
28 /**
29 * WGS84 ellipsoid
30 */
31 public static final Ellipsoid WGS84 = new Ellipsoid(6378137.0, 6356752.3142);
32
33 /**
34 * half long axis
35 */
36 public final double a;
37 /**
38 * half short axis
39 */
40 public final double b;
41 /**
42 * first eccentricity
43 */
44 public final double e;
45 /**
46 * first eccentricity squared
47 */
48 public final double e2;
49
50 /**
51 * square of the second eccentricity
52 */
53 public final double eb2;
54
55 /**
56 * create a new ellipsoid and precompute its parameters
57 *
58 * @param a ellipsoid long axis (in meters)
59 * @param b ellipsoid short axis (in meters)
60 */
61 public Ellipsoid(double a, double b) {
62 this.a = a;
63 this.b = b;
64 e2 = (a*a - b*b) / (a*a);
65 e = Math.sqrt(e2);
66 eb2 = e2 / (1.0 - e2);
67 }
68
69 /**
70 * Returns the <i>radius of curvature in the prime vertical</i>
71 * for this reference ellipsoid at the specified latitude.
72 *
73 * @param phi The local latitude (radians).
74 * @return The radius of curvature in the prime vertical (meters).
75 */
76 public double verticalRadiusOfCurvature(final double phi) {
77 return a / Math.sqrt(1.0 - (e2 * sqr(Math.sin(phi))));
78 }
79
80 private static double sqr(final double x) {
81 return x * x;
82 }
83
84 /**
85 * Returns the meridional arc, the true meridional distance on the
86 * ellipsoid from the equator to the specified latitude, in meters.
87 *
88 * @param phi The local latitude (in radians).
89 * @return The meridional arc (in meters).
90 */
91 public double meridionalArc(final double phi) {
92 final double sin2Phi = Math.sin(2.0 * phi);
93 final double sin4Phi = Math.sin(4.0 * phi);
94 final double sin6Phi = Math.sin(6.0 * phi);
95 final double sin8Phi = Math.sin(8.0 * phi);
96 // TODO . calculate 'f'
97 //double f = 1.0 / 298.257222101; // GRS80
98 double f = 1.0 / 298.257223563; // WGS84
99 final double n = f / (2.0 - f);
100 final double n2 = n * n;
101 final double n3 = n2 * n;
102 final double n4 = n3 * n;
103 final double n5 = n4 * n;
104 final double n1n2 = n - n2;
105 final double n2n3 = n2 - n3;
106 final double n3n4 = n3 - n4;
107 final double n4n5 = n4 - n5;
108 final double ap = a * (1.0 - n + (5.0 / 4.0) * (n2n3) + (81.0 / 64.0) * (n4n5));
109 final double bp = (3.0 / 2.0) * a * (n1n2 + (7.0 / 8.0) * (n3n4) + (55.0 / 64.0) * n5);
110 final double cp = (15.0 / 16.0) * a * (n2n3 + (3.0 / 4.0) * (n4n5));
111 final double dp = (35.0 / 48.0) * a * (n3n4 + (11.0 / 16.0) * n5);
112 final double ep = (315.0 / 512.0) * a * (n4n5);
113 return ap * phi - bp * sin2Phi + cp * sin4Phi - dp * sin6Phi + ep * sin8Phi;
114 }
115
116 /**
117 * Returns the <i>radius of curvature in the meridian<i>
118 * for this reference ellipsoid at the specified latitude.
119 *
120 * @param phi The local latitude (in radians).
121 * @return The radius of curvature in the meridian (in meters).
122 */
123 public double meridionalRadiusOfCurvature(final double phi) {
124 return verticalRadiusOfCurvature(phi)
125 / (1.0 + eb2 * sqr(Math.cos(phi)));
126 }
127
128 /**
129 * Returns isometric latitude of phi on given first eccentricity (e)
130 * @param phi The local latitude (radians).
131 * @return isometric latitude of phi on first eccentricity (e)
132 */
133 public double latitudeIsometric(double phi, double e) {
134 double v1 = 1-e*Math.sin(phi);
135 double v2 = 1+e*Math.sin(phi);
136 return Math.log(Math.tan(Math.PI/4+phi/2)*Math.pow(v1/v2,e/2));
137 }
138
139 /**
140 * Returns isometric latitude of phi on first eccentricity (e)
141 * @param phi The local latitude (radians).
142 * @return isometric latitude of phi on first eccentricity (e)
143 */
144 public double latitudeIsometric(double phi) {
145 double v1 = 1-e*Math.sin(phi);
146 double v2 = 1+e*Math.sin(phi);
147 return Math.log(Math.tan(Math.PI/4+phi/2)*Math.pow(v1/v2,e/2));
148 }
149
150 /*
151 * Returns geographic latitude of isometric latitude of first eccentricity (e)
152 * and epsilon precision
153 */
154 public double latitude(double latIso, double e, double epsilon) {
155 double lat0 = 2*Math.atan(Math.exp(latIso))-Math.PI/2;
156 double lati = lat0;
157 double lati1 = 1.0; // random value to start the iterative processus
158 while(Math.abs(lati1-lati)>=epsilon) {
159 lati = lati1;
160 double v1 = 1+e*Math.sin(lati);
161 double v2 = 1-e*Math.sin(lati);
162 lati1 = 2*Math.atan(Math.pow(v1/v2,e/2)*Math.exp(latIso))-Math.PI/2;
163 }
164 return lati1;
165 }
166}
Note: See TracBrowser for help on using the repository browser.