// // ConversionUtility.java // /* This source file is part of the edu.wisc.ssec.mcidas package and is Copyright (C) 1998 - 2017 by Tom Whittaker, Tommy Jasmin, Tom Rink, Don Murray, James Kelly, Bill Hibbard, Dave Glowacki, Curtis Rueden and others. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package edu.wisc.ssec.mcidas; /** * A collection of methods for doing various conversions. * <p> * * @version 1.3, 16 Nov 98 * @author Tommy Jasmin, SSEC */ public class ConversionUtility { /** * Find the distance in km between two points given the lats/lons. * * @param lat1 - latitude of first point * @param lat2 - latitude of second point * @param lon1 - longitude of first point * @param lon2 - longitude of second point * @return - the distance in km between the two input points */ public static float LatLonToDistance ( float lat1, float lon1, float lat2, float lon2 ) { double arcl; double cplat; double cplon; double crlat; double crlon; double dist; double plat; double plon; double rlat; double rlon; double srlat; double srlon; double splat; double splon; double xx; double yy; double zz; float r = 6371.0f; float z = 0.017453292f; rlat = (double) (lat1) * z; rlon = (double) (lon1) * z; plat = (double) (lat2) * z; plon = (double) (lon2) * z; crlat = Math.cos(rlat); crlon = Math.cos(rlon); srlat = Math.sin(rlat); srlon = Math.sin(rlon); cplat = Math.cos(plat); cplon = Math.cos(plon); splat = Math.sin(plat); splon = Math.sin(plon); xx = (cplat * cplon) - (crlat * crlon); yy = (cplat * splon) - (crlat * srlon); zz = splat - srlat; dist = Math.sqrt((xx * xx) + (yy * yy) + (zz * zz)); arcl = 2.0 * Math.asin(dist / 2.0) * r; return (float) (arcl); } /** * Convert a latitude or longitude in dddmmss format to floating point. * * @param dddmmss - latitude or longitude * @return - floating point representation of the input parameter. */ public static float FloatLatLon ( int dddmmss ) { int inVal; float negVal; float retVal; if (dddmmss < 0) { inVal = -dddmmss; negVal = -1.0f; } else { inVal = dddmmss; negVal = 1.0f; } retVal = (float) (inVal / 10000) + (float) ((inVal / 100) % 100) / 60.0f + (float) (inVal % 100) / 3600.0f; retVal = negVal * retVal; return (retVal); } /** * Convert a Gould format floating point number to native double format * * @param inVal - input Gould value * @return - the input value converted to double floating point */ public static double GouldToNative(int inVal) { int sign; int exponent; float mant; int byte0; int byte1; int byte2; double dblMant; double tempVal; double nativeVal; /* * an example conversion: * * input value (hex): BE DA 4D 07 * a) convert to binary: * 1011 1110 1101 1010 0100 1101 0000 0111 * b) sign bit is set, so take twos complement: * 0100 0001 0010 0101 1011 0010 1111 1001 * c) convert this back to hex: 41 25 B2 F9 * d) mantissa = 2470649 * e) exponent = 65 * f) tempVal = mantissa / 16 exp (70 - 65) * g) outputVal = tempVal * sign = -2.3561944 * */ sign = 1; if ((inVal & 0x80000000) != 0) { sign = -1; inVal = -inVal; } // set up munging bytes byte0 = (short)(inVal & 0x000000FF); byte1 = (short)((inVal >> 8) & 0x000000FF); byte2 = (short)((inVal >> 16) & 0x000000FF); exponent = ((inVal & 0x7F000000) >> 24); if (exponent == 0) { exponent = 64; } // determine the value of the mantissa, load into a double mant = (float) (byte0 + (byte1 * 256) + (byte2 * 65536)); mant = Math.abs(mant); dblMant = (double) mant; // now adjust the mantissa according to the exponent tempVal = Math.pow((double) 16, (double) (70 - exponent)); nativeVal = dblMant / tempVal; nativeVal = nativeVal * sign; return nativeVal; } /** * swap the bytes of an integer array * * @param array array of integers to be flipped * @param first starting element of the array * @param last last element of array to flip * */ public static void swap (int array[], int first, int last) { int i, k; for (i = first; i <= last; i++) { k = array[i]; array[i] = ( (k >>> 24) & 0xff) | ( (k >>> 8) & 0xff00) | ( (k & 0xff) << 24 ) | ( (k & 0xff00) << 8); } } }