001/* 002 * $Id: GeoPreviewSelection.java,v 1.55 2011/03/24 16:06:32 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 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 031package edu.wisc.ssec.mcidasv.data; 032 033import edu.wisc.ssec.mcidasv.data.hydra.HydraRGBDisplayable; 034import edu.wisc.ssec.mcidasv.data.hydra.MultiSpectralData; 035import edu.wisc.ssec.mcidasv.control.LambertAEA; 036 037import java.awt.BorderLayout; 038import java.awt.Color; 039import java.awt.geom.Rectangle2D; 040import java.awt.event.ComponentEvent; 041import java.awt.event.ComponentListener; 042import java.net.URL; 043import java.rmi.RemoteException; 044 045import javax.swing.*; 046 047import ucar.unidata.data.DataChoice; 048import ucar.unidata.data.DataSelection; 049import ucar.unidata.data.DataSourceImpl; 050import ucar.unidata.data.DataSelectionComponent; 051import ucar.unidata.data.GeoSelection; 052import ucar.unidata.data.grid.GridUtil; 053import ucar.unidata.idv.IdvObjectStore; 054import ucar.unidata.idv.MapViewManager; 055import ucar.unidata.util.Range; 056import ucar.unidata.view.geoloc.MapProjectionDisplay; 057import ucar.unidata.view.geoloc.MapProjectionDisplayJ3D; 058import ucar.visad.display.DisplayMaster; 059import ucar.visad.display.MapLines; 060 061import visad.*; 062import visad.data.mcidas.AREACoordinateSystem; 063import visad.data.mcidas.BaseMapAdapter; 064import ucar.visad.display.Displayable; 065import ucar.visad.display.LineDrawing; 066import visad.georef.MapProjection; 067import org.slf4j.Logger; 068import org.slf4j.LoggerFactory; 069 070 071public class GeoPreviewSelection extends DataSelectionComponent { 072 073 private static final Logger logger = LoggerFactory.getLogger(GeoPreviewSelection.class); 074 DataChoice dataChoice; 075 FlatField image; 076 boolean isLL; 077 MapProjection sampleProjection; 078 079 double[] x_coords = new double[2]; 080 double[] y_coords = new double[2]; 081 MapProjectionDisplayJ3D mapProjDsp; 082 DisplayMaster dspMaster; 083 MapViewManager mvm; 084 IdvObjectStore store; 085 086 final private GeoSubsetRubberBandBox rbb; 087 private int lineMag; 088 private int elementMag; 089 090 private GeoLatLonSelection laloSel; 091 092 private LineDrawing box; 093 094 public GeoPreviewSelection(DataSourceImpl dataSource, 095 DataChoice dataChoice, FlatField image, 096 GeoLatLonSelection laLoSel, 097 MapProjection sample, int lMag, int eMag, boolean showPreview) 098 throws VisADException, RemoteException { 099 super("Region"); 100 101 this.dataChoice = dataChoice; 102 this.image = image; 103 this.laloSel = laLoSel; 104 this.sampleProjection = sample; 105 106 if (lMag == 0) lMag = 1; 107 if (eMag == 0) eMag = 1; 108 this.lineMag = lMag; 109 this.elementMag = eMag; 110 sample = getDataProjection(); 111 112 if (this.sampleProjection == null) { 113 this.sampleProjection = sample; 114 } 115 116 isLL = sampleProjection.isLatLonOrder(); 117 118 mapProjDsp = new MapProjectionDisplayJ3D(MapProjectionDisplay.MODE_2Din3D); 119 mapProjDsp.enableRubberBanding(false); 120 dspMaster = mapProjDsp; 121 mapProjDsp.setMapProjection(sampleProjection); 122 RealType imageRangeType = 123 (((FunctionType)image.getType()).getFlatRange().getRealComponents())[0]; 124 HydraRGBDisplayable imageDsp = 125 new HydraRGBDisplayable("image", imageRangeType, null, true, null); 126 127 if (showPreview) imageDsp.setData(image); 128 129 MapLines mapLines = new MapLines("maplines"); 130 URL mapSource = 131 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPU"); 132 try { 133 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 134 mapLines.setMapLines(mapAdapter.getData()); 135 mapLines.setColor(java.awt.Color.cyan); 136 mapProjDsp.addDisplayable(mapLines); 137 } catch (Exception excp) { 138 System.err.println("Can't open map file " + mapSource); 139 System.err.println(excp); 140 } 141 142 mapLines = new MapLines("maplines"); 143 mapSource = 144 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPW"); 145 try { 146 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 147 mapLines.setMapLines(mapAdapter.getData()); 148 mapLines.setColor(java.awt.Color.cyan); 149 mapProjDsp.addDisplayable(mapLines); 150 } catch (Exception excp) { 151 System.err.println("Can't open map file " + mapSource); 152 System.err.println(excp); 153 } 154 155 mapLines = new MapLines("maplines"); 156 mapSource = 157 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLHPOL"); 158 try { 159 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 160 mapLines.setMapLines(mapAdapter.getData()); 161 mapLines.setColor(java.awt.Color.cyan); 162 mapProjDsp.addDisplayable(mapLines); 163 } catch (Exception excp) { 164 System.err.println("Can't open map file " + mapSource); 165 System.err.println(excp); 166 } 167 168 if (showPreview) dspMaster.addDisplayable(imageDsp); 169 rbb = 170 new GeoSubsetRubberBandBox(isLL, image, ((MapProjectionDisplay)mapProjDsp).getDisplayCoordinateSystem(), 1); 171 mvm = new MapViewManager(dataSource.getDataContext().getIdv()); 172 store = dataSource.getDataContext().getIdv().getStore(); 173 rbb.setColor((Color)store.get(mvm.PREF_FGCOLOR, Color.GREEN)); 174 rbb.addAction(new CellImpl() { 175 public void doAction() 176 throws VisADException, RemoteException 177 { 178 eraseBox(); 179 forceCoords(); 180 } 181 }); 182 addRBB(); 183 makeBox(); 184 185 dspMaster.draw(); 186 ScalarMap colorMap = imageDsp.getColorMap(); 187 if (showPreview) { 188 Range[] range = GridUtil.fieldMinMax(this.image); 189 Range imageRange = range[0]; 190 int max; 191 int min; 192 double dMax = imageRange.getMax(); 193 double dMin = imageRange.getMin(); 194 String name = this.dataChoice.getName(); 195 DataSelection ds = this.dataChoice.getDataSelection(); 196 if (ds != null) { 197 GeoSelection gs = ds.getGeoSelection(); 198 } 199 if (name.endsWith("TEMP")) { 200 min = (int)(dMax); 201 max = (int)(dMin); 202 } else { 203 max = (int)(dMin); 204 min = (int)(dMax); 205 } 206 colorMap.setRange(min, max); 207 BaseColorControl clrCntrl = (BaseColorControl) colorMap.getControl(); 208 clrCntrl.setTable(BaseColorControl.initTableGreyWedge(new float[4][256], true)); 209 } 210 } 211 212 public MapProjection getDataProjection() { 213 MapProjection mp = null; 214 Rectangle2D rect = MultiSpectralData.getLonLatBoundingBox(image); 215 try { 216 mp = new LambertAEA(rect); 217 } catch (Exception e) { 218 System.err.println("GeoPreviewSelection getDataProjection: e="+e); 219 } 220 return mp; 221 } 222 223 public void initBox() { 224 this.drawBox(); 225 } 226 227 protected JComponent doMakeContents() { 228 try { 229 JPanel panel = new JPanel(new BorderLayout()); 230 panel.add("Center", dspMaster.getDisplayComponent()); 231 panel.addComponentListener (new ComponentListener() { 232 public void componentHidden(ComponentEvent ce) { 233 dspMaster.getDisplayComponent().setVisible(false); 234 } 235 public void componentShown(ComponentEvent ce) { 236 dspMaster.getDisplayComponent().setVisible(true); 237 drawBox(); 238 rbb.resetExtremes(); 239 } 240 public void componentMoved(ComponentEvent ce) { 241 } 242 public void componentResized(ComponentEvent ce) { 243 } 244 }); 245 return panel; 246 } 247 catch (Exception e) { 248 System.err.println("GeoPreviewSelection doMakeContents: e=" + e); 249 } 250 return null; 251 } 252 253 public void setDataChoice(DataChoice choice) { 254 logger.trace("oldChoice={} newChoice={}", this.dataChoice, choice); 255 this.dataChoice = choice; 256 } 257 public DataChoice getDataChoice() { 258 return this.dataChoice; 259 } 260 261 private void forceCoords() { 262 float[] extrms = rbb.getRanges(); 263 x_coords[0] = (double)extrms[0]; 264 y_coords[0] = (double)extrms[1]; 265 x_coords[1] = (double)extrms[2]; 266 y_coords[1] = (double)extrms[3]; 267 268 int height = (int)(y_coords[1] - y_coords[0]); 269 int width = (int)(x_coords[1] - x_coords[0]); 270 if ((height < 1) || (width < 1)) return; 271 272 if (laloSel != null) { 273 int lineMid = (int)((y_coords[0] + y_coords[1])/2.0 + 0.5); 274 int eleMid = (int)((x_coords[0] + x_coords[1])/2.0 + 0.5); 275 double uLLine = y_coords[1]; 276 double uLEle = x_coords[0]; 277 if (height < 0) { 278 height *= -1; 279 uLLine = y_coords[0]; 280 } 281 if (width < 0) { 282 width *= -1; 283 uLEle = x_coords[1]; 284 } 285 286 int line = lineMid; 287 int ele = eleMid; 288 if (laloSel.getPlace().equals(laloSel.PLACE_ULEFT)) { 289 line = (int)Math.floor(uLLine + 0.5); 290 ele = (int)Math.floor(uLEle + 0.5); 291 } 292 293 int linRes = laloSel.getPreviewLineRes(); 294 int eleRes = laloSel.getPreviewEleRes(); 295 296 height *= linRes; 297 width *= eleRes; 298 laloSel.setBaseNumLines(height); 299 laloSel.setBaseNumElements(width); 300 301 this.lineMag = laloSel.getLineMag(); 302 this.elementMag = laloSel.getElementMag(); 303 if (lineMag > 0) { 304 height *= lineMag; 305 } else if (lineMag < 0) { 306 height /= -lineMag; 307 } 308 if (elementMag > 0) { 309 width *= elementMag; 310 } else if (elementMag < 0) { 311 width /= -elementMag; 312 } 313 314 Rectangle2D mapArea = sampleProjection.getDefaultMapArea(); 315 double previewXDim = mapArea.getWidth(); 316 double previewYDim = mapArea.getHeight(); 317 double dLin = (double)line; 318 double dEle = (double)ele; 319 if ((line < 0) || (dLin > previewYDim) || 320 (ele < 0) || (dEle > previewXDim)) { 321 line = -1; 322 ele = -1; 323 } 324 325// boolean lock = laloSel.getLockOn(); 326// laloSel.setLockOn(true); 327// int lineMag = 1; 328// int eleMag = 1; 329 laloSel.setNumLines(height); 330 laloSel.setNumEles(width); 331// laloSel.setBaseNumLines(height); 332// laloSel.setBaseNumElements(width); 333// laloSel.setLineMag(lineMag); 334// laloSel.setElementMag(eleMag); 335// laloSel.lineMagSlider.setValue(lineMag); 336// laloSel.setLRes(-1.0); 337// laloSel.elementMagSlider.setValue(eleMag); 338// laloSel.setERes(-1.0); 339// laloSel.amUpdating = true; 340// laloSel.lineMagSliderChanged(false); 341// laloSel.elementMagSliderChanged(false); 342// laloSel.amUpdating = false; 343// laloSel.setLockOn(lock); 344 345 laloSel.getGeoLocationInfo(line, ele); 346 String type = laloSel.getCoordinateType(); 347 int pos = 0; 348 if (laloSel.getPlace().equals(laloSel.PLACE_ULEFT)) pos = 1; 349 if (type.equals(laloSel.TYPE_LATLON)) { 350 double[][] pts = laloSel.getLatLonPoints(); 351 laloSel.setLatitude(pts[0][pos]); 352 laloSel.setLongitude(pts[1][pos]); 353 laloSel.convertToLineEle(); 354 } else { 355 double[][] pts = laloSel.getImagePoints(); 356 if (type.equals(laloSel.TYPE_AREA)) 357 pts = laloSel.getAreaPoints(); 358 laloSel.setElement((int)Math.floor(pts[0][pos] + 0.5)); 359 laloSel.setLine((int)Math.floor(pts[1][pos] + 0.5)); 360 laloSel.setLineElement(); 361 laloSel.convertToLatLon(); 362 } 363 } 364 } 365 366 @Override public void applyToDataSelection(DataSelection dataSelection) { 367 } 368 369 @Override public boolean getShowInControlProperties() { 370 return false; 371 } 372 373 public void drawBox() { 374 if (box == null) makeBox(); 375 removeRBB(); 376 377 double[][] elelin = laloSel.getDisplayELPoints(); 378 if (elelin == null) return; 379 380 for (int i=0; i<2; i++) { 381 for (int j=0; j<5; j++) { 382 Double val = new Double(elelin[i][j]); 383 if (val.isNaN()) { 384 eraseBox(); 385 return; 386 } 387 } 388 } 389 390 float[][] floatVals = new float[][] { 391 { (float)elelin[0][0], (float)elelin[0][1], (float)elelin[0][2], 392 (float)elelin[0][3], (float)elelin[0][4] }, 393 { (float)elelin[1][0], (float)elelin[1][1], (float)elelin[1][2], 394 (float)elelin[1][3], (float)elelin[1][4] }}; 395 396 float[][] dispVals = new float[][] { 397 { floatVals[0][1], floatVals[0][2], floatVals[0][4], 398 floatVals[0][3], floatVals[0][1] }, 399 { floatVals[1][1], floatVals[1][2], floatVals[1][4], 400 floatVals[1][3], floatVals[1][1] } 401 }; 402 403 try { 404 float[][] refVals = rbb.getDisplayCoordSystem().toReference(dispVals); 405 Gridded2DSet set = new Gridded2DSet(RealTupleType.SpatialCartesian2DTuple, 406 refVals, 5); 407 box.setData(set); 408 } catch (Exception e) { 409 System.err.println("GeoPreviewSelection drawBox: e=" + e); 410 } 411 } 412 413 private void makeBox() { 414 if (box == null) { 415 try { 416 box = new LineDrawing("box"); 417 box.setColor((Color)store.get(mvm.PREF_FGCOLOR, Color.GREEN)); 418 dspMaster.addDisplayable(box); 419 } catch (Exception e) { 420 System.err.println("GeoPreviewSelection makeBox: e=" + e); 421 } 422 } 423 } 424 425 private void eraseBox() { 426 Gridded2DSet set = null; 427 if (box == null) makeBox(); 428 try { 429 set = new Gridded2DSet(RealTupleType.LatitudeLongitudeTuple, 430 new float[][] { 431 { (float)0.0, (float)0.0 }, 432 { (float)0.0, (float)0.0 }, 433 }, 2); 434 box.setData(set); 435 } catch (Exception e) { 436 System.err.println("GeoPreviewSelection eraseBox: e=" + e); 437 } 438 addRBB(); 439 } 440 441 private boolean rBBPresent() { 442 Displayable[] dsps = dspMaster.getDisplayables(); 443 if (dsps.length > 0) { 444 for (int i = 0; i<dsps.length; i++) { 445 Displayable disp = dsps[i]; 446 if (disp == (Displayable)rbb) { 447 return true; 448 } 449 } 450 } 451 return false; 452 } 453 454 private void removeRBB() { 455 if (rBBPresent()) { 456 try { 457 dspMaster.removeDisplayable(rbb); 458 } catch (Exception e) { 459 System.err.println("GeoPreviewSelection removeRBB: e=" + e); 460 } 461 } 462 addRBB(); 463 } 464 465 private void addRBB() { 466 if (!rBBPresent()) { 467 try { 468 dspMaster.addDisplayable(rbb); 469 } catch (Exception e) { 470 System.err.println("GeoPreviewSelection addRBB: e=" + e); 471 } 472 } 473 } 474}