1   /* Copyright 2002-2025 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.files.ccsds.definitions;
18  
19  import java.util.Locale;
20  import java.util.function.Function;
21  
22  import org.orekit.annotation.DefaultDataContext;
23  import org.orekit.bodies.CelestialBodies;
24  import org.orekit.bodies.CelestialBody;
25  import org.orekit.bodies.CelestialBodyFactory;
26  import org.orekit.data.DataContext;
27  import org.orekit.frames.FactoryManagedFrame;
28  import org.orekit.frames.Frame;
29  import org.orekit.frames.Predefined;
30  
31  /** Orbit central bodies for which a Celestial body can be created.
32   * @author sports
33   * @since 6.1
34   */
35  public enum CenterName {
36      /** Solar system barycenter aggregated body. */
37      SOLAR_SYSTEM_BARYCENTER(CelestialBodies::getSolarSystemBarycenter),
38  
39      /** Sun body. */
40      SUN(CelestialBodies::getSun),
41  
42      /** Mercury body. */
43      MERCURY(CelestialBodies::getMercury),
44  
45      /** Venus body. */
46      VENUS(CelestialBodies::getVenus),
47  
48      /** Earth-Moon barycenter bodies pair. */
49      EARTH_MOON(CelestialBodies::getEarthMoonBarycenter),
50  
51      /** Earth body. */
52      EARTH(CelestialBodies::getEarth),
53  
54      /** Moon body. */
55      MOON(CelestialBodies::getMoon),
56  
57      /** Mars body. */
58      MARS(CelestialBodies::getMars),
59  
60      /** Jupiter body. */
61      JUPITER(CelestialBodies::getJupiter),
62  
63      /** Saturn body. */
64      SATURN(CelestialBodies::getSaturn),
65  
66      /** Uranus body. */
67      URANUS(CelestialBodies::getUranus),
68  
69      /** Neptune body. */
70      NEPTUNE(CelestialBodies::getNeptune),
71  
72      /** Pluto body. */
73      PLUTO(CelestialBodies::getPluto);
74  
75      /** Suffix of the name of the inertial frame attached to a planet. */
76      private static final String INERTIAL_FRAME_SUFFIX = "/inertial";
77  
78      /** Suffix of the name of the rotating frame attached to a planet. */
79      private static final String ROTATING_FRAME_SUFFIX = "/rotating";
80  
81      /**
82       * Standardized locale to use, to ensure files can be exchanged without
83       * internationalization issues.
84       */
85      private static final Locale STANDARDIZED_LOCALE = Locale.US;
86  
87      /** Substring common to all ITRF frames. */
88      /** Celestial body getter.
89       * @return getter for celestial body
90       */
91      private final transient Function<CelestialBodies, CelestialBody> celestialBodyGetter;
92  
93      /** Simple constructor.
94       * @param celestialBodyGetter getter for celestial body
95       */
96      CenterName(final Function<CelestialBodies, CelestialBody> celestialBodyGetter) {
97          this.celestialBodyGetter = celestialBodyGetter;
98      }
99  
100     /**
101      * Get the celestial body corresponding to the CCSDS constant.
102      *
103      * <p>This method uses the {@link DataContext#getDefault() default data context}.
104      *
105      * @return celestial body corresponding to the CCSDS constant
106      * @see #getCelestialBody(CelestialBodies)
107      */
108     @DefaultDataContext
109     public CelestialBody getCelestialBody() {
110         return getCelestialBody(DataContext.getDefault().getCelestialBodies());
111     }
112 
113     /**
114      * Get the celestial body corresponding to the CCSDS constant.
115      *
116      * @param celestialBodies the set of celestial bodies to use.
117      * @return celestial body corresponding to the CCSDS constant
118      * @since 10.1
119      */
120     public CelestialBody getCelestialBody(final CelestialBodies celestialBodies) {
121         return celestialBodyGetter.apply(celestialBodies);
122     }
123 
124     /**
125      * Guess the name of the center of the reference frame.
126      *
127      * @param frame a reference frame for ephemeris output.
128      * @return the string to use in the OEM file to describe the origin of {@code frame}.
129      */
130     public static String guessCenter(final Frame frame) {
131         final String name = frame.getName();
132         if (name.endsWith(INERTIAL_FRAME_SUFFIX) || name.endsWith(ROTATING_FRAME_SUFFIX)) {
133             return name.substring(0, name.length() - 9).toUpperCase(STANDARDIZED_LOCALE);
134         } else if (frame instanceof ModifiedFrame) {
135             return ((ModifiedFrame) frame).getCenterName();
136         } else if (frame.getName().equals(Predefined.ICRF.getName())) {
137             return CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER.toUpperCase(STANDARDIZED_LOCALE);
138         } else if (frame.getDepth() == 0 || frame instanceof FactoryManagedFrame) {
139             return "EARTH";
140         } else {
141             return "UNKNOWN";
142         }
143     }
144 
145     /**
146      * Map an Orekit frame to a CCSDS center.
147      *
148      * @param frame a reference frame.
149      * @return the string to use in the OEM file to describe the origin of {@code frame},
150      * or null if no such center can be found
151      */
152     public static CenterName map(final Frame frame) {
153         try {
154             return CenterName.valueOf(guessCenter(frame));
155         } catch (IllegalArgumentException iae) {
156             // we were unable to find a match
157             return null;
158         }
159     }
160 
161 }