1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import java.io.Serializable;
20 import java.text.NumberFormat;
21
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.util.CompositeFormat;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.MathUtils;
26 import org.hipparchus.util.SinCos;
27
28
29
30
31
32
33
34 public class GeodeticPoint implements Serializable {
35
36
37
38
39 public static final GeodeticPoint NORTH_POLE = new GeodeticPoint(+0.5 * FastMath.PI, 0.0, 0.0);
40
41
42
43
44 public static final GeodeticPoint SOUTH_POLE = new GeodeticPoint(-0.5 * FastMath.PI, 0.0, 0.0);
45
46
47 private static final long serialVersionUID = 7862466825590075399L;
48
49
50 private final double latitude;
51
52
53 private final double longitude;
54
55
56 private final double altitude;
57
58
59 private transient Vector3D zenith;
60
61
62 private transient Vector3D nadir;
63
64
65 private transient Vector3D north;
66
67
68 private transient Vector3D south;
69
70
71 private transient Vector3D east;
72
73
74 private transient Vector3D west;
75
76
77
78
79
80
81
82
83
84
85 public GeodeticPoint(final double latitude, final double longitude,
86 final double altitude) {
87 double lat = MathUtils.normalizeAngle(latitude, FastMath.PI / 2);
88 double lon = MathUtils.normalizeAngle(longitude, 0);
89 if (lat > FastMath.PI / 2.0) {
90
91 lat = FastMath.PI - lat;
92 lon = MathUtils.normalizeAngle(longitude + FastMath.PI, 0);
93 }
94 this.latitude = lat;
95 this.longitude = lon;
96 this.altitude = altitude;
97 }
98
99
100
101
102 public double getLatitude() {
103 return latitude;
104 }
105
106
107
108
109 public double getLongitude() {
110 return longitude;
111 }
112
113
114
115
116 public double getAltitude() {
117 return altitude;
118 }
119
120
121
122
123
124
125 public Vector3D getZenith() {
126 if (zenith == null) {
127 final SinCos scLat = FastMath.sinCos(latitude);
128 final SinCos scLon = FastMath.sinCos(longitude);
129 zenith = new Vector3D(scLon.cos() * scLat.cos(), scLon.sin() * scLat.cos(), scLat.sin());
130 }
131 return zenith;
132 }
133
134
135
136
137
138
139 public Vector3D getNadir() {
140 if (nadir == null) {
141 nadir = getZenith().negate();
142 }
143 return nadir;
144 }
145
146
147
148
149
150
151
152 public Vector3D getNorth() {
153 if (north == null) {
154 final SinCos scLat = FastMath.sinCos(latitude);
155 final SinCos scLon = FastMath.sinCos(longitude);
156 north = new Vector3D(-scLon.cos() * scLat.sin(), -scLon.sin() * scLat.sin(), scLat.cos());
157 }
158 return north;
159 }
160
161
162
163
164
165
166 public Vector3D getSouth() {
167 if (south == null) {
168 south = getNorth().negate();
169 }
170 return south;
171 }
172
173
174
175
176
177
178
179 public Vector3D getEast() {
180 if (east == null) {
181 final SinCos scLon = FastMath.sinCos(longitude);
182 east = new Vector3D(-scLon.sin(), scLon.cos(), 0);
183 }
184 return east;
185 }
186
187
188
189
190
191
192 public Vector3D getWest() {
193 if (west == null) {
194 west = getEast().negate();
195 }
196 return west;
197 }
198
199 @Override
200 public boolean equals(final Object object) {
201 if (object instanceof GeodeticPoint) {
202 final GeodeticPoint other = (GeodeticPoint) object;
203 return this.getLatitude() == other.getLatitude() &&
204 this.getLongitude() == other.getLongitude() &&
205 this.getAltitude() == other.getAltitude();
206 }
207 return false;
208 }
209
210 @Override
211 public int hashCode() {
212 return Double.valueOf(this.getLatitude()).hashCode() ^
213 Double.valueOf(this.getLongitude()).hashCode() ^
214 Double.valueOf(this.getAltitude()).hashCode();
215 }
216
217 @Override
218 public String toString() {
219 final NumberFormat format = CompositeFormat.getDefaultNumberFormat();
220 return "{lat: " +
221 format.format(FastMath.toDegrees(this.getLatitude())) +
222 " deg, lon: " +
223 format.format(FastMath.toDegrees(this.getLongitude())) +
224 " deg, alt: " +
225 format.format(this.getAltitude()) +
226 "}";
227 }
228 }