//
// RadarAdapter.java
//
/*
This sofware is part of the Australian Integrated Forecast System (AIFS)
Copyright (C) 2017 Bureau of Meteorology
*/
package visad.bom;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.rmi.RemoteException;
import javax.swing.JFrame;
import visad.CommonUnit;
import visad.DataReference;
import visad.DataReferenceImpl;
import visad.Display;
import visad.FlatField;
import visad.FunctionType;
import visad.GraphicsModeControl;
import visad.Gridded3DSet;
import visad.Integer2DSet;
import visad.Integer3DSet;
import visad.QuickSort;
import visad.RealTupleType;
import visad.RealType;
import visad.ScalarMap;
import visad.VisADException;
import visad.java3d.DisplayImplJ3D;
/**
* RadarAdapter
*
* @author - James Kelly : J.Kelly@bom.gov.au - Bill Hibbard (mainly, while
* working at BOM August 1999)
*
*
*/
public class RadarAdapter {
public RadarFile rf;
public class PolarData {
public double azimuth;
public double range;
}
public PolarData[] polar;
public int numVectors;
FlatField radar;
/**
* @deprecated
*/
public RadarAdapter(float centlat, float centlon, String radarSource,
boolean d3d)
throws IOException, VisADException {
this(centlat, centlon, 0.0f, radarSource, d3d);
}
public RadarAdapter(float centlat, float centlon, float centalt,
String radarSource, boolean d3d)
throws IOException, VisADException {
try {
rf = new RadarFile(radarSource);
// buildFlatField(rf);
} catch (IOException e) {throw new
VisADException("Problem with Radar file: " + e);
}
System.out.println("Radar Adapter : dtTime = " + rf.dtTime);
int naz = rf.pbdataArray.length;
float[] azs = new float[naz];
int nrad = 0;
//
// create an array "azs" containing all the azimuth values
// example:
// azs[0] = 61 degrees = radlow + 0
// azs[1] = 183 degrees = radlow + 122
// azs[2] = 261 degrees = radlow + 200
// azs[3] = 262 degrees = radlow + 201
// azs[4] = 262 degrees = radlow + 202
//
for (int i=0; i<naz; i++) {
int n = rf.pbdataArray[i].bdata.length;
if (n > nrad) nrad = n;
azs[i] = (float) rf.pbdataArray[i].azimuth;
// System.out.println("i, azs = " + i + " " + azs[i]);
}
int[] sortToOld = QuickSort.sort(azs);
// radlow : distance from radar of 1st "echo" (radial), in metres eg 4000m
float radlow = rf.startrng;
// radres : distance between subsequent radials eg 500m
float radres = rf.rngres;
float azlow = azs[0];
float azres = rf.azimuthres;
//
//
// azs above is the "old" array
// prepare to create a "new" array containing a continuous set of
// azimuth values between azs[0] and azs[naz-1] degrees
// newnaz is the number of continuous azimuth values
//
int newnaz = 1 + (int) ((azs[naz-1] - azs[0]) / azres);
int[] newToOld = new int[newnaz];
// for (int i=0; i<newnaz; i++) newToOld[i] = -1;
for (int i=0; i<newnaz; i++) newToOld[i] = 0;
//
// The old array above (azs) has only got "azimuth" values for
// radials with non-null data
// We want to fill in the array with these nulls
// So using the example above, newToOld will contain:
// newToOld[0] = 0
// newToOld[1] = -1 ......
// newToOld[122] = 1
// newToOld[123] = -1 ......
// newToOld[200] = 2
// newToOld[201] = 3
// newToOld[202] = 4
// newToOld[203] = -1.......
//
for (int i=0; i<naz; i++) {
int k = (int) ((azs[i] - azs[0]) / azres);
if (k < 0) k = 0;
if (k > (newnaz-1)) k = newnaz-1;
newToOld[k] = sortToOld[i];
// System.out.print("k, newToOld = " + k + " " + newToOld[k] + " ");
}
// System.out.println(" ");
Radar2DCoordinateSystem rcs2d = null;
Radar3DCoordinateSystem rcs3d = null;
float elevlow = 0.5f; // degrees
float elevres = 0.1f; // degrees
int nelev = 1;
if (d3d) {
//ref = new RealTupleType
// (RealType.Latitude, RealType.Longitude, RealType.Altitude);
rcs3d = new Radar3DCoordinateSystem(centlat, centlon, centalt,
radlow, radres, azlow, azres, elevlow, elevres);
}
else {
//ref = new RealTupleType (RealType.Latitude, RealType.Longitude);
rcs2d = new Radar2DCoordinateSystem(centlat, centlon,
radlow, radres, azlow, azres);
}
RealType azimuth =
RealType.getRealType("azimuth", CommonUnit.degree, null);
RealType range = RealType.getRealType("range", CommonUnit.meter, null);
// WLH 14 Oct 99
// RealType elevation =
// RealType.getRealType("elevation", CommonUnit.meter, null);
RealType elevation =
RealType.getRealType("elevation", CommonUnit.degree, null);
RealTupleType radaz = null;
if (d3d) {
RealType[] domain_components = { range, azimuth, elevation};
radaz = new RealTupleType(domain_components, rcs3d, null);
}
else {
RealType[] domain_components = {range, azimuth};
radaz = new RealTupleType(domain_components, rcs2d, null);
}
RealType reflection = RealType.getRealType("reflection");
FunctionType radar_image = new FunctionType(radaz, reflection);
//
// newnaz = 203 using example above
//
// System.out.println("newnaz = " + newnaz + " nrad = " + nrad);
// float[][] samples = new float[2][nrad * naz];
//
// For convenience, the "values" array has all the
// > 0 data values at the start of the array (indexed by k)
// while null data values are stored together at the end of the array
//
// WLH - 21 Sept 99
int bignaz = newnaz;
if (newnaz == 360) bignaz = 361;
float[][] values = new float[1][nrad * bignaz]; // WLH - 21 Sept 99
int m = 0;
for (int i=0; i<newnaz; i++) {
int k = newToOld[i];
if (k >= 0) {
// there is data for this azimuth
byte[] bd = rf.pbdataArray[newToOld[i]].bdata;
for (int j=0; j<nrad; j++) {
values[0][m] = bd[j];
// if (bd[j] > 0) System.out.println("i, j = " + i + " " + j + " values = " + values[0][m] );
m++;
}
}
else { // k < 0
//
// fill the rest of the array with NaNs
//
for (int j=0; j<nrad; j++) {
values[0][m] = Float.NaN;
m++;
}
}
}
// WLH - 21 Sept 99
if (newnaz == 360) {
int offset = nrad * newnaz;
for (int j=0; j<nrad; j++) values[0][offset + j] = values[0][j];
}
if (d3d) {
if (nelev == 1) {
float[][] samples = new float[3][nrad * bignaz];
int k = 0;
for (int j=0; j<bignaz; j++) {
for (int i=0; i<nrad; i++) {
samples[0][k] = i;
samples[1][k] = j;
samples[2][k] = 0;
k++;
}
}
Gridded3DSet set = new Gridded3DSet(radaz, samples, nrad, bignaz);
radar = new FlatField(radar_image, set);
}
else {
Integer3DSet set = new Integer3DSet(radaz, nrad, bignaz, nelev);
radar = new FlatField(radar_image, set);
}
}
else {
// Gridded2DSet set = new Gridded2DSet(radaz, samples, nrad, naz);
Integer2DSet set = new Integer2DSet(radaz, nrad, bignaz); // WLH - 21 Sept 99
radar = new FlatField(radar_image, set);
}
radar.setSamples(values);
}
public FlatField getData() {
return radar;
}
public static void main(String[] args) throws VisADException, RemoteException {
String radarSource = "radar.dat";
RadarAdapter ra = null;
try {
ra = new RadarAdapter(-34.9f, 138.5f, 4.0f, radarSource, false);
} catch (Exception e) {
System.err.println("Caught Exception for \"" + radarSource + "\": " +
e);
System.exit(1);
}
FlatField radar = ra.getData();
FunctionType radar_image = (FunctionType) radar.getType();
RealTupleType radaz = radar_image.getDomain();
RealType reflection = (RealType) radar_image.getRange();
DisplayImplJ3D display = new DisplayImplJ3D("radar");
ScalarMap lonmap = new ScalarMap(RealType.Longitude, Display.XAxis);
//lonmap.setRange(130.0, 150.0);
display.addMap(lonmap);
ScalarMap latmap = new ScalarMap(RealType.Latitude, Display.YAxis);
display.addMap(latmap);
display.addMap(new ScalarMap(RealType.Altitude, Display.ZAxis));
//latmap.setRange(-45.0, -25.0);
//ScalarMap reflectionmap = new ScalarMap(reflection, Display.ZAxis);
//display.addMap(reflectionmap);
//reflectionmap.setRange(0, 6);
// display.addMap(new ScalarMap(reflection, Display.RGB));
ScalarMap rgbMap = new ScalarMap(reflection, Display.RGB);
//ScalarMap rgbMap = new ScalarMap(reflection, Display.RGBA);
// rgbMap.setRange(0.,6.);
display.addMap(rgbMap);
GraphicsModeControl mode = display.getGraphicsModeControl();
mode.setScaleEnable(true);
// mode.setTextureEnable(false); WLH - 22 Sept 99
DataReference ref = new DataReferenceImpl("radar_ref");
ref.setData(radar);
display.addReference(ref);
JFrame frame = new JFrame("VisAD BOM radar image");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane().add(display.getComponent());
int WIDTH = 500;
int HEIGHT = 600;
frame.setSize(WIDTH, HEIGHT);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(screenSize.width/2 - WIDTH/2,
screenSize.height/2 - HEIGHT/2);
frame.setVisible(true);
/*
LabeledColorWidget lw = new LabeledColorWidget(rgbMap);
JFrame widgetFrame = new JFrame("VisAD Color Widget");
widgetFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
widgetFrame.getContentPane().add(lw);
widgetFrame.setSize(lw.getPreferredSize());
widgetFrame.setVisible(true);
*/
}
}