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