001/* 002 * $Id: MultiDimensionDataSource.java,v 1.30 2011/03/24 16:06:33 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.hydra; 032 033import java.awt.BorderLayout; 034import java.awt.Color; 035import java.awt.FlowLayout; 036import java.awt.event.ActionEvent; 037import java.awt.event.ActionListener; 038import java.io.File; 039import java.net.URL; 040import java.rmi.RemoteException; 041import java.util.Enumeration; 042import java.util.HashMap; 043import java.util.Hashtable; 044import java.util.List; 045 046import javax.swing.JComponent; 047import javax.swing.JLabel; 048import javax.swing.JPanel; 049import javax.swing.JTextField; 050 051import visad.CellImpl; 052import visad.Data; 053import visad.FlatField; 054import visad.Gridded2DSet; 055import visad.GriddedSet; 056import visad.RealTupleType; 057import visad.RealType; 058import visad.SampledSet; 059import visad.UnionSet; 060import visad.VisADException; 061import visad.data.mcidas.BaseMapAdapter; 062import visad.georef.MapProjection; 063 064import ucar.unidata.data.DataCategory; 065import ucar.unidata.data.DataChoice; 066import ucar.unidata.data.DataSelection; 067import ucar.unidata.data.DataSelectionComponent; 068import ucar.unidata.data.DataSourceDescriptor; 069import ucar.unidata.data.DirectDataChoice; 070import ucar.unidata.data.GeoLocationInfo; 071import ucar.unidata.data.GeoSelection; 072import ucar.unidata.geoloc.projection.LatLonProjection; 073import ucar.unidata.util.Misc; 074import ucar.unidata.view.geoloc.MapProjectionDisplay; 075import ucar.unidata.view.geoloc.MapProjectionDisplayJ3D; 076import ucar.visad.ProjectionCoordinateSystem; 077import ucar.visad.display.DisplayMaster; 078import ucar.visad.display.LineDrawing; 079import ucar.visad.display.MapLines; 080import ucar.visad.display.RubberBandBox; 081 082import edu.wisc.ssec.mcidasv.Constants; 083import edu.wisc.ssec.mcidasv.data.HydraDataSource; 084import edu.wisc.ssec.mcidasv.data.PreviewSelection; 085import edu.wisc.ssec.mcidasv.display.hydra.MultiSpectralDisplay; 086 087/** 088 * A data source for Multi Dimension Data 089 */ 090 091public class MultiDimensionDataSource extends HydraDataSource { 092 093 /** Sources file */ 094 protected String filename; 095 096 protected MultiDimensionReader reader; 097 098 protected MultiDimensionAdapter[] adapters = null; 099 private HashMap<String, MultiDimensionAdapter> adapterMap = new HashMap<String, MultiDimensionAdapter>(); 100 101 102 protected SpectrumAdapter spectrumAdapter; 103 104 private static final String DATA_DESCRIPTION = "Multi Dimension Data"; 105 106 private HashMap defaultSubset; 107 public TrackAdapter track_adapter; 108 private MultiSpectralData multiSpectData; 109 110 private List categories; 111 private boolean hasImagePreview = false; 112 private boolean hasTrackPreview = false; 113 114 /** 115 * Zero-argument constructor for construction via unpersistence. 116 */ 117 public MultiDimensionDataSource() {} 118 119 /** 120 * Construct a new HYDRA hdf data source. 121 * @param descriptor descriptor for this <code>DataSource</code> 122 * @param fileName name of the hdf file to read 123 * @param properties hashtable of properties 124 * 125 * @throws VisADException problem creating data 126 */ 127 public MultiDimensionDataSource(DataSourceDescriptor descriptor, 128 String fileName, Hashtable properties) 129 throws VisADException { 130 this(descriptor, Misc.newList(fileName), properties); 131 } 132 133 /** 134 * Construct a new HYDRA hdf data source. 135 * @param descriptor descriptor for this <code>DataSource</code> 136 * @param sources List of filenames 137 * @param properties hashtable of properties 138 * 139 * @throws VisADException problem creating data 140 */ 141 public MultiDimensionDataSource(DataSourceDescriptor descriptor, 142 List newSources, Hashtable properties) 143 throws VisADException { 144 super(descriptor, newSources, DATA_DESCRIPTION, properties); 145 146 this.filename = (String)sources.get(0); 147 148 try { 149 setup(); 150 } 151 catch (Exception e) { 152 e.printStackTrace(); 153 throw new VisADException(); 154 } 155 } 156 157 public void setup() throws Exception { 158 159 try { 160 reader = new NetCDFFile(filename); 161 } 162 catch (Exception e) { 163 e.printStackTrace(); 164 System.out.println("cannot create NetCDF reader for file: "+filename); 165 } 166 167 adapters = new MultiDimensionAdapter[1]; 168 Hashtable<String, String[]> properties = new Hashtable<String, String[]>(); 169 170 String name = (new File(filename)).getName(); 171 if ( name.startsWith("MOD04") || name.startsWith("MYD04")) { 172 HashMap table = SwathAdapter.getEmptyMetadataTable(); 173 table.put("array_name", "mod04/Data Fields/Optical_Depth_Land_And_Ocean"); 174 table.put("lon_array_name", "mod04/Geolocation Fields/Longitude"); 175 table.put("lat_array_name", "mod04/Geolocation Fields/Latitude"); 176 table.put("XTrack", "Cell_Across_Swath"); 177 table.put("Track", "Cell_Along_Swath"); 178 table.put("geo_Track", "Cell_Along_Swath"); 179 table.put("geo_XTrack", "Cell_Across_Swath"); 180 table.put("scale_name", "scale_factor"); 181 table.put("offset_name", "add_offset"); 182 table.put("fill_value_name", "_FillValue"); 183 table.put("range_name", "Optical_Depth_Land_And_Ocean"); 184 adapters[0] = new SwathAdapter(reader, table); 185 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 186 defaultSubset = adapters[0].getDefaultSubset(); 187 } 188 else if ( name.startsWith("MOD06") || name.startsWith("MYD06") ) { 189 hasImagePreview = true; 190 String path = "mod06/Data Fields/"; 191 String[] arrayNames = new String[] {"Cloud_Optical_Thickness", "Cloud_Effective_Radius", "Cloud_Water_Path"}; 192 String[] arrayNames_5km = new String[] {"Cloud_Top_Pressure", "Cloud_Top_Temperature", "Cloud_Fraction"}; 193 adapters = new MultiDimensionAdapter[arrayNames.length+arrayNames_5km.length]; 194 for (int k=0; k<arrayNames.length; k++) { 195 HashMap table = SwathAdapter.getEmptyMetadataTable(); 196 table.put("array_name", path.concat(arrayNames[k])); 197 table.put("lon_array_name", "mod06/Geolocation Fields/Longitude"); 198 table.put("lat_array_name", "mod06/Geolocation Fields/Latitude"); 199 table.put("XTrack", "Cell_Across_Swath_1km"); 200 table.put("Track", "Cell_Along_Swath_1km"); 201 table.put("geo_Track", "Cell_Along_Swath_5km"); 202 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 203 table.put("scale_name", "scale_factor"); 204 table.put("offset_name", "add_offset"); 205 table.put("fill_value_name", "_FillValue"); 206 table.put("range_name", arrayNames[k]); 207 208 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0)); 209 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0)); 210 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0)); 211 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0148148148)); 212 213 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 214 swathAdapter.setDefaultStride(10); 215 defaultSubset = swathAdapter.getDefaultSubset(); 216 adapters[k] = swathAdapter; 217 } 218 219 for (int k=0; k<arrayNames_5km.length; k++) { 220 HashMap table = SwathAdapter.getEmptyMetadataTable(); 221 table.put("array_name", path.concat(arrayNames_5km[k])); 222 table.put("lon_array_name", "mod06/Geolocation Fields/Longitude"); 223 table.put("lat_array_name", "mod06/Geolocation Fields/Latitude"); 224 table.put("XTrack", "Cell_Across_Swath_5km"); 225 table.put("Track", "Cell_Along_Swath_5km"); 226 table.put("geo_Track", "Cell_Along_Swath_5km"); 227 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 228 table.put("scale_name", "scale_factor"); 229 table.put("offset_name", "add_offset"); 230 table.put("fill_value_name", "_FillValue"); 231 table.put("range_name", arrayNames_5km[k]); 232 233 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 234 defaultSubset = swathAdapter.getDefaultSubset(); 235 adapters[arrayNames.length+k] = swathAdapter; 236 } 237 238 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 239 } 240 else if (name.startsWith("CAL_LID_L1")) { 241 HashMap table = ProfileAlongTrack.getEmptyMetadataTable(); 242 table.put(ProfileAlongTrack.array_name, "Total_Attenuated_Backscatter_532"); 243 table.put(ProfileAlongTrack.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/calipso/altitude"); 244 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 245 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 246 table.put(ProfileAlongTrack.profileTime_name, "Profile_Time"); 247 table.put(ProfileAlongTrack.longitude_name, "Longitude"); 248 table.put(ProfileAlongTrack.latitude_name, "Latitude"); 249 ProfileAlongTrack adapter = new Calipso2D(reader, table); 250 ProfileAlongTrack3D adapter3D = new ProfileAlongTrack3D(adapter); 251 HashMap subset = adapter.getDefaultSubset(); 252 adapters[0] = adapter3D; 253 defaultSubset = subset; 254 DataCategory.createCategory("ProfileAlongTrack"); 255 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 256 257 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 258 table = ProfileAlongTrack.getEmptyMetadataTable(); 259 table.put(ProfileAlongTrack.array_name, "Latitude"); 260 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 261 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 262 263 adapter_s[0] = new ArrayAdapter(reader, table); 264 table = ProfileAlongTrack.getEmptyMetadataTable(); 265 table.put(ProfileAlongTrack.array_name, "Surface_Elevation"); 266 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 267 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 268 269 adapter_s[1] = new ArrayAdapter(reader, table); 270 table = ProfileAlongTrack.getEmptyMetadataTable(); 271 table.put(ProfileAlongTrack.array_name, "Longitude"); 272 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 273 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 274 adapter_s[2] = new ArrayAdapter(reader, table); 275 276 track_adapter = new TrackAdapter(adapter_s[2], adapter_s[0], adapter_s[1]); 277 properties.put("medianFilter", new String[] {Double.toString(8), Double.toString(16)}); 278 properties.put("setBelowSfcMissing", new String[] {"true"}); 279 hasTrackPreview = true; 280 } 281 else if (name.indexOf("2B-GEOPROF") > 0) { 282 HashMap table = ProfileAlongTrack.getEmptyMetadataTable(); 283 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Data Fields/Radar_Reflectivity"); 284 table.put(ProfileAlongTrack.range_name, "2B-GEOPROF_RadarReflectivity"); 285 table.put(ProfileAlongTrack.scale_name, "factor"); 286 table.put(ProfileAlongTrack.offset_name, "offset"); 287 table.put(ProfileAlongTrack.fill_value_name, "_FillValue"); 288 table.put(ProfileAlongTrack.valid_range, "valid_range"); 289 table.put(ProfileAlongTrack.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/cloudsat/altitude"); 290 table.put(ProfileAlongTrack.trackDim_name, "nray"); 291 table.put(ProfileAlongTrack.vertDim_name, "nbin"); 292 table.put(ProfileAlongTrack.profileTime_name, "2B-GEOPROF/Geolocation Fields/Profile_Time"); 293 table.put(ProfileAlongTrack.longitude_name, "2B-GEOPROF/Geolocation Fields/Longitude"); 294 table.put(ProfileAlongTrack.latitude_name, "2B-GEOPROF/Geolocation Fields/Latitude"); 295 table.put(ProfileAlongTrack.product_name, "2B-GEOPROF"); 296 ProfileAlongTrack adapter = new CloudSat2D(reader, table); 297 ProfileAlongTrack3D adapter3D = new ProfileAlongTrack3D(adapter); 298 HashMap subset = adapter.getDefaultSubset(); 299 adapters[0] = adapter3D; 300 defaultSubset = subset; 301 DataCategory.createCategory("ProfileAlongTrack"); 302 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 303 304 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 305 table = ProfileAlongTrack.getEmptyMetadataTable(); 306 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation Fields/Latitude"); 307 table.put(ProfileAlongTrack.range_name, "Latitude"); 308 table.put(ProfileAlongTrack.trackDim_name, "nray"); 309 table.put(ProfileAlongTrack.vertDim_name, "nbin"); 310 adapter_s[0] = new ArrayAdapter(reader, table); 311 312 table = ProfileAlongTrack.getEmptyMetadataTable(); 313 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation Fields/DEM_elevation"); 314 table.put(ProfileAlongTrack.range_name, "DEM_elevation"); 315 table.put(ProfileAlongTrack.trackDim_name, "nray"); 316 table.put(ProfileAlongTrack.vertDim_name, "nbin"); 317 adapter_s[1] = new ArrayAdapter(reader, table); 318 319 table = ProfileAlongTrack.getEmptyMetadataTable(); 320 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation Fields/Longitude"); 321 table.put(ProfileAlongTrack.range_name, "Longitude"); 322 table.put(ProfileAlongTrack.trackDim_name, "nray"); 323 table.put(ProfileAlongTrack.vertDim_name, "nbin"); 324 adapter_s[2] = new ArrayAdapter(reader, table); 325 326 //-track_adapter = new TrackAdapter(adapter_s[2], adapter_s[0], adapter_s[1]); 327 track_adapter = new TrackAdapter(adapter_s[2], adapter_s[0], null); 328 properties.put("medianFilter", new String[] {Double.toString(6), Double.toString(14)}); 329 properties.put("setBelowSfcMissing", new String[] {"true"}); 330 hasTrackPreview = true; 331 } 332 else if ( name.startsWith("MHSx_xxx_1B") && name.endsWith("h5")) { 333 HashMap table = SwathAdapter.getEmptyMetadataTable(); 334 table.put("array_name", "U-MARF/EPS/MHSx_xxx_1B/DATA/Channel1"); 335 table.put("lon_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/IMAGE_LON_ARRAY"); 336 table.put("lat_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/IMAGE_LAT_ARRAY"); 337 table.put("XTrack", "dim1"); 338 table.put("Track", "dim0"); 339 table.put("geo_XTrack", "dim1"); 340 table.put("geo_Track", "dim0"); 341 table.put("product_name", "MHSx_xxx_1B"); 342 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 343 adapters[0] = swathAdapter; 344 HashMap subset = swathAdapter.getDefaultSubset(); 345 defaultSubset = subset; 346 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 347 } 348 setProperties(properties); 349 } 350 351 public void initAfterUnpersistence() { 352 try { 353 setup(); 354 } 355 catch (Exception e) { 356 } 357 } 358 359 /** 360 * Make and insert the <code>DataChoice</code>-s for this 361 * <code>DataSource</code>. 362 */ 363 public void doMakeDataChoices() { 364 DataChoice choice = null; 365 if (adapters != null) { 366 for (int idx=0; idx<adapters.length; idx++) { 367 try { 368 choice = doMakeDataChoice(idx, adapters[idx].getArrayName()); 369 adapterMap.put(choice.getName(), adapters[idx]); 370 } 371 catch (Exception e) { 372 e.printStackTrace(); 373 System.out.println("doMakeDataChoice failed"); 374 } 375 376 if (choice != null) { 377 addDataChoice(choice); 378 } 379 } 380 } 381 } 382 383 private DataChoice doMakeDataChoice(int idx, String var) throws Exception { 384 String name = var; 385 DataSelection dataSel = new MultiDimensionSubset(defaultSubset); 386 Hashtable subset = new Hashtable(); 387 subset.put(new MultiDimensionSubset(), dataSel); 388 DirectDataChoice ddc = new DirectDataChoice(this, idx, name, name, categories, subset); 389 390 return ddc; 391 } 392 393 /** 394 * Check to see if this <code>HDFHydraDataSource</code> is equal to the object 395 * in question. 396 * @param o object in question 397 * @return true if they are the same or equivalent objects 398 */ 399 public boolean equals(Object o) { 400 if ( !(o instanceof MultiDimensionDataSource)) { 401 return false; 402 } 403 return (this == (MultiDimensionDataSource) o); 404 } 405 406 public MultiSpectralData getMultiSpectralData() { 407 return multiSpectData; 408 } 409 410 public String getDatasetName() { 411 return filename; 412 } 413 414 public void setDatasetName(String name) { 415 filename = name; 416 } 417 418 public HashMap getSubsetFromLonLatRect(MultiDimensionSubset select, GeoSelection geoSelection) { 419 GeoLocationInfo ginfo = geoSelection.getBoundingBox(); 420 return adapters[0].getSubsetFromLonLatRect(select.getSubset(), ginfo.getMinLat(), ginfo.getMaxLat(), 421 ginfo.getMinLon(), ginfo.getMaxLon()); 422 } 423 424 425 protected Data getDataInner(DataChoice dataChoice, DataCategory category, 426 DataSelection dataSelection, Hashtable requestProperties) 427 throws VisADException, RemoteException { 428 429 //- this hack keeps the HydraImageProbe from doing a getData() 430 //- TODO: need to use categories? 431 if (requestProperties != null) { 432 if ((requestProperties.toString()).equals("{prop.requester=MultiSpectral}")) { 433 return null; 434 } 435 } 436 437 GeoLocationInfo ginfo = null; 438 GeoSelection geoSelection = null; 439 440 if ((dataSelection != null) && (dataSelection.getGeoSelection() != null)) { 441 geoSelection = (dataSelection.getGeoSelection().getBoundingBox() != null) ? dataSelection.getGeoSelection() : 442 dataChoice.getDataSelection().getGeoSelection(); 443 } 444 445 if (geoSelection != null) { 446 ginfo = geoSelection.getBoundingBox(); 447 } 448 449 Data data = null; 450 if (adapters == null) { 451 return data; 452 } 453 454 MultiDimensionAdapter adapter = null; 455 456 adapter = adapterMap.get(dataChoice.getName()); 457 458 try { 459 HashMap subset = null; 460 if (ginfo != null) { 461 subset = adapter.getSubsetFromLonLatRect(ginfo.getMinLat(), ginfo.getMaxLat(), 462 ginfo.getMinLon(), ginfo.getMaxLon(), 463 geoSelection.getXStride(), 464 geoSelection.getYStride(), 465 geoSelection.getZStride()); 466 } 467 else { 468 MultiDimensionSubset select = null; 469 Hashtable table = dataChoice.getProperties(); 470 Enumeration keys = table.keys(); 471 while (keys.hasMoreElements()) { 472 Object key = keys.nextElement(); 473 if (key instanceof MultiDimensionSubset) { 474 select = (MultiDimensionSubset) table.get(key); 475 } 476 } 477 478 subset = select.getSubset(); 479 480 if (dataSelection != null) { 481 Hashtable props = dataSelection.getProperties(); 482 if (props != null) { 483 } 484 } 485 } 486 487 if (subset != null) { 488 data = adapter.getData(subset); 489 data = applyProperties(data, requestProperties, subset); 490 } 491 } catch (Exception e) { 492 e.printStackTrace(); 493 System.out.println("getData exception e=" + e); 494 } 495 return data; 496 } 497 498 protected Data applyProperties(Data data, Hashtable requestProperties, HashMap subset) 499 throws VisADException, RemoteException { 500 Data new_data = data; 501 502 if (requestProperties == null) { 503 new_data = data; 504 return new_data; 505 } 506 507 if (requestProperties.containsKey("medianFilter")) { 508 String[] items = (String[]) requestProperties.get("medianFilter"); 509 double window_lenx = Double.parseDouble(items[0]); 510 double window_leny = Double.parseDouble(items[1]); 511 GriddedSet domainSet = (GriddedSet) ((FlatField)data).getDomainSet(); 512 int[] lens = domainSet.getLengths(); 513 float[] range_values = (((FlatField)data).getFloats())[0]; 514 range_values = 515 ProfileAlongTrack.medianFilter(range_values, lens[0], lens[1], 516 (int)window_lenx, (int)window_leny); 517 ((FlatField)new_data).setSamples(new float[][] {range_values}); 518 } 519 if (requestProperties.containsKey("setBelowSfcMissing")) { 520 String[] items = (String[]) requestProperties.get("setBelowSfcMissing"); 521 FlatField track = (FlatField) track_adapter.getData(subset); 522 float[] sfcElev = (track.getFloats())[0]; 523 FlatField field = (FlatField) new_data; 524 GriddedSet gset = (GriddedSet) field.getDomainSet(); 525 float[][] samples = gset.getSamples(false); 526 int[] lens = gset.getLengths(); 527 float[] range_values = (field.getFloats())[0]; 528 529 int trkIdx = ((ProfileAlongTrack3D)adapters[0]).adapter2D.getTrackTupIdx(); 530 int vrtIdx = ((ProfileAlongTrack3D)adapters[0]).adapter2D.getVertTupIdx(); 531 532 int k = 0; 533 for (int j=0; j<lens[trkIdx]; j++) { 534 float val = sfcElev[j]; 535 for (int i=0; i<lens[vrtIdx]; i++) { 536 if (vrtIdx < trkIdx) k = i + j*lens[0]; 537 if (trkIdx < vrtIdx) k = j + i*lens[0]; 538 if (samples[2][k] <= val || samples[2][k] < 0.0) { 539 range_values[k] = Float.NaN; 540 } 541 } 542 } 543 field.setSamples(new float[][] {range_values}); 544 } 545 return new_data; 546 } 547 548 protected void initDataSelectionComponents( 549 List<DataSelectionComponent> components, 550 final DataChoice dataChoice) { 551 552 if (hasImagePreview) { 553 try { 554 FlatField image = (FlatField) getDataInner(dataChoice, null, null, null); 555 components.add(new PreviewSelection(dataChoice, image, null)); 556 } catch (Exception e) { 557 System.out.println("Can't make PreviewSelection: "+e); 558 e.printStackTrace(); 559 } 560 } 561 if (hasTrackPreview) { 562 try { 563 FlatField track = track_adapter.getData(track_adapter.getDefaultSubset()); 564 components.add(new TrackSelection(dataChoice, track)); 565 } catch (Exception e) { 566 System.out.println("Can't make PreviewSelection: "+e); 567 e.printStackTrace(); 568 } 569 } 570 } 571} 572 573class TrackSelection extends DataSelectionComponent { 574 DataChoice dataChoice; 575 FlatField track; 576 577 double[] x_coords = new double[2]; 578 double[] y_coords = new double[2]; 579 boolean hasSubset = true; 580 MapProjectionDisplayJ3D mapProjDsp; 581 DisplayMaster dspMaster; 582 583 int trackStride; 584 int verticalStride; 585 586 JTextField trkStr; 587 JTextField vrtStr; 588 589 590 TrackSelection(DataChoice dataChoice, FlatField track) throws VisADException, RemoteException { 591 super("track"); 592 this.dataChoice = dataChoice; 593 this.track = track; 594 mapProjDsp = new MapProjectionDisplayJ3D(MapProjectionDisplay.MODE_2Din3D); 595 mapProjDsp.enableRubberBanding(false); 596 dspMaster = mapProjDsp; 597 mapProjDsp.setMapProjection(getDataProjection()); 598 LineDrawing trackDsp = new LineDrawing("track"); 599 trackDsp.setLineWidth(2f); 600 trackDsp.setData(track); 601 mapProjDsp.addDisplayable(trackDsp); 602 603 604 MapLines mapLines = new MapLines("maplines"); 605 URL mapSource = 606 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPU"); 607 try { 608 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 609 mapLines.setMapLines(mapAdapter.getData()); 610 mapLines.setColor(java.awt.Color.cyan); 611 mapProjDsp.addDisplayable(mapLines); 612 } catch (Exception excp) { 613 System.out.println("Can't open map file " + mapSource); 614 System.out.println(excp); 615 } 616 617 mapLines = new MapLines("maplines"); 618 mapSource = 619 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPW"); 620 try { 621 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 622 mapLines.setMapLines(mapAdapter.getData()); 623 mapLines.setColor(java.awt.Color.cyan); 624 mapProjDsp.addDisplayable(mapLines); 625 } catch (Exception excp) { 626 System.out.println("Can't open map file " + mapSource); 627 System.out.println(excp); 628 } 629 630 mapLines = new MapLines("maplines"); 631 mapSource = 632 mapProjDsp.getClass().getResource("/auxdata/maps/OUTLHPOL"); 633 try { 634 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 635 mapLines.setMapLines(mapAdapter.getData()); 636 mapLines.setColor(java.awt.Color.cyan); 637 mapProjDsp.addDisplayable(mapLines); 638 } catch (Exception excp) { 639 System.out.println("Can't open map file " + mapSource); 640 System.out.println(excp); 641 } 642 643 final LineDrawing selectBox = new LineDrawing("select"); 644 selectBox.setColor(Color.green); 645 646 final RubberBandBox rbb = 647 new RubberBandBox(RealType.Longitude, RealType.Latitude, 1); 648 rbb.setColor(Color.green); 649 rbb.addAction(new CellImpl() { 650 public void doAction() 651 throws VisADException, RemoteException 652 { 653 Gridded2DSet set = rbb.getBounds(); 654 float[] low = set.getLow(); 655 float[] hi = set.getHi(); 656 x_coords[0] = low[0]; 657 x_coords[1] = hi[0]; 658 y_coords[0] = low[1]; 659 y_coords[1] = hi[1]; 660 661 SampledSet[] sets = new SampledSet[4]; 662 sets[0] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, new float[][] {{low[0], hi[0]}, {low[1], low[1]}}, 2); 663 sets[1] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, new float[][] {{hi[0], hi[0]}, {low[1], hi[1]}}, 2); 664 sets[2] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, new float[][] {{hi[0], low[0]}, {hi[1], hi[1]}}, 2); 665 sets[3] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, new float[][] {{low[0], low[0]}, {hi[1], low[1]}}, 2); 666 UnionSet uset = new UnionSet(sets); 667 selectBox.setData(uset); 668 } 669 }); 670 dspMaster.addDisplayable(rbb); 671 dspMaster.addDisplayable(selectBox); 672 673 dspMaster.draw(); 674 } 675 676 public MapProjection getDataProjection() { 677 MapProjection mp = null; 678 try { 679 mp = new ProjectionCoordinateSystem(new LatLonProjection()); 680 } catch (Exception e) { 681 System.out.println(" getDataProjection"+e); 682 } 683 return mp; 684 } 685 686 protected JComponent doMakeContents() { 687 try { 688 JPanel panel = new JPanel(new BorderLayout()); 689 panel.add("Center", dspMaster.getDisplayComponent()); 690 691 JPanel stridePanel = new JPanel(new FlowLayout()); 692 trkStr = new JTextField(Integer.toString(5), 3); 693 vrtStr = new JTextField(Integer.toString(2), 3); 694 trkStr.addActionListener(new ActionListener() { 695 public void actionPerformed(ActionEvent ae) { 696 setTrackStride(Integer.valueOf(trkStr.getText().trim())); 697 } 698 }); 699 vrtStr.addActionListener(new ActionListener() { 700 public void actionPerformed(ActionEvent ae) { 701 setVerticalStride(Integer.valueOf(vrtStr.getText().trim())); 702 } 703 }); 704 705 stridePanel.add(new JLabel("track stride: ")); 706 stridePanel.add(trkStr); 707 stridePanel.add(new JLabel("vertical stride: ")); 708 stridePanel.add(vrtStr); 709 panel.add("South", stridePanel); 710 711 return panel; 712 } 713 catch (Exception e) { 714 System.out.println(e); 715 } 716 return null; 717 } 718 719 public void setTrackStride(int stride) { 720 trackStride = stride; 721 } 722 723 public void setVerticalStride(int stride) { 724 verticalStride = stride; 725 } 726 727 public void setTrackStride() { 728 trackStride = Integer.valueOf(trkStr.getText().trim()); 729 } 730 731 public void setVerticalStride() { 732 verticalStride = Integer.valueOf(vrtStr.getText().trim()); 733 } 734 735 public void applyToDataSelection(DataSelection dataSelection) { 736 setTrackStride(); 737 setVerticalStride(); 738 if (hasSubset) { 739 GeoSelection geoSelect = new GeoSelection( 740 new GeoLocationInfo(y_coords[1], x_coords[0], y_coords[0], x_coords[1])); 741 geoSelect.setXStride(trackStride); 742 geoSelect.setYStride(verticalStride); 743 dataSelection.setGeoSelection(geoSelect); 744 } 745 } 746}