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 SPACE = " ";
96
97
98 private static final String EMPTY_STRING = "";
99
100
101 private static final String FORMAT = "CPF";
102
103
104 private static final Locale STANDARDIZED_LOCALE = Locale.US;
105
106
107 private static final int DEFAULT_DIRECTION_FLAG = 0;
108
109
110 private final Appendable writer;
111
112
113 private final TimeScale timeScale;
114
115
116 private final CPFHeader header;
117
118
119
120
121
122
123
124
125 public StreamingCpfWriter(final Appendable writer,
126 final TimeScale timeScale,
127 final CPFHeader header) {
128
129 this.writer = writer;
130 this.timeScale = timeScale;
131 this.header = header;
132 }
133
134
135
136
137
138 public void writeHeader() throws IOException {
139
140
141 HeaderLineWriter.H1.write(header, writer, timeScale);
142 writer.append(NEW_LINE);
143
144
145 HeaderLineWriter.H2.write(header, writer, timeScale);
146 writer.append(NEW_LINE);
147
148
149 writer.append("H9");
150 writer.append(NEW_LINE);
151
152 }
153
154
155
156
157
158 public void writeEndOfFile() throws IOException {
159 writer.append("99");
160 }
161
162
163
164
165
166
167
168
169
170 public Segment newSegment(final Frame frame) {
171 return new Segment(frame);
172 }
173
174
175
176
177
178
179
180
181
182 private static void writeValue(final Appendable cpfWriter, final String format,
183 final String value, final boolean withSpace)
184 throws IOException {
185 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
186 }
187
188
189
190
191
192
193
194
195
196 private static void writeValue(final Appendable cpfWriter, final String format,
197 final int value, final boolean withSpace)
198 throws IOException {
199 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
200 }
201
202
203
204
205
206
207
208
209
210 private static void writeValue(final Appendable cpfWriter, final String format,
211 final double value, final boolean withSpace)
212 throws IOException {
213 cpfWriter.append(String.format(STANDARDIZED_LOCALE, format, value)).append(withSpace ? SPACE : EMPTY_STRING);
214 }
215
216
217
218
219
220
221
222
223
224 private static void writeValue(final Appendable cpfWriter, final String format,
225 final boolean value, final boolean withSpace)
226 throws IOException {
227
228 final int intValue = value ? 1 : 0;
229 writeValue(cpfWriter, format, intValue, withSpace);
230 }
231
232
233 public class Segment implements OrekitFixedStepHandler {
234
235
236 private final Frame frame;
237
238
239
240
241
242
243
244 private Segment(final Frame frame) {
245 this.frame = frame;
246 }
247
248
249 @Override
250 public void handleStep(final SpacecraftState currentState) {
251 try {
252
253
254 writeEphemerisLine(currentState.getPVCoordinates(frame));
255
256 } catch (IOException e) {
257 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
258 e.getLocalizedMessage());
259 }
260
261 }
262
263
264 @Override
265 public void finish(final SpacecraftState finalState) {
266 try {
267
268 writeEphemerisLine(finalState.getPVCoordinates(frame));
269
270
271 writeEndOfFile();
272
273 } catch (IOException e) {
274 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE,
275 e.getLocalizedMessage());
276 }
277
278 }
279
280
281
282
283
284
285
286
287 public void writeEphemerisLine(final TimeStampedPVCoordinates pv)
288 throws IOException {
289
290
291 writeValue(writer, A2, "10", true);
292 writeValue(writer, I1, DEFAULT_DIRECTION_FLAG, true);
293
294
295 final AbsoluteDate epoch = pv.getDate();
296 final DateTimeComponents dtc = epoch.getComponents(timeScale);
297 writeValue(writer, I5, dtc.getDate().getMJD(), true);
298 writeValue(writer, F13_6, dtc.getTime().getSecondsInLocalDay(), true);
299
300
301 writeValue(writer, I2, 0, true);
302
303
304 final Vector3D position = pv.getPosition();
305 writeValue(writer, F17_3, position.getX(), true);
306 writeValue(writer, F17_3, position.getY(), true);
307 writeValue(writer, F17_3, position.getZ(), false);
308
309
310 writer.append(NEW_LINE);
311
312 }
313
314 }
315
316
317 public enum HeaderLineWriter {
318
319
320 H1("H1") {
321
322
323 @Override
324 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
325 throws IOException {
326
327
328 writeValue(cpfWriter, A2, getIdentifier(), true);
329 writeValue(cpfWriter, A3, FORMAT, true);
330 writeValue(cpfWriter, I2, cpfHeader.getVersion(), true);
331 writeValue(cpfWriter, A1, SPACE, false);
332 writeValue(cpfWriter, A3, cpfHeader.getSource(), true);
333 writeValue(cpfWriter, I4, cpfHeader.getProductionEpoch().getYear(), true);
334 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getMonth(), true);
335 writeValue(cpfWriter, I2, cpfHeader.getProductionEpoch().getDay(), true);
336 writeValue(cpfWriter, I2, cpfHeader.getProductionHour(), true);
337 writeValue(cpfWriter, A1, SPACE, false);
338 writeValue(cpfWriter, I3, cpfHeader.getSequenceNumber(), true);
339
340
341 if (cpfHeader.getVersion() == 2) {
342 writeValue(cpfWriter, I2, cpfHeader.getSubDailySequenceNumber(), true);
343 }
344
345
346 writeValue(cpfWriter, A10, cpfHeader.getName(), true);
347
348
349 writeValue(cpfWriter, A10, SPACE, false);
350 }
351
352 },
353
354
355 H2("H2") {
356
357
358 @Override
359 public void write(final CPFHeader cpfHeader, final Appendable cpfWriter, final TimeScale timescale)
360 throws IOException {
361
362
363 writeValue(cpfWriter, A2, getIdentifier(), true);
364 writeValue(cpfWriter, A8, cpfHeader.getIlrsSatelliteId(), true);
365 writeValue(cpfWriter, A4, cpfHeader.getSic(), true);
366 writeValue(cpfWriter, A8, cpfHeader.getNoradId(), true);
367
368
369 final AbsoluteDate starting = cpfHeader.getStartEpoch();
370 final DateTimeComponents dtcStart = starting.getComponents(timescale);
371 writeValue(cpfWriter, I4, dtcStart.getDate().getYear(), true);
372 writeValue(cpfWriter, I2, dtcStart.getDate().getMonth(), true);
373 writeValue(cpfWriter, I2, dtcStart.getDate().getDay(), true);
374 writeValue(cpfWriter, I2, dtcStart.getTime().getHour(), true);
375 writeValue(cpfWriter, I2, dtcStart.getTime().getMinute(), true);
376 writeValue(cpfWriter, I2, (int) dtcStart.getTime().getSecond(), true);
377
378
379 final AbsoluteDate ending = cpfHeader.getEndEpoch();
380 final DateTimeComponents dtcEnd = ending.getComponents(timescale);
381 writeValue(cpfWriter, I4, dtcEnd.getDate().getYear(), true);
382 writeValue(cpfWriter, I2, dtcEnd.getDate().getMonth(), true);
383 writeValue(cpfWriter, I2, dtcEnd.getDate().getDay(), true);
384 writeValue(cpfWriter, I2, dtcEnd.getTime().getHour(), true);
385 writeValue(cpfWriter, I2, dtcEnd.getTime().getMinute(), true);
386 writeValue(cpfWriter, I2, (int) dtcEnd.getTime().getSecond(), true);
387
388
389 writeValue(cpfWriter, I5, cpfHeader.getStep(), true);
390 writeValue(cpfWriter, I1, cpfHeader.isCompatibleWithTIVs(), true);
391 writeValue(cpfWriter, I1, cpfHeader.getTargetClass(), true);
392 writeValue(cpfWriter, I2, cpfHeader.getRefFrameId(), true);
393 writeValue(cpfWriter, I1, cpfHeader.getRotationalAngleType(), true);
394 if (cpfHeader.getVersion() == 1) {
395 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), false);
396 } else {
397 writeValue(cpfWriter, I1, cpfHeader.isCenterOfMassCorrectionApplied(), true);
398 writeValue(cpfWriter, I2, cpfHeader.getTargetLocation(), false);
399 }
400
401 }
402
403 };
404
405
406 private final String identifier;
407
408
409
410
411 HeaderLineWriter(final String identifier) {
412 this.identifier = identifier;
413 }
414
415
416
417
418
419
420
421
422
423 public abstract void write(CPFHeader cpfHeader, Appendable cpfWriter, TimeScale timescale) throws IOException;
424
425
426
427
428
429 public String getIdentifier() {
430 return identifier;
431 }
432
433 }
434
435 }