1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.gravity.potential;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.nio.charset.StandardCharsets;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29
30 import org.hipparchus.util.FastMath;
31 import org.orekit.data.DataLoader;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitMessages;
34
35
36
37
38
39
40 public class AstronomicalAmplitudeReader implements DataLoader {
41
42
43 private static final String OPTIONAL_FIELD_PATTERN = "\\S*";
44
45
46 private static final String DOODSON_TYPE_PATTERN = "\\p{Digit}{2,3}[.,]\\p{Digit}{3}";
47
48
49 private static final String REAL_TYPE_PATTERN =
50 "[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?";
51
52
53 private static final Pattern PATTERN = Pattern.compile("[.,]");
54
55
56 private final String supportedNames;
57
58
59 private final Pattern regularLinePattern;
60
61
62 private final int columnDoodson;
63
64
65 private final int columnHf;
66
67
68 private final double scale;
69
70
71 private final Map<Integer, Double> amplitudesMap;
72
73
74
75
76
77
78
79
80 public AstronomicalAmplitudeReader(final String supportedNames, final int columns,
81 final int columnDoodson, final int columnHf,
82 final double scale) {
83
84
85 final StringBuilder builder = new StringBuilder("^\\p{Space}*");
86 for (int i = 1; i <= columns; ++i) {
87 builder.append("(");
88 if (i == columnDoodson) {
89 builder.append(DOODSON_TYPE_PATTERN);
90 } else if (i == columnHf) {
91 builder.append(REAL_TYPE_PATTERN);
92 } else {
93 builder.append(OPTIONAL_FIELD_PATTERN);
94 }
95 builder.append(")");
96 builder.append(i < FastMath.max(columnDoodson, columnHf) ? "\\p{Space}+" : "\\p{Space}*");
97 }
98 builder.append('$');
99 this.regularLinePattern = Pattern.compile(builder.toString());
100
101 this.supportedNames = supportedNames;
102 this.columnDoodson = columnDoodson;
103 this.columnHf = columnHf;
104 this.scale = scale;
105
106 this.amplitudesMap = new HashMap<>();
107
108 }
109
110
111
112
113 public String getSupportedNames() {
114 return supportedNames;
115 }
116
117
118 @Override
119 public boolean stillAcceptsData() {
120 return amplitudesMap.isEmpty();
121 }
122
123
124 @Override
125 public void loadData(final InputStream input, final String name)
126 throws IOException {
127
128 int lineNumber = 0;
129 String line = null;
130
131 try (BufferedReader r = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
132
133 for (line = r.readLine(); line != null; line = r.readLine()) {
134 ++lineNumber;
135
136
137
138 line = line.replace('\u2212', '-');
139
140 final Matcher regularMatcher = regularLinePattern.matcher(line);
141 if (regularMatcher.matches()) {
142
143 final int doodson = Integer.parseInt(PATTERN.matcher(regularMatcher.group(columnDoodson)).replaceAll(""));
144 final double hf = scale * Double.parseDouble(regularMatcher.group(columnHf));
145 amplitudesMap.put(doodson, hf);
146 }
147 }
148
149 } catch (NumberFormatException nfe) {
150 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
151 lineNumber, name, line);
152 }
153
154 if (amplitudesMap.isEmpty()) {
155 throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, name);
156 }
157
158 }
159
160
161
162
163
164 public Map<Integer, Double> getAstronomicalAmplitudesMap() {
165 return Collections.unmodifiableMap(amplitudesMap);
166 }
167
168 }