AggregatedPVCoordinatesProvider.java

  1. /* Copyright 2002-2022 Joseph Reed
  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.  * Joseph Reed 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.utils;

  18. import java.util.Objects;

  19. import org.orekit.errors.OrekitIllegalArgumentException;
  20. import org.orekit.errors.OrekitMessages;
  21. import org.orekit.frames.Frame;
  22. import org.orekit.time.AbsoluteDate;

  23. /** Aggreate multiple {@link PVCoordinatesProvider} instances together
  24.  *
  25.  * This can be used to describe an aircraft or surface vehicle.
  26.  *
  27.  * @author Joe Reed
  28.  * @since 11.3
  29.  */
  30. public class AggregatedPVCoordinatesProvider implements PVCoordinatesProvider {

  31.     /** Map of provider instances by transition time. */
  32.     private final TimeSpanMap<PVCoordinatesProvider> pvProvMap;

  33.     /** Earliest date at which {@link #getPVCoordinates(AbsoluteDate, Frame)} will return a valid result. */
  34.     private final AbsoluteDate minDate;

  35.     /** Latest date at which {@link #getPVCoordinates(AbsoluteDate, Frame)} will return a valid result. */
  36.     private final AbsoluteDate maxDate;

  37.     /** Class constructor.
  38.      *
  39.      * Note the provided {@code map} is used directly. Modification of the
  40.      * map after calling this constructor may result in undefined behavior.
  41.      *
  42.      * @param map the map of {@link PVCoordinatesProvider} instances by time.
  43.      */
  44.     public AggregatedPVCoordinatesProvider(final TimeSpanMap<PVCoordinatesProvider> map) {
  45.         this(map, null, null);
  46.     }

  47.     /** Class constructor.
  48.      *
  49.      * Note the provided {@code map} is used directly. Modification of the
  50.      * map after calling this constructor may result in undefined behavior.
  51.      *
  52.      * @param map the map of {@link PVCoordinatesProvider} instances by time.
  53.      * @param minDate the earliest valid date, {@code null} if always valid
  54.      * @param maxDate the latest valid date, {@code null} if always valid
  55.      */
  56.     public AggregatedPVCoordinatesProvider(final TimeSpanMap<PVCoordinatesProvider> map,
  57.             final AbsoluteDate minDate, final AbsoluteDate maxDate) {
  58.         this.pvProvMap = Objects.requireNonNull(map, "PVCoordinatesProvider map must be non-null");
  59.         this.minDate = minDate == null ? AbsoluteDate.PAST_INFINITY : minDate;
  60.         this.maxDate = maxDate == null ? AbsoluteDate.FUTURE_INFINITY : maxDate;
  61.     }

  62.     /** Get the first date of the range.
  63.      * @return the first date of the range
  64.      */
  65.     public AbsoluteDate getMinDate() {
  66.         return minDate;
  67.     }

  68.     /** Get the last date of the range.
  69.      * @return the last date of the range
  70.      */
  71.     public AbsoluteDate getMaxDate() {
  72.         return maxDate;
  73.     }

  74.     @Override
  75.     public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
  76.         if (date.isBefore(minDate) || date.isAfter(maxDate)) {
  77.             throw new OrekitIllegalArgumentException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE, date, minDate, maxDate);
  78.         }
  79.         return pvProvMap.get(date).getPVCoordinates(date, frame);
  80.     }

  81.     /**
  82.      * Builder class for {@link AggregatedPVCoordinatesProvider}.
  83.      */
  84.     public static class Builder {

  85.         /** Time span map holding the incremental values. */
  86.         private TimeSpanMap<PVCoordinatesProvider> pvProvMap = null;

  87.         /**
  88.          * Create a builder using the {@link InvalidPVProvider} as the initial provider.
  89.          */
  90.         public Builder() {
  91.             this(new InvalidPVProvider());
  92.         }

  93.         /**
  94.          * Create a builder using the provided initial provider.
  95.          *
  96.          * @param initialProvider the inital provider
  97.          */
  98.         public Builder(final PVCoordinatesProvider initialProvider) {
  99.             pvProvMap = new TimeSpanMap<PVCoordinatesProvider>(initialProvider);
  100.         }

  101.         /** Add a {@link PVCoordinatesProvider} to the collection.
  102.          *
  103.          * The provided date is the transition time, at which this provider will be used.
  104.          *
  105.          * @param date the transition date
  106.          * @param pvProv the provider
  107.          * @param erasesLater if true, the entry erases all existing transitions that are later than {@code date}
  108.          * @return this builder instance
  109.          * @see TimeSpanMap#addValidAfter(Object, AbsoluteDate, boolean)
  110.          */
  111.         public Builder addPVProviderAfter(final AbsoluteDate date,
  112.                                           final PVCoordinatesProvider pvProv,
  113.                                           final boolean erasesLater) {
  114.             pvProvMap.addValidAfter(pvProv, date, erasesLater);
  115.             return this;
  116.         }

  117.         /** Add a {@link PVCoordinatesProvider} to the collection.
  118.          *
  119.          * The provided date is the final transition time, before which this provider will be used.
  120.          *
  121.          * @param date the transition date
  122.          * @param pvProv the provider
  123.          * @param erasesEarlier if true, the entry erases all existing transitions that are earlier than {@code date}
  124.          * @return this builder instance
  125.          * @see TimeSpanMap#addValidBefore(Object, AbsoluteDate, boolean)
  126.          */
  127.         public Builder addPVProviderBefore(final AbsoluteDate date, final PVCoordinatesProvider pvProv, final boolean erasesEarlier) {
  128.             pvProvMap.addValidBefore(pvProv, date, erasesEarlier);
  129.             return this;
  130.         }

  131.         /** Indicate the date before which the resulting PVCoordinatesProvider is invalid.
  132.          *
  133.          * @param firstValidDate first date at which the resuling provider should be valid
  134.          * @return this instance
  135.          */
  136.         public Builder invalidBefore(final AbsoluteDate firstValidDate) {
  137.             pvProvMap.addValidBefore(new InvalidPVProvider(), firstValidDate, true);
  138.             return this;
  139.         }

  140.         /** Indicate the date after which the resulting PVCoordinatesProvider is invalid.
  141.          *
  142.          * @param lastValidDate last date at which the resuling provider should be valid
  143.          * @return this instance
  144.          */
  145.         public Builder invalidAfter(final AbsoluteDate lastValidDate) {
  146.             pvProvMap.addValidAfter(new InvalidPVProvider(), lastValidDate, true);
  147.             return this;
  148.         }

  149.         /** Build the aggregated PVCoordinatesProvider.
  150.          *
  151.          * @return the new provider instance.
  152.          */
  153.         public AggregatedPVCoordinatesProvider build() {
  154.             AbsoluteDate minDate = null;
  155.             AbsoluteDate maxDate = null;
  156.             // check the first span
  157.             if (pvProvMap.getFirstTransition() != null) {
  158.                 if (pvProvMap.getFirstTransition().getBefore() instanceof InvalidPVProvider) {
  159.                     minDate = pvProvMap.getFirstTransition().getDate();
  160.                 }
  161.             }
  162.             if (pvProvMap.getLastTransition() != null) {
  163.                 if (pvProvMap.getLastTransition().getAfter() instanceof InvalidPVProvider) {
  164.                     maxDate = pvProvMap.getLastTransition().getDate();
  165.                 }
  166.             }
  167.             return new AggregatedPVCoordinatesProvider(pvProvMap, minDate, maxDate);
  168.         }
  169.     }

  170.     /**  Implementation of {@link PVCoordinatesProvider} that throws an illegal state exception.
  171.      *
  172.      */
  173.     public static class InvalidPVProvider implements PVCoordinatesProvider {

  174.         @Override
  175.         public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
  176.             throw new IllegalStateException();
  177.         }
  178.     }
  179. }