// // RECTnav.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; /** * Navigation class for Radar (RECT) type nav. This code was modified * from the original FORTRAN code (nvxrect.dlm) on the McIDAS system. It * only supports latitude/longitude to line/element transformations (LL) * and vice/versa. Transform to 'XYZ' not implemented. * @see <A HREF="http://www.ssec.wisc.edu/mcidas/doc/prog_man.html"> * McIDAS Programmer's Manual</A> * * @author Don Murray */ public final class RECTnav extends AREAnav { int itype; int iwest; double xrow; double xcol; double zslat; double zslon; double zdlat; double zdlon; /** * Set up for the real math work. Must pass in the int array * of the RECT nav 'codicil'. * * @param iparms the nav block from the image file * @throws IllegalArgumentException * if the nav block is not a RECT type. */ public RECTnav (int[] iparms) throws IllegalArgumentException { /* No longer needed. Kept for consistency with nvxrect.dlm if (ifunc != 1) { if (iparms[0] == XY ) itype = 1; if (iparms[0] == LL ) itype = 2; return; } */ if (iparms[0] != RECT ) throw new IllegalArgumentException("Invalid navigation type" + iparms[0]); itype = 2; xrow = iparms[1]; int ipowlat = iparms[11]; if (ipowlat == 0) ipowlat = 4; zslat = iparms[2]/Math.pow(10.,ipowlat); xcol = iparms[3]; int ipowlon = iparms[12]; if (ipowlon == 0) ipowlon = 4; zslon = iparms[4]/Math.pow(10.,ipowlon); int ipowdlin = iparms[13]; if (ipowdlin == 0) ipowdlin = 4; zdlat = iparms[5]/Math.pow(10.,ipowdlin); int ipowdele = iparms[14]; if (ipowdele == 0) ipowdele = 4; zdlon = iparms[6]/Math.pow(10.,ipowdele); int ipowrad = iparms[15]; if (ipowrad == 0) ipowrad = 3; int ipowecc = iparms[16]; if (ipowecc == 0) ipowecc = 6; iwest = (iparms[10] >= 0) ? 1 : -1; if (xcol == 1) { zslon=zslon-180.0*iwest; } } /** converts from satellite coordinates to latitude/longitude * * @param linele array of line/element pairs. Where * linele[indexLine][] is a 'line' and * linele[indexEle][] is an element. These are in * 'file' coordinates (not "image" coordinates.) * * @return latlon[][] array of lat/long pairs. Output array is * latlon[indexLat][] of latitudes and * latlon[indexLon][] of longitudes. * */ public double[][] toLatLon(double[][] linele) { double xldif; double xedif; double xlon; double xlat; double xele; double xlin; int number = linele[0].length; double[][] latlon = new double[2][number]; // Convert array to Image coordinates for computations double[][] imglinele = areaCoordToImageCoord(linele); for (int point=0; point < number; point++) { xlin = imglinele[indexLine][point]; xele = imglinele[indexEle][point]; xldif = xrow - xlin; if (xcol == 1) { xedif = iwest * (xele-xcol); xlon = zslon + 180*iwest-xedif*zdlon; } else { xedif = iwest * (xcol-xele); xlon = zslon + xedif*zdlon; } xlat = zslat + xldif*zdlat; if (xlat > 90. || xlat < -90.) { xlat = Double.NaN; } if (xlon > (zslon+180) || xlon < (zslon-180)) { xlon = Double.NaN; } if (!Double.isNaN(xlon)) { if (xlon < -180.) { xlon = xlon + 360.; //if (xlon < -180.) xlon = Double.NaN; } if (xlon > 180) { xlon = xlon - 360.; //if (xlon > 180.) xlon = Double.NaN; } } if (Double.isNaN(xlat) || Double.isNaN(xlon)) { latlon[indexLat][point] = Double.NaN; latlon[indexLon][point] = Double.NaN; } else { latlon[indexLat][point] = xlat; latlon[indexLon][point] = (iwest == 1) ? -xlon : xlon; } } // end point for loop return latlon; } /** * toLinEle converts lat/long to satellite line/element * * @param latlon array of lat/long pairs. Where latlon[indexLat][] * are latitudes and latlon[indexLon][] are longitudes. * * @return linele[][] array of line/element pairs. Where * linele[indexLine][] is a line and linele[indexEle][] * is an element. These are in 'file' coordinates * (not "image" coordinates); */ public double[][] toLinEle(double[][] latlon) { double xlon; double xlat; double xlin; double xele; int number = latlon[0].length; double[][] linele = new double[2][number]; for (int point=0; point < number; point++) { xlat = latlon[indexLat][point]; // transform to McIDAS (west positive longitude) coordinates xlon = (iwest == 1) ? -latlon[indexLon][point] : latlon[indexLon][point]; if (xlon > (zslon+180)) { xlon = xlon-360; } else if (xlon < zslon-180) { xlon = xlon+360; } //if (iwest == -1 && xlon < zslon) xlon = xlon +360.; xlin = xrow - (xlat - zslat)/zdlat; if (xcol == 1) { xele = xcol - (xlon - zslon-180*iwest)/(zdlon*iwest); } else { xele = xcol - (xlon - zslon)/(zdlon*iwest); } linele[indexLine][point] = xlin; linele[indexEle][point] = xele; } // end point loop // Return in 'File' coordinates return imageCoordToAreaCoord(linele, linele); } /** converts from satellite coordinates to latitude/longitude * * @param linele array of line/element pairs. Where * linele[indexLine][] is a 'line' and * linele[indexEle][] is an element. These are in * 'file' coordinates (not "image" coordinates.) * * @return latlon[][] array of lat/long pairs. Output array is * latlon[indexLat][] of latitudes and * latlon[indexLon][] of longitudes. * */ public float[][] toLatLon(float[][] linele) { double xldif; double xedif; double xlon; double xlat; double xele; double xlin; int number = linele[0].length; float[][] latlon = new float[2][number]; // Convert array to Image coordinates for computations float[][] imglinele = areaCoordToImageCoord(linele); for (int point=0; point < number; point++) { xlin = imglinele[indexLine][point]; xele = imglinele[indexEle][point]; xldif = xrow - xlin; if (xcol == 1) { xedif = iwest * (xele-xcol); xlon = zslon + 180*iwest-xedif*zdlon; } else { xedif = iwest * (xcol-xele); xlon = zslon + xedif*zdlon; } xlat = zslat + xldif*zdlat; if (xlat > 90. || xlat < -90.) { xlat = Double.NaN; } if (xlon > (zslon+180) || xlon < (zslon-180)) { xlon = Double.NaN; } if (!Double.isNaN(xlon)) { if (xlon < -180.) { xlon = xlon + 360.; //if (xlon < -180.) xlon = Double.NaN; } if (xlon > 180) { xlon = xlon - 360.; //if (xlon > 180.) xlon = Double.NaN; } } if (Double.isNaN(xlat) || Double.isNaN(xlon)) { latlon[indexLat][point] = Float.NaN; latlon[indexLon][point] = Float.NaN; } else { latlon[indexLat][point] = (float) xlat; latlon[indexLon][point] = (float) ((iwest == 1) ? -xlon : xlon); } } // end point for loop return latlon; } /** * toLinEle converts lat/long to satellite line/element * * @param latlon array of lat/long pairs. Where latlon[indexLat][] * are latitudes and latlon[indexLon][] are longitudes. * * @return linele[][] array of line/element pairs. Where * linele[indexLine][] is a line and linele[indexEle][] * is an element. These are in 'file' coordinates * (not "image" coordinates); */ public float[][] toLinEle(float[][] latlon) { double xlon; double xlat; double xlin; double xele; int number = latlon[0].length; float[][] linele = new float[2][number]; for (int point=0; point < number; point++) { xlat = latlon[indexLat][point]; // transform to McIDAS (west positive longitude) coordinates xlon = (iwest == 1) ? -latlon[indexLon][point] : latlon[indexLon][point]; if (xlon > (zslon+180)) { xlon = xlon-360; } else if (xlon < zslon-180) { xlon = xlon+360; } //if (iwest == -1 && xlon < zslon) xlon = xlon +360.; xlin = xrow - (xlat - zslat)/zdlat; if (xcol == 1) { xele = xcol - (xlon - zslon-180*iwest)/(zdlon*iwest); } else { xele = xcol - (xlon - zslon)/(zdlon*iwest); } linele[indexLine][point] = (float) xlin; linele[indexEle][point] = (float) xele; } // end point loop // Return in 'File' coordinates return imageCoordToAreaCoord(linele, linele); } }