EGMFormatReader.java

  1. /* Copyright 2002-2015 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.forces.gravity.potential;

  18. import java.io.BufferedReader;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.InputStreamReader;
  22. import java.text.ParseException;
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Locale;

  26. import org.apache.commons.math3.util.FastMath;
  27. import org.apache.commons.math3.util.Precision;
  28. import org.orekit.errors.OrekitException;
  29. import org.orekit.errors.OrekitMessages;
  30. import org.orekit.utils.Constants;

  31. /**This reader is adapted to the EGM Format.
  32.  *
  33.  * <p> The proper way to use this class is to call the {@link GravityFieldFactory}
  34.  *  which will determine which reader to use with the selected gravity field file.</p>
  35.  *
  36.  * @see GravityFieldFactory
  37.  * @author Fabien Maussion
  38.  */
  39. public class EGMFormatReader extends PotentialCoefficientsReader {

  40.     /** Simple constructor.
  41.      * @param supportedNames regular expression for supported files names
  42.      * @param missingCoefficientsAllowed if true, allows missing coefficients in the input data
  43.      */
  44.     public EGMFormatReader(final String supportedNames, final boolean missingCoefficientsAllowed) {
  45.         super(supportedNames, missingCoefficientsAllowed);
  46.     }

  47.     /** {@inheritDoc} */
  48.     public void loadData(final InputStream input, final String name)
  49.         throws IOException, ParseException, OrekitException {

  50.         // reset the indicator before loading any data
  51.         setReadComplete(false);

  52.         // both EGM96 and EGM2008 use the same values for ae and mu
  53.         // if a new EGM model changes them, we should have some selection logic
  54.         // based on file name (a better way would be to have the data in the file...)
  55.         setAe(Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
  56.         setMu(Constants.EGM96_EARTH_MU);
  57.         final String lowerCaseName = name.toLowerCase(Locale.US);
  58.         if (lowerCaseName.contains("2008") || lowerCaseName.contains("zerotide")) {
  59.             setTideSystem(TideSystem.ZERO_TIDE);
  60.         } else {
  61.             setTideSystem(TideSystem.TIDE_FREE);
  62.         }

  63.         final BufferedReader r = new BufferedReader(new InputStreamReader(input, "UTF-8"));
  64.         final List<List<Double>> c = new ArrayList<List<Double>>();
  65.         final List<List<Double>> s = new ArrayList<List<Double>>();
  66.         boolean okFields = true;
  67.         for (String line = r.readLine(); okFields && line != null; line = r.readLine()) {
  68.             if (line.length() >= 15) {

  69.                 // get the fields defining the current the potential terms
  70.                 final String[] tab = line.trim().split("\\s+");
  71.                 if (tab.length != 6) {
  72.                     okFields = false;
  73.                 }

  74.                 final int i = Integer.parseInt(tab[0]);
  75.                 final int j = Integer.parseInt(tab[1]);
  76.                 if (i <= getMaxParseDegree() && j <= getMaxParseOrder()) {
  77.                     for (int k = 0; k <= i; ++k) {
  78.                         extendListOfLists(c, k, FastMath.min(k, getMaxParseOrder()),
  79.                                           missingCoefficientsAllowed() ? 0.0 : Double.NaN);
  80.                         extendListOfLists(s, k, FastMath.min(k, getMaxParseOrder()),
  81.                                           missingCoefficientsAllowed() ? 0.0 : Double.NaN);
  82.                     }
  83.                     parseCoefficient(tab[2], c, i, j, "C", name);
  84.                     parseCoefficient(tab[3], s, i, j, "S", name);
  85.                 }

  86.             }
  87.         }

  88.         if (missingCoefficientsAllowed() && getMaxParseDegree() > 0 && getMaxParseOrder() > 0) {
  89.             // ensure at least the (0, 0) element is properly set
  90.             extendListOfLists(c, 0, 0, 0.0);
  91.             extendListOfLists(s, 0, 0, 0.0);
  92.             if (Precision.equals(c.get(0).get(0), 0.0, 1)) {
  93.                 c.get(0).set(0, 1.0);
  94.             }
  95.         }

  96.         if ((!okFields) || (c.size() < 1)) {
  97.             String loaderName = getClass().getName();
  98.             loaderName = loaderName.substring(loaderName.lastIndexOf('.') + 1);
  99.             throw new OrekitException(OrekitMessages.UNEXPECTED_FILE_FORMAT_ERROR_FOR_LOADER,
  100.                                       name, loaderName);
  101.         }

  102.         setRawCoefficients(true, toArray(c), toArray(s), name);
  103.         setReadComplete(true);

  104.     }

  105.     /** Get a provider for read spherical harmonics coefficients.
  106.      * <p>
  107.      * EGM fields don't include time-dependent parts, so this method returns
  108.      * directly a constant provider.
  109.      * </p>
  110.      * @param wantNormalized if true, the provider will provide normalized coefficients,
  111.      * otherwise it will provide un-normalized coefficients
  112.      * @param degree maximal degree
  113.      * @param order maximal order
  114.      * @return a new provider
  115.      * @exception OrekitException if the requested maximal degree or order exceeds the
  116.      * available degree or order or if no gravity field has read yet
  117.      * @since 6.0
  118.      */
  119.     public RawSphericalHarmonicsProvider getProvider(final boolean wantNormalized,
  120.                                                      final int degree, final int order)
  121.         throws OrekitException {
  122.         return getConstantProvider(wantNormalized, degree, order);
  123.     }

  124. }