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 org.hipparchus.util.FastMath;
20 import org.hipparchus.util.Precision;
21 import org.orekit.errors.OrekitException;
22 import org.orekit.errors.OrekitMessages;
23 import org.orekit.utils.Constants;
24
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.nio.charset.StandardCharsets;
30 import java.text.ParseException;
31 import java.util.Locale;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39
40
41
42 public class EGMFormatReader extends PotentialCoefficientsReader {
43
44
45 private static final Pattern SEPARATOR = Pattern.compile("\\s+");
46
47
48 private static final int START_DEGREE_ORDER = 120;
49
50
51 private final boolean useWgs84Coefficients;
52
53
54
55
56
57 public EGMFormatReader(final String supportedNames, final boolean missingCoefficientsAllowed) {
58 this(supportedNames, missingCoefficientsAllowed, false);
59 }
60
61
62
63
64
65
66
67
68
69
70 public EGMFormatReader(final String supportedNames, final boolean missingCoefficientsAllowed,
71 final boolean useWgs84Coefficients) {
72 super(supportedNames, missingCoefficientsAllowed, null);
73 this.useWgs84Coefficients = useWgs84Coefficients;
74 }
75
76
77
78 public void loadData(final InputStream input, final String name)
79 throws IOException, ParseException, OrekitException {
80
81
82 setReadComplete(false);
83
84
85
86
87
88 if (this.useWgs84Coefficients) {
89 setAe(Constants.WGS84_EARTH_EQUATORIAL_RADIUS);
90 setMu(Constants.WGS84_EARTH_MU);
91 } else {
92 setAe(Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
93 setMu(Constants.EGM96_EARTH_MU);
94 }
95
96 final String lowerCaseName = name.toLowerCase(Locale.US);
97 if (lowerCaseName.contains("2008") || lowerCaseName.contains("zerotide")) {
98 setTideSystem(TideSystem.ZERO_TIDE);
99 } else {
100 setTideSystem(TideSystem.TIDE_FREE);
101 }
102
103 TemporaryCoefficientsContainer container = new TemporaryCoefficientsContainer(START_DEGREE_ORDER, START_DEGREE_ORDER,
104 missingCoefficientsAllowed() ? 0.0 : Double.NaN);
105 boolean okFields = true;
106 int maxDegree = -1;
107 int maxOrder = -1;
108 int lineNumber = 0;
109 String line = null;
110 try (BufferedReader r = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
111 for (line = r.readLine(); okFields && line != null; line = r.readLine()) {
112 lineNumber++;
113 if (line.length() >= 15) {
114
115
116 final String[] tab = SEPARATOR.split(line.trim());
117 if (tab.length != 6) {
118 okFields = false;
119 }
120
121 final int i = Integer.parseInt(tab[0]);
122 final int j = Integer.parseInt(tab[1]);
123 if (i < 0 || j < 0) {
124 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
125 lineNumber, name, line);
126 }
127
128 if (i <= getMaxParseDegree() && j <= getMaxParseOrder()) {
129
130 while (!container.getFlattener().withinRange(i, j)) {
131
132 container = container.resize(container.getFlattener().getDegree() * 2,
133 container.getFlattener().getOrder() * 2);
134 }
135
136 parseCoefficient(tab[2], container.getFlattener(), container.getC(), i, j, "C", name);
137 parseCoefficient(tab[3], container.getFlattener(), container.getS(), i, j, "S", name);
138 maxDegree = FastMath.max(maxDegree, i);
139 maxOrder = FastMath.max(maxOrder, j);
140
141 }
142
143 }
144 }
145 } catch (NumberFormatException nfe) {
146 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
147 lineNumber, name, line);
148 }
149
150 if (missingCoefficientsAllowed() && getMaxParseDegree() > 0 && getMaxParseOrder() > 0) {
151
152 if (Precision.equals(container.getC()[container.getFlattener().index(0, 0)], 0.0, 0)) {
153 container.getC()[container.getFlattener().index(0, 0)] = 1.0;
154 }
155 }
156
157 if (!(okFields && maxDegree >= 0)) {
158 String loaderName = getClass().getName();
159 loaderName = loaderName.substring(loaderName.lastIndexOf('.') + 1);
160 throw new OrekitException(OrekitMessages.UNEXPECTED_FILE_FORMAT_ERROR_FOR_LOADER,
161 name, loaderName);
162 }
163
164 container = container.resize(maxDegree, maxOrder);
165 setRawCoefficients(true, container.getFlattener(), container.getC(), container.getS(), name);
166 setReadComplete(true);
167
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182 public RawSphericalHarmonicsProvider getProvider(final boolean wantNormalized,
183 final int degree, final int order) {
184 return getBaseProvider(wantNormalized, degree, order);
185 }
186 }