ITRFVersion.java

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

  18. import java.util.regex.Matcher;
  19. import java.util.regex.Pattern;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.orekit.annotation.DefaultDataContext;
  22. import org.orekit.data.DataContext;
  23. import org.orekit.errors.OrekitException;
  24. import org.orekit.errors.OrekitMessages;
  25. import org.orekit.time.AbsoluteDate;
  26. import org.orekit.time.FieldAbsoluteDate;
  27. import org.orekit.time.TimeScale;

  28. /** Enumerate for ITRF versions.
  29.  * @see EOPEntry
  30.  * @see HelmertTransformation
  31.  * @author Luc Maisonobe
  32.  * @since 9.2
  33.  */
  34. public enum ITRFVersion {

  35.     /** Constant for ITRF 2014. */
  36.     ITRF_2014(2014),

  37.     /** Constant for ITRF 2008. */
  38.     ITRF_2008(2008),

  39.     /** Constant for ITRF 2005. */
  40.     ITRF_2005(2005),

  41.     /** Constant for ITRF 2000. */
  42.     ITRF_2000(2000),

  43.     /** Constant for ITRF 1997. */
  44.     ITRF_1997(1997),

  45.     /** Constant for ITRF 1996. */
  46.     ITRF_1996(1996),

  47.     /** Constant for ITRF 1994. */
  48.     ITRF_1994(1994),

  49.     /** Constant for ITRF 1993. */
  50.     ITRF_1993(1993),

  51.     /** Constant for ITRF 1992. */
  52.     ITRF_1992(1992),

  53.     /** Constant for ITRF 1991. */
  54.     ITRF_1991(1991),

  55.     /** Constant for ITRF 1990. */
  56.     ITRF_1990(1990),

  57.     /** Constant for ITRF 89. */
  58.     ITRF_1989(1989),

  59.     /** Constant for ITRF 88. */
  60.     ITRF_1988(1988);

  61.     /** Regular expression for ITRF names, using several variations. */
  62.     private static final Pattern PATTERN = Pattern.compile("[Ii][Tt][Rr][Ff][-_ ]?([0-9]{2,4})");

  63.     /** Reference year of the frame version. */
  64.     private final int year;

  65.     /** Name. */
  66.     private final String name;

  67.     /** Simple constructor.
  68.      * @param year reference year of the frame version
  69.      */
  70.     ITRFVersion(final int year) {
  71.         this.year = year;
  72.         this.name = "ITRF-" + year;
  73.     }

  74.     /** Get the reference year of the frame version.
  75.      * @return reference year of the frame version
  76.      */
  77.     public int getYear() {
  78.         return year;
  79.     }

  80.     /** Get the name the frame version.
  81.      * @return name of the frame version
  82.      */
  83.     public String getName() {
  84.         return name;
  85.     }

  86.     /** Find an ITRF version from its reference year.
  87.      * @param year reference year of the frame version
  88.      * @return ITRF version for specified year
  89.      */
  90.     public static ITRFVersion getITRFVersion(final int year) {

  91.         final int fixedYear = (year > 87 && year < 100) ? (year + 1900) : year;

  92.         // loop over all predefined frames versions
  93.         for (final ITRFVersion version : values()) {
  94.             if (version.getYear() == fixedYear) {
  95.                 return version;
  96.             }
  97.         }

  98.         // we don't have the required frame
  99.         throw new OrekitException(OrekitMessages.NO_SUCH_ITRF_FRAME, year);

  100.     }

  101.     /** Find an ITRF version from its name.
  102.      * @param name name of the frame version (case is ignored)
  103.      * @return ITRF version
  104.      */
  105.     public static ITRFVersion getITRFVersion(final String name) {

  106.         // extract year from name
  107.         final Matcher matcher = PATTERN.matcher(name);
  108.         if (matcher.matches()) {
  109.             try {
  110.                 return getITRFVersion(Integer.parseInt(matcher.group(1)));
  111.             } catch (OrekitException oe) {
  112.                 throw new OrekitException(OrekitMessages.NO_SUCH_ITRF_FRAME, name);
  113.             }
  114.         }

  115.         // we don't have the required frame
  116.         throw new OrekitException(OrekitMessages.NO_SUCH_ITRF_FRAME, name);

  117.     }

  118.     /** Find a converter between specified ITRF frames.
  119.      *
  120.      * <p>This method uses the {@link DataContext#getDefault() default data context}.
  121.      *
  122.      * @param origin origin ITRF
  123.      * @param destination destination ITRF
  124.      * @return transform from {@code origin} to {@code destination}
  125.      * @see #getConverter(ITRFVersion, ITRFVersion, TimeScale)
  126.      */
  127.     @DefaultDataContext
  128.     public static Converter getConverter(final ITRFVersion origin, final ITRFVersion destination) {
  129.         return getConverter(origin, destination,
  130.                 DataContext.getDefault().getTimeScales().getTT());
  131.     }

  132.     /** Find a converter between specified ITRF frames.
  133.      * @param origin origin ITRF
  134.      * @param destination destination ITRF
  135.      * @param tt TT time scale.
  136.      * @return transform from {@code origin} to {@code destination}
  137.      * @since 10.1
  138.      */
  139.     public static Converter getConverter(final ITRFVersion origin,
  140.                                          final ITRFVersion destination,
  141.                                          final TimeScale tt) {

  142.         TransformProvider provider = null;

  143.         // special case for no transform
  144.         if (origin == destination) {
  145.             provider = TransformProviderUtils.IDENTITY_PROVIDER;
  146.         }

  147.         if (provider == null) {
  148.             // try to find a direct provider
  149.             provider = getDirectTransformProvider(origin, destination, tt);
  150.         }

  151.         if (provider == null) {
  152.             // no direct provider found, use ITRF 2014 as a pivot frame
  153.             provider = TransformProviderUtils.getCombinedProvider(getDirectTransformProvider(origin, ITRF_2014, tt),
  154.                                                                   getDirectTransformProvider(ITRF_2014, destination, tt));
  155.         }

  156.         // build the converter, to keep the origin and destination information
  157.         return new Converter(origin, destination, provider);

  158.     }

  159.     /** Find a direct transform provider between specified ITRF frames.
  160.      * @param origin origin ITRF
  161.      * @param destination destination ITRF
  162.      * @param tt TT time scale.
  163.      * @return transform from {@code origin} to {@code destination}, or null if no direct transform is found
  164.      */
  165.     private static TransformProvider getDirectTransformProvider(
  166.             final ITRFVersion origin,
  167.             final ITRFVersion destination,
  168.             final TimeScale tt) {

  169.         // loop over all predefined transforms
  170.         for (final HelmertTransformation.Predefined predefined : HelmertTransformation.Predefined.values()) {
  171.             if (predefined.getOrigin() == origin && predefined.getDestination() == destination) {
  172.                 // we have an Helmert transformation in the specified direction
  173.                 return predefined.getTransformation(tt);
  174.             } else if (predefined.getOrigin() == destination && predefined.getDestination() == origin) {
  175.                 // we have an Helmert transformation in the opposite direction
  176.                 return TransformProviderUtils.getReversedProvider(predefined.getTransformation(tt));
  177.             }
  178.         }

  179.         // we don't have the required transform
  180.         return null;

  181.     }

  182.     /** Specialized transform provider between ITRF frames. */
  183.     public static class Converter implements TransformProvider {

  184.         /** Serializable UID. */
  185.         private static final long serialVersionUID = 20180330L;

  186.         /** Origin ITRF. */
  187.         private final ITRFVersion origin;

  188.         /** Destination ITRF. */
  189.         private final ITRFVersion destination;

  190.         /** Underlying provider. */
  191.         private final TransformProvider provider;

  192.         /** Simple constructor.
  193.          * @param origin origin ITRF
  194.          * @param destination destination ITRF
  195.          * @param provider underlying provider
  196.          */
  197.         Converter(final ITRFVersion origin, final ITRFVersion destination, final TransformProvider provider) {
  198.             this.origin      = origin;
  199.             this.destination = destination;
  200.             this.provider    = provider;
  201.         }

  202.         /** Get the origin ITRF.
  203.          * @return origin ITRF
  204.          */
  205.         public ITRFVersion getOrigin() {
  206.             return origin;
  207.         }

  208.         /** Get the destination ITRF.
  209.          * @return destination ITRF
  210.          */
  211.         public ITRFVersion getDestination() {
  212.             return destination;
  213.         }

  214.         /** {@inheritDoc} */
  215.         @Override
  216.         public Transform getTransform(final AbsoluteDate date) {
  217.             return provider.getTransform(date);
  218.         }

  219.         /** {@inheritDoc} */
  220.         @Override
  221.         public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
  222.             return provider.getTransform(date);
  223.         }

  224.     }

  225. }