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