ucar.nc2.iosp.adde.AreaFile3 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.iosp.adde;
// import edu.wisc.ssec.mcidas.*;
import edu.wisc.ssec.mcidas.AREAnav;
import edu.wisc.ssec.mcidas.AreaDirectory;
import edu.wisc.ssec.mcidas.AreaFile;
import edu.wisc.ssec.mcidas.AreaFileException;
import edu.wisc.ssec.mcidas.McIDASUtil;
import edu.wisc.ssec.mcidas.GVARnav;
import edu.wisc.ssec.mcidas.MOLLnav;
import edu.wisc.ssec.mcidas.MSATnav;
import edu.wisc.ssec.mcidas.RADRnav;
import edu.wisc.ssec.mcidas.RECTnav;
import edu.wisc.ssec.mcidas.GMSXnav;
import edu.wisc.ssec.mcidas.GOESnav;
import edu.wisc.ssec.mcidas.PSnav;
import edu.wisc.ssec.mcidas.MERCnav;
import edu.wisc.ssec.mcidas.LAMBnav;
import edu.wisc.ssec.mcidas.TANCnav;
import ucar.ma2.*;
import ucar.nc2.util.net.URLStreamHandlerFactory;
import java.io.*;
import java.lang.*;
import java.net.URL;
/**
* AreaFile interface with McIDAS 'area' file format image data. The
* data is made into an ucar.ma2.Array object.
*
* This will allow 'area' format data to be read from disk; the
* navigation block is made available (see GVARnav for example).
*
* This implementation does not do calibration (other than
* accounting for its presence in the data). Also, the 'valcode'
* is not checked on each line.
*
* @author John Caron : adapt to MultiArray, add getAreaNavigation
* @author Tom Whittaker & Tommy Jasmin at SSEC
*
* @version $Revision:51 $ $Date:2006-07-12 17:13:13Z $
*/
public class AreaFile3 {
// these should be static in AREAnav
private static final int indexLine=1;
private static final int indexEle=0;
private static final int indexLat=0;
private static final int indexLon=1;
private int numBands, numLines, numElems, dataSize;
private int datLoc, linePrefixLength, lineDataLength, lineLength;
private long position = 0;
private int[] dir;
private int[] navBlock;
private int[] cal;
private int[] aux;
private Array data;
private AreaDirectory areaDirectory = null;
private AREAnav areaNavigation = null;
private String imageSource;
private boolean showBBcalc = false;
/**
* Creates an AreaFile object that allows reading
* of McIDAS 'area' file format image data from a URL
*
* @param urlString - the adde url String
*
*/
public AreaFile3(String urlString) throws java.io.IOException, java.net.MalformedURLException {
long timeStart = System.currentTimeMillis();
URL url = URLStreamHandlerFactory.makeURL( urlString);
DataInputStream af = new DataInputStream(new BufferedInputStream(url.openStream()));
readMetaData( af);
readData( af);
/* long timeEnd = System.currentTimeMillis();
if (DebugFlags.isSet("AreaFile/readTiming"))
System.out.println("Time to read AreaFile = "+ .001*(timeEnd - timeStart)+" sec");
if ((log != null) && Debug.isSet("AreaFile/showFileStats")) {
log.println(" numBands = "+ numBands);
log.println(" numLines = "+ numLines);
log.println(" numElems = "+ numElems);
log.println(" dataElementSize = "+ dataSize);
log.println(" memory = "+ numBands*numLines*numElems*dataSize);
}
if ((log != null) && Debug.isSet("AreaFile/showAreaNav")) {
try {
AREAnav anav = getAreaNavigation();
log.println(" nav = "+ anav.getClass().getName()+"=="+anav);
log.println(" bb = "+ getBoundingBox());
} catch (AreaFileException afe) {
throw new IOException( afe.getMessage());
}
} */
}
public Array getData() { return data; }
/**
* Read the metadata for an area file (directory, nav, and cal).
*/
private void readMetaData(DataInputStream af) throws java.io.IOException {
int i;
boolean flipwords = false;
// read dir
dir = new int[AreaFile.AD_DIRSIZE];
for (i=0; i < AreaFile.AD_DIRSIZE; i++)
dir[i] = af.readInt();
position += AreaFile.AD_DIRSIZE * 4;
// see if the directory needs to be byte-flipped
if (dir[AreaFile.AD_VERSION] != AreaFile.VERSION_NUMBER) {
McIDASUtil.flip(dir,0,19);
// check again
if (dir[AreaFile.AD_VERSION] != AreaFile.VERSION_NUMBER)
throw new IOException("Invalid version number - probably not an AREA file");
// word 20 may contain characters -- if small integer, flip it...
if ( (dir[20] & 0xffff) == 0) McIDASUtil.flip(dir,20,20);
McIDASUtil.flip(dir,21,23);
// words 24-31 contain memo field
McIDASUtil.flip(dir,32,50);
// words 51-2 contain cal info
McIDASUtil.flip(dir,53,55);
// word 56 contains original source type (ascii)
McIDASUtil.flip(dir,57,63);
flipwords = true;
}
try {
areaDirectory = new AreaDirectory(dir);
} catch (AreaFileException afe) {
throw new IOException( afe.getMessage());
}
// pull together some values needed by other methods
numBands = dir[AreaFile.AD_NUMBANDS];
numLines = dir[AreaFile.AD_NUMLINES];
numElems = dir[AreaFile.AD_NUMELEMS];
dataSize = dir[AreaFile.AD_DATAWIDTH];
int navLoc = dir[AreaFile.AD_NAVOFFSET];
int calLoc = dir[AreaFile.AD_CALOFFSET];
int auxLoc = dir[AreaFile.AD_AUXOFFSET];
datLoc = dir[AreaFile.AD_DATAOFFSET];
linePrefixLength = dir[AreaFile.AD_DOCLENGTH] + dir[AreaFile.AD_CALLENGTH] + dir[AreaFile.AD_LEVLENGTH];
if (dir[AreaFile.AD_VALCODE] != 0) linePrefixLength = linePrefixLength + 4;
if (linePrefixLength != dir[AreaFile.AD_PFXSIZE])
throw new IOException("Invalid line prefix length in AREA file.");
lineDataLength = numBands * numElems * dir[AreaFile.AD_DATAWIDTH];
lineLength = linePrefixLength + lineDataLength;
int navbytes = 0, calbytes = 0, auxbytes = 0;
if (datLoc > 0 && datLoc != McIDASUtil.MCMISSING) {
navbytes = datLoc - navLoc;
calbytes = datLoc - calLoc;
auxbytes = datLoc - auxLoc;
}
if (auxLoc > 0 && auxLoc != McIDASUtil.MCMISSING) {
navbytes = auxLoc - navLoc;
calbytes = auxLoc - calLoc;
}
if (calLoc > 0 && calLoc != McIDASUtil.MCMISSING ) {
navbytes = calLoc - navLoc;
}
// Read in nav block
if (navLoc > 0 && navbytes > 0) {
navBlock = new int[navbytes/4];
long newPosition = (long) navLoc;
int skipByteCount = (int) (newPosition - position);
af.skipBytes(skipByteCount);
for (i=0; i 0 && calbytes > 0) {
cal = new int[calbytes/4];
long newPosition = (long)calLoc;
int skipByteCount = (int) (newPosition - position);
af.skipBytes(skipByteCount);
for (i=0; i 0 && auxbytes > 0) {
aux = new int[auxbytes/4];
long newPosition = (long) auxLoc;
int skipByteCount = (int) (newPosition - position);
af.skipBytes(skipByteCount);
for (i = 0; i < auxbytes/4; i++)
aux[i] = af.readInt();
position = auxLoc + auxbytes;
}
return;
}
/**
* Returns the directory block
*
* @return an integer array containing the area directory
*
*/
public int[] getDir() {
return dir;
}
/**
* Returns the AreaDirectory object for this AreaFile
*
* @return AreaDirectory
*/
public AreaDirectory getAreaDirectory() {
return areaDirectory;
}
/**
* Returns calibration block
*
* @return an integer array containing the nav block data
*
* @exception AreaFileException if there is a problem
* reading the calibration
*
*/
public int[] getCal() throws AreaFileException {
return cal;
}
/**
* Returns AUX block
*
* @return an integer array containing the aux block data
*
* @exception AreaFileException if there is a problem
* reading the aux block
*
*/
public int[] getAux() throws AreaFileException {
return aux;
}
private void readData(DataInputStream af) {
int i,j,k;
// create ucar.ma2.Array as 3D int array
if (dataSize == 1) {
// assume unsigned byte, must be promoted (2x storage !!)
data = new ArrayShort.D3(numBands, numLines, numElems);
} else if (dataSize == 2) {
data = new ArrayShort.D3(numBands, numLines, numElems);
} else if (dataSize == 4) {
data = new ArrayInt.D3(numBands, numLines, numElems);
}
Index ima = data.getIndex();
for (i = 0; i lineDataLength) {
data.setInt( ima.set(k, i, j), 0);
} else {
try {
if (dataSize == 1) {
short ival = (short) af.readByte();
if (ival < 0) ival += 256;
data.setShort( ima.set(k, i, j), ival);
position = position + 1;
}
if (dataSize == 2) {
data.setShort( ima.set(k, i, j), af.readShort());
position = position + 2;
}
if (dataSize == 4) {
data.setInt( ima.set(k, i, j), af.readInt());
position = position + 4;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return ;
}
/**
* selectively flip the bytes of words in nav block
*/
private void flipnav(int[] nav) {
// first word is always the satellite id in ASCII
// check on which type:
if (nav[0] == AREAnav.GVAR) {
McIDASUtil.flip(nav,2,126);
McIDASUtil.flip(nav,129,254);
McIDASUtil.flip(nav,257,382);
McIDASUtil.flip(nav,385,510);
McIDASUtil.flip(nav,513,638);
}
else if (nav[0] == AREAnav.DMSP) {
McIDASUtil.flip(nav,1,43);
McIDASUtil.flip(nav,45,51);
}
else if (nav[0] == AREAnav.POES) {
McIDASUtil.flip(nav,1,119);
}
else {
McIDASUtil.flip(nav,1,nav.length-1);
}
return;
}
/**
* Return an AREAnav based on the input nav block.
*/
public AREAnav getAreaNavigation( ) throws AreaFileException {
if (areaNavigation != null)
return areaNavigation;
try {
switch (navBlock[0]) {
case AREAnav.GVAR:
areaNavigation = new GVARnav(navBlock);
break;
case AREAnav.MOLL:
areaNavigation = new MOLLnav(navBlock);
break;
case AREAnav.MSAT:
areaNavigation = new MSATnav(navBlock);
break;
case AREAnav.RADR:
areaNavigation = new RADRnav(navBlock);
break;
case AREAnav.RECT:
areaNavigation = new RECTnav(navBlock);
break;
case AREAnav.GMSX:
areaNavigation = new GMSXnav(navBlock);
break;
case AREAnav.GOES:
areaNavigation = new GOESnav(navBlock);
break;
case AREAnav.PS:
areaNavigation = new PSnav(navBlock);
break;
case AREAnav.MERC:
areaNavigation = new MERCnav(navBlock);
break;
case AREAnav.LAMB:
areaNavigation = new LAMBnav(navBlock);
break;
case AREAnav.TANC:
areaNavigation = new TANCnav(navBlock);
break;
default:
throw new AreaFileException(
"AreaFile2.getAreaNav: Unknown navigation type" + navBlock[0]);
}
} catch (IllegalArgumentException excp) {
throw new AreaFileException( "AreaFile2.getAreaNav: bad nav block "+excp.getMessage());
}
areaNavigation.setImageStart(dir[5], dir[6]);
areaNavigation.setRes(dir[11], dir[12]);
areaNavigation.setStart(1,1);
areaNavigation.setMag(1,1);
return areaNavigation;
}
public java.awt.geom.Rectangle2D getBoundingBox() throws AreaFileException {
AREAnav anav = getAreaNavigation();
//double[][] linelem = makePerimeter(numElems, numLines);
double[][] linelem = makeArea(numElems, numLines);
int size = linelem[0].length;
// convert to lat/lon
double[][] latlon = anav.toLatLon(linelem);
// get bounding box
double maxLon = -Double.MAX_VALUE;
double maxLat = Double.MIN_VALUE;
double minLon = -Double.MAX_VALUE;
double minLat = Double.MAX_VALUE;
for (int i=0; i maxLat) maxLat = lat;
if (lat < minLat) minLat = lat;
}
if (!Double.isNaN(lon)) {
if (lon > maxLon) maxLon = lon;
if (lon < minLon) minLon = lon;
}
}
return new java.awt.geom.Rectangle2D.Double(minLon, minLat, maxLon-minLon, maxLat-minLat);
}
private double [][] makePerimeter(int numElems, int numLines) {
int size = 2*(numElems+numLines);
double[][] linelem = new double[2][size];
int count = 0;
// top line
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy