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("zerotide")) {
98 setTideSystem(TideSystem.ZERO_TIDE);
99 } else if (lowerCaseName.contains("tidefree")) {
100 setTideSystem(TideSystem.TIDE_FREE);
101 } else if (lowerCaseName.contains("2008")) {
102 setTideSystem(TideSystem.ZERO_TIDE);
103 } else {
104 setTideSystem(TideSystem.TIDE_FREE);
105 }
106
107 TemporaryCoefficientsContainer container = new TemporaryCoefficientsContainer(START_DEGREE_ORDER, START_DEGREE_ORDER,
108 missingCoefficientsAllowed() ? 0.0 : Double.NaN);
109 boolean okFields = true;
110 int maxDegree = -1;
111 int maxOrder = -1;
112 int lineNumber = 0;
113 String line = null;
114 try (BufferedReader r = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
115 for (line = r.readLine(); okFields && line != null; line = r.readLine()) {
116 lineNumber++;
117 if (line.length() >= 15) {
118
119
120 final String[] tab = SEPARATOR.split(line.trim());
121 if (tab.length != 6) {
122 okFields = false;
123 }
124
125 final int i = Integer.parseInt(tab[0]);
126 final int j = Integer.parseInt(tab[1]);
127 if (i < 0 || j < 0) {
128 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
129 lineNumber, name, line);
130 }
131
132 if (i <= getMaxParseDegree() && j <= getMaxParseOrder()) {
133
134 while (!container.getFlattener().withinRange(i, j)) {
135
136 container = container.resize(container.getFlattener().getDegree() * 2,
137 container.getFlattener().getOrder() * 2);
138 }
139
140 parseCoefficient(tab[2], container.getFlattener(), container.getC(), i, j, "C", name);
141 parseCoefficient(tab[3], container.getFlattener(), container.getS(), i, j, "S", name);
142 maxDegree = FastMath.max(maxDegree, i);
143 maxOrder = FastMath.max(maxOrder, j);
144
145 }
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 (missingCoefficientsAllowed() && getMaxParseDegree() > 0 && getMaxParseOrder() > 0) {
155
156 if (Precision.equals(container.getC()[container.getFlattener().index(0, 0)], 0.0, 0)) {
157 container.getC()[container.getFlattener().index(0, 0)] = 1.0;
158 }
159 }
160
161 if (!(okFields && maxDegree >= 0)) {
162 String loaderName = getClass().getName();
163 loaderName = loaderName.substring(loaderName.lastIndexOf('.') + 1);
164 throw new OrekitException(OrekitMessages.UNEXPECTED_FILE_FORMAT_ERROR_FOR_LOADER,
165 name, loaderName);
166 }
167
168 container = container.resize(maxDegree, maxOrder);
169 setRawCoefficients(true, container.getFlattener(), container.getC(), container.getS(), name);
170 setReadComplete(true);
171
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186 public RawSphericalHarmonicsProvider getProvider(final boolean wantNormalized,
187 final int degree, final int order) {
188 return getBaseProvider(wantNormalized, degree, order);
189 }
190 }