001 /* 002 * $Id: SubsetRubberBandBox.java,v 1.13 2012/03/27 21:58:01 rink Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2012 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030 031 package edu.wisc.ssec.mcidasv.data.hydra; 032 033 import edu.wisc.ssec.mcidasv.data.hydra.MyRubberBandBoxRendererJ3D; 034 035 import ucar.visad.display.Displayable; 036 import ucar.visad.display.LineDrawing; 037 038 import visad.*; 039 import visad.bom.*; 040 041 import java.rmi.RemoteException; 042 043 import java.awt.event.InputEvent; 044 045 046 public class SubsetRubberBandBox extends LineDrawing { 047 048 /** x type for the box */ 049 private RealType xType; 050 051 /** y type for the box */ 052 private RealType yType; 053 054 /** renderer */ 055 private MyRubberBandBoxRendererJ3D rubberBandBox; 056 057 /** bounds defined by the rubber band box */ 058 private Gridded2DSet bounds; 059 060 /** mouse event mask */ 061 private int mask; 062 063 private FlatField data; 064 private boolean isLL; 065 private boolean lastBoxOn; 066 067 private CoordinateSystem dataCS; 068 069 private CoordinateSystem displayCS; 070 071 private static int count = 0; 072 073 /** 074 * Construct a RubberBandBox using xType as the X coordinate and 075 * yType as the Y coordinate of the box. 076 * 077 * @param xType RealType of the X coordinate of the box 078 * @param yType RealType of the Y coordinate of the box 079 * 080 * @throws VisADException VisAD error 081 * @throws RemoteException Remote error 082 */ 083 public SubsetRubberBandBox(FlatField data, CoordinateSystem displayCS) 084 throws VisADException, RemoteException { 085 this(false, data, displayCS, 0); 086 } 087 088 public SubsetRubberBandBox(FlatField data, CoordinateSystem displayCS, int mask) 089 throws VisADException, RemoteException { 090 this(false, data, displayCS, mask); 091 } 092 093 public SubsetRubberBandBox(boolean isLL, FlatField data, CoordinateSystem displayCS, int mask) 094 throws VisADException, RemoteException { 095 this(isLL, data, displayCS, mask, true); 096 } 097 098 public SubsetRubberBandBox(FlatField data, CoordinateSystem displayCS, int mask, boolean lastBoxOn) 099 throws VisADException, RemoteException { 100 this(false, data, displayCS, mask, lastBoxOn); 101 } 102 103 104 105 /** 106 * Construct a RubberBandBox using xType as the X coordinate and 107 * yType as the Y coordinate of the box. 108 * 109 * @param xType RealType of the X coordinate of the box 110 * @param yType RealType of the Y coordinate of the box 111 * @param mask key mask to use for rubberbanding 112 * 113 * @throws VisADException VisAD error 114 * @throws RemoteException Remote error 115 */ 116 public SubsetRubberBandBox(boolean isLL, FlatField data, CoordinateSystem displayCS, int mask, boolean lastBoxOn) 117 throws VisADException, RemoteException { 118 super("Subset Rubber Band Box"); 119 120 this.data = data; 121 this.displayCS = displayCS; 122 this.isLL = isLL; 123 this.lastBoxOn = lastBoxOn; 124 125 RealTupleType rtype = ((FunctionType)data.getType()).getDomain(); 126 dataCS = rtype.getCoordinateSystem(); 127 if (dataCS == null) { 128 dataCS = new GridCoordinateSystem((GriddedSet)data.getDomainSet()); 129 } 130 131 IdentityCoordinateSystem iCS = 132 new IdentityCoordinateSystem( 133 new RealTupleType(new RealType[] {RealType.getRealType("ZZtop")})); 134 135 CoordinateSystem cs = 136 new CartesianProductCoordinateSystem(new CoordinateSystem[] {dataCS, iCS}); 137 138 CoordinateSystem new_cs = new DataToDisplayCoordinateSystem(isLL, cs, displayCS); 139 140 141 DisplayRealType displayLineType = 142 new DisplayRealType("displayLine_"+count, true, 0.0, 10000.0, 0.0, null); 143 DisplayRealType displayElemType = 144 new DisplayRealType("displayElem_"+count, true, 0.0, 10000.0, 0.0, null); 145 DisplayRealType displayAltType = 146 new DisplayRealType("displayAlt_"+count, true, -1.0, 1.0, 0.0, null); 147 DisplayTupleType dtt = 148 new DisplayTupleType(new DisplayRealType[] {displayLineType, displayElemType, displayAltType}, new_cs); 149 150 151 RealType elemType = RealType.getRealType("elem_"+count); 152 RealType lineType = RealType.getRealType("line_"+count); 153 this.xType = lineType; 154 this.yType = elemType; 155 this.mask = mask; 156 bounds = new Gridded2DSet(new RealTupleType(xType, yType), null, 1); 157 158 ScalarMap elemMap = new ScalarMap(elemType, displayElemType); 159 ScalarMap lineMap = new ScalarMap(lineType, displayLineType); 160 161 GriddedSet domainSet = (GriddedSet) data.getDomainSet(); 162 float[] low = domainSet.getLow(); 163 float[] hi = domainSet.getHi(); 164 165 elemMap.setRange(low[1], hi[1]); 166 lineMap.setRange(low[0], hi[0]); 167 168 addScalarMap(elemMap); 169 addScalarMap(lineMap); 170 171 setData(bounds); 172 count += 1; 173 } 174 175 /** 176 * Constructor for creating a RubberBandBox from another instance 177 * 178 * @param that other instance 179 * 180 * @throws VisADException VisAD error 181 * @throws RemoteException Remote error 182 */ 183 protected SubsetRubberBandBox(SubsetRubberBandBox that) 184 throws VisADException, RemoteException { 185 186 super(that); 187 188 this.xType = that.xType; 189 this.yType = that.yType; 190 this.bounds = that.bounds; 191 } 192 193 /** 194 * Invoked when box mouse is released. Subclasses should invoke 195 * super.dataChange() to ensure the the bounds are set. 196 * 197 * @throws RemoteException 198 * @throws VisADException 199 */ 200 protected void dataChange() throws VisADException, RemoteException { 201 202 bounds = (Gridded2DSet) getData(); 203 float[] highs = bounds.getHi(); 204 float[] lows = bounds.getLow(); 205 if (highs != null && lows != null) 206 super.dataChange(); 207 } 208 209 /** 210 * Return the bounds of the RubberBandBox. The Gridded2DSet that 211 * is returned contains the opposite (starting and ending) corners 212 * of the box. 213 * 214 * @return set containing the opposite corners of the box. 215 */ 216 public Gridded2DSet getBounds() { 217 return bounds; 218 } 219 220 /** 221 * Get the DataRenderer used for this displayable. 222 * 223 * @return RubberBandBoxRendererJ3D associated with this displayable 224 */ 225 protected DataRenderer getDataRenderer() { 226 rubberBandBox = new MyRubberBandBoxRendererJ3D(xType, yType, mask, 227 mask); 228 rubberBandBox.setKeepLastBoxOn(lastBoxOn); 229 230 return rubberBandBox; 231 } 232 233 /** 234 * Returns a clone of this instance suitable for another VisAD display. 235 * Underlying data objects are not cloned. 236 * 237 * @return A semi-deep clone of this instance. 238 * 239 * @throws VisADException VisAD failure. 240 * @throws RemoteException Java RMI failure. 241 */ 242 public Displayable cloneForDisplay() 243 throws RemoteException, VisADException { 244 return new SubsetRubberBandBox(this); 245 } 246 247 public void setBox(SubsetRubberBandBox rbb) { 248 rubberBandBox.setLastBox((MyRubberBandBoxRendererJ3D)rbb.getDataRenderer()); 249 } 250 251 public Gridded3DSet getLastBox() { 252 return rubberBandBox.last_box; 253 } 254 } 255 256 257 class DataToDisplayCoordinateSystem extends CoordinateSystem { 258 private CoordinateSystem dataCS; 259 private CoordinateSystem displayCS; 260 private boolean isLL; 261 262 263 DataToDisplayCoordinateSystem(boolean isLL, CoordinateSystem dataCS, CoordinateSystem displayCS) throws VisADException { 264 super(displayCS.getReference(), null); 265 try { 266 this.dataCS = dataCS; 267 this.displayCS = displayCS; 268 this.isLL = isLL; 269 } catch (Exception e) { 270 System.out.println("e=" + e); 271 } 272 } 273 274 public float[][] toReference(float[][] values) throws VisADException { 275 //- if (isLL) values = reverseArrayOrder(values); 276 float[][] new_values = dataCS.toReference(values); 277 if (isLL) new_values = reverseArrayOrder(new_values); 278 new_values = displayCS.toReference(new float[][] {new_values[1], new_values[0], new_values[2]}); 279 return new_values; 280 } 281 282 public float[][] fromReference(float[][] values) throws VisADException { 283 //- if (isLL) values = reverseArrayOrder(values); 284 float[][] new_values = displayCS.fromReference(values); 285 if (isLL) new_values = reverseArrayOrder(new_values); 286 new_values = dataCS.fromReference(new float[][] {new_values[1], new_values[0], new_values[2]}); 287 288 return new_values; 289 } 290 291 public double[][] toReference(double[][] values) throws VisADException { 292 //- if (isLL) values = reverseArrayOrder(values); 293 double[][] new_values = dataCS.toReference(values); 294 if (isLL) new_values = reverseArrayOrder(new_values); 295 new_values = displayCS.toReference(new double[][] {new_values[1], new_values[0], new_values[2]}); 296 297 return new_values; 298 } 299 300 public double[][] fromReference(double[][] values) throws VisADException { 301 //- if (isLL) values = reverseArrayOrder(values); 302 double[][] new_values = displayCS.fromReference(values); 303 if (isLL) new_values = reverseArrayOrder(new_values); 304 new_values = dataCS.fromReference(new double[][] {new_values[1], new_values[0], new_values[2]}); 305 return new_values; 306 } 307 308 public boolean equals(Object obj) { 309 return true; 310 } 311 312 private double[][] reverseArrayOrder(double[][] in) { 313 if (in.length < 2) return in; 314 int len1 = 2; 315 int len2 = in[0].length; 316 double[][] out = new double[in.length][len2];; 317 for (int i=0; i<len1; i++) { 318 for (int j=0; j<len2; j++) { 319 out[len1-i-1][j] = in[i][j]; 320 } 321 } 322 if (in.length > 2) { 323 for (int i=2; i<in.length; i++) { 324 for (int j=0; j<len2; j++) { 325 out[i][j] = in[i][j]; 326 } 327 } 328 } 329 return out; 330 } 331 332 333 private float[][] reverseArrayOrder(float[][] in) { 334 if (in.length < 2) return in; 335 int len1 = 2; 336 int len2 = in[0].length; 337 float[][] out = new float[in.length][len2];; 338 for (int i=0; i<len1; i++) { 339 for (int j=0; j<len2; j++) { 340 out[len1-i-1][j] = in[i][j]; 341 } 342 } 343 if (in.length > 2) { 344 for (int i=2; i<in.length; i++) { 345 for (int j=0; j<len2; j++) { 346 out[i][j] = in[i][j]; 347 } 348 } 349 } 350 return out; 351 } 352 }