1   /* Copyright 2002-2024 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.gnss;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  import java.util.function.Function;
22  
23  import org.orekit.errors.OrekitIllegalArgumentException;
24  import org.orekit.errors.OrekitMessages;
25  import org.orekit.time.TimeScale;
26  import org.orekit.time.TimeScales;
27  
28  /** Enumerate for the time systems used in navigation files.
29   *
30   * @author Thomas Neidhart
31   * @author Evan Ward
32   * @author Thomas Paulet
33   * @since 11.0
34   */
35  public enum TimeSystem {
36  
37      /** Global Positioning System. */
38      GPS("GPS", "GP", "G", ts -> ts.getGPS()),
39  
40      /** GLONASS. */
41      GLONASS("GLO", "GL", "R", ts -> ts.getGLONASS()),
42  
43      /** GALILEO. */
44      GALILEO("GAL", "GA", "E", ts -> ts.getGST()),
45  
46      /** International Atomic Time. */
47      TAI("TAI", null, null, ts -> ts.getTAI()),
48  
49      /** Coordinated Universal Time. */
50      UTC("UTC", "UT", null, ts -> ts.getUTC()),
51  
52      /** Quasi-Zenith System. */
53      QZSS("QZS", "QZ", "J", ts -> ts.getQZSS()),
54  
55      /** Beidou. */
56      BEIDOU("BDT", "BD", "C", ts -> ts.getBDT()),
57  
58      /** IRNSS. */
59      IRNSS("IRN", "IR", "I", ts -> ts.getIRNSS()),
60  
61      /** SBAS.
62       * @since 12.0
63       */
64      SBAS(null, "SB", "S", ts -> ts.getUTC()),
65  
66      /** GMT (should only by used in RUN BY / DATE entries).
67       * @since 12.0
68       */
69      GMT("GMT", null, null, ts -> ts.getUTC()),
70  
71      /** Unknown (should only by used in RUN BY / DATE entries). */
72      UNKNOWN("LCL", null, null, ts -> ts.getGPS());
73  
74      /** Parsing key map. */
75      private static final Map<String, TimeSystem> KEYS_MAP = new HashMap<>();
76  
77      /** Parsing two letters code map.
78       * @since 12.0
79       */
80      private static final Map<String, TimeSystem> TLC_MAP = new HashMap<>();
81  
82      /** Parsing one letters code map.
83       * @since 12.0
84       */
85      private static final Map<String, TimeSystem> OLC_MAP = new HashMap<>();
86  
87      static {
88          for (final TimeSystem timeSystem : values()) {
89              if (timeSystem.key != null) {
90                  KEYS_MAP.put(timeSystem.key, timeSystem);
91              }
92              if (timeSystem.twoLettersCode != null) {
93                  TLC_MAP.put(timeSystem.twoLettersCode, timeSystem);
94              }
95              if (timeSystem.oneLetterCode != null) {
96                  OLC_MAP.put(timeSystem.oneLetterCode, timeSystem);
97              }
98          }
99      }
100 
101     /** Key for the system. */
102     private final String key;
103 
104     /** Two-letters code.
105      * @since 12.0
106      */
107     private final String twoLettersCode;
108 
109     /** One-letter code.
110      * @since 12.0
111      */
112     private final String oneLetterCode;
113 
114     /** Time scale provider.
115      * @since 12.0
116      */
117     private final Function<TimeScales, TimeScale> timeScaleProvider;
118 
119     /** Simple constructor.
120      * @param key key letter (may be null)
121      * @param twoLettersCode two letters code (may be null)
122      * @param oneLetterCode one letter code (may be null)
123      * @param timeScaleProvider time scale provider
124      */
125     TimeSystem(final String key, final String twoLettersCode, final String oneLetterCode,
126                final Function<TimeScales, TimeScale> timeScaleProvider) {
127         this.key               = key;
128         this.twoLettersCode    = twoLettersCode;
129         this.oneLetterCode     = oneLetterCode;
130         this.timeScaleProvider = timeScaleProvider;
131     }
132 
133     /** Get the 3 letters key of the time system.
134      * @return 3 letters key
135      * @since 12.0
136      */
137     public String getKey() {
138         return key;
139     }
140 
141     /** Parse a string to get the time system.
142      * <p>
143      * The string must be the time system.
144      * </p>
145      * @param s string to parse
146      * @return the time system
147      * @exception OrekitIllegalArgumentException if the string does not correspond to a time system key
148      */
149     public static TimeSystem parseTimeSystem(final String s)
150         throws OrekitIllegalArgumentException {
151         final TimeSystem timeSystem = KEYS_MAP.get(s);
152         if (timeSystem == null) {
153             throw new OrekitIllegalArgumentException(OrekitMessages.UNKNOWN_TIME_SYSTEM, s);
154         }
155         return timeSystem;
156     }
157 
158     /** Parse a string to get the time system.
159      * <p>
160      * The string must be the two letters code of the time system.
161      * </p>
162      * @param code string to parse
163      * @return the time system
164      * @exception OrekitIllegalArgumentException if the string does not correspond to a time system key
165      */
166     public static TimeSystem parseTwoLettersCode(final String code)
167         throws OrekitIllegalArgumentException {
168         final TimeSystem timeSystem = TLC_MAP.get(code);
169         if (timeSystem == null) {
170             throw new OrekitIllegalArgumentException(OrekitMessages.UNKNOWN_TIME_SYSTEM, code);
171         }
172         return timeSystem;
173     }
174 
175     /** Parse a string to get the time system.
176      * <p>
177      * The string must be the one letters code of the time system.
178      * The one letter code is the RINEX GNSS system flag.
179      * </p>
180      * @param code string to parse
181      * @return the time system
182      * @exception OrekitIllegalArgumentException if the string does not correspond to a time system key
183      */
184     public static TimeSystem parseOneLetterCode(final String code)
185         throws OrekitIllegalArgumentException {
186         final TimeSystem timeSystem = OLC_MAP.get(code);
187         if (timeSystem == null) {
188             throw new OrekitIllegalArgumentException(OrekitMessages.UNKNOWN_TIME_SYSTEM, code);
189         }
190         return timeSystem;
191     }
192 
193     /** Get the time scale corresponding to time system.
194      * @param timeScales the set of time scales to use
195      * @return the time scale corresponding to time system in the set of time scales
196      */
197     public TimeScale getTimeScale(final TimeScales timeScales) {
198         return timeScaleProvider.apply(timeScales);
199     }
200 
201 }