1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.rinex.navigation.parsers;
18
19 import org.hipparchus.util.FastMath;
20 import org.orekit.errors.OrekitException;
21 import org.orekit.errors.OrekitMessages;
22 import org.orekit.files.rinex.navigation.EarthOrientationParameterMessage;
23 import org.orekit.files.rinex.navigation.IonosphereBDGIMMessage;
24 import org.orekit.files.rinex.navigation.IonosphereGlonassCdmsMessage;
25 import org.orekit.files.rinex.navigation.IonosphereKlobucharMessage;
26 import org.orekit.files.rinex.navigation.IonosphereNavICKlobucharMessage;
27 import org.orekit.files.rinex.navigation.IonosphereNavICNeQuickNMessage;
28 import org.orekit.files.rinex.navigation.IonosphereNequickGMessage;
29 import org.orekit.files.rinex.navigation.IonosphericCorrectionType;
30 import org.orekit.files.rinex.navigation.KlobucharIonosphericCorrection;
31 import org.orekit.files.rinex.navigation.NeQuickGIonosphericCorrection;
32 import org.orekit.files.rinex.navigation.RecordType;
33 import org.orekit.files.rinex.navigation.RinexNavigation;
34 import org.orekit.files.rinex.navigation.RinexNavigationHeader;
35 import org.orekit.files.rinex.navigation.SystemTimeOffsetMessage;
36 import org.orekit.files.rinex.navigation.parsers.ephemeris.BeidouCnv123Parser;
37 import org.orekit.files.rinex.navigation.parsers.ephemeris.BeidouD1D2Parser;
38 import org.orekit.files.rinex.navigation.parsers.ephemeris.GPSCnavParser;
39 import org.orekit.files.rinex.navigation.parsers.ephemeris.GPSLnavParser;
40 import org.orekit.files.rinex.navigation.parsers.ephemeris.GalileoParser;
41 import org.orekit.files.rinex.navigation.parsers.ephemeris.GlonassCdmaParser;
42 import org.orekit.files.rinex.navigation.parsers.ephemeris.GlonassFdmaParser;
43 import org.orekit.files.rinex.navigation.parsers.ephemeris.NavICL1NvParser;
44 import org.orekit.files.rinex.navigation.parsers.ephemeris.NavICLnavParser;
45 import org.orekit.files.rinex.navigation.parsers.ephemeris.QzssCnavParser;
46 import org.orekit.files.rinex.navigation.parsers.ephemeris.QzssLnavParser;
47 import org.orekit.files.rinex.navigation.parsers.ephemeris.SbasParser;
48 import org.orekit.files.rinex.navigation.parsers.ionosphere.BdgimParser;
49 import org.orekit.files.rinex.navigation.parsers.ionosphere.GlonassCdmsGParser;
50 import org.orekit.files.rinex.navigation.parsers.ionosphere.KlobucharParser;
51 import org.orekit.files.rinex.navigation.parsers.ionosphere.NavICKlobucharParser;
52 import org.orekit.files.rinex.navigation.parsers.ionosphere.NavICNeQuickNParser;
53 import org.orekit.files.rinex.navigation.parsers.ionosphere.NeQuickGParser;
54 import org.orekit.files.rinex.utils.ParsingUtils;
55 import org.orekit.gnss.PredefinedGnssSignal;
56 import org.orekit.gnss.SatelliteSystem;
57 import org.orekit.propagation.analytical.gnss.data.BeidouCivilianNavigationMessage;
58 import org.orekit.propagation.analytical.gnss.data.BeidouLegacyNavigationMessage;
59 import org.orekit.propagation.analytical.gnss.data.GLONASSFdmaNavigationMessage;
60 import org.orekit.propagation.analytical.gnss.data.GPSCivilianNavigationMessage;
61 import org.orekit.propagation.analytical.gnss.data.GPSLegacyNavigationMessage;
62 import org.orekit.propagation.analytical.gnss.data.GalileoNavigationMessage;
63 import org.orekit.propagation.analytical.gnss.data.NavICL1NvNavigationMessage;
64 import org.orekit.propagation.analytical.gnss.data.NavICLegacyNavigationMessage;
65 import org.orekit.propagation.analytical.gnss.data.QZSSCivilianNavigationMessage;
66 import org.orekit.propagation.analytical.gnss.data.QZSSLegacyNavigationMessage;
67 import org.orekit.propagation.analytical.gnss.data.SBASNavigationMessage;
68 import org.orekit.time.AbsoluteDate;
69 import org.orekit.time.TimeScale;
70 import org.orekit.time.TimeScales;
71 import org.orekit.utils.units.Unit;
72
73
74
75
76
77
78 public class ParseInfo {
79
80
81 private static final int INDEX_1 = 0;
82
83
84 private static final int INDEX_2 = 19;
85
86
87 private static final int INDEX_3 = 38;
88
89
90 private static final int INDEX_4 = 57;
91
92
93 private static final int LENGTH = 19;
94
95
96 private final String name;
97
98
99 private final TimeScales timeScales;
100
101
102 private final RinexNavigation file;
103
104
105 private int initialSpaces;
106
107
108 private boolean headerParsed;
109
110
111 private IonosphericCorrectionType ionosphericCorrectionType;
112
113
114 private char timeMark;
115
116
117 private double[] klobucharAlpha;
118
119
120 private double[] klobucharBeta;
121
122
123 private RecordLineParser recordLineParser;
124
125
126 private String line;
127
128
129 private int lineNumber;
130
131
132 private int recordLineNumber;
133
134
135
136
137
138 public ParseInfo(final String name, final TimeScales timeScales) {
139
140 this.name = name;
141 this.timeScales = timeScales;
142 this.file = new RinexNavigation();
143
144
145 this.file.getHeader().setProgramName(null);
146 this.file.getHeader().setRunByName(null);
147 this.file.getHeader().setCreationDateComponents(null);
148
149 }
150
151
152
153
154
155
156 public AbsoluteDate parseDate(final SatelliteSystem system) {
157 return parseDate(system.getObservationTimeScale().getTimeScale(timeScales));
158 }
159
160
161
162
163
164
165 public AbsoluteDate parseDate(final TimeScale timeScale) {
166 final int year = ParsingUtils.parseInt(line, 4, 4);
167 final int month = ParsingUtils.parseInt(line, 9, 2);
168 final int day = ParsingUtils.parseInt(line, 12, 2);
169 final int hours = ParsingUtils.parseInt(line, 15, 2);
170 final int min = ParsingUtils.parseInt(line, 18, 2);
171 final int sec = ParsingUtils.parseInt(line, 21, 2);
172 return new AbsoluteDate(year, month, day, hours, min, sec, timeScale);
173 }
174
175
176
177
178
179
180 public double parseDouble1(final Unit unit) {
181 return parseDouble(unit, initialSpaces + INDEX_1);
182 }
183
184
185
186
187
188 public int parseInt1() {
189 return parseInt(initialSpaces + INDEX_1);
190 }
191
192
193
194
195
196
197 public double parseDouble2(final Unit unit) {
198 return parseDouble(unit, initialSpaces + INDEX_2);
199 }
200
201
202
203
204
205 public int parseInt2() {
206 return parseInt(initialSpaces + INDEX_2);
207 }
208
209
210
211
212
213
214 public double parseDouble3(final Unit unit) {
215 return parseDouble(unit, initialSpaces + INDEX_3);
216 }
217
218
219
220
221
222 public int parseInt3() {
223 return parseInt(initialSpaces + INDEX_3);
224 }
225
226
227
228
229
230
231 public double parseDouble4(final Unit unit) {
232 return parseDouble(unit, initialSpaces + INDEX_4);
233 }
234
235
236
237
238
239 public int parseInt4() {
240 return parseInt(initialSpaces + INDEX_4);
241 }
242
243
244
245
246
247 private double rawDouble(final int index) {
248 return ParsingUtils.parseDouble(line, index, LENGTH);
249 }
250
251
252
253
254
255
256 private double parseDouble(final Unit unit, final int index) {
257 return unit.toSI(rawDouble(index));
258 }
259
260
261
262
263
264 private int parseInt(final int index) {
265 return (int) FastMath.rint(rawDouble(index));
266 }
267
268
269
270 public void parseComment() {
271 ParsingUtils.parseComment(lineNumber, line, file);
272 }
273
274
275
276 public void closePendingRecord() {
277 if (recordLineParser != null) {
278 recordLineParser.closeRecord(file);
279 recordLineParser = null;
280 }
281 }
282
283
284
285
286 public String getName() {
287 return name;
288 }
289
290
291
292
293 public TimeScales getTimeScales() {
294 return timeScales;
295 }
296
297
298
299
300 public RinexNavigation getCompletedFile() {
301
302
303 if (!headerParsed) {
304 throw new OrekitException(OrekitMessages.UNEXPECTED_END_OF_FILE, name);
305 }
306
307
308 closePendingRecord();
309
310 return file;
311
312 }
313
314
315
316
317 public RinexNavigationHeader getHeader() {
318 return file.getHeader();
319 }
320
321
322
323
324 public void setHeaderParsed(final boolean headerParsed) {
325 this.headerParsed = headerParsed;
326 }
327
328
329
330
331 public void setInitialSpaces(final int initialSpaces) {
332 this.initialSpaces = initialSpaces;
333 }
334
335
336
337
338 public String getLine() {
339 return line;
340 }
341
342
343
344
345 public void setLine(final String line) {
346 this.line = line;
347 ++lineNumber;
348 }
349
350
351
352
353 public int getLineNumber() {
354 return lineNumber;
355 }
356
357
358
359
360 public int getRecordLineNumber() {
361 return recordLineNumber;
362 }
363
364
365
366
367 public void setRecordLineParser(final RecordType recordType) {
368 final SatelliteSystem system = SatelliteSystem.parseSatelliteSystem(ParsingUtils.parseString(line, 6, 1));
369 final int prn = ParsingUtils.parseInt(line, 7, 2);
370 final String type = ParsingUtils.parseString(line, 10, 4);
371 final String subtype = ParsingUtils.parseString(line, 15, 4);
372 setRecordLineParser(recordType, system, prn, type, subtype);
373 }
374
375
376
377
378
379
380
381
382 public void setRecordLineParser(final RecordType recordType,
383 final SatelliteSystem system, final int prn,
384 final String messageType, final String subType) {
385
386
387 recordLineNumber = 0;
388
389 closePendingRecord();
390
391 recordLineParser = null;
392 switch (recordType) {
393 case STO:
394 recordLineParser = buildStoRecordLineParser(system, prn, messageType, subType);
395 break;
396 case EOP:
397 recordLineParser = buildEopRecordLineParser(system, prn, messageType, subType);
398 break;
399 case ION:
400 recordLineParser = buildIonRecordLineParser(system, prn, messageType, subType);
401 break;
402 case ORBIT :
403 recordLineParser = buildEphRecordLineParser(system, messageType);
404 break;
405 default :
406
407 }
408
409 if (recordLineParser == null) {
410 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
411 lineNumber, name, line);
412 }
413
414 }
415
416
417
418
419
420
421
422
423 private RecordLineParser buildStoRecordLineParser(final SatelliteSystem system, final int prn,
424 final String messageType, final String subType) {
425 return new SystemTimeOffsetParser(this, new SystemTimeOffsetMessage(system, prn,
426 messageType, subType));
427 }
428
429
430
431
432
433
434
435
436 private RecordLineParser buildEopRecordLineParser(final SatelliteSystem system, final int prn,
437 final String messageType, final String subType) {
438 return new EarthOrientationParameterParser(this, new EarthOrientationParameterMessage(system, prn,
439 messageType, subType));
440 }
441
442
443
444
445
446
447
448
449 private RecordLineParser buildIonRecordLineParser(final SatelliteSystem system, final int prn,
450 final String messageType, final String subType) {
451 if (system == SatelliteSystem.GALILEO) {
452 return new NeQuickGParser(this, new IonosphereNequickGMessage(system, prn, messageType, subType));
453 } else if (system == SatelliteSystem.BEIDOU && "CNVX".equals(messageType)) {
454
455
456
457 return new BdgimParser(this, new IonosphereBDGIMMessage(system, prn, messageType, subType));
458 } else if (system == SatelliteSystem.NAVIC &&
459 NavICL1NvNavigationMessage.L1NV.equals(messageType) &&
460 "KLOB".equals(subType)) {
461 return new NavICKlobucharParser(this, new IonosphereNavICKlobucharMessage(system, prn, messageType, subType));
462 } else if (system == SatelliteSystem.NAVIC &&
463 NavICL1NvNavigationMessage.L1NV.equals(messageType) &&
464 "NEQN".equals(subType)) {
465 return new NavICNeQuickNParser(this, new IonosphereNavICNeQuickNMessage(system, prn, messageType, subType));
466 } else if (system == SatelliteSystem.GLONASS) {
467 return new GlonassCdmsGParser(this, new IonosphereGlonassCdmsMessage(system, prn, messageType, subType));
468 } else {
469 return new KlobucharParser(this, new IonosphereKlobucharMessage(system, prn, messageType, subType));
470 }
471 }
472
473
474
475
476
477
478 private RecordLineParser buildEphRecordLineParser(final SatelliteSystem system, final String messageType) {
479 switch (system) {
480 case GPS:
481 if (messageType == null || messageType.equals(GPSLegacyNavigationMessage.LNAV)) {
482
483 return new GPSLnavParser(this,
484 new GPSLegacyNavigationMessage(timeScales,
485 SatelliteSystem.GPS,
486 GPSLegacyNavigationMessage.LNAV));
487 } else if (messageType.equals(GPSCivilianNavigationMessage.CNAV)) {
488
489 return new GPSCnavParser(this,
490 new GPSCivilianNavigationMessage(false,
491 timeScales,
492 SatelliteSystem.GPS,
493 GPSCivilianNavigationMessage.CNAV));
494 } else if (messageType.equals(GPSCivilianNavigationMessage.CNV2)) {
495
496 return new GPSCnavParser(this,
497 new GPSCivilianNavigationMessage(true,
498 timeScales,
499 SatelliteSystem.GPS,
500 GPSCivilianNavigationMessage.CNV2));
501 }
502 break;
503 case GALILEO:
504 if (messageType == null || messageType.equals(GalileoNavigationMessage.INAV) || messageType.equals(
505 GalileoNavigationMessage.FNAV)) {
506
507 return new GalileoParser(this, new GalileoNavigationMessage(timeScales,
508 SatelliteSystem.GPS,
509 messageType));
510 }
511 break;
512 case GLONASS:
513 if (messageType == null || messageType.equals("FDMA")) {
514 return new GlonassFdmaParser(this, new GLONASSFdmaNavigationMessage());
515 } else if (messageType.equals("L1OC") || messageType.equals("L3OC")) {
516 return new GlonassCdmaParser(this);
517 }
518 break;
519 case QZSS:
520 if (messageType == null || messageType.equals(QZSSLegacyNavigationMessage.LNAV)) {
521
522 return new QzssLnavParser(this,
523 new QZSSLegacyNavigationMessage(timeScales,
524 SatelliteSystem.GPS,
525 QZSSLegacyNavigationMessage.LNAV));
526 } else if (messageType.equals(QZSSCivilianNavigationMessage.CNAV)) {
527
528 return new QzssCnavParser(this,
529 new QZSSCivilianNavigationMessage(false,
530 timeScales,
531 SatelliteSystem.GPS,
532 QZSSCivilianNavigationMessage.CNAV));
533 } else if (messageType.equals(QZSSCivilianNavigationMessage.CNV2)) {
534
535 return new QzssCnavParser(this,
536 new QZSSCivilianNavigationMessage(true,
537 timeScales,
538 SatelliteSystem.GPS,
539 QZSSCivilianNavigationMessage.CNV2));
540 }
541 break;
542 case BEIDOU:
543 if (messageType == null || messageType.equals(BeidouLegacyNavigationMessage.D1) || messageType.equals(
544 BeidouLegacyNavigationMessage.D2)) {
545
546 return new BeidouD1D2Parser(this,
547 new BeidouLegacyNavigationMessage(timeScales,
548 SatelliteSystem.BEIDOU,
549 messageType));
550 } else if (messageType.equals(BeidouCivilianNavigationMessage.CNV1)) {
551
552 return new BeidouCnv123Parser(this,
553 new BeidouCivilianNavigationMessage(PredefinedGnssSignal.B1C,
554 timeScales,
555 SatelliteSystem.BEIDOU,
556 BeidouCivilianNavigationMessage.CNV1));
557 } else if (messageType.equals(BeidouCivilianNavigationMessage.CNV2)) {
558
559 return new BeidouCnv123Parser(this,
560 new BeidouCivilianNavigationMessage(PredefinedGnssSignal.B2A,
561 timeScales,
562 SatelliteSystem.BEIDOU,
563 BeidouCivilianNavigationMessage.CNV2));
564 } else if (messageType.equals(BeidouCivilianNavigationMessage.CNV3)) {
565
566 return new BeidouCnv123Parser(this,
567 new BeidouCivilianNavigationMessage(PredefinedGnssSignal.B2B,
568 timeScales,
569 SatelliteSystem.BEIDOU,
570 BeidouCivilianNavigationMessage.CNV3));
571 }
572 break;
573 case NAVIC:
574 if (messageType == null || messageType.equals(NavICLegacyNavigationMessage.LNAV)) {
575
576 return new NavICLnavParser(this,
577 new NavICLegacyNavigationMessage(timeScales,
578 SatelliteSystem.GPS,
579 NavICLegacyNavigationMessage.LNAV));
580 } else if (messageType.equals(NavICL1NvNavigationMessage.L1NV)) {
581
582 return new NavICL1NvParser(this,
583 new NavICL1NvNavigationMessage(timeScales,
584 SatelliteSystem.GPS,
585 NavICL1NvNavigationMessage.L1NV));
586 }
587 break;
588 case SBAS:
589 if (messageType == null || messageType.equals("SBAS")) {
590 return new SbasParser(this, new SBASNavigationMessage());
591 }
592 break;
593 default:
594
595 }
596
597
598 return null;
599
600 }
601
602
603
604
605 public RecordLineParser getRecordLineParser() {
606 return recordLineParser;
607 }
608
609
610
611 public void parseRecordLine() {
612 switch (++recordLineNumber) {
613 case 1: recordLineParser.parseLine01();
614 break;
615 case 2: recordLineParser.parseLine02();
616 break;
617 case 3: recordLineParser.parseLine03();
618 break;
619 case 4: recordLineParser.parseLine04();
620 break;
621 case 5: recordLineParser.parseLine05();
622 break;
623 case 6: recordLineParser.parseLine06();
624 break;
625 case 7: recordLineParser.parseLine07();
626 break;
627 case 8: recordLineParser.parseLine08();
628 break;
629 case 9: recordLineParser.parseLine09();
630 break;
631 default:
632
633 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
634 lineNumber, name, line);
635 }
636 }
637
638
639
640
641
642
643 public void setIonosphericCorrectionType(final IonosphericCorrectionType ionosphericCorrectionType) {
644 this.ionosphericCorrectionType = ionosphericCorrectionType;
645 }
646
647
648
649
650
651
652 public void setTimeMark(final char timeMark) {
653 this.timeMark = timeMark;
654 }
655
656
657
658
659
660 public void setKlobucharAlpha(final double[] klobucharAlpha) {
661 this.klobucharAlpha = klobucharAlpha.clone();
662 setKlobucharIfComplete();
663 }
664
665
666
667
668
669 public void setKlobucharBeta(final double[] klobucharBeta) {
670 this.klobucharBeta = klobucharBeta.clone();
671 setKlobucharIfComplete();
672 }
673
674
675
676 private void setKlobucharIfComplete() {
677 if (klobucharAlpha != null && klobucharBeta != null) {
678 file.getHeader().addIonosphericCorrection(new KlobucharIonosphericCorrection(ionosphericCorrectionType,
679 timeMark,
680 klobucharAlpha,
681 klobucharBeta));
682 ionosphericCorrectionType = null;
683 timeMark = 0;
684 klobucharAlpha = null;
685 klobucharBeta = null;
686 }
687 }
688
689
690
691
692
693 public void setNeQuickAlpha(final double[] neQuickAlpha) {
694 file.getHeader().addIonosphericCorrection(new NeQuickGIonosphericCorrection(ionosphericCorrectionType,
695 timeMark,
696 neQuickAlpha));
697 ionosphericCorrectionType = null;
698 timeMark = 0;
699 }
700
701 }