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 private Segment(final Frame frame) {
269 this.frame = frame;
270 }
271
272
273 @Override
274 public void handleStep(final SpacecraftState currentState) {
275 try {
276
277
278 writeEphemerisLine(currentState.getPVCoordinates(frame));
279
280 } catch (IOException e) {
281 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
282 e.getLocalizedMessage());
283 }
284
285 }
286
287
288 @Override
289 public void finish(final SpacecraftState finalState) {
290 try {
291
292 writeEphemerisLine(finalState.getPVCoordinates(frame));
293
294
295 writeEndOfFile();
296
297 } catch (IOException e) {
298 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
299 e.getLocalizedMessage());
300 }
301
302 }
303
304
305
306
307
308
309
310
311
312
313
314 public void writeEphemerisLine(final TimeStampedPVCoordinates pv)
315 throws IOException {
316
317
318 writeValue(writer, A2, "10", true);
319 writeValue(writer, I1, DEFAULT_DIRECTION_FLAG, true);
320
321
322 final AbsoluteDate epoch = pv.getDate();
323 final DateTimeComponents dtc = epoch.getComponents(timeScale).roundIfNeeded(60, 6);
324 writeValue(writer, I5, dtc.getDate().getMJD(), true);
325 writeValue(writer, F13_6, dtc.getTime().getSecondsInLocalDay(), true);
326
327
328 writeValue(writer, I2, 0, true);
329
330
331 final Vector3D position = pv.getPosition();
332 writeValue(writer, F17_3, position.getX(), true);
333 writeValue(writer, F17_3, position.getY(), true);
334 writeValue(writer, F17_3, position.getZ(), false);
335
336
337 writer.append(NEW_LINE);
338
339
340 if (velocityFlag) {
341
342
343 writeValue(writer, A2, "20", true);
344 writeValue(writer, I1, DEFAULT_DIRECTION_FLAG, true);
345
346
347 final Vector3D velocity = pv.getVelocity();
348 writeValue(writer, F19_6, velocity.getX(), true);
349 writeValue(writer, F19_6, velocity.getY(), true);
350 writeValue(writer, F19_6, velocity.getZ(), false);
351
352
353 writer.append(NEW_LINE);
354
355 }
356
357 }
358
359 }
360
361
362 public enum HeaderLineWriter {
363
364
365 H1("H1") {
366
367
368 @Override
369 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
370 throws IOException {
371
372
373 writeValue(cpfWriter, A2, getIdentifier(), true);
374 writeValue(cpfWriter, A3, FORMAT, true);
375 writeValue(cpfWriter, I2, cpfHeader.getVersion(), true);
376 writeValue(cpfWriter, A1, SPACE, false);
377 writeValue(cpfWriter, A3, cpfHeader.getSource(), true);
378 writeValue(cpfWriter, I4, cpfHeader.getProductionEpoch().getYear(), true);
379 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getMonth(), true);
380 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getDay(), true);
381 writeValue(cpfWriter, I2, cpfHeader.getProductionHour(), true);
382 writeValue(cpfWriter, A1, SPACE, false);
383 writeValue(cpfWriter, I3, cpfHeader.getSequenceNumber(), true);
384
385
386 if (cpfHeader.getVersion() == 2) {
387 writeValue(cpfWriter, I2, cpfHeader.getSubDailySequenceNumber(), true);
388 }
389
390
391 writeValue(cpfWriter, A10, cpfHeader.getName(), true);
392
393
394 writeValue(cpfWriter, A10, SPACE, false);
395 }
396
397 },
398
399
400 H2("H2") {
401
402
403 @Override
404 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
405 throws IOException {
406
407
408 writeValue(cpfWriter, A2, getIdentifier(), true);
409 writeValue(cpfWriter, A8, cpfHeader.getIlrsSatelliteId(), true);
410 writeValue(cpfWriter, A4, cpfHeader.getSic(), true);
411 writeValue(cpfWriter, A8, cpfHeader.getNoradId(), true);
412
413
414 final AbsoluteDate starting = cpfHeader.getStartEpoch();
415 final DateTimeComponents dtcStart = starting.getComponents(timescale);
416 writeValue(cpfWriter, I4, dtcStart.getDate().getYear(), true);
417 writeValue(cpfWriter, I2, dtcStart.getDate().getMonth(), true);
418 writeValue(cpfWriter, I2, dtcStart.getDate().getDay(), true);
419 writeValue(cpfWriter, I2, dtcStart.getTime().getHour(), true);
420 writeValue(cpfWriter, I2, dtcStart.getTime().getMinute(), true);
421 writeValue(cpfWriter, I2, (int) dtcStart.getTime().getSecond(), true);
422
423
424 final AbsoluteDate ending = cpfHeader.getEndEpoch();
425 final DateTimeComponents dtcEnd = ending.getComponents(timescale);
426 writeValue(cpfWriter, I4, dtcEnd.getDate().getYear(), true);
427 writeValue(cpfWriter, I2, dtcEnd.getDate().getMonth(), true);
428 writeValue(cpfWriter, I2, dtcEnd.getDate().getDay(), true);
429 writeValue(cpfWriter, I2, dtcEnd.getTime().getHour(), true);
430 writeValue(cpfWriter, I2, dtcEnd.getTime().getMinute(), true);
431 writeValue(cpfWriter, I2, (int) dtcEnd.getTime().getSecond(), true);
432
433
434 writeValue(cpfWriter, I5, cpfHeader.getStep(), true);
435 writeValue(cpfWriter, I1, cpfHeader.isCompatibleWithTIVs(), true);
436 writeValue(cpfWriter, I1, cpfHeader.getTargetClass(), true);
437 writeValue(cpfWriter, I2, cpfHeader.getRefFrameId(), true);
438 writeValue(cpfWriter, I1, cpfHeader.getRotationalAngleType(), true);
439 if (cpfHeader.getVersion() == 1) {
440 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), false);
441 } else {
442 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), true);
443 writeValue(cpfWriter, I2, cpfHeader.getTargetLocation(), false);
444 }
445
446 }
447
448 };
449
450
451 private final String identifier;
452
453
454
455
456 HeaderLineWriter(final String identifier) {
457 this.identifier = identifier;
458 }
459
460
461
462
463
464
465
466
467
468 public abstract void write(CPFHeader cpfHeader, Appendable cpfWriter, TimeScale timescale) throws IOException;
469
470
471
472
473
474 public String getIdentifier() {
475 return identifier;
476 }
477
478 }
479
480 }