1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth;
18
19 import static org.hamcrest.CoreMatchers.is;
20 import static org.hamcrest.CoreMatchers.nullValue;
21 import static org.hamcrest.CoreMatchers.sameInstance;
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.junit.Assert.assertEquals;
24 import static org.orekit.OrekitMatchers.closeTo;
25 import static org.orekit.OrekitMatchers.geodeticPointCloseTo;
26 import static org.orekit.OrekitMatchers.vectorCloseTo;
27
28 import java.util.Arrays;
29
30 import org.hipparchus.geometry.euclidean.threed.Line;
31 import org.hipparchus.geometry.euclidean.threed.Rotation;
32 import org.hipparchus.geometry.euclidean.threed.Vector3D;
33 import org.hipparchus.util.FastMath;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.junit.BeforeClass;
37 import org.junit.Test;
38 import org.orekit.Utils;
39 import org.orekit.bodies.GeodeticPoint;
40 import org.orekit.forces.gravity.potential.EGMFormatReader;
41 import org.orekit.forces.gravity.potential.GravityFieldFactory;
42 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
43 import org.orekit.frames.Frame;
44 import org.orekit.frames.FramesFactory;
45 import org.orekit.frames.Transform;
46 import org.orekit.time.AbsoluteDate;
47
48
49
50
51
52
53 public class GeoidTest {
54
55
56 private static final int maxOrder = 360;
57
58 private static final int maxDegree = 360;
59
60 private static ReferenceEllipsoid WGS84 = new ReferenceEllipsoid(
61 6378137.00, 1 / 298.257223563, FramesFactory.getGCRF(),
62 3.986004418e14, 7292115e-11);
63
64
65
66
67 private static NormalizedSphericalHarmonicsProvider potential;
68
69 private static AbsoluteDate date;
70
71
72
73
74
75
76 @BeforeClass
77 public static void setUpBefore() throws Exception {
78 Utils.setDataRoot("geoid:regular-data");
79 GravityFieldFactory.clearPotentialCoefficientsReaders();
80 GravityFieldFactory.addPotentialCoefficientsReader(
81 new EGMFormatReader("egm96", false));
82 potential = GravityFieldFactory.getConstantNormalizedProvider(
83 maxDegree, maxOrder);
84 date = null;
85 }
86
87
88 private double[][] reference;
89
90
91 @Before
92 public void setUp() {
93 reference = new double[][]{
94 {0, 75, -100.3168},
95 {-30, 60, 14.9214},
96 {0, 130, 76.6053},
97 {60, -30, 63.7979},
98 {40, -75, -34.0402},
99 {28, 92, -30.4056},
100 {45, 250, -7.4825},
101
102 {38.6281550, 269.7791550, -31.628},
103 {-14.6212170, 305.0211140, -2.969},
104 {46.8743190, 102.4487290, -43.575},
105 {-23.6174460, 133.8747120, 15.871},
106 {38.6254730, 359.9995000, 50.066},
107 {-.4667440, .0023000, 17.329}};
108 }
109
110
111
112
113
114
115
116 private Geoid getComponent() {
117 return new Geoid(potential, WGS84);
118 }
119
120
121 @Test
122 public void testGeoid() {
123 Geoid geoid = getComponent();
124
125 assertEquals(WGS84, geoid.getEllipsoid());
126
127 assertEquals(WGS84.getBodyFrame(), geoid.getBodyFrame());
128 }
129
130
131 @Test(expected = NullPointerException.class)
132 public void testGeoidNullPotential() {
133 new Geoid(null, WGS84);
134 }
135
136
137 @Test(expected = NullPointerException.class)
138 public void testGeoidNullEllipsoid() {
139 new Geoid(potential, null);
140 }
141
142
143
144
145
146
147
148
149
150
151 @Test
152 public void testGetUndulation() {
153
154
155
156
157 final double maxError = 3;
158
159
160 Geoid geoid = getComponent();
161 for (double[] row : reference) {
162 double lat = row[0];
163 double lon = row[1];
164 double undulation = geoid.getUndulation(FastMath.toRadians(lat),
165 FastMath.toRadians(lon), date);
166 double expected = row[2];
167
168
169 Assert.assertEquals(String.format("lat: %5g, lon: %5g", lat, lon),
170 undulation, expected, maxError);
171 }
172 }
173
174
175
176
177
178 @Test
179 public void testGetIntersectionPoint() {
180
181 Geoid geoid = getComponent();
182 Frame frame = geoid.getBodyFrame();
183
184 for (double[] point : reference) {
185 GeodeticPoint gp = new GeodeticPoint(FastMath.toRadians(point[0]),
186 FastMath.toRadians(point[1]), 0);
187 Vector3D expected = geoid.transform(gp);
188
189 Vector3D slope = gp.getZenith().scalarMultiply(0.1)
190 .add(gp.getNorth().scalarMultiply(0.9));
191 Vector3D close = expected.add(slope.scalarMultiply(100e3));
192 Vector3D pointOnLine = expected.add(slope);
193 Line line = new Line(close, pointOnLine, 0);
194
195 Line otherDirection = new Line(pointOnLine, close, 0);
196
197
198 GeodeticPoint actual = geoid.getIntersectionPoint(line, close,
199 frame, date);
200
201 GeodeticPoint actualReversed = geoid.getIntersectionPoint(
202 otherDirection, close, frame, date);
203
204
205 String message = String.format("point: %s%n",
206 Arrays.toString(point));
207
208 assertThat(message, actualReversed, geodeticPointCloseTo(gp, 1.3e-6));
209 assertThat(message, actual, geodeticPointCloseTo(gp, 1.3e-6));
210 }
211 }
212
213
214
215
216
217 @Test
218 public void testGetIntersectionPointFrame() {
219
220 Geoid geoid = getComponent();
221 Frame frame = new Frame(
222 geoid.getBodyFrame(),
223 new Transform(
224 date,
225 new Transform(
226 date,
227 new Vector3D(-1, 2, -3),
228 new Vector3D(4, -5, 6)),
229 new Transform(
230 date,
231 new Rotation(-7, 8, -9, 10, true),
232 new Vector3D(-11, 12, -13))),
233 "test frame");
234 GeodeticPoint gp = new GeodeticPoint(FastMath.toRadians(46.8743190),
235 FastMath.toRadians(102.4487290), 0);
236 Vector3D expected = geoid.transform(gp);
237
238 Vector3D slope = gp.getZenith().scalarMultiply(0.1)
239 .add(gp.getNorth().scalarMultiply(0.9));
240 Vector3D close = expected.add(slope.scalarMultiply(100));
241 Line line = new Line(expected.add(slope), close, 0);
242 Transform xform = geoid.getBodyFrame().getTransformTo(frame, date);
243
244 close = xform.transformPosition(close);
245 line = xform.transformLine(line);
246
247
248 GeodeticPoint actual = geoid.getIntersectionPoint(line, close, frame,
249 date);
250
251
252 assertThat(actual, geodeticPointCloseTo(gp, 1e-6));
253 }
254
255
256
257
258
259 @Test
260 public void testGetIntersectionPointNoIntersection() {
261 Geoid geoid = getComponent();
262 Vector3D closeMiss = new Vector3D(geoid.getEllipsoid()
263 .getEquatorialRadius() + 18, 0, 0);
264 Line line = new Line(closeMiss, closeMiss.add(Vector3D.PLUS_J), 0);
265
266
267 final GeodeticPoint actual = geoid.getIntersectionPoint(line,
268 closeMiss, geoid.getBodyFrame(), date);
269
270
271 assertThat(actual, nullValue());
272 }
273
274
275
276
277
278 @Test
279 public void testTransformVector3DFrameAbsoluteDate()
280 {
281
282 Frame frame = FramesFactory.getGCRF();
283 AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
284
285 Geoid geoid = getComponent();
286
287 Vector3D point = new Vector3D(WGS84.getEquatorialRadius(), 0, 0);
288 double undulation = geoid.getUndulation(0, 0, date);
289
290
291 GeodeticPoint ellipsoidal = geoid.getEllipsoid().transform(
292 point, frame, date);
293 GeodeticPoint geoidal = geoid.transform(point, frame, date);
294 assertThat(ellipsoidal.getAltitude() - geoidal.getAltitude(),
295 is(undulation));
296
297
298 point = new Vector3D(0.5, 0.4, 0.31).scalarMultiply(WGS84
299 .getEquatorialRadius());
300 Vector3D expected = geoid
301 .transform(geoid.transform(point, frame, date));
302
303 assertThat(point, vectorCloseTo(expected, 2));
304
305 }
306
307
308
309
310
311 @Test
312 public void testTransformGeodeticPoint() {
313
314 Geoid geoid = getComponent();
315
316 ReferenceEllipsoid ellipsoid = geoid.getEllipsoid();
317
318 GeodeticPoint orthometric = new GeodeticPoint(0, 75, 5);
319
320 double undulation = geoid.getUndulation(orthometric.getLatitude(),
321 orthometric.getLongitude(), date);
322
323 GeodeticPoint point = new GeodeticPoint(orthometric.getLatitude(),
324 orthometric.getLongitude(), orthometric.getAltitude()
325 + undulation);
326
327
328 Vector3D expected = ellipsoid.transform(point);
329 Vector3D actual = geoid.transform(orthometric);
330 assertThat(actual, is(expected));
331
332
333 expected = new Vector3D(WGS84.getEquatorialRadius()
334 + geoid.getUndulation(0, 0, date), 0, 0);
335 actual = geoid.transform(new GeodeticPoint(0, 0, 0));
336 assertThat(actual, vectorCloseTo(expected, 0));
337 }
338
339
340 @Test
341 public void testGetEllipsoid() {
342
343 Geoid geoid = new Geoid(potential, WGS84);
344
345
346 assertThat(geoid.getEllipsoid(), sameInstance(WGS84));
347 }
348
349
350
351
352 @Test
353 public void testProjectToGround() {
354
355 Vector3D p = new Vector3D(7e8, 1e3, 200);
356 Geoid geoid = new Geoid(potential, WGS84);
357
358
359 Vector3D actual = geoid.projectToGround(p, date, FramesFactory.getGCRF());
360
361
362 assertThat(
363 geoid.transform(actual, geoid.getBodyFrame(), date).getAltitude(),
364 closeTo(0.0, 1.1e-9));
365 }
366
367 }