Skip to content

Commit

Permalink
new feature allows user to change altitude unit from meter to hPa
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanho committed Aug 21, 2024
1 parent 01206ad commit e48e637
Showing 1 changed file with 181 additions and 3 deletions.
184 changes: 181 additions & 3 deletions src/ucar/unidata/idv/control/TimeHeightControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import ucar.visad.display.GridDisplayable;
import ucar.visad.display.XYDisplay;

import ucar.visad.quantities.AirPressure;
import ucar.visad.quantities.CommonUnits;
import ucar.visad.quantities.Length;
import visad.*;
Expand Down Expand Up @@ -150,6 +151,21 @@ public class TimeHeightControl extends LineProbeControl {
private String mySmoothingType;
/** the smoothing factor for second variable */
private int mySmoothingFactor;

private Unit altUnit = null;

float[][] latlonalt = null;
/** default pressure labels */
public static String[] DEFAULT_PRESSURE_LABELS = new String[] {
"1000", "700", "500", "300", "200", "100"
};
/** ScalarMap of Pressure to Display.YAxis */
private ScalarMap pressureMap = null;

/** vertical pressure axis scale */
private AxisScale pressureScale = null;
/** pressure labels being used */
private String[] pressureLabels = DEFAULT_PRESSURE_LABELS;
/**
* Default Contructor; sets flags. See init() for creation actions.
*/
Expand Down Expand Up @@ -228,7 +244,6 @@ public boolean init(DataChoice dataChoice)
RealTuple ss = getGridCenterPosition();
setProbePosition(ss);
setXAxisLabels((SampledSet) fieldImpl.getDomainSet());

timeHeightView.setShowDisplayList(false);
return true;
}
Expand Down Expand Up @@ -420,15 +435,15 @@ protected void displayTHForCoord(FieldImpl fi, int NN)
SampledSet ss = GridUtil.getSpatialDomain(fi);
RealType height =
(RealType) ((SetType) ss.getType()).getDomain().getComponent(NN);
float[][] latlonalt = ss.getSamples();
latlonalt = ss.getSamples();
Unit zUnit = ss.getSetUnits()[NN];
if ( !height.equals(RealType.Altitude)) {
CoordinateSystem cs = ss.getCoordinateSystem();
latlonalt = cs.toReference(latlonalt, ss.getSetUnits());
zUnit = cs
.getReferenceUnits()[cs.getReference().getIndex(RealType.Altitude)];
}

setYAxisLabels(latlonalt[NN]);
int numTimes = timeVals[0].length;
int numAlts = ss.getLength();

Expand Down Expand Up @@ -710,7 +725,134 @@ private void setXAxisLabels(SampledSet timeSet) throws VisADException {

} catch (RemoteException re) {} // can't happen
}
/**
* Set y (altitude) axis values from the data set supplied.
*
* @param altitude alt array to use
*
* @throws VisADException VisAD error
*/
private void setYAxisLabels(float[] altitude) throws VisADException {
if (altitude == null) {
return;
}
int step =8;
double start;
double end;
int len = altitude.length;
if(altitude[0] > altitude[1]) {
start = altitude[len-1];
end = altitude[0];
} else {
end = altitude[len-1];
start = altitude[0];

}
if(end >= 1000.0)
end = Math.round(end /1000)*1000.0;
if(start < 200)
start = 0.0;
double values[] = new double[5];
Hashtable labelTable = new Hashtable();
String [] labels = new String[5];
double averageTickSpacing = (end-start)/(double)(step);
if(averageTickSpacing >= 1000){
averageTickSpacing = Math.round(averageTickSpacing /1000)*1000.0;
} else if(averageTickSpacing >= 100){
averageTickSpacing = Math.round(averageTickSpacing /100)*100.0;
} else if(averageTickSpacing >= 10){
averageTickSpacing = Math.round(averageTickSpacing /10)*10.0;
}
for (int i = 4; i >= 0; i--) {
double value = end - (4 - i) * averageTickSpacing * 2;
values[i] = value;
labels[i] = String.valueOf(value);
}

for (int i = 0; i <= 4; i++) {
labelTable.put(new Double(values[i]), labels[i]);
}
AxisScale yScale = profileDisplay.getYAxisScale();
yScale.setTickBase(start);


//double averageTickSpacing = (end - start);
yScale.setMajorTickSpacing(averageTickSpacing);

//yScale.setMinorTickSpacing(averageTickSpacing * (1.0f/step));
yScale.setLabelTable(labelTable);
yScale.setMajorTicks(values);
//xScale.setTitle("Time (" + dt.getFormatTimeZone().getDisplayName() + ")");


}

/**
* Set y (altitude) axis pressure values
*
* @throws VisADException VisAD error
*/
private void setYAxisPressureLabels() throws VisADException {
// try {
/** default pressure labels */
String[] DEFAULT_PRESSURE_LABELS = new String[] {
"1000", "700", "500", "250", "100"
};

/** pressure labels being used */
String[] pressureLabels = DEFAULT_PRESSURE_LABELS;
Hashtable table = getPressureLabels(pressureLabels);
AxisScale yScale = profileDisplay.getYAxisScale();
java.util.Set keys = table.keySet();
Iterator iterator = keys.iterator();
double [] hkeys = new double [keys.size()];
int i = 0;
for(Object d: keys){
hkeys[i++] = ((Double)d).doubleValue();
}
yScale.setMajorTicks(hkeys);
yScale.setLabelTable(table);
//double averageTickSpacing = (end-start)/(double)(numSteps);

//xScale.setTitle("Time (" + dt.getFormatTimeZone().getDisplayName() + ")");


// } catch (IOException re) {} // can't happen
}
/**
* get y (altitude) axis pressure values hashtable
*
* @param labels pressure labels
*
* @throws VisADException VisAD error
*/
public Hashtable getPressureLabels(String[] labels) throws VisADException {
int numLabels = labels.length;
double value = Double.NaN;
double values[] = new double[labels.length];
Hashtable labelTable = new Hashtable();
for (int i = 0; i < numLabels; i++) {
try {
value = Misc.parseNumber(labels[i]);
} catch (NumberFormatException ne) {
value = Double.NaN;
}
values[i] = value;
}
double[] heights =
AirPressure.getStandardAtmosphereCS().toReference(new double[][] {
values
})[0];


for (int i = 0; i < numLabels; i++) {
labelTable.put(new Double(heights[i]), labels[i]);
}

return labelTable;
// set the field here in case there was an error.

}
/**
* Get the position as a lat/lon point
*
Expand Down Expand Up @@ -766,6 +908,29 @@ protected void getViewMenuItems(List items, boolean forMenuBar) {
//adding some control of probe: size, etc
items.add(doMakeProbeMenu(new JMenu("Probe")));
}

JMenuItem jmj;
jmj = new JMenuItem("Change Altitude Unit...");
jmj.addActionListener(new ObjectListener(new Integer(0)) {
public void actionPerformed(
ActionEvent ev) {
Unit newUnit =
getDisplayConventions().selectUnit(
CommonUnit.meter, CommonUnits.HECTOPASCAL, null);
altUnit = newUnit;
if (newUnit != null) {
try {
reSetTimeHeightAltitudeUnit(
altUnit);
} catch (Exception exc) {
logException(
"After changing units", exc);
}
}

}
});
items.add(jmj);
List paramItems = new ArrayList();
JMenuItem addParamItem = doMakeChangeParameterMenuItem();

Expand Down Expand Up @@ -1144,6 +1309,19 @@ public void setMySmoothingType(int smoothingFactor) throws RemoteException, VisA
this.mySmoothingFactor = smoothingFactor;
}

/**
* This gets called by changing the altitude unit
*
* @param aUnit _more_
*/
protected void reSetTimeHeightAltitudeUnit(Unit aUnit) throws VisADException {
if(aUnit.isConvertible(CommonUnits.HECTOPASCAL)){
setYAxisPressureLabels();
} else{
setYAxisLabels(latlonalt[2]);
}
updateLegendLabel();
}

static public class MyTimeHeightControl extends TimeHeightControl {
TimeHeightControl timeHeightControl;
Expand Down

0 comments on commit e48e637

Please sign in to comment.