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