/* Copyright 2002-2017 CS Systèmes d'Information * Licensed to CS Systèmes d'Information (CS) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * CS licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.orekit.propagation.events; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.geometry.partitioning.RegionFactory; import org.hipparchus.geometry.spherical.twod.S2Point; import org.hipparchus.geometry.spherical.twod.Sphere2D; import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet; import org.hipparchus.util.FastMath; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.orekit.Utils; import org.orekit.bodies.BodyShape; import org.orekit.bodies.OneAxisEllipsoid; import org.orekit.errors.OrekitException; import org.orekit.frames.FramesFactory; import org.orekit.orbits.EquinoctialOrbit; import org.orekit.orbits.Orbit; import org.orekit.propagation.Propagator; import org.orekit.propagation.analytical.EcksteinHechlerPropagator; import org.orekit.propagation.events.handlers.ContinueOnEvent; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScale; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.Constants; import org.orekit.utils.IERSConventions; import org.orekit.utils.PVCoordinates; public class GeographicZoneDetectorTest { @Test public void testFrance() throws OrekitException { final BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true)); GeographicZoneDetector d = new GeographicZoneDetector(20.0, 1.e-3, earth, buildFrance(), FastMath.toRadians(0.5)). withHandler(new ContinueOnEvent<GeographicZoneDetector>()); Assert.assertEquals(20.0, d.getMaxCheckInterval(), 1.0e-15); Assert.assertEquals(1.0e-3, d.getThreshold(), 1.0e-15); Assert.assertEquals(0.5, FastMath.toDegrees(d.getMargin()), 1.0e-15); Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, d.getMaxIterationCount()); final TimeScale utc = TimeScalesFactory.getUTC(); final Vector3D position = new Vector3D(-6142438.668, 3492467.56, -25767.257); final Vector3D velocity = new Vector3D(505.848, 942.781, 7435.922); final AbsoluteDate date = new AbsoluteDate(2003, 9, 16, utc); final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position, velocity), FramesFactory.getEME2000(), date, Constants.EIGEN5C_EARTH_MU); Propagator propagator = new EcksteinHechlerPropagator(orbit, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60); EventsLogger logger = new EventsLogger(); propagator.addEventDetector(logger.monitorDetector(d)); propagator.propagate(date.shiftedBy(10 * Constants.JULIAN_DAY)); Assert.assertEquals(26, logger.getLoggedEvents().size()); } @Test public void testSerialization() throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, OrekitException { final double r = Constants.WGS84_EARTH_EQUATORIAL_RADIUS; final BodyShape earth = new OneAxisEllipsoid(r, Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true)); GeographicZoneDetector d = new GeographicZoneDetector(20.0, 1.e-3, earth, buildFrance(), FastMath.toRadians(0.5)). withMargin(FastMath.toRadians(0.75)). withHandler(new ContinueOnEvent<GeographicZoneDetector>()); Assert.assertEquals(r, ((OneAxisEllipsoid) d.getBody()).getEquatorialRadius(), 1.0e-12); Assert.assertEquals(0.75, FastMath.toDegrees(d.getMargin()), 1.0e-12); Assert.assertEquals(5.6807e11, d.getZone().getSize() * r * r, 1.0e9); Assert.assertEquals(4.0289e6, d.getZone().getBoundarySize() * r, 1.0e3); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(d); Assert.assertTrue(bos.size() > 2100); Assert.assertTrue(bos.size() < 2200); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); GeographicZoneDetector deserialized = (GeographicZoneDetector) ois.readObject(); Assert.assertEquals(d.getZone().getSize(), deserialized.getZone().getSize(), 1.0e-3); Assert.assertEquals(d.getZone().getBoundarySize(), deserialized.getZone().getBoundarySize(), 1.0e-3); Assert.assertEquals(d.getZone().getTolerance(), deserialized.getZone().getTolerance(), 1.0e-15); Assert.assertEquals(d.getMaxCheckInterval(), deserialized.getMaxCheckInterval(), 1.0e-15); Assert.assertEquals(d.getThreshold(), deserialized.getThreshold(), 1.0e-15); Assert.assertEquals(d.getMaxIterationCount(), deserialized.getMaxIterationCount()); Assert.assertTrue(new RegionFactory<Sphere2D>().difference(d.getZone(), deserialized.getZone()).isEmpty()); } private SphericalPolygonsSet buildFrance() { final SphericalPolygonsSet continental = buildSimpleZone(new double[][] { { 51.14850, 2.51357 }, { 50.94660, 1.63900 }, { 50.12717, 1.33876 }, { 49.34737, -0.98946 }, { 49.77634, -1.93349 }, { 48.64442, -1.61651 }, { 48.90169, -3.29581 }, { 48.68416, -4.59234 }, { 47.95495, -4.49155 }, { 47.57032, -2.96327 }, { 46.01491, -1.19379 }, { 44.02261, -1.38422 }, { 43.42280, -1.90135 }, { 43.03401, -1.50277 }, { 42.34338, 1.82679 }, { 42.47301, 2.98599 }, { 43.07520, 3.10041 }, { 43.39965, 4.55696 }, { 43.12889, 6.52924 }, { 43.69384, 7.43518 }, { 44.12790, 7.54959 }, { 45.02851, 6.74995 }, { 45.33309, 7.09665 }, { 46.42967, 6.50009 }, { 46.27298, 6.02260 }, { 46.72577, 6.03738 }, { 47.62058, 7.46675 }, { 49.01778, 8.09927 }, { 49.20195, 6.65822 }, { 49.44266, 5.89775 }, { 49.98537, 4.79922 } }); final SphericalPolygonsSet corsica = buildSimpleZone(new double[][] { { 42.15249, 9.56001 }, { 43.00998, 9.39000 }, { 42.62812, 8.74600 }, { 42.25651, 8.54421 }, { 41.58361, 8.77572 }, { 41.38000, 9.22975 } }); return (SphericalPolygonsSet) new RegionFactory<Sphere2D>().union(continental, corsica); } private SphericalPolygonsSet buildSimpleZone(double[][] points) { final S2Point[] vertices = new S2Point[points.length]; for (int i = 0; i < points.length; ++i) { vertices[i] = new S2Point(FastMath.toRadians(points[i][1]), // points[i][1] is longitude FastMath.toRadians(90.0 - points[i][0])); // points[i][0] is latitude } return new SphericalPolygonsSet(1.0e-10, vertices); } @Before public void setUp() { Utils.setDataRoot("regular-data"); } }