1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ilrs;
18
19 import java.io.IOException;
20 import java.util.Locale;
21
22 import org.hipparchus.exception.LocalizedCoreFormats;
23 import org.hipparchus.geometry.euclidean.threed.Vector3D;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.frames.Frame;
26 import org.orekit.propagation.Propagator;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.propagation.sampling.OrekitFixedStepHandler;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.DateTimeComponents;
31 import org.orekit.time.TimeScale;
32 import org.orekit.utils.TimeStampedPVCoordinates;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class StreamingCpfWriter {
51
52
53 private static final String NEW_LINE = "\n";
54
55
56 private static final String A1 = "%1s";
57
58
59 private static final String A2 = "%2s";
60
61
62 private static final String A3 = "%3s";
63
64
65 private static final String A4 = "%4s";
66
67
68 private static final String A8 = "%8s";
69
70
71 private static final String A10 = "%10s";
72
73
74 private static final String I1 = "%1d";
75
76
77 private static final String I2 = "%2d";
78
79
80 private static final String I3 = "%3d";
81
82
83 private static final String I4 = "%4d";
84
85
86 private static final String I5 = "%5d";
87
88
89 private static final String F13_6 = "%13.6f";
90
91
92 private static final String F17_3 = "%17.3f";
93
94
95 private static final String F19_6 = "%19.6f";
96
97
98 private static final String SPACE = " ";
99
100
101 private static final String EMPTY_STRING = "";
102
103
104 private static final String FORMAT = "CPF";
105
106
107 private static final Locale STANDARDIZED_LOCALE = Locale.US;
108
109
110 private static final int DEFAULT_DIRECTION_FLAG = 0;
111
112
113 private final Appendable writer;
114
115
116 private final TimeScale timeScale;
117
118
119 private final CPFHeader header;
120
121
122 private final boolean velocityFlag;
123
124
125
126
127
128
129
130
131
132
133
134 public StreamingCpfWriter(final Appendable writer,
135 final TimeScale timeScale,
136 final CPFHeader header) {
137 this(writer, timeScale, header, false);
138 }
139
140
141
142
143
144
145
146
147
148
149 public StreamingCpfWriter(final Appendable writer,
150 final TimeScale timeScale,
151 final CPFHeader header,
152 final boolean velocityFlag) {
153 this.writer = writer;
154 this.timeScale = timeScale;
155 this.header = header;
156 this.velocityFlag = velocityFlag;
157 }
158
159
160
161
162
163 public void writeHeader() throws IOException {
164
165
166 HeaderLineWriter.H1.write(header, writer, timeScale);
167 writer.append(NEW_LINE);
168
169
170 HeaderLineWriter.H2.write(header, writer, timeScale);
171 writer.append(NEW_LINE);
172
173
174 writer.append("H9");
175 writer.append(NEW_LINE);
176
177 }
178
179
180
181
182
183 public void writeEndOfFile() throws IOException {
184 writer.append("99");
185 }
186
187
188
189
190
191
192
193
194
195 public Segment newSegment(final Frame frame) {
196 return new Segment(frame);
197 }
198
199
200
201
202
203
204
205
206
207 private static void writeValue(final Appendable cpfWriter, final String format,
208 final String value, final boolean withSpace)
209 throws IOException {
210 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
211 }
212
213
214
215
216
217
218
219
220
221 private static void writeValue(final Appendable cpfWriter, final String format,
222 final int value, final boolean withSpace)
223 throws IOException {
224 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
225 }
226
227
228
229
230
231
232
233
234
235 private static void writeValue(final Appendable cpfWriter, final String format,
236 final double value, final boolean withSpace)
237 throws IOException {
238 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
239 }
240
241
242
243
244
245
246
247
248
249 private static void writeValue(final Appendable cpfWriter, final String format,
250 final boolean value, final boolean withSpace)
251 throws IOException {
252
253 final int intValue = value ? 1 : 0;
254 writeValue(cpfWriter, format, intValue, withSpace);
255 }
256
257
258 public class Segment implements OrekitFixedStepHandler {
259
260
261 private final Frame frame;
262
263
264
265
266
267
268
269 private Segment(final Frame frame) {
270 this.frame = frame;
271 }
272
273
274 @Override
275 public void handleStep(final SpacecraftState currentState) {
276 try {
277
278
279 writeEphemerisLine(currentState.getPVCoordinates(frame));
280
281 } catch (IOException e) {
282 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
283 e.getLocalizedMessage());
284 }
285
286 }
287
288
289 @Override
290 public void finish(final SpacecraftState finalState) {
291 try {
292
293 writeEphemerisLine(finalState.getPVCoordinates(frame));
294
295
296 writeEndOfFile();
297
298 } catch (IOException e) {
299 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
300 e.getLocalizedMessage());
301 }
302
303 }
304
305
306
307
308
309
310
311
312
313
314
315 public void writeEphemerisLine(final TimeStampedPVCoordinates pv)
316 throws IOException {
317
318
319 writeValue(writer, A2, "10", true);
320 writeValue(writer, I1, DEFAULT_DIRECTION_FLAG, true);
321
322
323 final AbsoluteDate epoch = pv.getDate();
324 final DateTimeComponents dtc = epoch.getComponents(timeScale);
325 writeValue(writer, I5, dtc.getDate().getMJD(), true);
326 writeValue(writer, F13_6, dtc.getTime().getSecondsInLocalDay(), true);
327
328
329 writeValue(writer, I2, 0, true);
330
331
332 final Vector3D position = pv.getPosition();
333 writeValue(writer, F17_3, position.getX(), true);
334 writeValue(writer, F17_3, position.getY(), true);
335 writeValue(writer, F17_3, position.getZ(), false);
336
337
338 writer.append(NEW_LINE);
339
340
341 if (velocityFlag) {
342
343
344 writeValue(writer, A2, "20", true);
345 writeValue(writer, I1, DEFAULT_DIRECTION_FLAG, true);
346
347
348 final Vector3D velocity = pv.getVelocity();
349 writeValue(writer, F19_6, velocity.getX(), true);
350 writeValue(writer, F19_6, velocity.getY(), true);
351 writeValue(writer, F19_6, velocity.getZ(), false);
352
353
354 writer.append(NEW_LINE);
355
356 }
357
358 }
359
360 }
361
362
363 public enum HeaderLineWriter {
364
365
366 H1("H1") {
367
368
369 @Override
370 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
371 throws IOException {
372
373
374 writeValue(cpfWriter, A2, getIdentifier(), true);
375 writeValue(cpfWriter, A3, FORMAT, true);
376 writeValue(cpfWriter, I2, cpfHeader.getVersion(), true);
377 writeValue(cpfWriter, A1, SPACE, false);
378 writeValue(cpfWriter, A3, cpfHeader.getSource(), true);
379 writeValue(cpfWriter, I4, cpfHeader.getProductionEpoch().getYear(), true);
380 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getMonth(), true);
381 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getDay(), true);
382 writeValue(cpfWriter, I2, cpfHeader.getProductionHour(), true);
383 writeValue(cpfWriter, A1, SPACE, false);
384 writeValue(cpfWriter, I3, cpfHeader.getSequenceNumber(), true);
385
386
387 if (cpfHeader.getVersion() == 2) {
388 writeValue(cpfWriter, I2, cpfHeader.getSubDailySequenceNumber(), true);
389 }
390
391
392 writeValue(cpfWriter, A10, cpfHeader.getName(), true);
393
394
395 writeValue(cpfWriter, A10, SPACE, false);
396 }
397
398 },
399
400
401 H2("H2") {
402
403
404 @Override
405 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
406 throws IOException {
407
408
409 writeValue(cpfWriter, A2, getIdentifier(), true);
410 writeValue(cpfWriter, A8, cpfHeader.getIlrsSatelliteId(), true);
411 writeValue(cpfWriter, A4, cpfHeader.getSic(), true);
412 writeValue(cpfWriter, A8, cpfHeader.getNoradId(), true);
413
414
415 final AbsoluteDate starting = cpfHeader.getStartEpoch();
416 final DateTimeComponents dtcStart = starting.getComponents(timescale);
417 writeValue(cpfWriter, I4, dtcStart.getDate().getYear(), true);
418 writeValue(cpfWriter, I2, dtcStart.getDate().getMonth(), true);
419 writeValue(cpfWriter, I2, dtcStart.getDate().getDay(), true);
420 writeValue(cpfWriter, I2, dtcStart.getTime().getHour(), true);
421 writeValue(cpfWriter, I2, dtcStart.getTime().getMinute(), true);
422 writeValue(cpfWriter, I2, (int) dtcStart.getTime().getSecond(), true);
423
424
425 final AbsoluteDate ending = cpfHeader.getEndEpoch();
426 final DateTimeComponents dtcEnd = ending.getComponents(timescale);
427 writeValue(cpfWriter, I4, dtcEnd.getDate().getYear(), true);
428 writeValue(cpfWriter, I2, dtcEnd.getDate().getMonth(), true);
429 writeValue(cpfWriter, I2, dtcEnd.getDate().getDay(), true);
430 writeValue(cpfWriter, I2, dtcEnd.getTime().getHour(), true);
431 writeValue(cpfWriter, I2, dtcEnd.getTime().getMinute(), true);
432 writeValue(cpfWriter, I2, (int) dtcEnd.getTime().getSecond(), true);
433
434
435 writeValue(cpfWriter, I5, cpfHeader.getStep(), true);
436 writeValue(cpfWriter, I1, cpfHeader.isCompatibleWithTIVs(), true);
437 writeValue(cpfWriter, I1, cpfHeader.getTargetClass(), true);
438 writeValue(cpfWriter, I2, cpfHeader.getRefFrameId(), true);
439 writeValue(cpfWriter, I1, cpfHeader.getRotationalAngleType(), true);
440 if (cpfHeader.getVersion() == 1) {
441 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), false);
442 } else {
443 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), true);
444 writeValue(cpfWriter, I2, cpfHeader.getTargetLocation(), false);
445 }
446
447 }
448
449 };
450
451
452 private final String identifier;
453
454
455
456
457 HeaderLineWriter(final String identifier) {
458 this.identifier = identifier;
459 }
460
461
462
463
464
465
466
467
468
469 public abstract void write(CPFHeader cpfHeader, Appendable cpfWriter, TimeScale timescale) throws IOException;
470
471
472
473
474
475 public String getIdentifier() {
476 return identifier;
477 }
478
479 }
480
481 }