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.bodies;
18  
19  import org.orekit.annotation.DefaultDataContext;
20  import org.orekit.data.DataContext;
21  
22  /** Factory class for bodies of the solar system.
23   * <p>The {@link #getSun() Sun}, the {@link #getMoon() Moon} and the planets
24   * (including the Pluto dwarf planet) are provided by this factory. In addition,
25   * two important points are provided for convenience: the {@link
26   * #getSolarSystemBarycenter() solar system barycenter} and the {@link
27   * #getEarthMoonBarycenter() Earth-Moon barycenter}.</p>
28   * <p>The underlying body-centered frames are either direct children of {@link
29   * org.orekit.frames.FramesFactory#getEME2000() EME2000} (for {@link #getMoon() Moon}
30   * and {@link #getEarthMoonBarycenter() Earth-Moon barycenter}) or children from other
31   * body-centered frames. For example, the path from EME2000 to
32   * Jupiter-centered frame is: EME2000, Earth-Moon barycenter centered,
33   * solar system barycenter centered, Jupiter-centered. The defining transforms
34   * of these frames are combinations of simple linear {@link
35   * org.orekit.frames.Transform#Transform(org.orekit.time.AbsoluteDate,
36   * org.hipparchus.geometry.euclidean.threed.Vector3D,
37   * org.hipparchus.geometry.euclidean.threed.Vector3D) translation/velocity} transforms
38   * without any rotation. The frame axes are therefore always parallel to
39   * {@link org.orekit.frames.FramesFactory#getEME2000() EME2000} frame axes.</p>
40   * <p>The position of the bodies provided by this class are interpolated using
41   * the JPL DE 405/DE 406 ephemerides.</p>
42   * @author Luc Maisonobe
43   */
44  public class CelestialBodyFactory {
45  
46      /** Predefined name for solar system barycenter.
47       * @see #getBody(String)
48       */
49      public static final String SOLAR_SYSTEM_BARYCENTER = "solar system barycenter";
50  
51      /** Predefined name for Sun.
52       * @see #getBody(String)
53       */
54      public static final String SUN = "Sun";
55  
56      /** Predefined name for Mercury.
57       * @see #getBody(String)
58       */
59      public static final String MERCURY = "Mercury";
60  
61      /** Predefined name for Venus.
62       * @see #getBody(String)
63       */
64      public static final String VENUS = "Venus";
65  
66      /** Predefined name for Earth-Moon barycenter.
67       * @see #getBody(String)
68       */
69      public static final String EARTH_MOON = "Earth-Moon barycenter";
70  
71      /** Predefined name for Earth.
72       * @see #getBody(String)
73       */
74      public static final String EARTH = "Earth";
75  
76      /** Predefined name for Moon.
77       * @see #getBody(String)
78       */
79      public static final String MOON = "Moon";
80  
81      /** Predefined name for Mars.
82       * @see #getBody(String)
83       */
84      public static final String MARS = "Mars";
85  
86      /** Predefined name for Jupiter.
87       * @see #getBody(String)
88       */
89      public static final String JUPITER = "Jupiter";
90  
91      /** Predefined name for Saturn.
92       * @see #getBody(String)
93       */
94      public static final String SATURN = "Saturn";
95  
96      /** Predefined name for Uranus.
97       * @see #getBody(String)
98       */
99      public static final String URANUS = "Uranus";
100 
101     /** Predefined name for Neptune.
102      * @see #getBody(String)
103      */
104     public static final String NEPTUNE = "Neptune";
105 
106     /** Predefined name for Pluto.
107      * @see #getBody(String)
108      */
109     public static final String PLUTO = "Pluto";
110 
111     /** Private constructor.
112      * <p>This class is a utility class, it should neither have a public
113      * nor a default constructor. This private constructor prevents
114      * the compiler from generating one automatically.</p>
115      */
116     private CelestialBodyFactory() {
117     }
118 
119     /**
120      * Get the instance of {@link CelestialBodies} that is called by the static methods in
121      * this class.
122      *
123      * @return the reference frames used by this factory.
124      */
125     @DefaultDataContext
126     public static LazyLoadedCelestialBodies getCelestialBodies() {
127         return DataContext.getDefault().getCelestialBodies();
128     }
129 
130     /** Add a loader for celestial bodies.
131      * @param name name of the body (may be one of the predefined names or a user-defined name)
132      * @param loader custom loader to add for the body
133      * @see #addDefaultCelestialBodyLoader(String)
134      * @see #clearCelestialBodyLoaders(String)
135      * @see #clearCelestialBodyLoaders()
136      */
137     @DefaultDataContext
138     public static void addCelestialBodyLoader(final String name,
139                                               final CelestialBodyLoader loader) {
140         getCelestialBodies().addCelestialBodyLoader(name, loader);
141     }
142 
143     /** Add the default loaders for all predefined celestial bodies.
144      * @param supportedNames regular expression for supported files names
145      * (may be null if the default JPL file names are used)
146      * <p>
147      * The default loaders look for DE405 or DE406 JPL ephemerides.
148      * </p>
149      * @see <a href="ftp://ssd.jpl.nasa.gov/pub/eph/planets/Linux/de405/">DE405 JPL ephemerides</a>
150      * @see <a href="ftp://ssd.jpl.nasa.gov/pub/eph/planets/Linux/de406/">DE406 JPL ephemerides</a>
151      * @see #addCelestialBodyLoader(String, CelestialBodyLoader)
152      * @see #addDefaultCelestialBodyLoader(String)
153      * @see #clearCelestialBodyLoaders(String)
154      * @see #clearCelestialBodyLoaders()
155      */
156     @DefaultDataContext
157     public static void addDefaultCelestialBodyLoader(final String supportedNames) {
158         getCelestialBodies().addDefaultCelestialBodyLoader(supportedNames);
159     }
160 
161     /** Add the default loaders for celestial bodies.
162      * @param name name of the body (if not one of the predefined names, the method does nothing)
163      * @param supportedNames regular expression for supported files names
164      * (may be null if the default JPL file names are used)
165      * <p>
166      * The default loaders look for DE405 or DE406 JPL ephemerides.
167      * </p>
168      * @see <a href="ftp://ssd.jpl.nasa.gov/pub/eph/planets/Linux/de405/">DE405 JPL ephemerides</a>
169      * @see <a href="ftp://ssd.jpl.nasa.gov/pub/eph/planets/Linux/de406/">DE406 JPL ephemerides</a>
170      * @see #addCelestialBodyLoader(String, CelestialBodyLoader)
171      * @see #addDefaultCelestialBodyLoader(String)
172      * @see #clearCelestialBodyLoaders(String)
173      * @see #clearCelestialBodyLoaders()
174      */
175     @DefaultDataContext
176     public static void addDefaultCelestialBodyLoader(final String name,
177                                                      final String supportedNames) {
178         getCelestialBodies().addDefaultCelestialBodyLoader(name, supportedNames);
179     }
180 
181     /** Clear loaders for one celestial body.
182      * <p>
183      * Calling this method also clears the celestial body that
184      * has been loaded via this {@link CelestialBodyLoader}.
185      * </p>
186      * @param name name of the body
187      * @see #addCelestialBodyLoader(String, CelestialBodyLoader)
188      * @see #clearCelestialBodyLoaders()
189      * @see #clearCelestialBodyCache(String)
190      */
191     @DefaultDataContext
192     public static void clearCelestialBodyLoaders(final String name) {
193         getCelestialBodies().clearCelestialBodyLoaders(name);
194     }
195 
196     /** Clear loaders for all celestial bodies.
197      * <p>
198      * Calling this method also clears all loaded celestial bodies.
199      * </p>
200      * @see #addCelestialBodyLoader(String, CelestialBodyLoader)
201      * @see #clearCelestialBodyLoaders(String)
202      * @see #clearCelestialBodyCache()
203      */
204     @DefaultDataContext
205     public static void clearCelestialBodyLoaders() {
206         getCelestialBodies().clearCelestialBodyLoaders();
207     }
208 
209     /** Clear the specified celestial body from the internal cache.
210      * @param name name of the body
211      */
212     @DefaultDataContext
213     public static void clearCelestialBodyCache(final String name) {
214         getCelestialBodies().clearCelestialBodyCache(name);
215     }
216 
217     /** Clear all loaded celestial bodies.
218      * <p>
219      * Calling this method will remove all loaded bodies from the internal
220      * cache. Subsequent calls to {@link #getBody(String)} or similar methods
221      * will result in a reload of the requested body from the configured loader(s).
222      * </p>
223      */
224     @DefaultDataContext
225     public static void clearCelestialBodyCache() {
226         getCelestialBodies().clearCelestialBodyCache();
227     }
228 
229     /** Get the solar system barycenter aggregated body.
230      * <p>
231      * Both the {@link CelestialBody#getInertiallyOrientedFrame() inertially
232      * oriented frame} and {@link CelestialBody#getBodyOrientedFrame() body
233      * oriented frame} for this aggregated body are aligned with
234      * {@link org.orekit.frames.FramesFactory#getICRF() ICRF} (and therefore also
235      * {@link org.orekit.frames.FramesFactory#getGCRF() GCRF})
236      * </p>
237      * @return solar system barycenter aggregated body
238      */
239     @DefaultDataContext
240     public static CelestialBody getSolarSystemBarycenter() {
241         return getCelestialBodies().getSolarSystemBarycenter();
242     }
243 
244     /** Get the Sun singleton body.
245      * @return Sun body
246      */
247     @DefaultDataContext
248     public static CelestialBody getSun() {
249         return getCelestialBodies().getSun();
250     }
251 
252     /** Get the Mercury singleton body.
253      * @return Sun body
254      */
255     @DefaultDataContext
256     public static CelestialBody getMercury() {
257         return getCelestialBodies().getMercury();
258     }
259 
260     /** Get the Venus singleton body.
261      * @return Venus body
262      */
263     @DefaultDataContext
264     public static CelestialBody getVenus() {
265         return getCelestialBodies().getVenus();
266     }
267 
268     /** Get the Earth-Moon barycenter singleton bodies pair.
269      * <p>
270      * Both the {@link CelestialBody#getInertiallyOrientedFrame() inertially
271      * oriented frame} and {@link CelestialBody#getBodyOrientedFrame() body
272      * oriented frame} for this bodies pair are aligned with
273      * {@link org.orekit.frames.FramesFactory#getICRF() ICRF} (and therefore also
274      * {@link org.orekit.frames.FramesFactory#getGCRF() GCRF})
275      * </p>
276      * @return Earth-Moon barycenter bodies pair
277      */
278     @DefaultDataContext
279     public static CelestialBody getEarthMoonBarycenter() {
280         return getCelestialBodies().getEarthMoonBarycenter();
281     }
282 
283     /** Get the Earth singleton body.
284      * @return Earth body
285      */
286     @DefaultDataContext
287     public static CelestialBody getEarth() {
288         return getCelestialBodies().getEarth();
289     }
290 
291     /** Get the Moon singleton body.
292      * @return Moon body
293      */
294     @DefaultDataContext
295     public static CelestialBody getMoon() {
296         return getCelestialBodies().getMoon();
297     }
298 
299     /** Get the Mars singleton body.
300      * @return Mars body
301      */
302     @DefaultDataContext
303     public static CelestialBody getMars() {
304         return getCelestialBodies().getMars();
305     }
306 
307     /** Get the Jupiter singleton body.
308      * @return Jupiter body
309      */
310     @DefaultDataContext
311     public static CelestialBody getJupiter() {
312         return getCelestialBodies().getJupiter();
313     }
314 
315     /** Get the Saturn singleton body.
316      * @return Saturn body
317      */
318     @DefaultDataContext
319     public static CelestialBody getSaturn() {
320         return getCelestialBodies().getSaturn();
321     }
322 
323     /** Get the Uranus singleton body.
324      * @return Uranus body
325      */
326     @DefaultDataContext
327     public static CelestialBody getUranus() {
328         return getCelestialBodies().getUranus();
329     }
330 
331     /** Get the Neptune singleton body.
332      * @return Neptune body
333      */
334     @DefaultDataContext
335     public static CelestialBody getNeptune() {
336         return getCelestialBodies().getNeptune();
337     }
338 
339     /** Get the Pluto singleton body.
340      * @return Pluto body
341      */
342     @DefaultDataContext
343     public static CelestialBody getPluto() {
344         return getCelestialBodies().getPluto();
345     }
346 
347     /** Get a celestial body.
348      * <p>
349      * If no {@link CelestialBodyLoader} has been added by calling {@link
350      * #addCelestialBodyLoader(String, CelestialBodyLoader)
351      * addCelestialBodyLoader} or if {@link #clearCelestialBodyLoaders(String)
352      * clearCelestialBodyLoaders} has been called afterwards,
353      * the {@link #addDefaultCelestialBodyLoader(String, String)
354      * addDefaultCelestialBodyLoader} method will be called automatically,
355      * once with the default name for JPL DE ephemerides and once with the
356      * default name for IMCCE INPOP files.
357      * </p>
358      * @param name name of the celestial body
359      * @return celestial body
360      */
361     @DefaultDataContext
362     public static CelestialBody getBody(final String name) {
363         return getCelestialBodies().getBody(name);
364     }
365 
366 }