1   /* Copyright 2002-2022 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.propagation.events;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.geometry.partitioning.RegionFactory;
21  import org.hipparchus.geometry.spherical.twod.S2Point;
22  import org.hipparchus.geometry.spherical.twod.Sphere2D;
23  import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet;
24  import org.hipparchus.util.FastMath;
25  import org.junit.Assert;
26  import org.junit.Before;
27  import org.junit.Test;
28  import org.orekit.Utils;
29  import org.orekit.bodies.BodyShape;
30  import org.orekit.bodies.OneAxisEllipsoid;
31  import org.orekit.frames.FramesFactory;
32  import org.orekit.orbits.EquinoctialOrbit;
33  import org.orekit.orbits.Orbit;
34  import org.orekit.propagation.Propagator;
35  import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
36  import org.orekit.propagation.events.handlers.ContinueOnEvent;
37  import org.orekit.time.AbsoluteDate;
38  import org.orekit.time.TimeScale;
39  import org.orekit.time.TimeScalesFactory;
40  import org.orekit.utils.Constants;
41  import org.orekit.utils.IERSConventions;
42  import org.orekit.utils.PVCoordinates;
43  
44  public class GeographicZoneDetectorTest {
45  
46      @Test
47      public void testFrance() {
48  
49          final BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
50                                                       Constants.WGS84_EARTH_FLATTENING,
51                                                       FramesFactory.getITRF(IERSConventions.IERS_2010, true));
52  
53          GeographicZoneDetector d =
54                  new GeographicZoneDetector(20.0, 1.e-3, earth, buildFrance(), FastMath.toRadians(0.5)).
55                  withHandler(new ContinueOnEvent<GeographicZoneDetector>());
56  
57          Assert.assertEquals(20.0, d.getMaxCheckInterval(), 1.0e-15);
58          Assert.assertEquals(1.0e-3, d.getThreshold(), 1.0e-15);
59          Assert.assertEquals(0.5, FastMath.toDegrees(d.getMargin()), 1.0e-15);
60          Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, d.getMaxIterationCount());
61  
62          final TimeScale utc = TimeScalesFactory.getUTC();
63          final Vector3D position = new Vector3D(-6142438.668, 3492467.56, -25767.257);
64          final Vector3D velocity = new Vector3D(505.848, 942.781, 7435.922);
65          final AbsoluteDate date = new AbsoluteDate(2003, 9, 16, utc);
66          final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position,  velocity),
67                                                   FramesFactory.getEME2000(), date,
68                                                   Constants.EIGEN5C_EARTH_MU);
69  
70          Propagator propagator =
71              new EcksteinHechlerPropagator(orbit,
72                                            Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
73                                            Constants.EIGEN5C_EARTH_MU,
74                                            Constants.EIGEN5C_EARTH_C20,
75                                            Constants.EIGEN5C_EARTH_C30,
76                                            Constants.EIGEN5C_EARTH_C40,
77                                            Constants.EIGEN5C_EARTH_C50,
78                                            Constants.EIGEN5C_EARTH_C60);
79  
80          EventsLogger logger = new EventsLogger();
81          propagator.addEventDetector(logger.monitorDetector(d));
82  
83          propagator.propagate(date.shiftedBy(10 * Constants.JULIAN_DAY));
84          Assert.assertEquals(26, logger.getLoggedEvents().size());
85  
86      }
87  
88      private SphericalPolygonsSet buildFrance() {
89  
90          final SphericalPolygonsSet continental = buildSimpleZone(new double[][] {
91              { 51.14850,  2.51357 }, { 50.94660,  1.63900 }, { 50.12717,  1.33876 }, { 49.34737, -0.98946 },
92              { 49.77634, -1.93349 }, { 48.64442, -1.61651 }, { 48.90169, -3.29581 }, { 48.68416, -4.59234 },
93              { 47.95495, -4.49155 }, { 47.57032, -2.96327 }, { 46.01491, -1.19379 }, { 44.02261, -1.38422 },
94              { 43.42280, -1.90135 }, { 43.03401, -1.50277 }, { 42.34338,  1.82679 }, { 42.47301,  2.98599 },
95              { 43.07520,  3.10041 }, { 43.39965,  4.55696 }, { 43.12889,  6.52924 }, { 43.69384,  7.43518 },
96              { 44.12790,  7.54959 }, { 45.02851,  6.74995 }, { 45.33309,  7.09665 }, { 46.42967,  6.50009 },
97              { 46.27298,  6.02260 }, { 46.72577,  6.03738 }, { 47.62058,  7.46675 }, { 49.01778,  8.09927 },
98              { 49.20195,  6.65822 }, { 49.44266,  5.89775 }, { 49.98537,  4.79922 }
99            });
100 
101         final SphericalPolygonsSet corsica = buildSimpleZone(new double[][] {
102             { 42.15249,  9.56001 }, { 43.00998,  9.39000 }, { 42.62812,  8.74600 }, { 42.25651,  8.54421 },
103             { 41.58361,  8.77572 }, { 41.38000,  9.22975 }
104           });
105 
106           return (SphericalPolygonsSet) new RegionFactory<Sphere2D>().union(continental, corsica);
107 
108     }
109 
110     private SphericalPolygonsSet buildSimpleZone(double[][] points) {
111         final S2Point[] vertices = new S2Point[points.length];
112         for (int i = 0; i < points.length; ++i) {
113             vertices[i] = new S2Point(FastMath.toRadians(points[i][1]),         // points[i][1] is longitude
114                                       FastMath.toRadians(90.0 - points[i][0])); // points[i][0] is latitude
115         }
116         return new SphericalPolygonsSet(1.0e-10, vertices);
117     }
118 
119     @Before
120     public void setUp() {
121         Utils.setDataRoot("regular-data");
122     }
123 
124 }
125