All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.bodies.LazyLoadedCelestialBodies Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Contributed in the public domain.
 * Licensed to CS GROUP (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.bodies;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.orekit.data.DataProvidersManager;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.frames.Frame;
import org.orekit.time.TimeScales;

/**
 * This class lazily loads auxiliary data when it is needed by a requested body. It is
 * designed to match the behavior of {@link CelestialBodyFactory} in Orekit 10.0.
 *
 * @author Luc Maisonobe
 * @author Evan Ward
 * @see CelestialBodyFactory
 * @since 10.1
 */
public class LazyLoadedCelestialBodies implements CelestialBodies {

    /** Supplies the auxiliary data files. */
    private final DataProvidersManager dataProvidersManager;
    /** Provides access to time scales when parsing bodies. */
    private final TimeScales timeScales;
    /** Earth centered frame aligned with ICRF. */
    private final Frame gcrf;
    /** Celestial body loaders map. */
    private final Map> loadersMap = new HashMap<>();

    /** Celestial body map. */
    private final Map celestialBodyMap = new HashMap<>();

    /**
     * Create a celestial body factory with the given auxiliary data sources.
     *
     * @param dataProvidersManager supplies JPL ephemerides auxiliary data files.
     * @param timeScales           set of time scales to use when loading bodies.
     * @param gcrf                 Earth centered frame aligned with ICRF.
     */
    public LazyLoadedCelestialBodies(final DataProvidersManager dataProvidersManager,
                                     final TimeScales timeScales,
                                     final Frame gcrf) {
        this.dataProvidersManager = dataProvidersManager;
        this.timeScales = timeScales;
        this.gcrf = gcrf;
    }

    /** Add a loader for celestial bodies.
     * @param name name of the body (may be one of the predefined names or a user-defined name)
     * @param loader custom loader to add for the body
     * @see #addDefaultCelestialBodyLoader(String)
     * @see #clearCelestialBodyLoaders(String)
     * @see #clearCelestialBodyLoaders()
     */
    public void addCelestialBodyLoader(final String name,
                                       final CelestialBodyLoader loader) {
        synchronized (loadersMap) {
            loadersMap.computeIfAbsent(name, k -> new ArrayList<>()).add(loader);
        }
    }

    /** Add the default loaders for all predefined celestial bodies.
     * @param supportedNames regular expression for supported files names
     * (may be null if the default JPL file names are used)
     * 

* The default loaders look for DE405 or DE406 JPL ephemerides. *

* @see DE405 JPL ephemerides * @see DE406 JPL ephemerides * @see #addCelestialBodyLoader(String, CelestialBodyLoader) * @see #addDefaultCelestialBodyLoader(String) * @see #clearCelestialBodyLoaders(String) * @see #clearCelestialBodyLoaders() */ public void addDefaultCelestialBodyLoader(final String supportedNames) { addDefaultCelestialBodyLoader(CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.SUN, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.MERCURY, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.VENUS, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.EARTH_MOON, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.EARTH, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.MOON, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.MARS, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.JUPITER, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.SATURN, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.URANUS, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.NEPTUNE, supportedNames); addDefaultCelestialBodyLoader(CelestialBodyFactory.PLUTO, supportedNames); } /** Add the default loaders for celestial bodies. * @param name name of the body (if not one of the predefined names, the method does nothing) * @param supportedNames regular expression for supported files names * (may be null if the default JPL file names are used) *

* The default loaders look for DE405 or DE406 JPL ephemerides. *

* @see DE405 JPL ephemerides * @see DE406 JPL ephemerides * @see #addCelestialBodyLoader(String, CelestialBodyLoader) * @see #addDefaultCelestialBodyLoader(String) * @see #clearCelestialBodyLoaders(String) * @see #clearCelestialBodyLoaders() */ public void addDefaultCelestialBodyLoader(final String name, final String supportedNames) { CelestialBodyLoader loader = null; if (name.equalsIgnoreCase(CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.SOLAR_SYSTEM_BARYCENTER, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.SUN)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.SUN, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.MERCURY)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.MERCURY, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.VENUS)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.VENUS, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.EARTH_MOON)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.EARTH_MOON, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.EARTH)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.EARTH, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.MOON)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.MOON, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.MARS)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.MARS, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.JUPITER)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.JUPITER, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.SATURN)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.SATURN, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.URANUS)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.URANUS, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.NEPTUNE)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.NEPTUNE, dataProvidersManager, timeScales, gcrf); } else if (name.equalsIgnoreCase(CelestialBodyFactory.PLUTO)) { loader = new JPLEphemeridesLoader(supportedNames, JPLEphemeridesLoader.EphemerisType.PLUTO, dataProvidersManager, timeScales, gcrf); } if (loader != null) { addCelestialBodyLoader(name, loader); } } /** Clear loaders for one celestial body. *

* Calling this method also clears the celestial body that * has been loaded via this {@link CelestialBodyLoader}. *

* @param name name of the body * @see #addCelestialBodyLoader(String, CelestialBodyLoader) * @see #clearCelestialBodyLoaders() * @see #clearCelestialBodyCache(String) */ public void clearCelestialBodyLoaders(final String name) { // use same synchronization order as in getBody to prevent deadlocks synchronized (celestialBodyMap) { // take advantage of reentrent synchronization as // clearCelestialBodyCache uses the same lock inside clearCelestialBodyCache(name); synchronized (loadersMap) { loadersMap.remove(name); } } } /** Clear loaders for all celestial bodies. *

* Calling this method also clears all loaded celestial bodies. *

* @see #addCelestialBodyLoader(String, CelestialBodyLoader) * @see #clearCelestialBodyLoaders(String) * @see #clearCelestialBodyCache() */ public void clearCelestialBodyLoaders() { synchronized (celestialBodyMap) { clearCelestialBodyCache(); synchronized (loadersMap) { loadersMap.clear(); } } } /** Clear the specified celestial body from the internal cache. * @param name name of the body */ public void clearCelestialBodyCache(final String name) { synchronized (celestialBodyMap) { celestialBodyMap.remove(name); } } /** Clear all loaded celestial bodies. *

* Calling this method will remove all loaded bodies from the internal * cache. Subsequent calls to {@link #getBody(String)} or similar methods * will result in a reload of the requested body from the configured loader(s). *

*/ public void clearCelestialBodyCache() { synchronized (celestialBodyMap) { celestialBodyMap.clear(); } } @Override public CelestialBody getSolarSystemBarycenter() { return getBody(CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER); } @Override public CelestialBody getSun() { return getBody(CelestialBodyFactory.SUN); } @Override public CelestialBody getMercury() { return getBody(CelestialBodyFactory.MERCURY); } @Override public CelestialBody getVenus() { return getBody(CelestialBodyFactory.VENUS); } @Override public CelestialBody getEarthMoonBarycenter() { return getBody(CelestialBodyFactory.EARTH_MOON); } @Override public CelestialBody getEarth() { return getBody(CelestialBodyFactory.EARTH); } @Override public CelestialBody getMoon() { return getBody(CelestialBodyFactory.MOON); } @Override public CelestialBody getMars() { return getBody(CelestialBodyFactory.MARS); } @Override public CelestialBody getJupiter() { return getBody(CelestialBodyFactory.JUPITER); } @Override public CelestialBody getSaturn() { return getBody(CelestialBodyFactory.SATURN); } @Override public CelestialBody getUranus() { return getBody(CelestialBodyFactory.URANUS); } @Override public CelestialBody getNeptune() { return getBody(CelestialBodyFactory.NEPTUNE); } @Override public CelestialBody getPluto() { return getBody(CelestialBodyFactory.PLUTO); } /** * {@inheritDoc} * *

* If no {@link CelestialBodyLoader} has been added by calling {@link * #addCelestialBodyLoader(String, CelestialBodyLoader) addCelestialBodyLoader} or if * {@link #clearCelestialBodyLoaders(String) clearCelestialBodyLoaders} has been * called afterwards, the {@link #addDefaultCelestialBodyLoader(String, String) * addDefaultCelestialBodyLoader} method will be called automatically, once with the * default name for JPL DE ephemerides and once with the default name for IMCCE INPOP * files. *

*/ @Override public CelestialBody getBody(final String name) { synchronized (celestialBodyMap) { CelestialBody body = celestialBodyMap.get(name); if (body == null) { synchronized (loadersMap) { List loaders = loadersMap.get(name); if (loaders == null || loaders.isEmpty()) { addDefaultCelestialBodyLoader(name, JPLEphemeridesLoader.DEFAULT_DE_SUPPORTED_NAMES); addDefaultCelestialBodyLoader(name, JPLEphemeridesLoader.DEFAULT_INPOP_SUPPORTED_NAMES); loaders = loadersMap.get(name); } OrekitException delayedException = null; for (CelestialBodyLoader loader : loaders) { try { body = loader.loadCelestialBody(name); if (body != null) { break; } } catch (OrekitException oe) { delayedException = oe; } } if (body == null) { throw (delayedException != null) ? delayedException : new OrekitException(OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY, name); } } // save the body celestialBodyMap.put(name, body); } return body; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy