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

org.orekit.utils.TimeSpanMap 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
/* Copyright 2002-2018 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.utils;

import java.util.Collections;
import java.util.NavigableSet;
import java.util.SortedSet;
import java.util.TreeSet;

import org.orekit.time.AbsoluteDate;
import org.orekit.time.ChronologicalComparator;
import org.orekit.time.TimeStamped;

/** Container for objects that apply to spans of time.

 * @param  Type of the data.

 * @author Luc Maisonobe
 * @since 7.1
 */
public class TimeSpanMap {

    /** Container for the data. */
    private final NavigableSet> data;

    /** Create a map containing a single object, initially valid throughout the timeline.
     * 

* The real validity of this first entry will be truncated as other * entries are either {@link #addValidBefore(Object, AbsoluteDate) * added before} it or {@link #addValidAfter(Object, AbsoluteDate) * added after} it. *

* @param entry entry (initially valid throughout the timeline) */ public TimeSpanMap(final T entry) { data = new TreeSet>(new ChronologicalComparator()); data.add(new Transition(AbsoluteDate.J2000_EPOCH, entry, entry)); } /** Add an entry valid before a limit date. *

* As an entry is valid, it truncates the validity of the neighboring * entries already present in the map. *

*

* The transition dates should be entered only once, either * by a call to this method or by a call to {@link #addValidAfter(Object, * AbsoluteDate)}. Repeating a transition date will lead to unexpected * result and is not supported. *

* @param entry entry to add * @param latestValidityDate date before which the entry is valid * (must be different from all dates already used for transitions) */ public void addValidBefore(final T entry, final AbsoluteDate latestValidityDate) { if (data.size() == 1) { final Transition single = data.first(); if (single.getBefore() == single.getAfter()) { // the single entry was a dummy one, without a real transition // we replace it entirely data.clear(); data.add(new Transition(latestValidityDate, entry, single.getAfter())); return; } } final Transition previous = data.floor(new Transition(latestValidityDate, entry, null)); if (previous == null) { // the new transition will be the first one data.add(new Transition(latestValidityDate, entry, data.first().getBefore())); } else { // the new transition will be after the previous one data.remove(previous); data.add(new Transition(previous.date, previous.getBefore(), entry)); data.add(new Transition(latestValidityDate, entry, previous.getAfter())); } } /** Add an entry valid after a limit date. *

* As an entry is valid, it truncates the validity of the neighboring * entries already present in the map. *

*

* The transition dates should be entered only once, either * by a call to this method or by a call to {@link #addValidBefore(Object, * AbsoluteDate)}. Repeating a transition date will lead to unexpected * result and is not supported. *

* @param entry entry to add * @param earliestValidityDate date after which the entry is valid * (must be different from all dates already used for transitions) */ public void addValidAfter(final T entry, final AbsoluteDate earliestValidityDate) { if (data.size() == 1) { final Transition single = data.first(); if (single.getBefore() == single.getAfter()) { // the single entry was a dummy one, without a real transition // we replace it entirely data.clear(); data.add(new Transition(earliestValidityDate, single.getBefore(), entry)); return; } } final Transition next = data.ceiling(new Transition(earliestValidityDate, entry, null)); if (next == null) { // the new transition will be the last one data.add(new Transition(earliestValidityDate, data.last().getAfter(), entry)); } else { // the new transition will be before the next one data.remove(next); data.add(new Transition(earliestValidityDate, next.getBefore(), entry)); data.add(new Transition(next.date, entry, next.getAfter())); } } /** Get the entry valid at a specified date. * @param date date at which the entry must be valid * @return valid entry at specified date */ public T get(final AbsoluteDate date) { final Transition previous = data.floor(new Transition(date, null, null)); if (previous == null) { // there are no transition before the specified date // return the first valid entry return data.first().getBefore(); } else { return previous.getAfter(); } } /** Extract a range of the map. *

* The object returned will be a new independent instance that will contain * only the transitions that lie in the specified range. *

*

* Consider for example a map containing objects O₀ valid before t₁, O₁ valid * between t₁ and t₂, O₂ valid between t₂ and t₃, O₃ valid between t₃ and t₄, * and O₄ valid after t₄. then calling this method with a {@code start} * date between t₁ and t₂ and a {@code end} date between t₃ and t₄ * will result in a new map containing objects O₁ valid before t₂, O₂ * valid between t₂ and t₃, and O₃ valid after t₃. The validity of O₁ * is therefore extended in the past, and the validity of O₃ is extended * in the future. *

* @param start earliest date at which a transition is included in the range * (may be set to {@link AbsoluteDate#PAST_INFINITY} to keep all early transitions) * @param end latest date at which a transition is included in the r * (may be set to {@link AbsoluteDate#FUTURE_INFINITY} to keep all late transitions) * @return a new instance with all transitions restricted to the specified range * @since 9.2 */ public TimeSpanMap extractRange(final AbsoluteDate start, final AbsoluteDate end) { final NavigableSet> inRange = data.subSet(new Transition(start, null, null), true, new Transition(end, null, null), true); if (inRange.isEmpty()) { // there are no transitions at all in the range // we need to pick up the only valid object return new TimeSpanMap<>(get(start)); } final TimeSpanMap range = new TimeSpanMap<>(inRange.first().before); for (final Transition transition : inRange) { range.addValidAfter(transition.after, transition.getDate()); } return range; } /** Get an unmodifiable view of the sorted transitions. * @return unmodifiable view of the sorted transitions */ public SortedSet> getTransitions() { return Collections.unmodifiableSortedSet(data); } /** Local class holding transition times. */ public static class Transition implements TimeStamped { /** Transition date. */ private final AbsoluteDate date; /** Entry valid before the transition. */ private final S before; /** Entry valid after the transition. */ private final S after; /** Simple constructor. * @param date transition date * @param before entry valid before the transition * @param after entry valid after the transition */ private Transition(final AbsoluteDate date, final S before, final S after) { this.date = date; this.before = before; this.after = after; } /** Get the transition date. * @return transition date */ @Override public AbsoluteDate getDate() { return date; } /** Get the entry valid before transition. * @return entry valid before transition */ public S getBefore() { return before; } /** Get the entry valid after transition. * @return entry valid after transition */ public S getAfter() { return after; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy