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.files.rinex.navigation;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.orekit.files.rinex.RinexFile;
26  import org.orekit.gnss.SatelliteSystem;
27  import org.orekit.models.earth.ionosphere.KlobucharIonoModel;
28  import org.orekit.models.earth.ionosphere.NeQuickModel;
29  import org.orekit.propagation.analytical.gnss.data.BeidouCivilianNavigationMessage;
30  import org.orekit.propagation.analytical.gnss.data.BeidouLegacyNavigationMessage;
31  import org.orekit.propagation.analytical.gnss.data.GLONASSNavigationMessage;
32  import org.orekit.propagation.analytical.gnss.data.GPSCivilianNavigationMessage;
33  import org.orekit.propagation.analytical.gnss.data.GPSLegacyNavigationMessage;
34  import org.orekit.propagation.analytical.gnss.data.GalileoNavigationMessage;
35  import org.orekit.propagation.analytical.gnss.data.IRNSSNavigationMessage;
36  import org.orekit.propagation.analytical.gnss.data.QZSSCivilianNavigationMessage;
37  import org.orekit.propagation.analytical.gnss.data.QZSSLegacyNavigationMessage;
38  import org.orekit.propagation.analytical.gnss.data.SBASNavigationMessage;
39  
40  /**
41   * Represents a parsed RINEX navigation messages files.
42   * @author Bryan Cazabonne
43   * @author Luc Maisonobe
44   * @since 11.0
45   */
46  public class RinexNavigation extends RinexFile<RinexNavigationHeader> {
47  
48      /** The 4 Klobuchar coefficients of a cubic equation representing the amplitude of the vertical delay. */
49      private double[] klobucharAlpha;
50  
51      /** The 4 coefficients of a cubic equation representing the period of the model. */
52      private double[] klobucharBeta;
53  
54      /** The three ionospheric coefficients broadcast in the Galileo navigation message. */
55      private double[] neQuickAlpha;
56  
57      /** A map containing the GPS navigation messages. */
58      private final Map<String, List<GPSLegacyNavigationMessage>> gpsLegacyData;
59  
60      /** A map containing the GPS navigation messages. */
61      private final Map<String, List<GPSCivilianNavigationMessage>> gpsCivilianData;
62  
63      /** A map containing the Galileo navigation messages. */
64      private final Map<String, List<GalileoNavigationMessage>> galileoData;
65  
66      /** A map containing the Beidou navigation messages. */
67      private final Map<String, List<BeidouLegacyNavigationMessage>> beidouLegacyData;
68  
69      /** A map containing the Beidou navigation messages. */
70      private final Map<String, List<BeidouCivilianNavigationMessage>> beidouCivilianData;
71  
72      /** A map containing the QZSS navigation messages. */
73      private final Map<String, List<QZSSLegacyNavigationMessage>> qzssLegacyData;
74  
75      /** A map containing the QZSS navigation messages. */
76      private final Map<String, List<QZSSCivilianNavigationMessage>> qzssCivilianData;
77  
78      /** A map containing the IRNSS navigation messages. */
79      private final Map<String, List<IRNSSNavigationMessage>> irnssData;
80  
81      /** A map containing the GLONASS navigation messages. */
82      private final Map<String, List<GLONASSNavigationMessage>> glonassData;
83  
84      /** A map containing the SBAS navigation messages. */
85      private final Map<String, List<SBASNavigationMessage>> sbasData;
86  
87      /** System time offsets.
88       * @since 12.0
89       */
90      private final List<SystemTimeOffsetMessage> systemTimeOffsets;
91  
92      /** Earth orientation parameters.
93       * @since 12.0
94       */
95      private final List<EarthOrientationParameterMessage> eops;
96  
97      /** Ionosphere Klobuchar messages.
98       * @since 12.0
99       */
100     private final List<IonosphereKlobucharMessage> klobucharMessages;
101 
102     /** Ionosphere Nequick G messages.
103      * @since 12.0
104      */
105     private final List<IonosphereNequickGMessage> nequickGMessages;
106 
107     /** Ionosphere BDGIM messages.
108      * @since 12.0
109      */
110     private final List<IonosphereBDGIMMessage> bdgimMessages;
111 
112     /** Constructor. */
113     public RinexNavigation() {
114         super(new RinexNavigationHeader());
115         this.gpsLegacyData      = new HashMap<>();
116         this.gpsCivilianData    = new HashMap<>();
117         this.galileoData        = new HashMap<>();
118         this.beidouLegacyData   = new HashMap<>();
119         this.beidouCivilianData = new HashMap<>();
120         this.qzssLegacyData     = new HashMap<>();
121         this.qzssCivilianData   = new HashMap<>();
122         this.irnssData          = new HashMap<>();
123         this.glonassData        = new HashMap<>();
124         this.sbasData           = new HashMap<>();
125         this.systemTimeOffsets  = new ArrayList<>();
126         this.eops               = new ArrayList<>();
127         this.klobucharMessages  = new ArrayList<>();
128         this.nequickGMessages   = new ArrayList<>();
129         this.bdgimMessages      = new ArrayList<>();
130     }
131 
132     /**
133      * Get the "alpha" ionospheric parameters.
134      * <p>
135      * They are used to initialize the {@link KlobucharIonoModel}.
136      * </p>
137      * @return the "alpha" ionospheric parameters
138      */
139     public double[] getKlobucharAlpha() {
140         return klobucharAlpha.clone();
141     }
142 
143     /**
144      * Set the "alpha" ionspheric parameters.
145      * @param klobucharAlpha the "alpha" ionspheric parameters to set
146      */
147     public void setKlobucharAlpha(final double[] klobucharAlpha) {
148         this.klobucharAlpha = klobucharAlpha.clone();
149     }
150 
151     /**
152      * Get the "beta" ionospheric parameters.
153      * <p>
154      * They are used to initialize the {@link KlobucharIonoModel}.
155      * </p>
156      * @return the "beta" ionospheric parameters
157      */
158     public double[] getKlobucharBeta() {
159         return klobucharBeta.clone();
160     }
161 
162     /**
163      * Set the "beta" ionospheric parameters.
164      * @param klobucharBeta the "beta" ionospheric parameters to set
165      */
166     public void setKlobucharBeta(final double[] klobucharBeta) {
167         this.klobucharBeta = klobucharBeta.clone();
168     }
169 
170     /**
171      * Get the "alpha" ionospheric parameters.
172      * <p>
173      * They are used to initialize the {@link NeQuickModel}.
174      * </p>
175      * @return the "alpha" ionospheric parameters
176      */
177     public double[] getNeQuickAlpha() {
178         return neQuickAlpha.clone();
179     }
180 
181     /**
182      * Set the "alpha" ionospheric parameters.
183      * @param neQuickAlpha the "alpha" ionospheric parameters to set
184      */
185     public void setNeQuickAlpha(final double[] neQuickAlpha) {
186         this.neQuickAlpha = neQuickAlpha.clone();
187     }
188 
189     /**
190      * Get all the GPS legacy navigation messages contained in the file.
191      * @return an unmodifiable list of GPS legacy navigation messages
192      * @since 12.0
193      */
194     public Map<String, List<GPSLegacyNavigationMessage>> getGPSLegacyNavigationMessages() {
195         return Collections.unmodifiableMap(gpsLegacyData);
196     }
197 
198     /**
199      * Get the GPS legacy navigation messages for the given satellite Id.
200      * @param satId satellite Id (i.e. Satellite System (e.g. G) + satellite number)
201      * @return an unmodifiable list of GPS legacy navigation messages
202      * @since 12.0
203      */
204     public List<GPSLegacyNavigationMessage> getGPSLegacyNavigationMessages(final String satId) {
205         return Collections.unmodifiableList(gpsLegacyData.get(satId));
206     }
207 
208     /**
209      * Add a GPS legacy navigation message to the list.
210      * @param message message to add
211      * @since 12.0
212      */
213     public void addGPSLegacyNavigationMessage(final GPSLegacyNavigationMessage message) {
214         final int    gpsPRN = message.getPRN();
215         final String prnString = gpsPRN < 10 ? "0" + String.valueOf(gpsPRN) : String.valueOf(gpsPRN);
216         final String satId = SatelliteSystem.GPS.getKey() + prnString;
217         gpsLegacyData.putIfAbsent(satId, new ArrayList<>());
218         gpsLegacyData.get(satId).add(message);
219     }
220 
221     /**
222      * Get all the GPS civilian navigation messages contained in the file.
223      * @return an unmodifiable list of GPS civilian navigation messages
224      * @since 12.0
225      */
226     public Map<String, List<GPSCivilianNavigationMessage>> getGPSCivilianNavigationMessages() {
227         return Collections.unmodifiableMap(gpsCivilianData);
228     }
229 
230     /**
231      * Get the GPS civilian navigation messages for the given satellite Id.
232      * @param satId satellite Id (i.e. Satellite System (e.g. G) + satellite number)
233      * @return an unmodifiable list of GPS civilian navigation messages
234      * @since 12.0
235      */
236     public List<GPSCivilianNavigationMessage> getGPSCivilianNavigationMessages(final String satId) {
237         return Collections.unmodifiableList(gpsCivilianData.get(satId));
238     }
239 
240     /**
241      * Add a GPS civilian navigation message to the list.
242      * @param message message to add
243      * @since 12.0
244      */
245     public void addGPSLegacyNavigationMessage(final GPSCivilianNavigationMessage message) {
246         final int    gpsPRN = message.getPRN();
247         final String prnString = gpsPRN < 10 ? "0" + String.valueOf(gpsPRN) : String.valueOf(gpsPRN);
248         final String satId = SatelliteSystem.GPS.getKey() + prnString;
249         gpsCivilianData.putIfAbsent(satId, new ArrayList<>());
250         gpsCivilianData.get(satId).add(message);
251     }
252 
253     /**
254      * Get all the Galileo navigation messages contained in the file.
255      * @return an unmodifiable list of Galileo navigation messages
256      */
257     public Map<String, List<GalileoNavigationMessage>> getGalileoNavigationMessages() {
258         return Collections.unmodifiableMap(galileoData);
259     }
260 
261     /**
262      * Get the Galileo navigation messages for the given satellite Id.
263      * @param satId satellite Id (i.e. Satellite System (e.g. E) + satellite number)
264      * @return an unmodifiable list of Galileo navigation messages
265      */
266     public List<GalileoNavigationMessage> getGalileoNavigationMessages(final String satId) {
267         return Collections.unmodifiableList(galileoData.get(satId));
268     }
269 
270     /**
271      * Add a Galileo navigation message to the list.
272      * @param message message to add
273      */
274     public void addGalileoNavigationMessage(final GalileoNavigationMessage message) {
275         final int    galPRN = message.getPRN();
276         final String prnString = galPRN < 10 ? "0" + String.valueOf(galPRN) : String.valueOf(galPRN);
277         final String satId = SatelliteSystem.GALILEO.getKey() + prnString;
278         galileoData.putIfAbsent(satId, new ArrayList<>());
279         galileoData.get(satId).add(message);
280     }
281 
282     /**
283      * Get all the Beidou navigation messages contained in the file.
284      * @return an unmodifiable list of Beidou navigation messages
285      * @since 12.0
286      */
287     public Map<String, List<BeidouLegacyNavigationMessage>> getBeidouLegacyNavigationMessages() {
288         return Collections.unmodifiableMap(beidouLegacyData);
289     }
290 
291     /**
292      * Get the Beidou navigation messages for the given satellite Id.
293      * @param satId satellite Id (i.e. Satellite System (e.g. C) + satellite number)
294      * @return an unmodifiable list of Beidou navigation messages
295      * @since 12.0
296      */
297     public List<BeidouLegacyNavigationMessage> getBeidouLegacyNavigationMessages(final String satId) {
298         return Collections.unmodifiableList(beidouLegacyData.get(satId));
299     }
300 
301     /**
302      * Add a Beidou navigation message to the list.
303      * @param message message to add
304      * @since 12.0
305      */
306     public void addBeidouLegacyNavigationMessage(final BeidouLegacyNavigationMessage message) {
307         final int    bdtPRN = message.getPRN();
308         final String prnString = bdtPRN < 10 ? "0" + String.valueOf(bdtPRN) : String.valueOf(bdtPRN);
309         final String satId = SatelliteSystem.BEIDOU.getKey() + prnString;
310         beidouLegacyData.putIfAbsent(satId, new ArrayList<>());
311         beidouLegacyData.get(satId).add(message);
312     }
313 
314     /**
315      * Get all the Beidou navigation messages contained in the file.
316      * @return an unmodifiable list of Beidou navigation messages
317      * @since 12.0
318      */
319     public Map<String, List<BeidouCivilianNavigationMessage>> getBeidouCivilianNavigationMessages() {
320         return Collections.unmodifiableMap(beidouCivilianData);
321     }
322 
323     /**
324      * Get the Beidou navigation messages for the given satellite Id.
325      * @param satId satellite Id (i.e. Satellite System (e.g. C) + satellite number)
326      * @return an unmodifiable list of Beidou navigation messages
327      * @since 12.0
328      */
329     public List<BeidouCivilianNavigationMessage> getBeidouCivilianNavigationMessages(final String satId) {
330         return Collections.unmodifiableList(beidouCivilianData.get(satId));
331     }
332 
333     /**
334      * Add a Beidou navigation message to the list.
335      * @param message message to add
336      * @since 12.0
337      */
338     public void addBeidouCivilianNavigationMessage(final BeidouCivilianNavigationMessage message) {
339         final int    bdtPRN = message.getPRN();
340         final String prnString = bdtPRN < 10 ? "0" + String.valueOf(bdtPRN) : String.valueOf(bdtPRN);
341         final String satId = SatelliteSystem.BEIDOU.getKey() + prnString;
342         beidouCivilianData.putIfAbsent(satId, new ArrayList<>());
343         beidouCivilianData.get(satId).add(message);
344     }
345 
346     /**
347      * Get all the QZSS navigation messages contained in the file.
348      * @return an unmodifiable list of QZSS navigation messages
349      * @since 12.0
350      */
351     public Map<String, List<QZSSLegacyNavigationMessage>> getQZSSLegacyNavigationMessages() {
352         return Collections.unmodifiableMap(qzssLegacyData);
353     }
354 
355     /**
356      * Get the QZSS navigation messages for the given satellite Id.
357      * @param satId satellite Id (i.e. Satellite System (e.g. J) + satellite number)
358      * @return an unmodifiable list of QZSS navigation messages
359      * @since 12.0
360      */
361     public List<QZSSLegacyNavigationMessage> getQZSSLegacyNavigationMessages(final String satId) {
362         return Collections.unmodifiableList(qzssLegacyData.get(satId));
363     }
364 
365     /**
366      * Add a QZSS navigation message to the list.
367      * @param message message to add
368      * @since 12.0
369      */
370     public void addQZSSLegacyNavigationMessage(final QZSSLegacyNavigationMessage message) {
371         final int    qzsPRN = message.getPRN();
372         final String prnString = qzsPRN < 10 ? "0" + String.valueOf(qzsPRN) : String.valueOf(qzsPRN);
373         final String satId = SatelliteSystem.QZSS.getKey() + prnString;
374         qzssLegacyData.putIfAbsent(satId, new ArrayList<>());
375         qzssLegacyData.get(satId).add(message);
376     }
377 
378     /**
379      * Get all the QZSS navigation messages contained in the file.
380      * @return an unmodifiable list of QZSS navigation messages
381      * @since 12.0
382      */
383     public Map<String, List<QZSSCivilianNavigationMessage>> getQZSSCivilianNavigationMessages() {
384         return Collections.unmodifiableMap(qzssCivilianData);
385     }
386 
387     /**
388      * Get the QZSS navigation messages for the given satellite Id.
389      * @param satId satellite Id (i.e. Satellite System (e.g. J) + satellite number)
390      * @return an unmodifiable list of QZSS navigation messages
391      * @since 12.0
392      */
393     public List<QZSSCivilianNavigationMessage> getQZSSCivilianNavigationMessages(final String satId) {
394         return Collections.unmodifiableList(qzssCivilianData.get(satId));
395     }
396 
397     /**
398      * Add a QZSS navigation message to the list.
399      * @param message message to add
400      * @since 12.0
401      */
402     public void addQZSSCivilianNavigationMessage(final QZSSCivilianNavigationMessage message) {
403         final int    qzsPRN = message.getPRN();
404         final String prnString = qzsPRN < 10 ? "0" + String.valueOf(qzsPRN) : String.valueOf(qzsPRN);
405         final String satId = SatelliteSystem.QZSS.getKey() + prnString;
406         qzssCivilianData.putIfAbsent(satId, new ArrayList<>());
407         qzssCivilianData.get(satId).add(message);
408     }
409 
410     /**
411      * Get all the IRNSS navigation messages contained in the file.
412      * @return an unmodifiable list of IRNSS navigation messages
413      */
414     public Map<String, List<IRNSSNavigationMessage>> getIRNSSNavigationMessages() {
415         return Collections.unmodifiableMap(irnssData);
416     }
417 
418     /**
419      * Get the IRNSS navigation messages for the given satellite Id.
420      * @param satId satellite Id (i.e. Satellite System (e.g. I) + satellite number)
421      * @return an unmodifiable list of IRNSS navigation messages
422      */
423     public List<IRNSSNavigationMessage> getIRNSSNavigationMessages(final String satId) {
424         return Collections.unmodifiableList(irnssData.get(satId));
425     }
426 
427     /**
428      * Add a IRNSS navigation message to the list.
429      * @param message message to add
430      */
431     public void addIRNSSNavigationMessage(final IRNSSNavigationMessage message) {
432         final int    irsPRN = message.getPRN();
433         final String prnString = irsPRN < 10 ? "0" + String.valueOf(irsPRN) : String.valueOf(irsPRN);
434         final String satId = SatelliteSystem.IRNSS.getKey() + prnString;
435         irnssData.putIfAbsent(satId, new ArrayList<>());
436         irnssData.get(satId).add(message);
437     }
438 
439     /**
440      * Get all the Glonass navigation messages contained in the file.
441      * @return an unmodifiable list of Glonass navigation messages
442      */
443     public Map<String, List<GLONASSNavigationMessage>> getGlonassNavigationMessages() {
444         return Collections.unmodifiableMap(glonassData);
445     }
446 
447     /**
448      * Get the Glonass navigation messages for the given satellite Id.
449      * @param satId satellite Id (i.e. Satellite System (e.g. R) + satellite number)
450      * @return an unmodifiable list of Glonass navigation messages
451      */
452     public List<GLONASSNavigationMessage> getGlonassNavigationMessages(final String satId) {
453         return Collections.unmodifiableList(glonassData.get(satId));
454     }
455 
456     /**
457      * Add a Glonass navigation message to the list.
458      * @param message message to add
459      */
460     public void addGlonassNavigationMessage(final GLONASSNavigationMessage message) {
461         final int    gloPRN = message.getPRN();
462         final String prnString = gloPRN < 10 ? "0" + String.valueOf(gloPRN) : String.valueOf(gloPRN);
463         final String satId = SatelliteSystem.GLONASS.getKey() + prnString;
464         glonassData.putIfAbsent(satId, new ArrayList<>());
465         glonassData.get(satId).add(message);
466     }
467 
468     /**
469      * Get all the SBAS navigation messages contained in the file.
470      * @return an unmodifiable list of SBAS navigation messages
471      */
472     public Map<String, List<SBASNavigationMessage>> getSBASNavigationMessages() {
473         return Collections.unmodifiableMap(sbasData);
474     }
475 
476     /**
477      * Get the SBAS navigation messages for the given satellite Id.
478      * @param satId satellite Id (i.e. Satellite System (e.g. S) + satellite number)
479      * @return an unmodifiable list of SBAS navigation messages
480      */
481     public List<SBASNavigationMessage> getSBASNavigationMessages(final String satId) {
482         return Collections.unmodifiableList(sbasData.get(satId));
483     }
484 
485     /**
486      * Add a SBAS navigation message to the list.
487      * @param message message to add
488      */
489     public void addSBASNavigationMessage(final SBASNavigationMessage message) {
490         final int    sbsPRN = message.getPRN();
491         final String prnString = sbsPRN < 10 ? "0" + String.valueOf(sbsPRN) : String.valueOf(sbsPRN);
492         final String satId = SatelliteSystem.SBAS.getKey() + prnString;
493         sbasData.putIfAbsent(satId, new ArrayList<>());
494         sbasData.get(satId).add(message);
495     }
496 
497     /**
498      * Get the system time offsets.
499      * @return an unmodifiable list of system time offsets
500      * @since 12.0
501      */
502     public List<SystemTimeOffsetMessage> getSystemTimeOffsets() {
503         return Collections.unmodifiableList(systemTimeOffsets);
504     }
505 
506     /**
507      * Add a system time offset.
508      * @param systemTimeOffset system time offset message
509      * @since 12.0
510      */
511     public void addSystemTimeOffset(final SystemTimeOffsetMessage systemTimeOffset) {
512         systemTimeOffsets.add(systemTimeOffset);
513     }
514 
515     /**
516      * Get the Earth orientation parameters.
517      * @return an unmodifiable list of Earth orientation parameters
518      * @since 12.0
519      */
520     public List<EarthOrientationParameterMessage> getEarthOrientationParameters() {
521         return Collections.unmodifiableList(eops);
522     }
523 
524     /**
525      * Add an Earth orientation parameter.
526      * @param eop Earth orientation oarameter message
527      * @since 12.0
528      */
529     public void addEarthOrientationParameter(final EarthOrientationParameterMessage eop) {
530         eops.add(eop);
531     }
532 
533     /**
534      * Get the ionosphere Klobuchar messages.
535      * @return an unmodifiable list of ionosphere Klobuchar messages
536      * @since 12.0
537      */
538     public List<IonosphereKlobucharMessage> getKlobucharMessages() {
539         return Collections.unmodifiableList(klobucharMessages);
540     }
541 
542     /**
543      * Add an ionosphere Klobuchar message.
544      * @param klobuchar ionosphere Klobuchar message
545      * @since 12.0
546      */
547     public void addKlobucharMessage(final IonosphereKlobucharMessage klobuchar) {
548         klobucharMessages.add(klobuchar);
549     }
550 
551     /**
552      * Get the ionosphere Nequick-G messages.
553      * @return an unmodifiable list of ionosphere Nequick-G messages
554      * @since 12.0
555      */
556     public List<IonosphereNequickGMessage> getNequickGMessages() {
557         return Collections.unmodifiableList(nequickGMessages);
558     }
559 
560     /**
561      * Add an ionosphere Nequick-G message.
562      * @param nequickG ionosphere Nequick-G message
563      * @since 12.0
564      */
565     public void addNequickGMessage(final IonosphereNequickGMessage nequickG) {
566         nequickGMessages.add(nequickG);
567     }
568 
569     /**
570      * Get the ionosphere BDGIM messages.
571      * @return an unmodifiable list of ionosphere BDGIM messages
572      * @since 12.0
573      */
574     public List<IonosphereBDGIMMessage> getBDGIMMessages() {
575         return Collections.unmodifiableList(bdgimMessages);
576     }
577 
578     /**
579      * Add an ionosphere BDGIM message.
580      * @param bdgim ionosphere BDGIM message
581      * @since 12.0
582      */
583     public void addBDGIMMessage(final IonosphereBDGIMMessage bdgim) {
584         bdgimMessages.add(bdgim);
585     }
586 
587 }