Hi James,
> Thanks for the recommendation. I've gone for option 2, but have run into
> difficulty as described below.
Not exactly my recommendation (separate Data object and ScalarMap
to Shape), but good enough. You can fix the problem by adding:
TextControl tcontrol = (TextControl) flows_text_map.getControl();
tcontrol.setNumberFormat(new DecimalFormat());
after 'display.addMap(flows_text_map);', and 'import java.text.*;'
at the top. The default NumberFormat must deal with NaN incorrectly.
I attached a fixed version of your code.
Cheers,
Bill
> I'd like to embed new data (as per your suggestion) in the same tuple as
> the existing wind data, and also have the wind speed displayed as text
> on the screen.
>
> To do this, I'm thinking of a tuple like this:
> (lat,lon,(dir,speed),(variable_dir, variable_speed))
>
> To indicate a variable wind, the following sequence would occur:
> 1) user presses V
> 2) dir is set to NaN (and wind barb disappears from the screen)
> 3) variable_dir is set to the old value of dir (in case the user presses
> V again to turn off the variable direction we can restore dir to its
> original value).
> 4) variable_speed is set to speed
> 5) variable_speed has been mapped to Display.Text, and so the "variable"
> speed is displayed on the screen.
>
> This is pretty much what I want (and could optionally do a shape as
> well), but this isn't working for me.
>
> To illustrate the problem, I've modified visad.bom.BarbRendererJ3D
> (attached).
> In it, I've set "varable_speed" to NaN, and mapped this to Display.Text,
> and expect no text to appear on the display. However, if you run the
> code with:
> java visad.bom.BarbRendererJ3D 1 1
> you will see a "0" displayed alongside every wind barb.
>
> This problem doesn't occur with "speed", just with "variable_speed". To
> confirm this (correct) behaviour:
> * uncomment line 177:
> // ScalarMap flows_text_map = new ScalarMap(flow_speed, Display.Text);
> * comment out line 179:
> ScalarMap flows_text_map = new ScalarMap(flow_variable_speed,
> Display.Text
> * uncomment lines 218 and 219 which hardware "speed" to NaN:
> // values[2][m] = Double.NaN;
> // values[3][m] = Double.NaN;
>
> Then run the code again and you will see nothing displayed (ie no wind
> barbs and no text as expected).
>
> So why can't I make the text for "variable_speed" disappear by setting
> it to NaN?
>
> Cheers,
>
> James
>
>
>
>
>
> Bill Hibbard wrote:
> >
> > Hi James,
> >
> > ....
> > 2. An alternative is for your application to note where it wants
> > variable winds. It could set those wind components to NaN to
> > disable the usual barb rendering, and then create new Data with
> > a MathType something like:
> >
> > (x, y, aux_speed)
> >
> > with the ScalarMaps:
> >
> > x -> XAxis
> > y -> YAxis
> > aux_speed -> Shape
> >
> > and just create an array of shapes for the variable circles for
> > various speed values.
> >
>
> --
> James Kelly Regional Computing
> Phone: 61-3-9669-4724 Fax: 61-3-9669-4128 Email: J.Kelly@xxxxxxxxxx
>
//
// BarbRendererJ3D.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2002 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
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 visad.bom;
import visad.*;
import visad.java3d.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.rmi.*;
import java.text.*; // WLH
/**
BarbRendererJ3D is the VisAD class for rendering of
wind barbs under Java3D - otherwise it behaves just
like DefaultRendererJ3D
*/
public class BarbRendererJ3D extends DefaultRendererJ3D
implements BarbRenderer {
private BarbManipulationRendererJ3D bmr;
/** this DataRenderer supports direct manipulation for RealTuple
representations of wind barbs; four of the RealTuple's Real
components must be mapped to XAxis, YAxis, Flow1X and Flow1Y */
public BarbRendererJ3D () {
super();
bmr = new BarbManipulationRendererJ3D();
}
public ShadowType makeShadowFunctionType(
FunctionType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowBarbFunctionTypeJ3D(type, link, parent);
}
public ShadowType makeShadowRealTupleType(
RealTupleType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowBarbRealTupleTypeJ3D(type, link, parent);
}
public ShadowType makeShadowRealType(
RealType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowBarbRealTypeJ3D(type, link, parent);
}
public ShadowType makeShadowSetType(
SetType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowBarbSetTypeJ3D(type, link, parent);
}
public ShadowType makeShadowTupleType(
TupleType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowBarbTupleTypeJ3D(type, link, parent);
}
public void setKnotsConvert(boolean enable) {
bmr.setKnotsConvert(enable);
}
public boolean getKnotsConvert() {
return bmr.getKnotsConvert();
}
public float[] makeVector(boolean south, float x, float y, float z,
float scale, float pt_size, float f0, float f1,
float[] vx, float[] vy, float[] vz, int[] numv,
float[] tx, float[] ty, float[] tz, int[] numt) {
return bmr.makeVector(south, x, y, z, scale, pt_size, f0, f1, vx, vy, vz,
numv, tx, ty, tz, numt);
}
public Object clone() {
return new BarbRendererJ3D();
}
static final int N = 5;
/** run 'java visad.bom.BarbRendererJ3D middle_latitude'
to test with Cartesian winds
run 'java visad.bom.BarbRendererJ3D middle_latitude x'
to test with polar winds
adjust middle_latitude for south or north barbs */
public static void main(String args[])
throws VisADException, RemoteException {
double mid_lat = -10.0;
if (args.length > 0) {
try {
mid_lat = Double.valueOf(args[0]).doubleValue();
}
catch(NumberFormatException e) { }
}
RealType lat = RealType.Latitude;
RealType lon = RealType.Longitude;
RealType flowx = RealType.getRealType("flowx",
CommonUnit.meterPerSecond);
RealType flowy = RealType.getRealType("flowy",
CommonUnit.meterPerSecond);
RealType red = RealType.getRealType("red");
RealType green = RealType.getRealType("green");
RealType index = RealType.getRealType("index");
EarthVectorType flowxy = new EarthVectorType(flowx, flowy);
TupleType range = null;
RealType flow_degree = RealType.getRealType("flow_degree",
CommonUnit.degree);
RealType flow_speed = RealType.getRealType("flow_speed",
CommonUnit.meterPerSecond);
// jk start
RealType flow_variable_degree = RealType.getRealType("flow_variable_degree",
CommonUnit.degree);
RealType flow_variable_speed = RealType.getRealType("flow_variable_speed",
CommonUnit.meterPerSecond);
// jk end
if (args.length > 1) {
System.out.println("polar winds");
RealTupleType flowds =
new RealTupleType(new RealType[] {flow_degree, flow_speed},
new WindPolarCoordinateSystem(flowxy), null);
// jk start
RealTupleType flow_variable_ds =
new RealTupleType(new RealType[] {flow_variable_degree,
flow_variable_speed},
new WindPolarCoordinateSystem(flowxy), null);
// range = new TupleType(new MathType[] {lon, lat, flowds, red, green});
range = new TupleType(new MathType[] {lon, lat, flowds, red, green,
flow_variable_ds});
// jk end
}
else {
System.out.println("Cartesian winds");
range = new TupleType(new MathType[] {lon, lat, flowxy, red, green});
}
FunctionType flow_field = new FunctionType(index, range);
DisplayImpl display = new DisplayImplJ3D("display1");
ScalarMap xmap = new ScalarMap(lon, Display.XAxis);
display.addMap(xmap);
ScalarMap ymap = new ScalarMap(lat, Display.YAxis);
display.addMap(ymap);
if (args.length > 1) {
ScalarMap flowd_map = new ScalarMap(flow_degree, Display.Flow1Azimuth);
display.addMap(flowd_map);
flowd_map.setRange(0.0, 360.0);
ScalarMap flows_map = new ScalarMap(flow_speed, Display.Flow1Radial);
display.addMap(flows_map);
flows_map.setRange(0.0, 1.0);
// jk start
// uncomment this line to give expected behaviour
// ScalarMap flows_text_map = new ScalarMap(flow_speed, Display.Text);
// but this line gives unexpected "0" everywhere when variable speed is
NaN
ScalarMap flows_text_map = new ScalarMap(flow_variable_speed,
Display.Text);
display.addMap(flows_text_map);
// jk end
TextControl tcontrol = (TextControl) flows_text_map.getControl(); // WLH
tcontrol.setNumberFormat(new DecimalFormat()); // WLH
FlowControl flow_control = (FlowControl) flows_map.getControl();
flow_control.setFlowScale(0.1f);
}
else {
ScalarMap flowx_map = new ScalarMap(flowx, Display.Flow1X);
display.addMap(flowx_map);
flowx_map.setRange(-1.0, 1.0);
ScalarMap flowy_map = new ScalarMap(flowy, Display.Flow1Y);
display.addMap(flowy_map);
flowy_map.setRange(-1.0, 1.0);
FlowControl flow_control = (FlowControl) flowy_map.getControl();
flow_control.setFlowScale(0.1f);
}
display.addMap(new ScalarMap(red, Display.Red));
display.addMap(new ScalarMap(green, Display.Green));
display.addMap(new ConstantMap(1.0, Display.Blue));
Integer1DSet set = new Integer1DSet(N * N);
// jk start
// double[][] values = new double[6][N * N];
double[][] values = new double[8][N * N];
// jk end
int m = 0;
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
double u = 2.0 * i / (N - 1.0) - 1.0;
double v = 2.0 * j / (N - 1.0) - 1.0;
values[0][m] = 10.0 * u;
values[1][m] = 10.0 * v + mid_lat;
double fx = 30.0 * u;
double fy = 30.0 * v;
if (args.length > 1) {
values[2][m] =
Data.RADIANS_TO_DEGREES * Math.atan2(-fx, -fy);
values[3][m] = Math.sqrt(fx * fx + fy * fy);
values[6][m] = Double.NaN;
values[7][m] = Double.NaN;
}
else {
values[2][m] = fx;
values[3][m] = fy;
}
values[4][m] = u;
values[5][m] = v;
m++;
}
}
FlatField field = new FlatField(flow_field, set);
field.setSamples(values);
DataReferenceImpl ref = new DataReferenceImpl("ref");
ref.setData(field);
BarbRendererJ3D renderer = new BarbRendererJ3D();
renderer.setKnotsConvert(true);
display.addReferences(renderer, ref);
// create JFrame (i.e., a window) for display and slider
JFrame frame = new JFrame("test BarbRendererJ3D");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
// create JPanel in JFrame
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setAlignmentY(JPanel.TOP_ALIGNMENT);
panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
frame.getContentPane().add(panel);
// add display to JPanel
panel.add(display.getComponent());
// set size of JFrame and make it visible
frame.setSize(500, 500);
frame.setVisible(true);
}
}