1   /* Copyright 2002-2019 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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  
19  import org.hipparchus.RealFieldElement;
20  import org.orekit.errors.OrekitException;
21  import org.orekit.errors.OrekitMessages;
22  import org.orekit.frames.HelmertTransformation;
23  import org.orekit.time.AbsoluteDate;
24  import org.orekit.time.FieldAbsoluteDate;
25  
26  /** Enumerate for ITRF versions.
27   * @see EOPEntry
28   * @see HelmertTransformation
29   * @author Luc Maisonobe
30   * @since 9.2
31   */
32  public enum ITRFVersion {
33  
34      /** Constant for ITRF 2014. */
35      ITRF_2014(2014),
36  
37      /** Constant for ITRF 2008. */
38      ITRF_2008(2008),
39  
40      /** Constant for ITRF 2005. */
41      ITRF_2005(2005),
42  
43      /** Constant for ITRF 2000. */
44      ITRF_2000(2000),
45  
46      /** Constant for ITRF 97. */
47      ITRF_97(1997),
48  
49      /** Constant for ITRF 96. */
50      ITRF_96(1996),
51  
52      /** Constant for ITRF 94. */
53      ITRF_94(1994),
54  
55      /** Constant for ITRF 93. */
56      ITRF_93(1993),
57  
58      /** Constant for ITRF 92. */
59      ITRF_92(1992),
60  
61      /** Constant for ITRF 91. */
62      ITRF_91(1991),
63  
64      /** Constant for ITRF 90. */
65      ITRF_90(1990),
66  
67      /** Constant for ITRF 89. */
68      ITRF_89(1989),
69  
70      /** Constant for ITRF 88. */
71      ITRF_88(1988);
72  
73      /** Reference year of the frame version. */
74      private final int year;
75  
76      /** Name. */
77      private final String name;
78  
79      /** Simple constructor.
80       * @param year reference year of the frame version
81       */
82      ITRFVersion(final int year) {
83          this.year = year;
84          this.name = "ITRF-" + ((year >= 2000) ? year : (year - 1900));
85      }
86  
87      /** Get the reference year of the frame version.
88       * @return reference year of the frame version
89       */
90      public int getYear() {
91          return year;
92      }
93  
94      /** Get the name the frame version.
95       * @return name of the frame version
96       */
97      public String getName() {
98          return name;
99      }
100 
101     /** Find an ITRF version from its reference year.
102      * @param year reference year of the frame version
103      * @return ITRF version for specified year
104      */
105     public static ITRFVersion getITRFVersion(final int year) {
106 
107         // loop over all predefined frames versions
108         for (final ITRFVersion version : values()) {
109             if (version.getYear() == year) {
110                 return version;
111             }
112         }
113 
114         // we don't have the required frame
115         throw new OrekitException(OrekitMessages.NO_SUCH_ITRF_FRAME, year);
116 
117     }
118 
119     /** Find an ITRF version from its name.
120      * @param name name of the frame version (case is ignored)
121      * @return ITRF version
122      */
123     public static ITRFVersion getITRFVersion(final String name) {
124 
125         // loop over all predefined frames versions
126         for (final ITRFVersion version : values()) {
127             if (version.getName().equalsIgnoreCase(name)) {
128                 return version;
129             }
130         }
131 
132         // we don't have the required frame
133         throw new OrekitException(OrekitMessages.NO_SUCH_ITRF_FRAME, name);
134 
135     }
136 
137     /** Find a converter between specified ITRF frames.
138      * @param origin origin ITRF
139      * @param destination destination ITRF
140      * @return transform from {@code origin} to {@code destination}
141      */
142     public static Converter getConverter(final ITRFVersionRFVersion">ITRFVersion origin, final ITRFVersion destination) {
143 
144         TransformProvider provider = null;
145 
146         // special case for no transform
147         if (origin == destination) {
148             provider = TransformProviderUtils.IDENTITY_PROVIDER;
149         }
150 
151         if (provider == null) {
152             // try to find a direct provider
153             provider = getDirectTransformProvider(origin, destination);
154         }
155 
156         if (provider == null) {
157             // no direct provider found, use ITRF 2014 as a pivot frame
158             provider = TransformProviderUtils.getCombinedProvider(getDirectTransformProvider(origin, ITRF_2014),
159                                                                   getDirectTransformProvider(ITRF_2014, destination));
160         }
161 
162         // build the converter, to keep the origin and destination information
163         return new Converter(origin, destination, provider);
164 
165     }
166 
167     /** Find a direct transform provider between specified ITRF frames.
168      * @param origin origin ITRF
169      * @param destination destination ITRF
170      * @return transform from {@code origin} to {@code destination}, or null if no direct transform is found
171      */
172     private static TransformProvider getDirectTransformProvider(final ITRFVersionRFVersion">ITRFVersion origin, final ITRFVersion destination) {
173 
174         // loop over all predefined transforms
175         for (final HelmertTransformation.Predefined predefined : HelmertTransformation.Predefined.values()) {
176             if (predefined.getOrigin() == origin && predefined.getDestination() == destination) {
177                 // we have an Helmert transformation in the specified direction
178                 return predefined.getTransformation();
179             } else if (predefined.getOrigin() == destination && predefined.getDestination() == origin) {
180                 // we have an Helmert transformation in the opposite direction
181                 return TransformProviderUtils.getReversedProvider(predefined.getTransformation());
182             }
183         }
184 
185         // we don't have the required transform
186         return null;
187 
188     }
189 
190     /** Specialized transform provider between ITRF frames. */
191     public static class Converter implements TransformProvider {
192 
193         /** Serializable UID. */
194         private static final long serialVersionUID = 20180330L;
195 
196         /** Origin ITRF. */
197         private final ITRFVersion origin;
198 
199         /** Destination ITRF. */
200         private final ITRFVersion destination;
201 
202         /** Underlying provider. */
203         private final TransformProvider provider;
204 
205         /** Simple constructor.
206          * @param origin origin ITRF
207          * @param destination destination ITRF
208          * @param provider underlying provider
209          */
210         Converter(final ITRFVersionRFVersion">ITRFVersion origin, final ITRFVersion destination, final TransformProvider provider) {
211             this.origin      = origin;
212             this.destination = destination;
213             this.provider    = provider;
214         }
215 
216         /** Get the origin ITRF.
217          * @return origin ITRF
218          */
219         public ITRFVersion getOrigin() {
220             return origin;
221         }
222 
223         /** Get the destination ITRF.
224          * @return destination ITRF
225          */
226         public ITRFVersion getDestination() {
227             return destination;
228         }
229 
230         /** {@inheritDoc} */
231         @Override
232         public Transform getTransform(final AbsoluteDate date) {
233             return provider.getTransform(date);
234         }
235 
236         /** {@inheritDoc} */
237         @Override
238         public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
239             return provider.getTransform(date);
240         }
241 
242     }
243 
244 }