1   /* Copyright 2002-2021 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.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.gnss.SatelliteSystem;
26  import org.orekit.models.earth.ionosphere.KlobucharIonoModel;
27  import org.orekit.models.earth.ionosphere.NeQuickModel;
28  import org.orekit.propagation.analytical.gnss.data.BeidouNavigationMessage;
29  import org.orekit.propagation.analytical.gnss.data.GLONASSNavigationMessage;
30  import org.orekit.propagation.analytical.gnss.data.GPSNavigationMessage;
31  import org.orekit.propagation.analytical.gnss.data.GalileoNavigationMessage;
32  import org.orekit.propagation.analytical.gnss.data.IRNSSNavigationMessage;
33  import org.orekit.propagation.analytical.gnss.data.QZSSNavigationMessage;
34  import org.orekit.propagation.analytical.gnss.data.SBASNavigationMessage;
35  import org.orekit.time.AbsoluteDate;
36  
37  /**
38   * Represents a parsed RINEX navigation messages files.
39   * @author Bryan Cazabonne
40   * @since 11.0
41   */
42  public class RinexNavigation {
43  
44      /** Format version. */
45      private double formatVersion;
46  
47      /** File type ('N' for navigation data). */
48      private String fileType;
49  
50      /** Satellite system. */
51      private SatelliteSystem satelliteSystem;
52  
53      /** Name of the program creating current file. */
54      private String programName;
55  
56      /** Name of the agency creating the current file. */
57      private String agencyName;
58  
59      /** Date of the file creation as a string. */
60      private String creationDateString;
61  
62      /** Time of the file creation as a string. */
63      private String creationTimeString;
64  
65      /** Time zone of the file creation as a string. */
66      private String creationTimeZoneString;
67  
68      /** Creation date as absolute date. */
69      private AbsoluteDate creationDate;
70  
71      /** Comments. */
72      private String comments;
73  
74      /** Ionospheric correction type. */
75      private String ionosphericCorrectionType;
76  
77      /** The 4 Klobuchar coefficients of a cubic equation representing the amplitude of the vertical delay. */
78      private double[] klobucharAlpha;
79  
80      /** The 4 coefficients of a cubic equation representing the period of the model. */
81      private double[] klobucharBeta;
82  
83      /** The three ionospheric coefficients broadcast in the Galileo navigation message. */
84      private double[] neQuickAlpha;
85  
86      /** List of time system corrections. */
87      private List<TimeSystemCorrection> timeSystemCorrections;
88  
89      /** Current number of leap seconds. */
90      private int numberOfLeapSeconds;
91  
92      /** A map containing the GPS navigation messages. */
93      private Map<String, List<GPSNavigationMessage>> gpsData;
94  
95      /** A map containing the Galileo navigation messages. */
96      private Map<String, List<GalileoNavigationMessage>> galileoData;
97  
98      /** A map containing the Beidou navigation messages. */
99      private Map<String, List<BeidouNavigationMessage>> beidouData;
100 
101     /** A map containing the QZSS navigation messages. */
102     private Map<String, List<QZSSNavigationMessage>> qzssData;
103 
104     /** A map containing the IRNSS navigation messages. */
105     private Map<String, List<IRNSSNavigationMessage>> irnssData;
106 
107     /** A map containing the GLONASS navigation messages. */
108     private Map<String, List<GLONASSNavigationMessage>> glonassData;
109 
110     /** A map containing the SBAS navigation messages. */
111     private Map<String, List<SBASNavigationMessage>> sbasData;
112 
113     /** Constructor. */
114     public RinexNavigation() {
115         this.comments              = "";
116         this.timeSystemCorrections = new ArrayList<>();
117         this.gpsData               = new HashMap<>();
118         this.galileoData           = new HashMap<>();
119         this.beidouData            = new HashMap<>();
120         this.qzssData              = new HashMap<>();
121         this.irnssData             = new HashMap<>();
122         this.glonassData           = new HashMap<>();
123         this.sbasData              = new HashMap<>();
124     }
125 
126     /**
127      * Getter for the format version.
128      * @return the format version
129      */
130     public double getFormatVersion() {
131         return formatVersion;
132     }
133 
134     /**
135      * Setter for the format version.
136      * @param formatVersion the format version to set
137      */
138     public void setFormatVersion(final double formatVersion) {
139         this.formatVersion = formatVersion;
140     }
141 
142     /**
143      * Get the file type.
144      * @return 'N' for navigation data.
145      */
146     public String getFileType() {
147         return fileType;
148     }
149 
150     /**
151      * Setter for the file type.
152      * @param fileType must be 'N' for navigation data
153      */
154     public void setFileType(final String fileType) {
155         this.fileType = fileType;
156     }
157 
158     /**
159      * Getter for the satellite system.
160      * <p>
161      * Not specified for RINEX 2.X versions (value is null).
162      * </p>
163      * @return the satellite system
164      */
165     public SatelliteSystem getSatelliteSystem() {
166         return satelliteSystem;
167     }
168 
169     /**
170      * Setter for the satellite system.
171      * @param satelliteSystem the satellite system to set
172      */
173     public void setSatelliteSystem(final SatelliteSystem satelliteSystem) {
174         this.satelliteSystem = satelliteSystem;
175     }
176 
177     /**
178      * Getter for the program name.
179      * @return the program name
180      */
181     public String getProgramName() {
182         return programName;
183     }
184 
185     /**
186      * Setter for the program name.
187      * @param programName the program name to set
188      */
189     public void setProgramName(final String programName) {
190         this.programName = programName;
191     }
192 
193     /**
194      * Getter for the agency name.
195      * @return the agencyName
196      */
197     public String getAgencyName() {
198         return agencyName;
199     }
200 
201     /**
202      * Setter for the agency name.
203      * @param agencyName the agency name to set
204      */
205     public void setAgencyName(final String agencyName) {
206         this.agencyName = agencyName;
207     }
208 
209     /**
210      * Getter for the creation date of the file as a string.
211      * @return the creation date as a string
212      */
213     public String getCreationDateString() {
214         return creationDateString;
215     }
216 
217     /**
218      * Setter for the creation date as a string.
219      * @param creationDateString the creation date as a string to set
220      */
221     public void setCreationDateString(final String creationDateString) {
222         this.creationDateString = creationDateString;
223     }
224 
225     /**
226      * Getter for the creation time of the file as a string.
227      * @return the creation time as a string
228      */
229     public String getCreationTimeString() {
230         return creationTimeString;
231     }
232 
233     /**
234      * Setter for the creation time as a string.
235      * @param creationTimeString the creation time as a string to set
236      */
237     public void setCreationTimeString(final String creationTimeString) {
238         this.creationTimeString = creationTimeString;
239     }
240 
241     /**
242      * Getter for the creation time zone of the file as a string.
243      * @return the creation time zone as a string
244      */
245     public String getCreationTimeZoneString() {
246         return creationTimeZoneString;
247     }
248 
249     /**
250      * Setter for the creation time zone.
251      * @param creationTimeZoneString the creation time zone as a string to set
252      */
253     public void setCreationTimeZoneString(final String creationTimeZoneString) {
254         this.creationTimeZoneString = creationTimeZoneString;
255     }
256 
257     /**
258      * Getter for the creation date.
259      * @return the creation date
260      */
261     public AbsoluteDate getCreationDate() {
262         return creationDate;
263     }
264 
265     /**
266      * Setter for the creation date.
267      * @param creationDate the creation date to set
268      */
269     public void setCreationDate(final AbsoluteDate creationDate) {
270         this.creationDate = creationDate;
271     }
272 
273     /**
274      * Getter for the comments.
275      * @return the comments
276      */
277     public String getComments() {
278         return comments;
279     }
280 
281     /**
282      * Add a comment line.
283      * @param comment the comment line to add
284      */
285     public void addComment(final String comment) {
286         this.comments = comments.concat(comment);
287     }
288 
289     /**
290      * Getter for the ionospheric correction type.
291      * <p>
292      * Only the three first characters are given (e.g. GAL, GPS, QZS, BDS, or IRN)
293      * </p>
294      * @return the ionospheric correction type
295      */
296     public String getIonosphericCorrectionType() {
297         return ionosphericCorrectionType;
298     }
299 
300     /**
301      * Setter for the ionospheric correction type.
302      * @param ionosphericCorrectionType the ionospheric correction type to set
303      */
304     public void setIonosphericCorrectionType(final String ionosphericCorrectionType) {
305         this.ionosphericCorrectionType = ionosphericCorrectionType;
306     }
307 
308     /**
309      * Get the "alpha" ionospheric parameters.
310      * <p>
311      * They are used to initialize the {@link KlobucharIonoModel}.
312      * </p>
313      * @return the "alpha" ionospheric parameters
314      */
315     public double[] getKlobucharAlpha() {
316         return klobucharAlpha.clone();
317     }
318 
319     /**
320      * Set the "alpha" ionspheric parameters.
321      * @param klobucharAlpha the "alpha" ionspheric parameters to set
322      */
323     public void setKlobucharAlpha(final double[] klobucharAlpha) {
324         this.klobucharAlpha = klobucharAlpha.clone();
325     }
326 
327     /**
328      * Get the "beta" ionospheric parameters.
329      * <p>
330      * They are used to initialize the {@link KlobucharIonoModel}.
331      * </p>
332      * @return the "beta" ionospheric parameters
333      */
334     public double[] getKlobucharBeta() {
335         return klobucharBeta.clone();
336     }
337 
338     /**
339      * Set the "beta" ionospheric parameters.
340      * @param klobucharBeta the "beta" ionospheric parameters to set
341      */
342     public void setKlobucharBeta(final double[] klobucharBeta) {
343         this.klobucharBeta = klobucharBeta.clone();
344     }
345 
346     /**
347      * Get the "alpha" ionospheric parameters.
348      * <p>
349      * They are used to initialize the {@link NeQuickModel}.
350      * </p>
351      * @return the "alpha" ionospheric parameters
352      */
353     public double[] getNeQuickAlpha() {
354         return neQuickAlpha.clone();
355     }
356 
357     /**
358      * Set the "alpha" ionospheric parameters.
359      * @param neQuickAlpha the "alpha" ionospheric parameters to set
360      */
361     public void setNeQuickAlpha(final double[] neQuickAlpha) {
362         this.neQuickAlpha = neQuickAlpha.clone();
363     }
364 
365     /**
366      * Getter for the time system corrections contained in the file header.
367      * <p>
368      * Corrections to transform the system time to UTC or oter time system.
369      * </p>
370      * @return the list of time system corrections
371      */
372     public List<TimeSystemCorrection> getTimeSystemCorrections() {
373         return timeSystemCorrections;
374     }
375 
376     /**
377      * Add a time system correction to the list.
378      * @param timeSystemCorrection the element to add
379      */
380     public void addTimeSystemCorrections(final TimeSystemCorrection timeSystemCorrection) {
381         this.timeSystemCorrections.add(timeSystemCorrection);
382     }
383 
384     /**
385      * Getter for the current number of leap seconds.
386      * @return the current number of leap seconds
387      */
388     public int getNumberOfLeapSeconds() {
389         return numberOfLeapSeconds;
390     }
391 
392     /**
393      * Setter for the current number of leap seconds.
394      * @param numberOfLeapSeconds the number of leap seconds to set
395      */
396     public void setNumberOfLeapSeconds(final int numberOfLeapSeconds) {
397         this.numberOfLeapSeconds = numberOfLeapSeconds;
398     }
399 
400     /**
401      * Get all the GPS navigation messages contained in the file.
402      * @return an unmodifiable list of GPS navigation messages
403      */
404     public Map<String, List<GPSNavigationMessage>> getGPSNavigationMessages() {
405         return Collections.unmodifiableMap(gpsData);
406     }
407 
408     /**
409      * Get the GPS navigation messages for the given satellite Id.
410      * @param satId satellite Id (i.e. Satellite System (e.g. G) + satellite number)
411      * @return an unmodifiable list of GPS navigation messages
412      */
413     public List<GPSNavigationMessage> getGPSNavigationMessages(final String satId) {
414         return Collections.unmodifiableList(gpsData.get(satId));
415     }
416 
417     /**
418      * Add a GPS navigation message to the list.
419      * @param message message to add
420      */
421     public void addGPSNavigationMessage(final GPSNavigationMessage message) {
422         final int    gpsPRN = message.getPRN();
423         final String prnString = gpsPRN < 10 ? "0" + String.valueOf(gpsPRN) : String.valueOf(gpsPRN);
424         final String satId = SatelliteSystem.GPS.getKey() + prnString;
425         gpsData.putIfAbsent(satId, new ArrayList<GPSNavigationMessage>());
426         gpsData.get(satId).add(message);
427     }
428 
429     /**
430      * Get all the Galileo navigation messages contained in the file.
431      * @return an unmodifiable list of Galileo navigation messages
432      */
433     public Map<String, List<GalileoNavigationMessage>> getGalileoNavigationMessages() {
434         return Collections.unmodifiableMap(galileoData);
435     }
436 
437     /**
438      * Get the Galileo navigation messages for the given satellite Id.
439      * @param satId satellite Id (i.e. Satellite System (e.g. E) + satellite number)
440      * @return an unmodifiable list of Galileo navigation messages
441      */
442     public List<GalileoNavigationMessage> getGalileoNavigationMessages(final String satId) {
443         return Collections.unmodifiableList(galileoData.get(satId));
444     }
445 
446     /**
447      * Add a Galileo navigation message to the list.
448      * @param message message to add
449      */
450     public void addGalileoNavigationMessage(final GalileoNavigationMessage message) {
451         final int    galPRN = message.getPRN();
452         final String prnString = galPRN < 10 ? "0" + String.valueOf(galPRN) : String.valueOf(galPRN);
453         final String satId = SatelliteSystem.GALILEO.getKey() + prnString;
454         galileoData.putIfAbsent(satId, new ArrayList<GalileoNavigationMessage>());
455         galileoData.get(satId).add(message);
456     }
457 
458     /**
459      * Get all the Beidou navigation messages contained in the file.
460      * @return an unmodifiable list of Beidou navigation messages
461      */
462     public Map<String, List<BeidouNavigationMessage>> getBeidouNavigationMessages() {
463         return Collections.unmodifiableMap(beidouData);
464     }
465 
466     /**
467      * Get the Beidou navigation messages for the given satellite Id.
468      * @param satId satellite Id (i.e. Satellite System (e.g. C) + satellite number)
469      * @return an unmodifiable list of Beidou navigation messages
470      */
471     public List<BeidouNavigationMessage> getBeidouNavigationMessages(final String satId) {
472         return Collections.unmodifiableList(beidouData.get(satId));
473     }
474 
475     /**
476      * Add a Beidou navigation message to the list.
477      * @param message message to add
478      */
479     public void addBeidouNavigationMessage(final BeidouNavigationMessage message) {
480         final int    bdtPRN = message.getPRN();
481         final String prnString = bdtPRN < 10 ? "0" + String.valueOf(bdtPRN) : String.valueOf(bdtPRN);
482         final String satId = SatelliteSystem.BEIDOU.getKey() + prnString;
483         beidouData.putIfAbsent(satId, new ArrayList<BeidouNavigationMessage>());
484         beidouData.get(satId).add(message);
485     }
486 
487     /**
488      * Get all the QZSS navigation messages contained in the file.
489      * @return an unmodifiable list of QZSS navigation messages
490      */
491     public Map<String, List<QZSSNavigationMessage>> getQZSSNavigationMessages() {
492         return Collections.unmodifiableMap(qzssData);
493     }
494 
495     /**
496      * Get the QZSS navigation messages for the given satellite Id.
497      * @param satId satellite Id (i.e. Satellite System (e.g. J) + satellite number)
498      * @return an unmodifiable list of QZSS navigation messages
499      */
500     public List<QZSSNavigationMessage> getQZSSNavigationMessages(final String satId) {
501         return Collections.unmodifiableList(qzssData.get(satId));
502     }
503 
504     /**
505      * Add a QZSS navigation message to the list.
506      * @param message message to add
507      */
508     public void addQZSSNavigationMessage(final QZSSNavigationMessage message) {
509         final int    qzsPRN = message.getPRN();
510         final String prnString = qzsPRN < 10 ? "0" + String.valueOf(qzsPRN) : String.valueOf(qzsPRN);
511         final String satId = SatelliteSystem.QZSS.getKey() + prnString;
512         qzssData.putIfAbsent(satId, new ArrayList<QZSSNavigationMessage>());
513         qzssData.get(satId).add(message);
514     }
515 
516     /**
517      * Get all the IRNSS navigation messages contained in the file.
518      * @return an unmodifiable list of IRNSS navigation messages
519      */
520     public Map<String, List<IRNSSNavigationMessage>> getIRNSSNavigationMessages() {
521         return Collections.unmodifiableMap(irnssData);
522     }
523 
524     /**
525      * Get the IRNSS navigation messages for the given satellite Id.
526      * @param satId satellite Id (i.e. Satellite System (e.g. I) + satellite number)
527      * @return an unmodifiable list of IRNSS navigation messages
528      */
529     public List<IRNSSNavigationMessage> getIRNSSNavigationMessages(final String satId) {
530         return Collections.unmodifiableList(irnssData.get(satId));
531     }
532 
533     /**
534      * Add a IRNSS navigation message to the list.
535      * @param message message to add
536      */
537     public void addIRNSSNavigationMessage(final IRNSSNavigationMessage message) {
538         final int    irsPRN = message.getPRN();
539         final String prnString = irsPRN < 10 ? "0" + String.valueOf(irsPRN) : String.valueOf(irsPRN);
540         final String satId = SatelliteSystem.IRNSS.getKey() + prnString;
541         irnssData.putIfAbsent(satId, new ArrayList<IRNSSNavigationMessage>());
542         irnssData.get(satId).add(message);
543     }
544 
545     /**
546      * Get all the Glonass navigation messages contained in the file.
547      * @return an unmodifiable list of Glonass navigation messages
548      */
549     public Map<String, List<GLONASSNavigationMessage>> getGlonassNavigationMessages() {
550         return Collections.unmodifiableMap(glonassData);
551     }
552 
553     /**
554      * Get the Glonass navigation messages for the given satellite Id.
555      * @param satId satellite Id (i.e. Satellite System (e.g. R) + satellite number)
556      * @return an unmodifiable list of Glonass navigation messages
557      */
558     public List<GLONASSNavigationMessage> getGlonassNavigationMessages(final String satId) {
559         return Collections.unmodifiableList(glonassData.get(satId));
560     }
561 
562     /**
563      * Add a Glonass navigation message to the list.
564      * @param message message to add
565      */
566     public void addGlonassNavigationMessage(final GLONASSNavigationMessage message) {
567         final int    gloPRN = message.getPRN();
568         final String prnString = gloPRN < 10 ? "0" + String.valueOf(gloPRN) : String.valueOf(gloPRN);
569         final String satId = SatelliteSystem.GLONASS.getKey() + prnString;
570         glonassData.putIfAbsent(satId, new ArrayList<GLONASSNavigationMessage>());
571         glonassData.get(satId).add(message);
572     }
573 
574     /**
575      * Get all the SBAS navigation messages contained in the file.
576      * @return an unmodifiable list of SBAS navigation messages
577      */
578     public Map<String, List<SBASNavigationMessage>> getSBASNavigationMessages() {
579         return Collections.unmodifiableMap(sbasData);
580     }
581 
582     /**
583      * Get the SBAS navigation messages for the given satellite Id.
584      * @param satId satellite Id (i.e. Satellite System (e.g. S) + satellite number)
585      * @return an unmodifiable list of SBAS navigation messages
586      */
587     public List<SBASNavigationMessage> getSBASNavigationMessages(final String satId) {
588         return Collections.unmodifiableList(sbasData.get(satId));
589     }
590 
591     /**
592      * Add a SBAS navigation message to the list.
593      * @param message message to add
594      */
595     public void addSBASNavigationMessage(final SBASNavigationMessage message) {
596         final int    sbsPRN = message.getPRN();
597         final String prnString = sbsPRN < 10 ? "0" + String.valueOf(sbsPRN) : String.valueOf(sbsPRN);
598         final String satId = SatelliteSystem.SBAS.getKey() + prnString;
599         sbasData.putIfAbsent(satId, new ArrayList<SBASNavigationMessage>());
600         sbasData.get(satId).add(message);
601     }
602 
603     /** Container for time system corrections. */
604     public static class TimeSystemCorrection {
605 
606         /** Time system correction type. */
607         private String timeSystemCorrectionType;
608 
609         /** A0 coefficient of linear polynomial for time system correction. */
610         private double timeSystemCorrectionA0;
611 
612         /** A1 coefficient of linear polynomial for time system correction. */
613         private double timeSystemCorrectionA1;
614 
615         /** Reference time for time system correction (seconds into GNSS week). */
616         private int timeSystemCorrectionSecOfWeek;
617 
618         /** Reference week number for time system correction. */
619         private int timeSystemCorrectionWeekNumber;
620 
621         /**
622          * Constructor.
623          * @param timeSystemCorrectionType       time system correction type
624          * @param timeSystemCorrectionA0         A0 coefficient of linear polynomial for time system correction
625          * @param timeSystemCorrectionA1         A1 coefficient of linear polynomial for time system correction
626          * @param timeSystemCorrectionSecOfWeek  reference time for time system correction
627          * @param timeSystemCorrectionWeekNumber reference week number for time system correction
628          */
629         public TimeSystemCorrection(final String timeSystemCorrectionType,
630                                     final double timeSystemCorrectionA0,
631                                     final double timeSystemCorrectionA1,
632                                     final int timeSystemCorrectionSecOfWeek,
633                                     final int timeSystemCorrectionWeekNumber) {
634             this.timeSystemCorrectionType       = timeSystemCorrectionType;
635             this.timeSystemCorrectionA0         = timeSystemCorrectionA0;
636             this.timeSystemCorrectionA1         = timeSystemCorrectionA1;
637             this.timeSystemCorrectionSecOfWeek  = timeSystemCorrectionSecOfWeek;
638             this.timeSystemCorrectionWeekNumber = timeSystemCorrectionWeekNumber;
639         }
640 
641         /**
642          * Getter for the time system correction type.
643          * @return the time system correction type
644          */
645         public String getTimeSystemCorrectionType() {
646             return timeSystemCorrectionType;
647         }
648 
649         /**
650          * Getter for the A0 coefficient of the time system correction.
651          * <p>
652          * deltaT = {@link #getTimeSystemCorrectionA0() A0} +
653          *          {@link #getTimeSystemCorrectionA1() A1} * (t - tref)
654          * </p>
655          * @return the A0 coefficient of the time system correction
656          */
657         public double getTimeSystemCorrectionA0() {
658             return timeSystemCorrectionA0;
659         }
660 
661         /**
662          * Getter for the A1 coefficient of the time system correction.
663          * <p>
664          * deltaT = {@link #getTimeSystemCorrectionA0() A0} +
665          *          {@link #getTimeSystemCorrectionA1() A1} * (t - tref)
666          * </p>
667          * @return the A1 coefficient of the time system correction
668          */
669         public double getTimeSystemCorrectionA1() {
670             return timeSystemCorrectionA1;
671         }
672 
673         /**
674          * Getter for the reference time of the time system correction polynomial.
675          * <p>
676          * Seconds into GNSS week
677          * </p>
678          * @return the reference time of the time system correction polynomial
679          */
680         public int getTimeSystemCorrectionSecOfWeek() {
681             return timeSystemCorrectionSecOfWeek;
682         }
683 
684         /**
685          * Getter for the reference week number of the time system correction polynomial.
686          * <p>
687          * Continuous number since the reference epoch of the corresponding GNSS constellation
688          * </p>
689          * @return the reference week number of the time system correction polynomial
690          */
691         public int getTimeSystemCorrectionWeekNumber() {
692             return timeSystemCorrectionWeekNumber;
693         }
694 
695     }
696 
697 }