/* VisAD Tutorial Copyright (C) 2000-2001 Ugo Taddei */ package tutorial.s6; // Import needed classes import visad.*; import visad.java2d.DisplayImplJ2D; import visad.java2d.DirectManipulationRendererJ2D; import visad.java3d.*; import visad.util.*; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.util.Vector; /** VisAD Tutorial example 6_08 Direct Manipulation of a line Resample surface into a line with MathType (easting -> temperature ) Use Gridded1DSet for line and two VisADSliders to control northing and number of points Run program with java P6_08 * */ public class P6_08{ // Declare variables // The quantities to be displayed in x- and y-axes private RealType easting, northing, temperature; // lat and lon form a domain private RealTupleType domain; // A Tuple of Reals (a subclass of VisAD Data) // which will hold cursor data. private Real cursorCoords; // and this FlatField will hold the surface private FlatField surfsField; // Set for temperLine private Set tLineSet; // The temperature line private FlatField temperLine; // The white line private Set whiteLine; // The DataReferences from the data to display private DataReferenceImpl cursorDataRef, surfDataRef; private DataReferenceImpl wLineDataRef, tLineDataRef; // this Real hold the number of points per line private Real nPoints; // data reference for the number of points private DataReference nPointsRef; // The 2D display, and its the maps private DisplayImpl[] displays; private ScalarMap lonMap, latMap, rgbMap; public P6_08 (String[] args) throws RemoteException, VisADException { // Create the quantities easting = RealType.getRealType("easting", SI.meter, null); northing = RealType.getRealType("northing", SI.meter, null); temperature = RealType.getRealType("temperature", SI.kelvin, null); //...and the domain domain = new RealTupleType(easting, northing); // Create the Data: // The cursor double initLatitude = 0.0; cursorCoords = new Real(northing, initLatitude); // Create the DataReference cursorDataRef = new DataReferenceImpl("cursorDataRef"); // ...and initialize it with the RealTuple cursorDataRef.setData( cursorCoords ); // More Data: create a Surface object and get its data // ...which we know from section 3.5 that is a FlatField // with MathType ( (easting, northing) -> elevation ) Surface surf = new Surface(); surfsField = surf.getData(); surfDataRef = new DataReferenceImpl("surfDataRef"); surfDataRef.setData(surfsField); // number of points as a real and its reference nPoints = new Real(100.0); nPointsRef = new DataReferenceImpl("nPointsRef"); nPointsRef.setData(nPoints); // Create the white line // with so many points int numberOfPoints = (int) nPoints.getValue(); whiteLine = (Set) makeLineSet(initLatitude, numberOfPoints); // Create the line's data ref and set data wLineDataRef = new DataReferenceImpl("wLineDataRef"); wLineDataRef.setData(whiteLine); // Create the temperature line to be shown on display // ...using a different function String newFuncStr = "( easting -> temperature )"; FunctionType lineType = (FunctionType) surfsField.getType().stringToType( newFuncStr ) ; // get samples from white line float[][] lonSamples = whiteLine.getSamples(false); // create line function set tLineSet = new Linear1DSet( easting, lonSamples[0][0], lonSamples[0][ numberOfPoints-1] , numberOfPoints); // create Function (FlatField) and set the data temperLine = new FlatField( lineType, tLineSet ); temperLine.setSamples( surfsField.resample( whiteLine).getFloats(false), false); // create and set data reference tLineDataRef = new DataReferenceImpl("tLineDataRef"); tLineDataRef.setData(temperLine); CellImpl cell = new CellImpl() { public void doAction() throws RemoteException, VisADException { // get the data object from the reference. We know it's a RealTuple Real lat = (Real) cursorDataRef.getData(); // test if cursor postion (northing) has changed significantly if( Util.isApproximatelyEqual( lat.getValue(), cursorCoords.getValue(), 0.1 ) && Util.isApproximatelyEqual( nPoints.getValue(), ((Real) nPointsRef.getData()).getValue(), 2 ) ){ return; // leave method and thus don't update line } double latValue = lat.getValue(); // make a new line for display 1: will have only 2 points int nOfPoints = 2; whiteLine = (Set) makeLineSet(latValue, nOfPoints); // Re-set Data, will update display wLineDataRef.setData(whiteLine); // now create a larger white line set to compute the temperature line nOfPoints = (int) ((Real) nPointsRef.getData()).getValue(); whiteLine = (Set) makeLineSet(latValue, nOfPoints); // get samples from white line float[][] lonSamps = whiteLine.getSamples(false); // create line function set tLineSet = new Linear1DSet( easting, lonSamps[0][0], lonSamps[0][ nOfPoints-1] , nOfPoints); // fuction will have this type String funcStr = "( easting -> temperature )"; // create Function (FlatField) and set the data temperLine = new FlatField( (FunctionType) MathType.stringToType( funcStr ), tLineSet ); temperLine.setSamples( surfsField.resample( whiteLine).getFloats(false), false); // and update ist data reference -> will update display tLineDataRef.setData(temperLine); // assign current cursor position to old cursor position cursorCoords = lat; } }; // link cursor to cell // so that doAction gets called whenever cursor moves cell.addReference(cursorDataRef); cell.addReference(nPointsRef); // create a slider, to show and control northing values VisADSlider latSlider = new VisADSlider(cursorDataRef, -4, 4, 0, northing, "Northing"); // this slider will control the number of points VisADSlider pointsSlider = new VisADSlider(nPointsRef, 2, 100, 50, RealType.Generic, "Points/Line"); // Create the Displays and their maps // Two 2D displays displays = new DisplayImpl[2]; for( int i = 0; i<2;i++){ displays[i] = new DisplayImplJ2D("display" + i); } // Get display's graphics mode control draw scales for( int i = 0; i<2;i++){ GraphicsModeControl dispGMC = (GraphicsModeControl) displays[i].getGraphicsModeControl(); dispGMC.setScaleEnable(true); } // Create the ScalarMaps lonMap = new ScalarMap( easting, Display.XAxis ); latMap = new ScalarMap( northing, Display.YAxis ); rgbMap = new ScalarMap( temperature, Display.RGB ); // Add maps to display displays[0].addMap( lonMap ); displays[0].addMap( latMap ); displays[0].addMap( rgbMap ); // Copy those maps and add to second display // but choose only two of the maps displays[1].addMap( (ScalarMap) lonMap.clone() ); displays[1].addMap( (ScalarMap) rgbMap.clone() ); displays[1].addMap( new ScalarMap( temperature, Display.YAxis) ); // uncomment here if your display 1 is 3D //displays[1].addMap( new ScalarMap( northing, Display.ZAxis) ); // Also create constant maps to define cursor size, color, etc... ConstantMap[] cMaps = { new ConstantMap( 0.0f, Display.Red ), new ConstantMap( 1.0f, Display.Green ), new ConstantMap( 0.0f, Display.Blue ), new ConstantMap( 1.0f, Display.XAxis ), new ConstantMap( 3.50f, Display.PointSize ) }; // ...and constant maps to make lines slightly thicker ConstantMap[] wLineMaps = { new ConstantMap( 0.70f, Display.Red ), new ConstantMap( 0.70f, Display.Green ), new ConstantMap( 0.70f, Display.Blue ), new ConstantMap( 3.50f, Display.LineWidth ) }; ConstantMap[] tLineMaps = { new ConstantMap( 2.0f, Display.LineWidth ) }; // Now Add reference to display // But using a direct manipulation renderer // display 1 displays[0].addReferences( new DirectManipulationRendererJ2D(), cursorDataRef, cMaps ); displays[0].addReference(surfDataRef); displays[0].addReference(wLineDataRef, wLineMaps); // display 2 displays[1].addReference(tLineDataRef, tLineMaps); // Create application window, put display into it JFrame jframe = new JFrame("VisAD Tutorial example 6_08"); jframe.getContentPane().setLayout(new BorderLayout()); JPanel dispPanel = new JPanel( new GridLayout(1,2) ); dispPanel.add(displays[0].getComponent()); dispPanel.add(displays[1].getComponent()); jframe.getContentPane().add(dispPanel, BorderLayout.CENTER); dispPanel = new JPanel( new GridLayout(1,2) ); dispPanel.add(latSlider); dispPanel.add(pointsSlider); jframe.getContentPane().add(dispPanel, BorderLayout.SOUTH); // Set window size and make it visible jframe.setSize(600, 300); jframe.setVisible(true); } private Set makeLineSet( double northingValue, int pointsPerLine ) throws VisADException, RemoteException { // arbitrary easting end values of the line double lowVal = -4.0; double hiVal = 4.0; double[][] domainSamples = new double[2][pointsPerLine]; double lonVal = lowVal; double increment = ( hiVal - lowVal )/ (double) (pointsPerLine-1) ; for(int i=0;i