// // GEOSnav.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; /* This code translated to Java from the original McIDAS module: nvxgeos.dlm. The following notice is included in that code: C**************************************************************** C AUTHOR : Oscar Alonso Lasheras C COPYRIGHT GMV S.A. 2006 C PROPERTY OF GMV S.A.; ALL RIGHTS RESERVED C C PROJECT : S3GICast C FILE NAME : nvxgeos.dlm C LANGUAGE : FORTRAN-77 C TYPE : Funcion auxliar para creacion de navegacion GEOS C DESCRIPTION : Navega los productos MPEF y OSIS, ademas de los productos C de los servidores FSDX y SAFN-HDF5 en McIDAS C */ public class GEOSnav extends AREAnav { private static final long serialVersionUID = 1L; final int loff, coff, lfac, cfac, plon, bres; final double radpol = 6356.5838; final double radeq = 6378.1690; final double X42 = 42164.0; private boolean isEastPositive = true; public GEOSnav(int[] iparms) throws IllegalArgumentException { if (iparms[0] != GEOS) throw new IllegalArgumentException ("Invald navigation type " + iparms[0]); loff = iparms[1]; coff = iparms[2]; lfac = iparms[3]; cfac = iparms[4]; plon = iparms[5]; //System.err.println("iparms.length: " + iparms.length); if ( iparms.length > 6 && iparms[6] > 0 ) { bres = iparms[6]; //System.err.println("Using bres from iparms: " + bres); } else { bres = 1; //System.err.println("Using default bres of 1. iparms contained: " + iparms[6]); } } /** * @param latlon lat and lon of points (N and E are positive) */ public double[][] toLinEle(double[][] latlon) { double xlat, xlon, xlin, xele, rlin, rele; double c_lat, cosc_lat, rn, r1, r2, r3, rl; double x,y; double lat,lon,splon; double ad2, bd, cd, delta2, halfsom, r_eq2, r_pol2; int number = latlon[0].length; double[][] linele = new double[2][number]; for (int point=0; point < number; point++) { xlat = latlon[indexLat][point]; xlon = latlon[indexLon][point]; if (!isEastPositive) xlon = -xlon; // --- Coordinates are computed accroding EUMETSAT's LRIT/HRIT Global Spec // --- Doc No: CGMS 03 // --- Coordinates are converted to Radians lat = xlat*Math.PI/180.; lon = xlon*Math.PI/180.0; splon = plon/10. * Math.PI/180.0; // --- Intermediate data c_lat=Math.atan(0.993243*Math.tan(lat)); cosc_lat=Math.cos(c_lat); r_pol2= radpol * radpol; r_eq2 = radeq * radeq; rl=radpol/(Math.sqrt(1-((r_eq2-r_pol2)/r_eq2)*cosc_lat*cosc_lat)); r1=X42-rl*cosc_lat*Math.cos(lon-splon); r2=-rl*cosc_lat*Math.sin(lon-splon); r3=rl*Math.sin(c_lat); rn=Math.sqrt(r1*r1+r2*r2+r3*r3); // --- Compute variables useful to check if pixel is visible ad2 = r1*r1 + r2*r2 + r3*r3*r_eq2 / r_pol2; bd = X42*r1; cd = X42*X42 - r_eq2; delta2 = bd*bd-ad2*cd; halfsom = bd*rn/ad2; if ((delta2 >= 0.) && (rn <= halfsom)) { // ------- Intermediate coordinates x = Math.atan(-r2/r1); y = Math.asin(-r3/rn); x = x * 180./Math.PI; y = y * 180./Math.PI; xele = coff/10. + x / Math.pow(2,16) * cfac/10.; xlin = loff/10. + y / Math.pow(2,16) * lfac/10.; rlin = (xlin*bres)-(bres-1); rele = (xele*bres)-(bres-1); } else { rlin=Double.NaN; rele=Double.NaN; } linele[indexLine][point] = rlin; linele[indexEle][point] = rele; } return imageCoordToAreaCoord(linele, linele); } public double[][] toLatLon(double[][] linele) { double xlat, xlon, xlin, xele, rlin, rele; double x,y; double s1, s2, s3, sxy, sn, sd, sdd; double aux, aux2; double cosx, cosy, sinx, siny; // --- Coordinates are computed accroding EUMETSAT's LRIT/HRIT Global Spec // --- Doc No: CGMS 03 int number = linele[0].length; double[][] latlon = new double[2][number]; double[][] imglinele = areaCoordToImageCoord(linele); for (int point=0; point < number; point++ ) { rlin = imglinele[indexLine][point]; rele = imglinele[indexEle][point]; // use bres to adjust the coordinates xlin = (rlin + (bres-1)) / bres; xele = (rele + (bres-1)) / bres; // --- Intermediate coordinates x = (xele - coff/10.) * Math.pow(2,16) / (cfac/10.); y = (xlin - loff/10.) * Math.pow(2,16) / (lfac/10.); x = x * Math.PI/180.; y = y * Math.PI/180.; //c --- Intermediate data cosx=Math.cos(x); cosy=Math.cos(y); sinx=Math.sin(x); siny=Math.sin(y); aux=X42*cosx*cosy; aux2=cosy*cosy+1.006803*siny*siny; sdd=aux*aux-aux2*1737121856.0; if (sdd < 0.0) { xlat=Double.NaN; xlon=Double.NaN; } else { sd=Math.sqrt(sdd); sn=(aux-sd)/aux2; s1=X42 - sn*cosx*cosy; s2=sn*sinx*cosy; s3= -sn*siny; sxy=Math.sqrt(s1*s1+s2*s2); // --- Computation xlon = Math.atan(s2/s1); xlon = xlon * 180./Math.PI + plon/10.; xlat = Math.atan(1.006803*s3/sxy)* 180./Math.PI; // --- Longitudes in [-180,180] if(xlon > 180.0) xlon = xlon - 360.; if(xlon < -180.0) xlon = xlon + 360.; } if (!isEastPositive) xlon = -xlon; latlon[indexLat][point] = xlat; latlon[indexLon][point] = xlon; } return latlon; } }