/** check for flow mappings; does not allow flow mapping through CoordinateSystem */ private String findFlow( ShadowTupleType shadow, DisplayImpl display, DisplayTupleType[] tuples, int[] flowToComponent) { ShadowRealType[] components = shadow.getRealComponents(); for (int i = 0; i < components.length; i++) { int num_flow_per_real = 0; Enumeration maps = components[i].getSelectedMapVector().elements(); while (maps.hasMoreElements()) { ScalarMap map = (ScalarMap) maps.nextElement(); DisplayRealType dreal = map.getDisplayScalar(); DisplayTupleType tuple = dreal.getTuple(); if (Display.DisplayFlow1Tuple.equals(tuple) || Display.DisplayFlow2Tuple.equals(tuple)) { if (tuples[0] != null) { if (!tuples[0].equals(tuple)) { return multipleFlowTuples; } } else { tuples[0] = tuple; } num_flow_per_real++; if (num_flow_per_real > 1) { return multipleFlowMapping; } int index = dreal.getTupleIndex(); flowToComponent[index] = i; directMap[index] = map; } else if (Display.DisplayFlow1SphericalTuple.equals(tuple) || Display.DisplayFlow2SphericalTuple.equals(tuple)) { if (tuples[0] != null) { if (!tuples[0].equals(tuple)) { return multipleFlowTuples; } } else { tuples[0] = tuple; coord = tuple.getCoordinateSystem(); } num_flow_per_real++; if (num_flow_per_real > 1) { return multipleFlowMapping; } int index = dreal.getTupleIndex(); flowToComponent[index] = i; directMap[index] = map; } } // while (maps.hasMoreElements()) } return null; }
/** ensure that non-Manual components of flow_tuple have equal dataRanges symmetric about 0.0 */ public static void equalizeFlow(Vector mapVector, DisplayTupleType flow_tuple) throws VisADException, RemoteException { double[] range = new double[2]; double low = Double.MAX_VALUE; double hi = -Double.MAX_VALUE; boolean anyAuto = false; Enumeration maps = mapVector.elements(); while (maps.hasMoreElements()) { ScalarMap map = ((ScalarMap) maps.nextElement()); DisplayRealType dtype = map.getDisplayScalar(); DisplayTupleType tuple = dtype.getTuple(); if (flow_tuple.equals(tuple) && !map.isManual && !map.badRange()) { anyAuto = true; low = Math.min(low, map.dataRange[0]); hi = Math.max(hi, map.dataRange[1]); } } if (!anyAuto) return; hi = Math.max(hi, -low); low = -hi; maps = mapVector.elements(); while (maps.hasMoreElements()) { ScalarMap map = ((ScalarMap) maps.nextElement()); DisplayRealType dtype = map.getDisplayScalar(); DisplayTupleType tuple = dtype.getTuple(); if (flow_tuple.equals(tuple) && !map.isManual && !map.badRange()) { map.setRange(null, low, hi, false); } } }
/** * prepare for transforming Data into scene graph depictions, including possible auto-scaling of * ScalarMaps * * @param temp Vector of DataRenderers * @param tmap Vector of ScalarMaps * @param go flag indicating whether Data transforms are requested * @param initialize flag indicating whether auto-scaling is requested * @throws VisADException a VisAD error occurred * @throws RemoteException an RMI error occurred */ public void prepareAction(Vector temp, Vector tmap, boolean go, boolean initialize) throws VisADException, RemoteException { DataShadow shadow = null; Enumeration renderers = temp.elements(); while (renderers.hasMoreElements()) { DataRenderer renderer = (DataRenderer) renderers.nextElement(); shadow = renderer.prepareAction(go, initialize, shadow); } if (shadow != null) { // apply RealType ranges and animationSampling Enumeration maps = tmap.elements(); while (maps.hasMoreElements()) { ScalarMap map = ((ScalarMap) maps.nextElement()); map.setRange(shadow); } } ScalarMap.equalizeFlow(tmap, Display.DisplayFlow1Tuple); ScalarMap.equalizeFlow(tmap, Display.DisplayFlow2Tuple); }
/** * Set <CODE>Vector</CODE> of <CODE>String</CODE>s describing the cursor location from the cursor * location; this is invoked when the cursor location changes or the cursor display status changes */ public void setCursorStringVector() { synchronized (cursorStringVector) { cursorStringVector.removeAllElements(); float[][] cursor = new float[3][1]; double[] cur = getCursor(); cursor[0][0] = (float) cur[0]; cursor[1][0] = (float) cur[1]; cursor[2][0] = (float) cur[2]; Enumeration maps = display.getMapVector().elements(); while (maps.hasMoreElements()) { try { ScalarMap map = (ScalarMap) maps.nextElement(); DisplayRealType dreal = map.getDisplayScalar(); DisplayTupleType tuple = dreal.getTuple(); int index = dreal.getTupleIndex(); if (tuple != null && (tuple.equals(Display.DisplaySpatialCartesianTuple) || (tuple.getCoordinateSystem() != null && tuple .getCoordinateSystem() .getReference() .equals(Display.DisplaySpatialCartesianTuple)))) { float[] fval = new float[1]; if (tuple.equals(Display.DisplaySpatialCartesianTuple)) { fval[0] = cursor[index][0]; } else { float[][] new_cursor = tuple.getCoordinateSystem().fromReference(cursor); fval[0] = new_cursor[index][0]; } float[] dval = map.inverseScaleValues(fval); RealType real = (RealType) map.getScalar(); // WLH 31 Aug 2000 Real r = new Real(real, dval[0]); Unit overrideUnit = map.getOverrideUnit(); Unit rtunit = real.getDefaultUnit(); // units not part of Time string // DRM 2003-08-19: don't check for equality since toString // may be different if (overrideUnit != null && // !overrideUnit.equals(rtunit) && (!Unit.canConvert(rtunit, CommonUnit.secondsSinceTheEpoch) || rtunit.getAbsoluteUnit().equals(rtunit))) { dval[0] = (float) overrideUnit.toThis((double) dval[0], rtunit); r = new Real(real, dval[0], overrideUnit); } String valueString = r.toValueString(); // WLH 27 Oct 2000 String s = map.getScalarName() + " = " + valueString; // String s = real.getName() + " = " + valueString; cursorStringVector.addElement(s); } // end if (tuple != null && ...) } catch (VisADException e) { } } // end while(maps.hasMoreElements()) } // end synchronized (cursorStringVector) render_trigger(); }
protected void copy(ScalarMap map) throws VisADException, RemoteException { map.isScaled = isScaled; map.isManual = isManual; map.dataRange[0] = dataRange[0]; map.dataRange[1] = dataRange[1]; map.defaultUnitRange[0] = defaultUnitRange[0]; map.defaultUnitRange[1] = defaultUnitRange[1]; map.displayRange[0] = displayRange[0]; map.displayRange[1] = displayRange[1]; map.scale = scale; map.offset = offset; map.axisScale = (axisScale != null) ? axisScale.clone(map) : null; map.scale_flag = scale_flag; map.back_scale_flag = back_scale_flag; if (map.display != null) { map.setControl(); } }
/** * Compares this ScalarMap with another ScalarMap. The ScalarType-s are first compared; if they * compare equal, then the DisplayRealType-s are compared. * * @param that The other ScalarMap. * @return A value that is negative, zero, or positive depending on whether this ScalarMap is * considered less than, equal to, or greater than the other ScalarMap, respectively. */ protected int compareTo(ScalarMap that) { int comp = getScalar().compareTo(that.getScalar()); if (comp == 0) comp = getDisplayScalar().compareTo(that.getDisplayScalar()); return comp; }
/** * transform data into a (Java3D or Java2D) scene graph; add generated scene graph components as * children of group; group is Group (Java3D) or VisADGroup (Java2D); value_array are inherited * valueArray values; default_values are defaults for each display.DisplayRealTypeVector; return * true if need post-process */ public boolean doTransform( Object group, Data data, float[] value_array, float[] default_values, DataRenderer renderer, ShadowType shadow_api) throws VisADException, RemoteException { if (data.isMissing()) return false; if (LevelOfDifficulty == NOTHING_MAPPED) return false; if (!(data instanceof Text)) { throw new DisplayException("data must be Text: " + "ShadowTextType.doTransform"); } // get some precomputed values useful for transform // length of ValueArray int valueArrayLength = display.getValueArrayLength(); // mapping from ValueArray to DisplayScalar int[] valueToScalar = display.getValueToScalar(); // mapping from ValueArray to MapVector int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); // array to hold values for various mappings float[][] display_values = new float[valueArrayLength][]; // ???? // get values inherited from parent; // assume these do not include SelectRange, SelectValue // or Animation values - see temporary hack in // DataRenderer.isTransformControl int[] inherited_values = getInheritedValues(); for (int i = 0; i < valueArrayLength; i++) { if (inherited_values[i] > 0) { display_values[i] = new float[1]; display_values[i][0] = value_array[i]; } } boolean[][] range_select = shadow_api.assembleSelect( display_values, 1, valueArrayLength, valueToScalar, display, shadow_api); if (range_select[0] != null && !range_select[0][0]) { // data not selected return false; } // get any text String and TextControl inherited from parent String text_value = shadow_api.getParentText(); TextControl text_control = shadow_api.getParentTextControl(); boolean anyText = getAnyText(); if (anyText && text_value == null) { // get any text String and TextControl from this Vector maps = getSelectedMapVector(); if (!maps.isEmpty()) { text_value = ((Text) data).getValue(); ScalarMap map = (ScalarMap) maps.firstElement(); text_control = (TextControl) map.getControl(); } } // // never renders text ???? // // add values to value_array according to SelectedMapVector if (getIsTerminal()) { // ???? return terminalTupleOrScalar( group, display_values, text_value, text_control, valueArrayLength, valueToScalar, default_values, inherited_values, renderer, shadow_api); } else { // nothing to render at a non-terminal TextType } return false; }
/** test BarbManipulationRendererJ3D */ public static void main(String args[]) throws VisADException, RemoteException { System.out.println("BMR.main()"); // construct RealTypes for wind record components RealType lat = RealType.Latitude; RealType lon = RealType.Longitude; RealType windx = RealType.getRealType("windx", CommonUnit.meterPerSecond); RealType windy = RealType.getRealType("windy", CommonUnit.meterPerSecond); RealType red = RealType.getRealType("red"); RealType green = RealType.getRealType("green"); // EarthVectorType extends RealTupleType and says that its // components are vectors in m/s with components parallel // to Longitude (positive east) and Latitude (positive north) EarthVectorType windxy = new EarthVectorType(windx, windy); RealType wind_dir = RealType.getRealType("wind_dir", CommonUnit.degree); RealType wind_speed = RealType.getRealType("wind_speed", CommonUnit.meterPerSecond); RealTupleType windds = null; if (args.length > 0) { System.out.println("polar winds"); windds = new RealTupleType( new RealType[] {wind_dir, wind_speed}, new WindPolarCoordinateSystem(windxy), null); } // construct Java3D display and mappings that govern // how wind records are displayed DisplayImpl display = new DisplayImplJ3D("display1", new TwoDDisplayRendererJ3D()); ScalarMap lonmap = new ScalarMap(lon, Display.XAxis); display.addMap(lonmap); ScalarMap latmap = new ScalarMap(lat, Display.YAxis); display.addMap(latmap); FlowControl flow_control; if (args.length > 0) { ScalarMap winds_map = new ScalarMap(wind_speed, Display.Flow1Radial); display.addMap(winds_map); winds_map.setRange(0.0, 1.0); // do this for barb rendering ScalarMap windd_map = new ScalarMap(wind_dir, Display.Flow1Azimuth); display.addMap(windd_map); windd_map.setRange(0.0, 360.0); // do this for barb rendering flow_control = (FlowControl) windd_map.getControl(); flow_control.setFlowScale(0.15f); // this controls size of barbs } else { ScalarMap windx_map = new ScalarMap(windx, Display.Flow1X); display.addMap(windx_map); windx_map.setRange(-1.0, 1.0); // do this for barb rendering ScalarMap windy_map = new ScalarMap(windy, Display.Flow1Y); display.addMap(windy_map); windy_map.setRange(-1.0, 1.0); // do this for barb rendering flow_control = (FlowControl) windy_map.getControl(); flow_control.setFlowScale(0.15f); // this controls size of barbs } display.addMap(new ScalarMap(red, Display.Red)); display.addMap(new ScalarMap(green, Display.Green)); display.addMap(new ConstantMap(1.0, Display.Blue)); DataReferenceImpl[] refs = new DataReferenceImpl[N * N]; int k = 0; // create an array of N by N winds 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; // each wind record is a Tuple (lon, lat, (windx, windy), red, green) // set colors by wind components, just for grins Tuple tuple; double fx = 30.0 * u; double fy = 30.0 * v; if (args.length > 0) { double fd = Data.RADIANS_TO_DEGREES * Math.atan2(-fx, -fy); double fs = Math.sqrt(fx * fx + fy * fy); tuple = new Tuple( new Data[] { new Real(lon, 10.0 * u), new Real(lat, 10.0 * v - 40.0), new RealTuple(windds, new double[] {fd, fs}), new Real(red, u), new Real(green, v) }); } else { tuple = new Tuple( new Data[] { new Real(lon, 10.0 * u), new Real(lat, 10.0 * v - 40.0), new RealTuple(windxy, new double[] {fx, fy}), new Real(red, u), new Real(green, v) }); } // construct reference for wind record refs[k] = new DataReferenceImpl("ref_" + k); refs[k].setData(tuple); // link wind record to display via BarbManipulationRendererJ3D // so user can change barb by dragging it // drag with right mouse button and shift to change direction // drag with right mouse button and no shift to change speed BarbManipulationRendererJ3D renderer = new BarbManipulationRendererJ3D(); renderer.setKnotsConvert(true); display.addReferences(renderer, refs[k]); // link wind record to a CellImpl that will listen for changes // and print them WindGetterJ3D cell = new WindGetterJ3D(flow_control, refs[k]); cell.addReference(refs[k]); k++; } } // instead of linking the wind record "DataReferenceImpl refs" to // the WindGetterJ3Ds, you can have some user interface event (e.g., // the user clicks on "DONE") trigger code that does a getData() on // all the refs and stores the records in a file. // create JFrame (i.e., a window) for display and slider JFrame frame = new JFrame("test BarbManipulationRendererJ3D"); 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); }
/** * run 'java FlowTest middle_latitude' to test with (lat, lon) run 'java FlowTest middle_latitude * x' to test with (lon, lat) adjust middle_latitude for south or north */ 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) { } } boolean swap = (args.length > 1); RealType lat = RealType.Latitude; RealType lon = RealType.Longitude; RealType[] types; if (swap) { types = new RealType[] {lon, lat}; } else { types = new RealType[] {lat, lon}; } RealTupleType earth_location = new RealTupleType(types); System.out.println("earth_location = " + earth_location + " mid_lat = " + mid_lat); RealType flowx = RealType.getRealType("flowx", CommonUnit.meterPerSecond); RealType flowy = RealType.getRealType("flowy", CommonUnit.meterPerSecond); RealType red = RealType.getRealType("red"); RealType green = RealType.getRealType("green"); EarthVectorType flowxy = new EarthVectorType(flowx, flowy); TupleType range = null; range = new TupleType(new MathType[] {flowxy, red, green}); FunctionType flow_field = new FunctionType(earth_location, range); DisplayImpl display = new DisplayImplJ3D("display1", new TwoDDisplayRendererJ3D()); ScalarMap xmap = new ScalarMap(lon, Display.XAxis); display.addMap(xmap); ScalarMap ymap = new ScalarMap(lat, Display.YAxis); display.addMap(ymap); ScalarMap flowx_map = new ScalarMap(flowx, Display.Flow1X); display.addMap(flowx_map); flowx_map.setRange(-10.0, 10.0); ScalarMap flowy_map = new ScalarMap(flowy, Display.Flow1Y); display.addMap(flowy_map); flowy_map.setRange(-10.0, 10.0); FlowControl flow_control = (FlowControl) flowy_map.getControl(); flow_control.setFlowScale(0.05f); display.addMap(new ScalarMap(red, Display.Red)); display.addMap(new ScalarMap(green, Display.Green)); display.addMap(new ConstantMap(1.0, Display.Blue)); double lonlow = -10.0; double lonhi = 10.0; double latlow = mid_lat - 10.0; double lathi = mid_lat + 10.0; Linear2DSet set; if (swap) { set = new Linear2DSet(earth_location, lonlow, lonhi, N, latlow, lathi, N); } else { set = new Linear2DSet(earth_location, latlow, lathi, N, lonlow, lonhi, N); } double[][] values = new double[4][N * N]; int m = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int k = i; int l = j; if (swap) { k = j; l = i; } double u = (N - 1.0) / 2.0 - l; double v = k - (N - 1.0) / 2.0; // double u = 2.0 * k / (N - 1.0) - 1.0; // double v = 2.0 * l / (N - 1.0); double fx = 6.0 * u; double fy = 6.0 * v; values[0][m] = fx; values[1][m] = fy; values[2][m] = u; values[3][m] = v; m++; } } FlatField field = new FlatField(flow_field, set); field.setSamples(values); DataReferenceImpl ref = new DataReferenceImpl("ref"); ref.setData(field); display.addReference(ref); // create JFrame (i.e., a window) for display and slider JFrame frame = new JFrame("test FlowTest"); 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); }