/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2006-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.referencing.operation.transform; import java.io.*; import java.util.StringTokenizer; import org.geotoolkit.resources.Errors; import org.geotoolkit.io.ContentFormatException; import static org.geotoolkit.referencing.operation.transform.EarthGravitationalModel.DEFAULT_ORDER; import static org.geotoolkit.referencing.operation.transform.EarthGravitationalModel.locatingArray; /** * Reads the ASCII files provided by the Earth-Info web site, and eventually write * it as a binary file. * * @author Martin Desruisseaux (Geomatys) * @version 3.00 * * @since 3.00 */ public final class Compiler { /** * The geopotential coefficients read from the ASCII file. * Those arrays are filled by the {@link #load} method. */ final double[] cnmGeopCoef, snmGeopCoef; /** * Creates a new compiler. */ Compiler() { final int geopCoefLength = locatingArray(DEFAULT_ORDER + 1); cnmGeopCoef = new double[geopCoefLength]; snmGeopCoef = new double[geopCoefLength]; } /** * Loads the coefficients from the specified ASCII file and initialize the internal * <cite>clenshaw arrays</cite>. * * @param filename The filename, relative to this class directory. * @throws IOException if the file can't be read or has an invalid content. */ final void load(final String filename) throws IOException { final InputStream stream = Compiler.class.getResourceAsStream(filename); if (stream == null) { throw new FileNotFoundException(filename); } try (LineNumberReader in = new LineNumberReader(new InputStreamReader(stream, "ISO-8859-1"))) { String line; while ((line = in.readLine()) != null) { final StringTokenizer tokens = new StringTokenizer(line); try { /* * Note: we use 'parseShort' instead of 'parseInt' as an easy way to ensure that * the values are in some reasonable range. The range is typically [0..180]. * We don't check that, but at least 'parseShort' disallows values greater * than 32767. Additional note: we real all lines in all cases even if we * discard some of them, in order to check the file format. */ final int n = Short.parseShort (tokens.nextToken()); final int m = Short.parseShort (tokens.nextToken()); if (n <= 0 || m < 0 || m > n) { throw new ContentFormatException("n="+ n +" and m=" + m); } final double cbar = Double.parseDouble(tokens.nextToken()); final double sbar = Double.parseDouble(tokens.nextToken()); final int ll = locatingArray(n) + m; cnmGeopCoef[ll] = cbar; snmGeopCoef[ll] = sbar; } catch (RuntimeException cause) { /* * Catch the following exceptions: * - NoSuchElementException if a line has too few numbers. * - NumberFormatException if a number can't be parsed. * - IndexOutOfBoundsException if 'n' or 'm' values are illegal. */ throw new IOException(Errors.format(Errors.Keys.IllegalLineInFile_2, filename, in.getLineNumber()), cause); } } } } /** * Writes the data in a binary form. The file must not exist. * * @param file The destination file, relative to the current directory. * @throws IOException if the file can't be writin. */ private void save(final File file) throws IOException { if (file.exists()) { throw new IOException("File already exists."); } try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { for (int i=0; i<cnmGeopCoef.length; i++) { out.writeDouble(cnmGeopCoef[i]); out.writeDouble(snmGeopCoef[i]); } } } /** * Reads the coefficients from the ASCII file and writes them to a binary file. * Runs this command with no argument for a summary of the expected arguments. * * @param args The command-line arguments. * @throws IOException If an error occurred while reading the ASCII file or writing the binary file. */ public static void main(final String[] args) throws IOException { if (args.length != 2) { System.out.println("Reads the coefficients from the ASCII file and writes them to a binary file."); System.out.println("This command tool expects two arguments:"); System.out.println(" 1) The input filename relative to the Compiler class (example: EGM180.nor)"); System.out.println(" 2) The output file relative to current directory."); return; } final Compiler compiler = new Compiler(); compiler.load(args[0]); compiler.save(new File(args[1])); } }