source: josm/trunk/src/org/openstreetmap/josm/data/projection/proj/AbstractProj.java@ 9428

Last change on this file since 9428 was 9428, checked in by Don-vip, 9 years ago

see #12186 - fix some javadoc warnings

  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection.proj;
3
4import org.openstreetmap.josm.data.projection.ProjectionConfigurationException;
5
6/**
7 * Abstract base class providing utilities for implementations of the Proj
8 * interface.
9 *
10 * This class has been derived from the implementation of the Geotools project;
11 * git 8cbf52d, org.geotools.referencing.operation.projection.MapProjection
12 * at the time of migration.
13 * <p>
14 *
15 * @author André Gosselin
16 * @author Martin Desruisseaux (PMO, IRD)
17 * @author Rueben Schulz
18*/
19public abstract class AbstractProj implements Proj {
20
21 /**
22 * Maximum number of iterations for iterative computations.
23 */
24 private static final int MAXIMUM_ITERATIONS = 15;
25
26 /**
27 * Relative iteration precision used in the <code>mlfn</code> method
28 */
29 private static final double MLFN_TOL = 1E-11;
30
31 /**
32 * Constants used to calculate {@link #en0}, {@link #en1},
33 * {@link #en2}, {@link #en3}, {@link #en4}.
34 */
35 private static final double C00 = 1.0,
36 C02 = 0.25,
37 C04 = 0.046875,
38 C06 = 0.01953125,
39 C08 = 0.01068115234375,
40 C22 = 0.75,
41 C44 = 0.46875,
42 C46 = 0.01302083333333333333,
43 C48 = 0.00712076822916666666,
44 C66 = 0.36458333333333333333,
45 C68 = 0.00569661458333333333,
46 C88 = 0.3076171875;
47
48 /**
49 * Constant needed for the <code>mlfn</code> method.
50 * Setup at construction time.
51 */
52 protected double en0, en1, en2, en3, en4;
53
54 /**
55 * Ellipsoid excentricity, equals to <code>sqrt({@link #e2 excentricity squared})</code>.
56 * Value 0 means that the ellipsoid is spherical.
57 *
58 * @see #e2
59 */
60 protected double e;
61
62 /**
63 * The square of excentricity: e² = (a²-b²)/a² where
64 * <var>e</var> is the excentricity,
65 * <var>a</var> is the semi major axis length and
66 * <var>b</var> is the semi minor axis length.
67 *
68 * @see #e
69 */
70 protected double e2;
71
72 @Override
73 public void initialize(ProjParameters params) throws ProjectionConfigurationException {
74 e2 = params.ellps.e2;
75 e = params.ellps.e;
76 // Compute constants for the mlfn
77 double t;
78 en0 = C00 - e2 * (C02 + e2 *
79 (C04 + e2 * (C06 + e2 * C08)));
80 en1 = e2 * (C22 - e2 *
81 (C04 + e2 * (C06 + e2 * C08)));
82 en2 = (t = e2 * e2) *
83 (C44 - e2 * (C46 + e2 * C48));
84 en3 = (t *= e2) * (C66 - e2 * C68);
85 en4 = t * e2 * C88;
86 }
87
88 /**
89 * Calculates the meridian distance. This is the distance along the central
90 * meridian from the equator to {@code phi}. Accurate to &lt; 1e-5 meters
91 * when used in conjuction with typical major axis values.
92 *
93 * @param phi latitude to calculate meridian distance for.
94 * @param sphi sin(phi).
95 * @param cphi cos(phi).
96 * @return meridian distance for the given latitude.
97 */
98 protected final double mlfn(final double phi, double sphi, double cphi) {
99 cphi *= sphi;
100 sphi *= sphi;
101 return en0 * phi - cphi *
102 (en1 + sphi *
103 (en2 + sphi *
104 (en3 + sphi *
105 (en4))));
106 }
107
108 /**
109 * Calculates the latitude ({@code phi}) from a meridian distance.
110 * Determines phi to TOL (1e-11) radians, about 1e-6 seconds.
111 *
112 * @param arg meridian distance to calulate latitude for.
113 * @return the latitude of the meridian distance.
114 * @throws RuntimeException if the itteration does not converge.
115 */
116 protected final double inv_mlfn(double arg) {
117 double s, t, phi, k = 1.0/(1.0 - e2);
118 int i;
119 phi = arg;
120 for (i = MAXIMUM_ITERATIONS; true;) { // rarely goes over 5 iterations
121 if (--i < 0) {
122 throw new RuntimeException("Too many iterations");
123 }
124 s = Math.sin(phi);
125 t = 1.0 - e2 * s * s;
126 t = (mlfn(phi, s, Math.cos(phi)) - arg) * (t * Math.sqrt(t)) * k;
127 phi -= t;
128 if (Math.abs(t) < MLFN_TOL) {
129 return phi;
130 }
131 }
132 }
133
134 public static double normalizeLon(double lon) {
135 if (lon >= -Math.PI && lon <= Math.PI)
136 return lon;
137 else {
138 lon = lon % (2 * Math.PI);
139 if (lon > Math.PI) {
140 return lon - 2 * Math.PI;
141 } else if (lon < -Math.PI) {
142 return lon + 2 * Math.PI;
143 }
144 return lon;
145 }
146 }
147
148 /**
149 * Computes function <code>f(s,c,e²) = c/sqrt(1 - s²&times;e²)</code> needed for the true scale
150 * latitude (Snyder 14-15), where <var>s</var> and <var>c</var> are the sine and cosine of
151 * the true scale latitude, and <var>e²</var> is the {@linkplain #e2 eccentricity squared}.
152 * @param s sine of the true scale latitude
153 * @param c cosine of the true scale latitude
154 * @return <code>c/sqrt(1 - s²&times;e²)</code>
155 */
156 final double msfn(final double s, final double c) {
157 return c / Math.sqrt(1.0 - (s*s) * e2);
158 }
159
160 /**
161 * Computes function (15-9) and (9-13) from Snyder.
162 * Equivalent to negative of function (7-7).
163 */
164 final double tsfn(final double lat, double sinlat) {
165 sinlat *= e;
166 // NOTE: change sign to get the equivalent of Snyder (7-7).
167 return Math.tan(0.5 * (Math.PI/2 - lat)) / Math.pow((1 - sinlat) / (1 + sinlat), 0.5*e);
168 }
169}
Note: See TracBrowser for help on using the repository browser.