001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv.data.adde; 030 031 import java.awt.Component; 032 import java.awt.Container; 033 import java.awt.Dimension; 034 import java.awt.event.ActionEvent; 035 import java.awt.event.ActionListener; 036 import java.io.File; 037 import java.io.RandomAccessFile; 038 import java.rmi.RemoteException; 039 import java.text.SimpleDateFormat; 040 import java.util.ArrayList; 041 import java.util.Arrays; 042 import java.util.Comparator; 043 import java.util.Enumeration; 044 import java.util.HashMap; 045 import java.util.Hashtable; 046 import java.util.Iterator; 047 import java.util.List; 048 import java.util.Map; 049 import java.util.StringTokenizer; 050 import java.util.TimeZone; 051 import java.util.TreeMap; 052 053 import javax.swing.BoxLayout; 054 import javax.swing.JCheckBox; 055 import javax.swing.JComponent; 056 import javax.swing.JLabel; 057 import javax.swing.JPanel; 058 import javax.swing.JScrollPane; 059 import javax.swing.JTabbedPane; 060 061 import org.slf4j.Logger; 062 import org.slf4j.LoggerFactory; 063 064 import edu.wisc.ssec.mcidas.AREAnav; 065 import edu.wisc.ssec.mcidas.AreaDirectory; 066 import edu.wisc.ssec.mcidas.AreaDirectoryList; 067 import edu.wisc.ssec.mcidas.AreaFile; 068 import edu.wisc.ssec.mcidas.AreaFileException; 069 import edu.wisc.ssec.mcidas.adde.AddeImageURL; 070 import edu.wisc.ssec.mcidas.adde.AddeTextReader; 071 072 import visad.Data; 073 import visad.DateTime; 074 import visad.FlatField; 075 import visad.FunctionType; 076 import visad.MathType; 077 import visad.RealType; 078 import visad.Set; 079 import visad.VisADException; 080 import visad.data.DataRange; 081 import visad.data.mcidas.AREACoordinateSystem; 082 import visad.data.mcidas.AreaAdapter; 083 import visad.georef.MapProjection; 084 import visad.meteorology.ImageSequence; 085 import visad.meteorology.ImageSequenceImpl; 086 import visad.meteorology.ImageSequenceManager; 087 import visad.meteorology.SingleBandedImage; 088 import visad.util.ThreadManager; 089 090 import ucar.nc2.iosp.mcidas.McIDASAreaProjection; 091 import ucar.unidata.data.BadDataException; 092 import ucar.unidata.data.CompositeDataChoice; 093 import ucar.unidata.data.DataCategory; 094 import ucar.unidata.data.DataChoice; 095 import ucar.unidata.data.DataSelection; 096 import ucar.unidata.data.DataSelectionComponent; 097 import ucar.unidata.data.DataSourceDescriptor; 098 import ucar.unidata.data.DirectDataChoice; 099 import ucar.unidata.data.GeoLocationInfo; 100 import ucar.unidata.data.GeoSelection; 101 import ucar.unidata.data.imagery.AddeImageDataSource; 102 import ucar.unidata.data.imagery.AddeImageDescriptor; 103 import ucar.unidata.data.imagery.AddeImageInfo; 104 import ucar.unidata.data.imagery.BandInfo; 105 import ucar.unidata.data.imagery.ImageDataset; 106 import ucar.unidata.geoloc.LatLonPoint; 107 import ucar.unidata.geoloc.ProjectionImpl; 108 import ucar.unidata.idv.DisplayControl; 109 import ucar.unidata.util.GuiUtils; 110 import ucar.unidata.util.IOUtil; 111 import ucar.unidata.util.LogUtil; 112 import ucar.unidata.util.PollingInfo; 113 import ucar.unidata.util.StringUtil; 114 import ucar.unidata.util.ThreeDSize; 115 import ucar.unidata.util.TwoFacedObject; 116 import ucar.visad.Util; 117 import ucar.visad.data.AreaImageFlatField; 118 119 import edu.wisc.ssec.mcidasv.chooser.adde.AddeImageParameterChooser; 120 import edu.wisc.ssec.mcidasv.data.GeoLatLonSelection; 121 import edu.wisc.ssec.mcidasv.data.GeoPreviewSelection; 122 123 /** 124 * Abstract DataSource class for images files. 125 */ 126 public class AddeImageParameterDataSource extends AddeImageDataSource { 127 128 private static final Logger logger = LoggerFactory.getLogger(AddeImageParameterDataSource.class); 129 130 /** 131 * Public keys for server, group, dataset, user, project. 132 */ 133 public final static String SIZE_KEY = "size"; 134 public final static String PLACE_KEY = "place"; 135 public final static String LATLON_KEY = "latlon"; 136 public final static String LINELE_KEY = "linele"; 137 public final static String MAG_KEY = "mag"; 138 public final static String BAND_KEY = "band"; 139 public final static String BANDINFO_KEY = "bandinfo"; 140 public final static String UNIT_KEY = "unit"; 141 public final static String PREVIEW_KEY = "preview"; 142 public final static String SPAC_KEY = "spac"; 143 public final static String NAV_KEY = "nav"; 144 public final static String AUX_KEY = "aux"; 145 public final static String DOC_KEY = "doc"; 146 public final static String SPACING_BRIT = "1"; 147 public final static String SPACING_NON_BRIT = "4"; 148 149 /** The first projection we find */ 150 protected ProjectionImpl sampleProjection; 151 public MapProjection sampleMapProjection; 152 153 /** list of twod categories */ 154 private List twoDCategories; 155 156 /** list of 2D time series categories */ 157 private List twoDTimeSeriesCategories; 158 159 /** list of twod categories */ 160 private List bandCategories; 161 162 /** list of 2D time series categories */ 163 private List bandTimeSeriesCategories; 164 165 /* ADDE request string */ 166 private String source; 167 private String baseSource; 168 169 /* properties for this data source */ 170 private Hashtable sourceProps; 171 private Hashtable selectionProps; 172 173 private int lineResolution; 174 private int elementResolution; 175 private float lRes; 176 private float eRes; 177 private int lineMag = 1; 178 private int elementMag = 1; 179 180 private GeoSelection lastGeoSelection; 181 private DataChoice lastChoice = null; 182 private Boolean showPreview = Boolean.FALSE; 183 private FlatField previewImage = null; 184 private MapProjection previewProjection; 185 private Hashtable initProps; 186 187 private AreaDirectory previewDir = null; 188 private AREAnav previewNav = null; 189 private boolean haveDataSelectionComponents = false; 190 191 private GeoPreviewSelection previewSel; 192 private GeoLatLonSelection laLoSel; 193 194 private String choiceName; 195 196 private String saveCoordType; 197 private String savePlace; 198 private double saveLat; 199 private double saveLon; 200 private int saveNumLine; 201 private int saveNumEle; 202 private int saveLineMag; 203 private int saveEleMag; 204 private Boolean saveShowPreview; 205 206 private String displaySource; 207 208 protected List<DataChoice> stashedChoices = null; 209 private List iml = new ArrayList(); 210 private List saveImageList = new ArrayList(); 211 212 private int previewLineRes = 1; 213 private int previewEleRes = 1; 214 215 /** Whether or not this DataSource was loaded from a bundle. */ 216 private boolean fromBundle = false; 217 218 /** Are any of the data choices based upon remote files? */ 219 private boolean hasRemoteChoices = false; 220 221 private Map<String, AreaDirectory> requestIdToDirectory = new HashMap<String, AreaDirectory>(); 222 223 public AddeImageParameterDataSource() {} 224 225 /** 226 * Creates a {@code AddeImageParameterDataSource} with a single ADDE URL. 227 * <b>Note:</b> the URLs should point at {@literal "image"} data. 228 * 229 * @param descriptor {@link ucar.unidata.data.DataSourceDescriptor DataSourceDescriptor} for this data source. 230 * @param image ADDE URL 231 * @param properties The properties for this data source. 232 * 233 * @throws VisADException 234 */ 235 public AddeImageParameterDataSource(DataSourceDescriptor descriptor, String image, 236 Hashtable properties) 237 throws VisADException { 238 super(descriptor, new String[] { image }, properties); 239 logger.trace("desc={}, image={}, properties={}", new Object[] { descriptor, image, properties }); 240 } 241 242 /** 243 * Create a new AddeImageParameterDataSource with an array of ADDE URL strings. 244 * <b>Note:</b> the URLs should point at {@literal "image"} data. 245 * 246 * @param descriptor {@link ucar.unidata.data.DataSourceDescriptor DataSourceDescriptor} for this data source. 247 * @param images Array of ADDE URLs. 248 * @param properties Properties for this data source. 249 * 250 * @throws VisADException 251 */ 252 public AddeImageParameterDataSource(DataSourceDescriptor descriptor, String[] images, 253 Hashtable properties) throws VisADException { 254 super(descriptor, images, properties); 255 logger.trace("desc={}, images={}, properties={}", new Object[] { descriptor, images, properties }); 256 } 257 258 /** 259 * Creates a new {@code AddeImageParameterDataSource} with an 260 * {@link java.util.List List} of ADDE URL strings. 261 * <b>Note:</b> the URLs should point at {@literal "image"} data. 262 * 263 * @param descriptor {@link ucar.unidata.data.DataSourceDescriptor DataSourceDescriptor} for this data source. 264 * @param images {@code List} of ADDE URL strings. 265 * @param properties Properties for this data source. 266 * 267 * @throws VisADException 268 */ 269 public AddeImageParameterDataSource(DataSourceDescriptor descriptor, List images, 270 Hashtable properties) throws VisADException { 271 super(descriptor, images, properties); 272 logger.trace("desc={}, images={}, properties={}", new Object[] { descriptor, images, properties }); 273 } 274 275 /** 276 * Create a new AddeImageParameterDataSource with the given dataset. 277 * 278 * @param descriptor {@link ucar.unidata.data.DataSourceDescriptor DataSourceDescriptor} for this data source. 279 * @param ids Dataset. 280 * @param properties Properties for this data source. 281 * 282 * @throws VisADException 283 */ 284 public AddeImageParameterDataSource(DataSourceDescriptor descriptor, ImageDataset ids, 285 Hashtable properties) throws VisADException { 286 super(descriptor, ids, properties); 287 logger.trace("desc={}, ids={}, properties={}", new Object[] { descriptor, ids, properties }); 288 this.sourceProps = properties; 289 if (properties.containsKey((Object)PREVIEW_KEY)) { 290 this.showPreview = (Boolean)(properties.get((Object)PREVIEW_KEY)); 291 saveShowPreview = showPreview; 292 } else { 293 if (saveShowPreview != null) { 294 showPreview = saveShowPreview; 295 } 296 } 297 298 List descs = ids.getImageDescriptors(); 299 AddeImageDescriptor aid = (AddeImageDescriptor)descs.get(0); 300 this.source = aid.getSource(); 301 if (this.source.contains("localhost")) { 302 AreaDirectory areaDirectory = aid.getDirectory(); 303 if (!sourceProps.containsKey((Object)UNIT_KEY)) { 304 if (!sourceProps.containsKey((Object)BAND_KEY)) { 305 String calType = areaDirectory.getCalibrationType(); 306 if (!calType.equals("RAW")) { 307 sourceProps.put(UNIT_KEY, calType); 308 int[] bandNums = areaDirectory.getBands(); 309 String bandString = new Integer(bandNums[0]).toString(); 310 sourceProps.put(BAND_KEY, bandString); 311 } 312 } 313 } 314 } 315 setMag(); 316 getAreaDirectory(properties); 317 } 318 319 @Override protected void propertiesChanged() { 320 logger.trace("fired"); 321 super.propertiesChanged(); 322 } 323 324 @Override protected boolean initDataFromPollingInfo() { 325 boolean result = super.initDataFromPollingInfo(); 326 logger.trace("result={}", result); 327 return result; 328 } 329 330 @Override protected boolean isPolling() { 331 boolean result = super.isPolling(); 332 logger.trace("isPolling={}", result); 333 return result; 334 } 335 336 @Override public void setPollingInfo(PollingInfo value) { 337 logger.trace("value={}", value); 338 super.setPollingInfo(value); 339 } 340 341 @Override protected boolean hasPollingInfo() { 342 boolean result = super.hasPollingInfo(); 343 logger.trace("hasPollingInfo={}", result); 344 return result; 345 } 346 347 @Override public PollingInfo getPollingInfo() { 348 PollingInfo result = super.getPollingInfo(); 349 logger.trace("getPollingInfo={}", result); 350 return result; 351 } 352 353 @Override public void initAfterUnpersistence() { 354 logger.trace("unbundled!"); 355 super.initAfterUnpersistence(); 356 357 if (this.sourceProps.containsKey(PREVIEW_KEY)) { 358 this.showPreview = (Boolean)this.sourceProps.get(PREVIEW_KEY); 359 if (this.showPreview == null) { 360 this.showPreview = Boolean.FALSE; 361 } 362 this.saveShowPreview = this.showPreview; 363 } 364 365 this.fromBundle = true; 366 List<AddeImageDescriptor> descriptors = (List<AddeImageDescriptor>)getImageList(); 367 this.source = descriptors.get(0).getSource(); // TODO: why not use the source from 368 // each AddeImageDescriptor? 369 for (AddeImageDescriptor descriptor : descriptors) { 370 if (!isFromFile(descriptor)) { 371 this.hasRemoteChoices = true; 372 break; 373 } 374 } 375 } 376 377 @Override public boolean canSaveDataToLocalDisk() { 378 return true; 379 } 380 381 private Hashtable<DataChoice, DataSelection> choiceToSel = new Hashtable<DataChoice, DataSelection>(); 382 383 public DataSelection getSelForChoice(final DataChoice choice) { 384 return choiceToSel.get(choice); 385 } 386 public boolean hasSelForChoice(final DataChoice choice) { 387 return choiceToSel.containsKey(choice); 388 } 389 public void putSelForChoice(final DataChoice choice, final DataSelection sel) { 390 choiceToSel.put(choice, sel); 391 } 392 393 /** 394 * Save files to local disk 395 * 396 * @param prefix destination dir and file prefix 397 * @param loadId For JobManager 398 * @param changeLinks Change internal file references 399 * 400 * @return Files copied 401 * 402 * @throws Exception On badness 403 */ 404 @Override protected List saveDataToLocalDisk(String prefix, Object loadId, boolean changeLinks) throws Exception { 405 logger.trace("prefix={} loadId={} changeLinks={}", new Object[] { prefix, loadId, changeLinks }); 406 final List<JCheckBox> checkboxes = new ArrayList<JCheckBox>(); 407 List categories = new ArrayList(); 408 Hashtable catMap = new Hashtable(); 409 Hashtable currentDataChoices = new Hashtable(); 410 411 List displays = getIdv().getDisplayControls(); 412 for (int i = 0; i < displays.size(); i++) { 413 List dataChoices = ((DisplayControl)displays.get(i)).getDataChoices(); 414 if (dataChoices == null) { 415 continue; 416 } 417 List finalOnes = new ArrayList(); 418 for (int j = 0; j < dataChoices.size(); j++) { 419 ((DataChoice)dataChoices.get(j)).getFinalDataChoices(finalOnes); 420 } 421 for (int dcIdx = 0; dcIdx < finalOnes.size(); dcIdx++) { 422 DataChoice dc = (DataChoice)finalOnes.get(dcIdx); 423 if (!(dc instanceof DirectDataChoice)) { 424 continue; 425 } 426 DirectDataChoice ddc = (DirectDataChoice) dc; 427 if (ddc.getDataSource() != this) { 428 continue; 429 } 430 currentDataChoices.put(ddc.getName(), ""); 431 } 432 } 433 434 for (int i = 0; i < dataChoices.size(); i++) { 435 DataChoice dataChoice = (DataChoice) dataChoices.get(i); 436 if (!(dataChoice instanceof DirectDataChoice)) { 437 continue; 438 } 439 440 // skip over datachoices that the user has not already loaded. 441 // (but fill the "slot" with null (it's a hack to signify that 442 // the "download" loop should skip over the data choice associated 443 // with this slot) 444 if (!currentDataChoices.containsKey(dataChoice.getName())) { 445 checkboxes.add(null); // 446 continue; 447 } 448 449 String label = dataChoice.getDescription(); 450 if (label.length() > 30) { 451 label = label.substring(0, 29) + "..."; 452 } 453 JCheckBox cbx = 454 new JCheckBox(label, 455 currentDataChoices.get(dataChoice.getName()) 456 != null); 457 ThreeDSize size = (ThreeDSize)dataChoice.getProperty(SIZE_KEY); 458 cbx.setToolTipText(dataChoice.getName()); 459 checkboxes.add(cbx); 460 DataCategory dc = dataChoice.getDisplayCategory(); 461 if (dc == null) { 462 dc = DataCategory.createCategory(DataCategory.CATEGORY_IMAGE); 463 } 464 List comps = (List)catMap.get(dc); 465 if (comps == null) { 466 comps = new ArrayList(); 467 catMap.put(dc, comps); 468 categories.add(dc); 469 } 470 comps.add(cbx); 471 comps.add(GuiUtils.filler()); 472 if (size != null) { 473 JLabel sizeLabel = GuiUtils.rLabel(size.getSize() + " "); 474 sizeLabel.setToolTipText(size.getLabel()); 475 comps.add(sizeLabel); 476 } else { 477 comps.add(new JLabel("")); 478 } 479 } 480 final JCheckBox allCbx = new JCheckBox("Select All"); 481 allCbx.addActionListener(new ActionListener() { 482 public void actionPerformed(ActionEvent ae) { 483 for (JCheckBox cbx : checkboxes) { 484 if (cbx != null) { 485 cbx.setSelected(allCbx.isSelected()); 486 } 487 } 488 } 489 }); 490 List catComps = new ArrayList(); 491 JTabbedPane tab = new JTabbedPane(JTabbedPane.LEFT); 492 493 for (int i = 0; i < categories.size(); i++) { 494 List comps = (List)catMap.get(categories.get(i)); 495 JPanel innerPanel = GuiUtils.doLayout(comps, 3, GuiUtils.WT_NYN, GuiUtils.WT_N); 496 JScrollPane sp = new JScrollPane(GuiUtils.top(innerPanel)); 497 sp.setPreferredSize(new Dimension(500, 400)); 498 JPanel top = GuiUtils.right(GuiUtils.rLabel(" ")); 499 JComponent inner = GuiUtils.inset(GuiUtils.topCenter(top, sp), 5); 500 tab.addTab(categories.get(i).toString(), inner); 501 } 502 503 JComponent contents = tab; 504 contents = GuiUtils.topCenter( 505 GuiUtils.inset( 506 GuiUtils.leftRight( 507 new JLabel("Select the fields to download"), 508 allCbx), 5), contents); 509 JLabel label = new JLabel(getNameForDataSource(this, 50, true)); 510 contents = GuiUtils.topCenter(label, contents); 511 contents = GuiUtils.inset(contents, 5); 512 if (!GuiUtils.showOkCancelDialog(null, "", contents, null)) { 513 return null; 514 } 515 516 // iterate through user's selection to build list of things to download 517 List<String> realUrls = new ArrayList<String>(); 518 List<AddeImageDescriptor> descriptorsToSave = new ArrayList<AddeImageDescriptor>(); 519 List<BandInfo> bandInfos = (List<BandInfo>)getProperty(PROP_BANDINFO, (Object)null); 520 List<BandInfo> savedBands = new ArrayList<BandInfo>(); 521 for (int i = 0; i < dataChoices.size(); i++) { 522 DataChoice dataChoice = (DataChoice)dataChoices.get(i); 523 if (!(dataChoice instanceof DirectDataChoice)) { 524 continue; 525 } 526 JCheckBox cbx = (JCheckBox)checkboxes.get(i); 527 if (cbx == null || !cbx.isSelected()) { 528 continue; 529 } 530 531 if (dataChoice.getDataSelection() == null) { 532 dataChoice.setDataSelection(getSelForChoice(dataChoice)); 533 } 534 logger.trace("selected choice={} id={}", dataChoice.getName(), dataChoice.getId()); 535 List<AddeImageDescriptor> descriptors = getDescriptors(dataChoice, dataChoice.getDataSelection()); 536 logger.trace("descriptors={}", descriptors); 537 538 BandInfo bandInfo; 539 Object dataChoiceId = dataChoice.getId(); 540 if (dataChoiceId instanceof BandInfo) { 541 bandInfo = (BandInfo)dataChoiceId; 542 } else { 543 bandInfo = bandInfos.get(0); 544 } 545 String preferredUnit = bandInfo.getPreferredUnit(); 546 List<TwoFacedObject> filteredCalUnits = new ArrayList<TwoFacedObject>(); 547 for (TwoFacedObject tfo : (List<TwoFacedObject>)bandInfo.getCalibrationUnits()) { 548 if (preferredUnit.equals(tfo.getId())) { 549 filteredCalUnits.add(tfo); 550 } 551 } 552 bandInfo.setCalibrationUnits(filteredCalUnits); 553 savedBands.add(bandInfo); 554 555 DataSelection selection = dataChoice.getDataSelection(); 556 if (selection == null) { 557 if (getSelForChoice(dataChoice) != null) { 558 selection = getSelForChoice(dataChoice); 559 } else { 560 selection = getDataSelection(); 561 } 562 } 563 564 Hashtable selectionProperties = selection.getProperties(); 565 // Hashtable selectionProperties; 566 // if (selection != null) { 567 // selectionProperties = selection.getProperties(); 568 // } else { 569 // DataSelection sel = this.getDataSelection(); 570 // selectionProperties = new Hashtable(); 571 // } 572 logger.trace("bandinfo.getUnit={} selection props={}", bandInfo.getPreferredUnit(), selectionProperties); 573 for (AddeImageDescriptor descriptor : descriptors) { 574 // AddeImageInfo aii = (AddeImageInfo)descriptor.getImageInfo().clone(); 575 if (!isFromFile(descriptor)) { 576 String src = descriptor.getSource(); 577 logger.trace("src before={}", src); 578 src = replaceKey(src, AddeImageURL.KEY_UNIT, bandInfo.getPreferredUnit()); 579 if (selectionProperties.containsKey(AddeImageURL.KEY_PLACE)) { 580 src = replaceKey(src, AddeImageURL.KEY_PLACE, selectionProperties.get(AddeImageURL.KEY_PLACE)); 581 } 582 if (selectionProperties.containsKey(AddeImageURL.KEY_LATLON)) { 583 src = replaceKey(src, AddeImageURL.KEY_LINEELE, AddeImageURL.KEY_LATLON, selectionProperties.get(AddeImageURL.KEY_LATLON)); 584 } 585 if (selectionProperties.containsKey(AddeImageURL.KEY_LINEELE)) { 586 src = removeKey(src, AddeImageURL.KEY_LATLON); 587 src = replaceKey(src, AddeImageURL.KEY_LINEELE, selectionProperties.get(AddeImageURL.KEY_LINEELE)); 588 } 589 if (selectionProperties.containsKey(AddeImageURL.KEY_MAG)) { 590 src = replaceKey(src, AddeImageURL.KEY_MAG, selectionProperties.get(AddeImageURL.KEY_MAG)); 591 } 592 if (selectionProperties.containsKey(AddeImageURL.KEY_SIZE)) { 593 src = replaceKey(src, AddeImageURL.KEY_SIZE, selectionProperties.get(AddeImageURL.KEY_SIZE)); 594 } 595 logger.trace("src after={}", src); 596 descriptor.setSource(src); 597 } 598 descriptorsToSave.add(descriptor); 599 } 600 // descriptorsToSave.addAll(descriptors); 601 } 602 if (!savedBands.isEmpty()) { 603 setProperty(PROP_BANDINFO, savedBands); 604 } 605 if (descriptorsToSave.isEmpty()) { 606 return null; 607 } 608 609 //Start the load, showing the dialog 610 List<String> suffixes = new ArrayList<String>(); 611 SimpleDateFormat sdf = new SimpleDateFormat("_" + DATAPATH_DATE_FORMAT); 612 sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 613 for (int i = 0; i < descriptorsToSave.size(); i++) { 614 AddeImageDescriptor descriptor = descriptorsToSave.get(i); 615 AddeImageInfo aii = descriptor.getImageInfo(); 616 DateTime dttm = (DateTime)timeMap.get(descriptor.getSource()); 617 if (dttm != null) { 618 suffixes.add(sdf.format(ucar.visad.Util.makeDate(dttm)) + ".area"); 619 } else if (aii != null) { 620 String suffix = "_Band"+aii.getBand()+"_Unit"+aii.getUnit()+"_Pos"+i+".area"; 621 suffixes.add(suffix); 622 logger.trace("test suffix={}", suffix); 623 } else { 624 suffixes.add(i + ".area"); 625 } 626 realUrls.add(descriptor.getSource()); 627 } 628 logger.trace("urls={}", realUrls); 629 logger.trace("prefix={}", prefix); 630 logger.trace("suffixes={}", suffixes); 631 logger.trace("loadId={}", loadId); 632 List newFiles = IOUtil.writeTo(realUrls, prefix, suffixes, loadId); 633 logger.trace("files={}", newFiles); 634 if (newFiles == null) { 635 logger.trace("failed while in writeTo?"); 636 return null; 637 } else { 638 logger.trace("finished writeTo!"); 639 } 640 if (changeLinks) { 641 imageList = newFiles; 642 } 643 644 // write 0 as the first word 645 for (int i = 0; i < newFiles.size(); i++) { 646 try { 647 RandomAccessFile to = new RandomAccessFile((String)newFiles.get(i), "rw"); 648 to.seek(0); 649 to.writeInt(0); 650 to.close(); 651 } catch (Exception e) { 652 logger.error("unable to set first word to zero", e); 653 } 654 } 655 656 657 // if (geoSubset != null) { 658 // geoSubset.clearStride(); 659 // geoSubset.setBoundingBox(null); 660 // if (geoSelectionPanel != null) { 661 // geoSelectionPanel.initWith(doMakeGeoSelectionPanel()); 662 // } 663 // } 664 665 // List newFiles = Misc.newList(path); 666 // if (changeLinks) { 667 // //Get rid of the resolver URL 668 // getProperties().remove(PROP_RESOLVERURL); 669 // setNewFiles(newFiles); 670 // } 671 // 672 logger.trace("returning={}", newFiles); 673 return newFiles; 674 } 675 676 @Override protected String getDataPrefix() { 677 String tmp = StringUtil.replace(getName(), ' ', ""); 678 tmp = StringUtil.replace(tmp, '/', ""); 679 tmp = StringUtil.replace(tmp, "(AllBands)", ""); 680 tmp = IOUtil.cleanFileName(tmp); 681 logger.trace("data prefix={}", tmp); 682 return tmp; 683 } 684 685 /** 686 * A utility method that helps us deal with legacy bundles that used to 687 * have String file names as the id of a data choice. 688 * 689 * @param object May be an AddeImageDescriptor (for new bundles) or a 690 * String that is converted to an image descriptor. 691 * @return The image descriptor. 692 */ 693 @Override public AddeImageDescriptor getDescriptor(Object object) { 694 // logger.trace("--------------------"); 695 if (object == null) { 696 // logger.trace("null obj"); 697 return null; 698 } 699 if (object instanceof DataChoice) { 700 object = ((DataChoice)object).getId(); 701 logger.trace("datachoice getId={}", object); 702 } 703 if (object instanceof ImageDataInfo) { 704 int index = ((ImageDataInfo) object).getIndex(); 705 if (index < myDataChoices.size()) { 706 DataChoice dc = (DataChoice)myDataChoices.get(index); 707 Object tmpObject = dc.getId(); 708 if (tmpObject instanceof ImageDataInfo) { 709 // logger.trace("returning imagedatainfo"); 710 return ((ImageDataInfo)tmpObject).getAid(); 711 } 712 } 713 // logger.trace("invalid idx for imagedatainfo? (idx={} vs size={})", index, myDataChoices.size()); 714 return null; 715 // return ((ImageDataInfo) object).getAid(); 716 } 717 718 if (object instanceof AddeImageDescriptor) { 719 // logger.trace("already addeimagedesc! desc={}", object); 720 return (AddeImageDescriptor)object; 721 } 722 AddeImageDescriptor tmp = new AddeImageDescriptor(object.toString()); 723 // logger.trace("return descriptor={}", tmp); 724 // logger.trace("--------------------"); 725 return tmp; 726 } 727 728 /** 729 * Overwrite base class method to return the name of this class. 730 * 731 * @return The name. 732 */ 733 public String getImageDataSourceName() { 734 return "Adde Image Data Source (Parameter)"; 735 } 736 737 private void setMag() { 738 Object magKey = (Object)"mag"; 739 if (sourceProps.containsKey(magKey)) { 740 String magVal = (String)(sourceProps.get(magKey)); 741 String[] magVals = magVal.split(" "); 742 this.lineMag = new Integer(magVals[0]).intValue(); 743 this.elementMag = new Integer(magVals[1]).intValue(); 744 } 745 } 746 747 private void getAreaDirectory(Hashtable properties) { 748 String addeCmdBuff = source; 749 if (addeCmdBuff.contains("BAND=")) { 750 String bandStr = getKey(addeCmdBuff, "BAND"); 751 if (bandStr.length() == 0) { 752 addeCmdBuff = replaceKey(addeCmdBuff, "BAND", "1"); 753 } 754 } 755 if (addeCmdBuff.contains("MAG=")) { 756 String[] segs = addeCmdBuff.split("MAG="); 757 String seg0 = segs[0]; 758 String seg1 = segs[1]; 759 int indx = seg1.indexOf("&"); 760 seg1 = seg1.substring(indx); 761 String magString = lineMag + " " + elementMag; 762 addeCmdBuff = seg0 + "MAG=" + magString + seg1; 763 } 764 addeCmdBuff = addeCmdBuff.replace("imagedata", "imagedir"); 765 AreaDirectoryList dirList = null; 766 try { 767 dirList = new AreaDirectoryList(addeCmdBuff); 768 } catch (Exception e) { 769 try { 770 List<BandInfo> bandInfos = (List<BandInfo>)getProperty(PROP_BANDINFO, (Object)null); 771 BandInfo bi = bandInfos.get(0); 772 // String bandStr = new Integer(bi.getBandNumber()).toString(); 773 addeCmdBuff = replaceKey(addeCmdBuff, "BAND", bi.getBandNumber()); 774 dirList = new AreaDirectoryList(addeCmdBuff); 775 } catch (Exception eOpen) { 776 setInError(true); 777 logger.error("problem opening AREA file", eOpen); 778 } 779 } 780 781 try { 782 List areaDirs = dirList.getDirs(); 783 AreaDirectory ad = (AreaDirectory)areaDirs.get(0); 784 float[] res = getLineEleResolution(ad); 785 float resol = res[0]; 786 if (this.lineMag < 0) { 787 resol *= Math.abs(this.lineMag); 788 } 789 // this.lineResolution = ad.getValue(11); 790 this.lineResolution = ad.getValue(AreaFile.AD_LINERES); 791 this.lRes = resol; 792 resol = res[1]; 793 if (this.elementMag < 0) { 794 resol *= Math.abs(this.elementMag); 795 } 796 // this.elementResolution = ad.getValue(12); 797 this.elementResolution = ad.getValue(AreaFile.AD_ELEMRES); 798 this.eRes = resol; 799 } catch (Exception e) { 800 setInError(true); 801 logger.error("getting area directory", e); 802 } 803 baseSource = addeCmdBuff; 804 } 805 806 protected void initDataSelectionComponents( 807 List<DataSelectionComponent> components, final DataChoice dataChoice) { 808 809 if (fromBundle && !hasRemoteChoices) { 810 components.add(new BundlePreviewSelection("Region (Disabled)")); 811 components.add(new BundlePreviewSelection("Advanced (Disabled)")); 812 return; 813 } 814 815 getIdv().showWaitCursor(); 816 817 boolean hasImagePreview = true; 818 if (this.showPreview == null) { 819 this.showPreview = true; 820 } 821 boolean basically = false; 822 if (this.lastChoice != null) { 823 basically = dataChoice.basicallyEquals(this.lastChoice); 824 } 825 logger.trace("dataChoice={}", dataChoice); 826 // check for comps and whether or not dataChoice is hooping right back into line 827 if (this.haveDataSelectionComponents && dataChoice.equals(this.lastChoice)) { 828 try { 829 // did the datachoice ever actually get data? 830 if (dataChoice.getDataSelection() == null) { 831 if (!basically) { 832 this.laLoSel = new GeoLatLonSelection(this, 833 dataChoice, this.initProps, this.previewProjection, 834 previewDir, previewNav); 835 } 836 this.lineMag = this.laLoSel.getLineMag(); 837 this.elementMag = this.laLoSel.getElementMag(); 838 839 /* DAVEP: Force preview on. "No preview" means blank image */ 840 // this.previewSel = new GeoPreviewSelection(this, dataChoice, this.previewImage, 841 // this.laLoSel, this.previewProjection, 842 // this.lineMag, this.elementMag, this.showPreview); 843 this.previewSel = new GeoPreviewSelection(this, dataChoice, this.previewImage, 844 this.laLoSel, this.previewProjection, 845 this.lineMag, this.elementMag, true); 846 } 847 components.add(this.previewSel); 848 components.add(this.laLoSel); 849 } catch (Exception e) { 850 logger.error("error while repeating addition of selection components", e); 851 getIdv().showNormalCursor(); 852 } 853 } else { 854 try { 855 hasImagePreview = makePreviewImage(dataChoice); 856 if (basically) { 857 getSaveComponents(); 858 } 859 } catch (Exception e) { 860 JLabel label = new JLabel("Can't make preview image"); 861 JPanel contents = GuiUtils.top(GuiUtils.inset(label, label.getText().length() + 12)); 862 GuiUtils.showOkDialog(null, "No Preview Image", contents, null); 863 getIdv().showNormalCursor(); 864 logger.error("problem creating preview image", e); 865 return; 866 } 867 this.lastChoice = dataChoice; 868 if (hasImagePreview) { 869 try { 870 String magStr = getKey(baseSource, MAG_KEY); 871 String saveMagStr = magStr; 872 String[] vals = StringUtil.split(magStr, " ", 2); 873 Integer iVal = new Integer(vals[0]); 874 int lMag = iVal.intValue() * -1; 875 if (lMag == -1) { 876 lMag = 1; 877 } 878 iVal = new Integer(vals[1]); 879 int eMag = iVal.intValue() * -1; 880 if (eMag == -1) { 881 eMag = 1; 882 } 883 magStr = lMag + " " + eMag; 884 replaceKey(MAG_KEY, magStr); 885 // String saveStr = baseSource; 886 // if (!showPreview) { 887 // replaceKey(SIZE_KEY, "2 2"); 888 // } 889 AreaAdapter aa = null; 890 AREACoordinateSystem acs = null; 891 try { 892 logger.trace("creating AreaFile from src={}", baseSource); 893 if (showPreview) { 894 aa = new AreaAdapter(baseSource, false); 895 this.previewImage = (FlatField)aa.getImage(); 896 } else { 897 this.previewImage = Util.makeField(0, 1, 1, 0, 1, 1, 0, "TEMP"); 898 } 899 900 AreaFile af = new AreaFile(baseSource); 901 previewNav = af.getNavigation(); 902 AreaDirectory ad = af.getAreaDirectory(); 903 this.lineResolution = ad.getValue(AreaFile.AD_LINERES); 904 this.elementResolution = ad.getValue(AreaFile.AD_ELEMRES); 905 acs = new AREACoordinateSystem(af); 906 } catch (Exception e) { 907 String excp = e.toString(); 908 int indx = excp.lastIndexOf(":"); 909 String errorText = excp.substring(indx+1); 910 JLabel label = new JLabel(errorText); 911 JPanel contents = GuiUtils.top(GuiUtils.inset(label, label.getText().length() + 12)); 912 GuiUtils.showOkDialog(null, "Can't Make Geographical Selection Tabs", contents, null); 913 getIdv().showNormalCursor(); 914 logger.error("problem creating preview image", e); 915 return; 916 } 917 this.initProps = new Hashtable(); 918 Enumeration propEnum = sourceProps.keys(); 919 for (int i = 0; propEnum.hasMoreElements(); i++) { 920 String key = propEnum.nextElement().toString(); 921 Object val = sourceProps.get(key); 922 key = key.toUpperCase(); 923 if (val instanceof String) { 924 String str = (String)val; 925 val = (Object)(str.toUpperCase()); 926 } 927 this.initProps.put(key,val); 928 } 929 replaceKey(MAG_KEY, saveMagStr); 930 magStr = getKey(baseSource, MAG_KEY); 931 vals = StringUtil.split(magStr, " ", 2); 932 iVal = new Integer(vals[0]); 933 lMag = iVal.intValue(); 934 iVal = new Integer(vals[1]); 935 eMag = iVal.intValue(); 936 937 this.initProps.put("LRES", String.valueOf((this.lRes))); 938 this.initProps.put("ERES", String.valueOf((this.eRes))); 939 this.initProps.put("PLRES", String.valueOf((this.previewLineRes))); 940 this.initProps.put("PERES", String.valueOf((this.previewEleRes))); 941 this.previewProjection = (MapProjection)acs; 942 943 String coordType = ""; 944 double coords[] = { 0.0, 0.0 }; 945 946 logger.trace("basically={} laLoSel==null?={}", basically, (this.laLoSel==null)); 947 if (!basically) { 948 if (this.laLoSel != null) { 949 coordType = this.laLoSel.getCoordinateType(); 950 if (coordType.equals(this.laLoSel.getLatLonType())) { 951 coords[0] = this.laLoSel.getLatitude(); 952 coords[1] = this.laLoSel.getLongitude(); 953 } else { 954 coords[0] = (double)this.laLoSel.getLine(); 955 coords[1] = (double)this.laLoSel.getElement(); 956 } 957 958 // turns out that laLoSel is reused for datachoices 959 // from the same source. if you don't update laLoSel's 960 // dataChoice, it'll apply whatever data selection 961 // you set up... to the first data choice that you 962 // loaded! (and causing an NPE when attempting to 963 // bundle the dataselection for the newly-selected 964 // datachoice. 965 this.previewSel.setDataChoice(dataChoice); 966 this.laLoSel.setDataChoice(dataChoice); 967 this.laLoSel.setPreviewLineRes(this.previewLineRes); 968 this.laLoSel.setPreviewEleRes(this.previewEleRes); 969 this.laLoSel.update(previewDir, this.previewProjection, previewNav, 970 coordType, coords); 971 972 } else { 973 this.laLoSel = new GeoLatLonSelection(this, 974 dataChoice, this.initProps, this.previewProjection, 975 previewDir, previewNav); 976 this.lineMag = this.laLoSel.getLineMag(); 977 this.elementMag = this.laLoSel.getElementMag(); 978 } 979 } else { 980 if (this.laLoSel != null) { 981 this.previewSel.setDataChoice(dataChoice); 982 this.laLoSel.setDataChoice(dataChoice); 983 } 984 } 985 /* DAVEP: Force preview on. "No preview" means blank image */ 986 // this.previewSel = new GeoPreviewSelection(this, dataChoice, this.previewImage, 987 // this.laLoSel, this.previewProjection, 988 // this.lineMag, this.elementMag, this.showPreview); 989 this.previewSel = new GeoPreviewSelection(this, dataChoice, this.previewImage, 990 this.laLoSel, this.previewProjection, 991 this.lineMag, this.elementMag, true); 992 993 } catch (Exception e) { 994 logger.error("problem making selection components", e); 995 getIdv().showNormalCursor(); 996 } 997 this.haveDataSelectionComponents = true; 998 // replaceKey(MAG_KEY, (Object)(this.lineMag + " " + this.elementMag)); 999 replaceKey(MAG_KEY, (this.lineMag + " " + this.elementMag)); 1000 components.add(this.previewSel); 1001 components.add(this.laLoSel); 1002 } 1003 } 1004 if (this.previewSel != null) { 1005 this.previewSel.initBox(); 1006 } 1007 getIdv().showNormalCursor(); 1008 } 1009 1010 /** 1011 * A hook to allow this data source to add data selection components 1012 * to the IDV field selector 1013 * 1014 * @param dataChoice the data choice 1015 * 1016 * @return list of components 1017 */ 1018 // @Override public List<DataSelectionComponent> getDataSelectionComponents(DataChoice dataChoice) { 1019 //// List<DataSelectionComponent> dataSelectionComponents = new ArrayList<DataSelectionComponent>(); 1020 //// initDataSelectionComponents(dataSelectionComponents, dataChoice); 1021 //// return dataSelectionComponents; 1022 // return new ArrayList<DataSelectionComponent>(); 1023 // } 1024 1025 private boolean makePreviewImage(DataChoice dataChoice) { 1026 logger.trace("starting with dataChoice={}", dataChoice); 1027 getIdv().showWaitCursor(); 1028 1029 boolean msgFlag = false; 1030 showPreview = saveShowPreview; 1031 List<BandInfo> bandInfos = (List<BandInfo>)getProperty(PROP_BANDINFO, (Object) null); 1032 BandInfo bi = null; 1033 1034 String saveBand = getKey(source, BAND_KEY); 1035 1036 int bandIdx = 0; 1037 1038 logger.trace("band index stuff: saveBand={}, bandIdx={}, source={}", new Object[] { saveBand, bandIdx, source }); 1039 List<TwoFacedObject> calList = null; 1040 try { 1041 Object dcObj = dataChoice.getId(); 1042 if (dcObj instanceof BandInfo) { 1043 bi = (BandInfo) dcObj; 1044 Integer bandInt = new Integer(bandInfos.indexOf(dcObj)+1); 1045 saveBand = bandInt.toString(); 1046 } else { 1047 msgFlag = true; 1048 bi = bandInfos.get(bandIdx); 1049 this.showPreview = false; 1050 } 1051 // pull out the list of cal units, we'll need for type check later... 1052 calList = bi.getCalibrationUnits(); 1053 logger.trace("replacing band: new={} from={}", bi.getBandNumber(), source); 1054 // source = replaceKey(source, BAND_KEY, (Object) (bi.getBandNumber())); 1055 source = replaceKey(source, BAND_KEY, bi.getBandNumber()); 1056 // if we're replacing the band, replace cal type with preferred 1057 // type for that band 1058 logger.trace("replacing unit: new={} from={}", bi.getPreferredUnit(), source); 1059 // source = replaceKey(source, UNIT_KEY, (Object) bi.getPreferredUnit()); 1060 source = replaceKey(source, UNIT_KEY, bi.getPreferredUnit()); 1061 } catch (Exception excp) { 1062 handlePreviewImageError(1, excp); 1063 } 1064 String name = dataChoice.getName(); 1065 int idx = name.lastIndexOf('_'); 1066 String unit = name.substring(idx + 1); 1067 1068 // if this is not a valid cal unit (e.g. could be set to a plugin formula name) 1069 // set it to something valid 1070 boolean validCal = false; 1071 for (TwoFacedObject tfo : calList) { 1072 if (unit.equals((String) tfo.getId())) { 1073 validCal = true; 1074 break; 1075 } 1076 } 1077 if (!validCal) { 1078 unit = bi.getPreferredUnit(); 1079 } 1080 1081 if (getKey(source, UNIT_KEY).length() == 0) { 1082 logger.trace("non-empty unit, replacing: new={} from={}", unit, source); 1083 // source = replaceKey(source, UNIT_KEY, (Object)(unit)); 1084 source = replaceKey(source, UNIT_KEY, unit); 1085 } 1086 1087 AddeImageDescriptor aid = null; 1088 while (aid == null) { 1089 try { 1090 logger.trace("creating new AddeImageDescriptor from {}", this.source); 1091 aid = new AddeImageDescriptor(this.source); 1092 } catch (Exception excp) { 1093 msgFlag = true; 1094 if (bandIdx > bandInfos.size()) { 1095 return false; 1096 } 1097 bi = bandInfos.get(bandIdx); 1098 logger.trace("replacing band: new={} from={}", bi.getBandNumber(), source); 1099 // source = replaceKey(source, BAND_KEY, (Object)(bi.getBandNumber())); 1100 source = replaceKey(source, BAND_KEY, bi.getBandNumber()); 1101 ++bandIdx; 1102 } 1103 } 1104 // previewDir = getPreviewDirectory(aid); 1105 AddeImageDescriptor previewDescriptor = getPreviewDirectory(aid); 1106 previewDir = previewDescriptor.getDirectory(); 1107 logger.trace("using previewDir={}", previewDir); 1108 // try { 1109 // logger.trace("preview areadir: stlines={} stelements={} lines={} elements={}", new Object[] { previewDir.getValue(AreaFile.AD_STLINE), previewDir.getValue(AreaFile.AD_STELEM), previewDir.getLines(), previewDir.getElements() }); 1110 // } catch (Exception e) { 1111 // logger.error("error logging areadir preview", e); 1112 // } 1113 int eMag = 1; 1114 int lMag = 1; 1115 int eSize = 1; 1116 int lSize = 1; 1117 try { 1118 int plMag = 1; 1119 int peMag = 1; 1120 Object magKey = (Object)"mag"; 1121 if (sourceProps.containsKey(magKey)) { 1122 String magVal = (String)(sourceProps.get(magKey)); 1123 String[] magVals = magVal.split(" "); 1124 peMag = new Integer(magVals[0]).intValue(); 1125 plMag = new Integer(magVals[1]).intValue(); 1126 } 1127 double feSize = (double)previewDir.getElements(); 1128 double flSize = (double)previewDir.getLines(); 1129 double feMag = (double)peMag; 1130 double flMag = (double)plMag; 1131 if (feSize > flSize) { 1132 feMag = feSize/525.0; 1133 flMag = feMag * (double)plMag/(double)peMag; 1134 } else { 1135 flMag = flSize/500.0; 1136 feMag = flMag * (double)peMag/(double)plMag; 1137 } 1138 eMag = (int)Math.ceil(feMag); 1139 lMag = (int)Math.ceil(flMag); 1140 } catch(Exception excp) { 1141 handlePreviewImageError(3, excp); 1142 } 1143 if (eMag < 1) eMag = 1; 1144 if (lMag < 1) lMag = 1; 1145 1146 eSize = 525; 1147 lSize = 500; 1148 if ((baseSource == null) || msgFlag) { 1149 logger.trace("replacing\nbaseSource={}\nsource={}", baseSource, source); 1150 baseSource = source; 1151 } 1152 this.previewLineRes = lMag; 1153 this.previewEleRes = eMag; 1154 String uLStr = "0 0 F"; 1155 try { 1156 int startLine = previewDir.getValue(AreaFile.AD_STLINE); 1157 int startEle = previewDir.getValue(AreaFile.AD_STELEM); 1158 uLStr = startLine + " " + startEle + " I"; 1159 } catch (Exception e) { 1160 } 1161 // String src = aid.getSource(); 1162 String src = previewDescriptor.getSource(); 1163 logger.trace("building preview request from src={}", src); 1164 1165 src = removeKey(src, LATLON_KEY); 1166 src = replaceKey(src, LINELE_KEY, uLStr); 1167 src = replaceKey(src, PLACE_KEY, "ULEFT"); 1168 src = replaceKey(src, SIZE_KEY,(lSize + " " + eSize)); 1169 src = replaceKey(src, MAG_KEY, (lMag + " " + eMag)); 1170 src = replaceKey(src, BAND_KEY, bi.getBandNumber()); 1171 src = replaceKey(src, UNIT_KEY, unit); 1172 // if (aid.getIsRelative()) { 1173 // logger.trace("injecting POS={}", aid.getRelativeIndex()); 1174 // src = replaceKey(src, "POS", (Object)aid.getRelativeIndex()); 1175 // } 1176 // if (previewDescriptor.getIsRelative()) { 1177 // logger.trace("inject POS={} into src={}", previewDescriptor.getRelativeIndex(), src); 1178 // src = replaceKey(src, "POS", (Object)previewDescriptor.getRelativeIndex()); 1179 // src = replaceKey(src, "POS", previewDescriptor.getRelativeIndex()); 1180 // } 1181 1182 logger.trace("creating AddeImageDescriptor from src={}", src); 1183 try { 1184 aid = new AddeImageDescriptor(src); 1185 } catch (Exception excp) { 1186 handlePreviewImageError(4, excp); 1187 src = replaceKey(src, BAND_KEY, saveBand); 1188 aid = new AddeImageDescriptor(src); 1189 src = replaceKey(src, BAND_KEY, bi.getBandNumber()); 1190 } 1191 if (msgFlag && (!"ALL".equals(saveBand))) { 1192 src = replaceKey(src, BAND_KEY, saveBand); 1193 } 1194 logger.trace("overwriting\nbaseSource={}\nsrc={}", baseSource, src); 1195 baseSource = src; 1196 getIdv().showNormalCursor(); 1197 return true; 1198 } 1199 1200 /** 1201 * Show the given error to the user. 1202 * 1203 * @param excp The exception 1204 */ 1205 protected void handlePreviewImageError(int flag, Exception excp) { 1206 getIdv().showNormalCursor(); 1207 LogUtil.userErrorMessage("Error in makePreviewImage e=" + flag + " " + excp); 1208 } 1209 1210 private String removeKey(String src, String key) { 1211 String returnString = src; 1212 key = key.toUpperCase() + '='; 1213 if (returnString.contains(key)) { 1214 String[] segs = returnString.split(key); 1215 String seg0 = segs[0]; 1216 String seg1 = segs[1]; 1217 int indx = seg1.indexOf('&'); 1218 if (indx >= 0) { 1219 seg1 = seg1.substring(indx + 1); 1220 } 1221 returnString = seg0 + seg1; 1222 } 1223 return returnString; 1224 } 1225 1226 private static <T> String replaceKey(String sourceUrl, String key, T value) { 1227 String returnString = sourceUrl; 1228 1229 // make sure we got valid key/value pair 1230 if ((key == null) || (value == null)) { 1231 return returnString; 1232 } 1233 1234 key = key.toUpperCase() + '='; 1235 String strValue = value.toString(); 1236 if (returnString.contains(key)) { 1237 String[] segs = returnString.split(key); 1238 String seg0 = segs[0]; 1239 String seg1 = segs[1]; 1240 int indx = seg1.indexOf('&'); 1241 if (indx < 0) { 1242 seg1 = ""; 1243 } else if (indx > 0) { 1244 seg1 = seg1.substring(indx); 1245 } 1246 returnString = seg0 + key + strValue + seg1; 1247 } else { 1248 returnString = returnString + '&' + key + strValue; 1249 } 1250 1251 // if key is for cal units, and it was changed to BRIT, 1252 // must change the spacing key too 1253 if ((key.equals(UNIT_KEY + '=')) && ("BRIT".equals(strValue))) { 1254 returnString = replaceKey(returnString, SPAC_KEY, SPAC_KEY, SPACING_BRIT); 1255 } else { 1256 returnString = replaceKey(returnString, SPAC_KEY, SPAC_KEY, SPACING_NON_BRIT); 1257 } 1258 return returnString; 1259 } 1260 1261 private static <T> String replaceKey(String src, String oldKey, String newKey, T value) { 1262 String returnString = src; 1263 oldKey = oldKey.toUpperCase() + '='; 1264 newKey = newKey.toUpperCase() + '='; 1265 if (returnString.contains(oldKey)) { 1266 String[] segs = returnString.split(oldKey); 1267 String seg0 = segs[0]; 1268 String seg1 = segs[1]; 1269 int indx = seg1.indexOf('&'); 1270 if (indx < 0) { 1271 seg1 = ""; 1272 } else if (indx > 0) { 1273 seg1 = seg1.substring(indx); 1274 } 1275 returnString = seg0 + newKey + value.toString() + seg1; 1276 } 1277 else { 1278 returnString = returnString + '&' + newKey + value.toString(); 1279 } 1280 return returnString; 1281 } 1282 1283 private <T> void replaceKey(String key, T value) { 1284 baseSource = replaceKey(baseSource, key, value); 1285 } 1286 1287 private String getKey(String src, String key) { 1288 String returnString = ""; 1289 key = key.toUpperCase() + '='; 1290 if (src.contains(key)) { 1291 String[] segs = src.split(key); 1292 segs = segs[1].split("&"); 1293 returnString = segs[0]; 1294 } 1295 return returnString; 1296 } 1297 1298 1299 /** 1300 * Create the set of {@link ucar.unidata.data.DataChoice} that represent 1301 * the data held by this data source. We create one top-level 1302 * {@link ucar.unidata.data.CompositeDataChoice} that represents 1303 * all of the image time steps. We create a set of children 1304 * {@link ucar.unidata.data.DirectDataChoice}, one for each time step. 1305 */ 1306 public void doMakeDataChoices() { 1307 super.doMakeDataChoices(); 1308 List<BandInfo> bandInfos = (List<BandInfo>)getProperty(PROP_BANDINFO, (Object)null); 1309 String name = ""; 1310 if (this.choiceName != null) { 1311 name = this.choiceName; 1312 } 1313 if (name.length() != 0) { 1314 logger.trace("already have a name={}", name); 1315 return; 1316 } 1317 if (!sourceProps.containsKey(UNIT_KEY)) { 1318 logger.trace("sourceProps has no unit key={}", sourceProps); 1319 return; 1320 } 1321 BandInfo bi = null; 1322 if (sourceProps.containsKey(BAND_KEY)) { 1323 int bandProp = new Integer((String)(sourceProps.get(BAND_KEY))).intValue(); 1324 int bandIndex = BandInfo.findIndexByNumber(bandProp, bandInfos); 1325 bi = (BandInfo)bandInfos.get(bandIndex); 1326 if (sourceProps.containsKey(UNIT_KEY)) { 1327 bi.setPreferredUnit((String)(sourceProps.get(UNIT_KEY))); 1328 } else { 1329 bi.setPreferredUnit(""); 1330 } 1331 name = makeBandParam(bi); 1332 } 1333 else if (sourceProps.containsKey(BANDINFO_KEY)) { 1334 ArrayList al = (ArrayList)sourceProps.get(BANDINFO_KEY); 1335 bi = (BandInfo)al.get(0); 1336 name = makeBandParam(bi); 1337 } 1338 if (stashedChoices != null) { 1339 int numChoices = stashedChoices.size(); 1340 for (int i = 0; i < numChoices; i++) { 1341 DataChoice choice = (DataChoice)stashedChoices.get(i); 1342 if (name.equals(choice.getName())) { 1343 setProperty(PROP_DATACHOICENAME, choice.getName()); 1344 } 1345 } 1346 } 1347 } 1348 1349 /** 1350 * Overridden so that McIDAS-V can <i>attempt</i> to return the correct 1351 * {@code DataSelection} for the current {@code DataChoice}. 1352 */ 1353 @Override public DataSelection getDataSelection() { 1354 DataSelection tmp; 1355 if (this.laLoSel == null || this.choiceToSel == null || !this.choiceToSel.containsKey(this.laLoSel.getDataChoice())) { 1356 logger.trace("* idvland getDataSelection"); 1357 tmp = super.getDataSelection(); 1358 } else { 1359 logger.trace("* mcv getSelForChoice"); 1360 tmp = this.getSelForChoice(this.laLoSel.getDataChoice()); 1361 } 1362 logger.trace("return selection props={} geo={}", tmp.getProperties(), tmp.getGeoSelection()); 1363 return tmp; 1364 } 1365 1366 /** 1367 * Overridden so that McIDAS-V can associate this data source's current 1368 * {@code DataChoice} with the given {@code DataSelection}. 1369 */ 1370 @Override public void setDataSelection(DataSelection s) { 1371 super.setDataSelection(s); 1372 if (this.laLoSel != null) { 1373 this.putSelForChoice(this.laLoSel.getDataChoice(), s); 1374 } 1375 logger.trace("setting selection props={} geo={}", s.getProperties(), s.getGeoSelection()); 1376 } 1377 1378 // @Override public int canShowParameter(String name) { 1379 // int result = super.canShowParameter(name); 1380 // switch (result) { 1381 // case 0: //show=yes 1382 // logger.trace("can show param={}", name); 1383 // break; 1384 // case 1: // show=hide 1385 // logger.trace("hide param={}", name); 1386 // break; 1387 // case 2: // show=no 1388 // logger.trace("no show param={}", name); 1389 // break; 1390 // default: 1391 // logger.trace("trouble for param={}", name); 1392 // break; 1393 // } 1394 // return result; 1395 // 1396 // } 1397 1398 /** 1399 * Insert the new DataChoice into the dataChoice list. 1400 * 1401 * @param choice new choice to add 1402 */ 1403 protected void addDataChoice(DataChoice choice) { 1404 logger.trace("choice={}", choice); 1405 super.addDataChoice(choice); 1406 if (stashedChoices == null) { 1407 stashedChoices = new ArrayList(); 1408 } 1409 stashedChoices.add(choice); 1410 } 1411 1412 1413 /** 1414 * Initialize the {@link ucar.unidata.data.DataCategory} objects that 1415 * this data source uses. 1416 */ 1417 private void makeCategories() { 1418 twoDTimeSeriesCategories = 1419 DataCategory.parseCategories("IMAGE-2D-TIME;", false); 1420 twoDCategories = DataCategory.parseCategories("IMAGE-2D;", false); 1421 bandCategories = DataCategory.parseCategories("IMAGE-BAND;", false); 1422 bandTimeSeriesCategories = 1423 DataCategory.parseCategories("IMAGE-BAND-TIME;", false); 1424 1425 } 1426 1427 /** 1428 * Checks to see if a given {@code AddeImageDescriptor} is based upon a 1429 * local (or remote) file. 1430 * 1431 * <p>The check is pretty simple: is {@code descriptor.getSource()} a valid 1432 * path? 1433 * 1434 * @param descriptor {@code AddeImageDescriptor} of questionable origins. Shouldn't be {@code null}. 1435 * 1436 * @return {@code true} if {@code descriptor}'s source is a valid path. 1437 */ 1438 public static boolean isFromFile(final AddeImageDescriptor descriptor) { 1439 return new File(descriptor.getSource()).exists(); 1440 } 1441 1442 /** 1443 * Create the actual data represented by the given 1444 * {@link ucar.unidata.data.DataChoice}. 1445 * 1446 * @param dataChoice Either the 1447 * {@link ucar.unidata.data.CompositeDataChoice} 1448 * representing all time steps or a 1449 * {@link ucar.unidata.data.DirectDataChoice} 1450 * representing a single time step. 1451 * @param category Not really used. 1452 * @param dataSelection Defines any time subsets. 1453 * @param requestProperties extra request properties 1454 * 1455 * @return The image or image sequence data. 1456 * 1457 * @throws RemoteException Java RMI problem 1458 * @throws VisADException VisAD problem 1459 */ 1460 protected Data getDataInner(DataChoice dataChoice, DataCategory category, 1461 DataSelection dataSelection, 1462 Hashtable requestProperties) 1463 throws VisADException, RemoteException { 1464 Data img = null; 1465 iml = new ArrayList(); 1466 1467 if (dataSelection == null) { 1468 return null; 1469 } 1470 setDataSelection(dataSelection); 1471 1472 GeoSelection geoSelection = dataSelection.getGeoSelection(true); 1473 if (geoSelection == null) { 1474 return null; 1475 } 1476 1477 boolean validState = geoSelection.getHasValidState(); 1478 if (!validState) { 1479 return null; 1480 } 1481 1482 if (this.lastGeoSelection == null) { 1483 this.lastGeoSelection = geoSelection; 1484 } 1485 1486 this.selectionProps = dataSelection.getProperties(); 1487 Enumeration propEnum = this.selectionProps.keys(); 1488 for (int i = 0; propEnum.hasMoreElements(); i++) { 1489 String key = propEnum.nextElement().toString(); 1490 if (key.compareToIgnoreCase(LATLON_KEY) == 0) { 1491 String val = (String)this.selectionProps.get(key); 1492 if (val.contains("NaN")) { 1493 return img; 1494 } 1495 } 1496 if (key.compareToIgnoreCase(LINELE_KEY) == 0) { 1497 String val = (String)this.selectionProps.get(key); 1498 if (val.contains("NaN")) { 1499 return img; 1500 } 1501 } 1502 } 1503 1504 if (this.selectionProps.containsKey("MAG")) { 1505 String str = (String)this.selectionProps.get("MAG"); 1506 String[] strs = StringUtil.split(str, " ", 2); 1507 this.lineMag = new Integer(strs[0]).intValue(); 1508 this.elementMag = new Integer(strs[1]).intValue(); 1509 } 1510 this.choiceName = dataChoice.getName(); 1511 if (this.choiceName != null) { 1512 setProperty(PROP_DATACHOICENAME, this.choiceName); 1513 } 1514 try { 1515 img = super.getDataInner(dataChoice, category, dataSelection, requestProperties); 1516 } catch (Exception e) { 1517 String displaySrc = getDisplaySource(); 1518 if (displaySrc != null) { 1519 AddeImageDescriptor aid = new AddeImageDescriptor(displaySrc); 1520 dataChoice.setId((Object)aid); 1521 img = super.getDataInner(dataChoice, category, dataSelection, requestProperties); 1522 } 1523 } 1524 return img; 1525 } 1526 1527 /** 1528 * Check if the DataChoice has a BandInfo for it's Id 1529 * 1530 * @param dataChoice choice to check 1531 * 1532 * @return true if the choice ID is a BandInfo 1533 */ 1534 private boolean hasBandInfo(DataChoice dataChoice) { 1535 Object id = dataChoice.getId(); 1536 return id instanceof BandInfo; 1537 } 1538 1539 /** _more_ */ 1540 AreaDirectory[][] currentDirs; 1541 1542 /** 1543 * Create the image sequence defined by the given dataChoice. 1544 * 1545 * @param dataChoice The choice. 1546 * @param subset any time subsets. 1547 * @return The image sequence. 1548 * 1549 * @throws RemoteException Java RMI problem 1550 * @throws VisADException VisAD problem 1551 */ 1552 protected ImageSequence makeImageSequence(DataChoice dataChoice, DataSelection subset) 1553 throws VisADException, RemoteException { 1554 1555 // if (dataChoice.getDataSelection() == null) { 1556 // dataChoice.setDataSelection(subset); 1557 // } 1558 Hashtable subsetProperties = subset.getProperties(); 1559 Enumeration propEnum = subsetProperties.keys(); 1560 int numLines = 0; 1561 int numEles = 0; 1562 for (int i = 0; propEnum.hasMoreElements(); i++) { 1563 String key = propEnum.nextElement().toString(); 1564 if (key.compareToIgnoreCase(SIZE_KEY) == 0) { 1565 String sizeStr = (String)(subsetProperties.get(key)); 1566 String[] vals = StringUtil.split(sizeStr, " ", 2); 1567 Integer iVal = new Integer(vals[0]); 1568 numLines = iVal.intValue(); 1569 iVal = new Integer(vals[1]); 1570 numEles = iVal.intValue(); 1571 break; 1572 } 1573 } 1574 1575 if (sampleMapProjection == null) { 1576 String addeCmdBuff = baseSource; 1577 AreaFile af = null; 1578 try { 1579 af = new AreaFile(addeCmdBuff); 1580 } catch (Exception eOpen) { 1581 logger.error("could not open area file: {}", eOpen); 1582 setInError(true); 1583 throw new BadDataException("Opening area file: " + eOpen.getMessage()); 1584 } 1585 try { 1586 McIDASAreaProjection map = new McIDASAreaProjection(af); 1587 AREACoordinateSystem acs = new AREACoordinateSystem(af); 1588 sampleMapProjection = (MapProjection)acs; 1589 sampleProjection = map; 1590 } catch (Exception e) { 1591 logger.error("making area projection: {}", e); 1592 setInError(true); 1593 throw new BadDataException("Making area projection: " + e.getMessage()); 1594 } 1595 } 1596 AREACoordinateSystem macs = (AREACoordinateSystem)sampleMapProjection; 1597 int[] dirBlk = macs.getDirBlock(); 1598 if (numLines == 0) { 1599 double elelin[][] = new double[2][2]; 1600 double latlon[][] = new double[2][2]; 1601 GeoSelection gs = subset.getGeoSelection(); 1602 GeoLocationInfo gli = gs.getBoundingBox(); 1603 if ((gli == null) && (lastGeoSelection != null)) { 1604 subset.setGeoSelection(lastGeoSelection); 1605 gs = lastGeoSelection; 1606 gli = gs.getBoundingBox(); 1607 } 1608 LatLonPoint llp = gli.getUpperLeft(); 1609 latlon[0][0] = llp.getLatitude(); 1610 latlon[1][0] = llp.getLongitude(); 1611 llp = gli.getLowerRight(); 1612 latlon[0][1] = llp.getLatitude(); 1613 latlon[1][1] = llp.getLongitude(); 1614 elelin = macs.fromReference(latlon); 1615 numLines = (int)(Math.abs(elelin[1][0] - elelin[1][1]))*dirBlk[11]; 1616 numEles = (int)(Math.abs(elelin[0][1] - elelin[0][0]))*dirBlk[12]; 1617 } 1618 1619 try { 1620 List descriptorsToUse = new ArrayList(); 1621 if (hasBandInfo(dataChoice)) { 1622 descriptorsToUse = getDescriptors(dataChoice, subset); 1623 } else { 1624 List choices = (dataChoice instanceof CompositeDataChoice) 1625 ? getChoicesFromSubset( 1626 (CompositeDataChoice) dataChoice, subset) 1627 : Arrays.asList(new DataChoice[] { 1628 dataChoice }); 1629 for (Iterator iter = choices.iterator(); iter.hasNext(); ) { 1630 DataChoice subChoice = (DataChoice) iter.next(); 1631 AddeImageDescriptor aid = 1632 getDescriptor(subChoice.getId()); 1633 if (aid == null) { 1634 continue; 1635 } 1636 DateTime dttm = aid.getImageTime(); 1637 if ((subset != null) && (dttm != null)) { 1638 List times = getTimesFromDataSelection(subset, 1639 dataChoice); 1640 if ((times != null) && (times.indexOf(dttm) == -1)) { 1641 continue; 1642 } 1643 } 1644 descriptorsToUse.add(aid); 1645 } 1646 } 1647 1648 if (descriptorsToUse.size() == 0) { 1649 return null; 1650 } 1651 AddeImageInfo biggestPosition = null; 1652 int pos = 0; 1653 boolean anyRelative = false; 1654 // Find the descriptor with the largets position 1655 for (Iterator iter = 1656 descriptorsToUse.iterator(); iter.hasNext(); ) { 1657 AddeImageDescriptor aid = (AddeImageDescriptor) iter.next(); 1658 if (aid.getIsRelative()) { 1659 anyRelative = true; 1660 } 1661 AddeImageInfo aii = aid.getImageInfo(); 1662 1663 //Are we dealing with area files here? 1664 if (aii == null) { 1665 break; 1666 } 1667 1668 //Check if this is absolute time 1669 if ((aii.getStartDate() != null) 1670 || (aii.getEndDate() != null)) { 1671 biggestPosition = null; 1672 break; 1673 } 1674 if ((biggestPosition == null) || (Math.abs(aii.getDatasetPosition()) > pos)) { 1675 pos = Math.abs(aii.getDatasetPosition()); 1676 biggestPosition = aii; 1677 } 1678 } 1679 1680 if (getCacheDataToDisk() && anyRelative && (biggestPosition != null)) { 1681 biggestPosition.setRequestType(AddeImageInfo.REQ_IMAGEDIR); 1682 AreaDirectoryList adl = new AreaDirectoryList(biggestPosition.getURLString()); 1683 biggestPosition.setRequestType(AddeImageInfo.REQ_IMAGEDATA); 1684 currentDirs = adl.getSortedDirs(); 1685 } else { 1686 currentDirs = null; 1687 } 1688 1689 ThreadManager threadManager = new ThreadManager("image data reading"); 1690 final ImageSequenceManager sequenceManager = new ImageSequenceManager(); 1691 int cnt = 1; 1692 DataChoice parent = dataChoice.getParent(); 1693 final List<SingleBandedImage> images = new ArrayList<SingleBandedImage>(); 1694 MathType rangeType = null; 1695 for (Iterator iter = descriptorsToUse.iterator(); iter.hasNext(); ) { 1696 final AddeImageDescriptor aid = (AddeImageDescriptor) iter.next(); 1697 if (currentDirs != null) { 1698 int idx = Math.abs(aid.getImageInfo().getDatasetPosition()); 1699 if (idx >= currentDirs.length) { 1700 continue; 1701 } 1702 } 1703 1704 String label = ""; 1705 if (parent != null) { 1706 label = label + parent.toString() + ' '; 1707 } else { 1708 DataCategory displayCategory = dataChoice.getDisplayCategory(); 1709 if (displayCategory != null) { 1710 label = label + displayCategory + ' '; 1711 } 1712 } 1713 label = label + dataChoice.toString(); 1714 final String readLabel = "Time: " + (cnt++) + '/' 1715 + descriptorsToUse.size() + ' ' 1716 + label; 1717 1718 String src = aid.getSource(); 1719 if (!isFromFile(aid)) { 1720 try { 1721 src = replaceKey(src, LINELE_KEY, (Object)("1 1")); 1722 String sizeString = "10 10"; 1723 src = replaceKey(src, SIZE_KEY, (Object)(sizeString)); 1724 String name = dataChoice.getName(); 1725 int idx = name.lastIndexOf('_'); 1726 String unit = name.substring(idx+1); 1727 if (getKey(src, UNIT_KEY).length() == 0) { 1728 src = replaceKey(src, UNIT_KEY, (Object)(unit)); 1729 } 1730 int lSize = numLines; 1731 int eSize = numEles; 1732 sizeString = lSize + " " + eSize; 1733 src = replaceKey(src, SIZE_KEY, (Object)(sizeString)); 1734 src = replaceKey(src, MAG_KEY, (Object)(this.lineMag + " " + this.elementMag)); 1735 aid.setSource(src); 1736 } catch (Exception exc) { 1737 logger.error("error trying to adjust AddeImageDescriptor: {}", exc); 1738 super.makeImageSequence(dataChoice, subset); 1739 } 1740 } 1741 1742 try { 1743 SingleBandedImage image = makeImage(aid, rangeType, true, readLabel, subset); 1744 if (image != null) { 1745 if(rangeType==null) { 1746 rangeType = ((FunctionType) image.getType()).getRange(); 1747 } 1748 synchronized (images) { 1749 images.add(image); 1750 } 1751 } 1752 } catch (VisADException e) { 1753 logger.error("avoiding visad exception: ",e); 1754 } catch (RemoteException e) { 1755 logger.error("avoiding remote exception: ", e); 1756 } 1757 } 1758 1759 TreeMap imageMap = new TreeMap(); 1760 for (SingleBandedImage image : images) { 1761 imageMap.put(image.getStartTime(), image); 1762 } 1763 List<SingleBandedImage> sortedImages = (List<SingleBandedImage>) new ArrayList(imageMap.values()); 1764 if ((sortedImages.size() > 0) && (sortedImages.get(0) instanceof AreaImageFlatField)) { 1765 DataRange[] sampleRanges = null; 1766 Set domainSet = null; 1767 for (SingleBandedImage sbi : sortedImages) { 1768 AreaImageFlatField aiff = (AreaImageFlatField) sbi; 1769 sampleRanges = aiff.getRanges(true); 1770 if (domainSet == null) { 1771 domainSet = aiff.getDomainSet(); 1772 } 1773 if ((sampleRanges != null) && (sampleRanges.length > 0)) { 1774 for (int rangeIdx = 0; rangeIdx < sampleRanges.length; rangeIdx++) { 1775 DataRange r = sampleRanges[rangeIdx]; 1776 if (Double.isInfinite(r.getMin()) || Double.isInfinite(r.getMax())) { 1777 sampleRanges = null; 1778 break; 1779 } 1780 } 1781 } 1782 if (sampleRanges != null) { 1783 break; 1784 } 1785 } 1786 1787 if (sampleRanges != null) { 1788 for (SingleBandedImage sbi : sortedImages) { 1789 AreaImageFlatField aiff = (AreaImageFlatField) sbi; 1790 aiff.setSampleRanges(sampleRanges); 1791 aiff.setDomainIfNeeded(domainSet); 1792 } 1793 } 1794 } 1795 1796 SingleBandedImage[] imageArray = 1797 (SingleBandedImage[]) sortedImages.toArray( 1798 new SingleBandedImage[sortedImages.size()]); 1799 FunctionType imageFunction = 1800 (FunctionType) imageArray[0].getType(); 1801 FunctionType ftype = new FunctionType(RealType.Time, 1802 imageFunction); 1803 return new ImageSequenceImpl(ftype, imageArray); 1804 } catch (Exception exc) { 1805 throw new ucar.unidata.util.WrapperException(exc); 1806 } 1807 } 1808 1809 // private String extractTimestampFromUrl(final String url) { 1810 // String day = getKey(url, "DAY"); 1811 // String time = getKey(url, "TIME"); 1812 // 1813 // } 1814 1815 /** 1816 * Create the single image defined by the given {@link ucar.unidata.data.imagery.AddeImageDescriptor AddeImageDescriptor}. 1817 * 1818 * @param aid Holds image directory and location of the desired image. 1819 * @param rangeType {@literal "rangeType"} to use (if non-{@code null}). 1820 * @param fromSequence _more_ 1821 * @param readLabel 1822 * @param subset geographical subsetting info 1823 * 1824 * @return The data. 1825 * 1826 * @throws RemoteException Java RMI problem 1827 * @throws VisADException VisAD problem 1828 */ 1829 private SingleBandedImage makeImage(AddeImageDescriptor aid, 1830 MathType rangeType, 1831 boolean fromSequence, 1832 String readLabel, DataSelection subset) 1833 throws VisADException, RemoteException { 1834 1835 if (aid == null) { 1836 return null; 1837 } 1838 1839 logger.trace("incoming src={} DateTime={} readLabel={}", new Object[] { aid.getSource(), aid.getImageTime(), readLabel }); 1840 String src = aid.getSource(); 1841 1842 Hashtable props = subset.getProperties(); 1843 1844 // String areaDirectoryKey = getKey(src, "POS"); 1845 String areaDirectoryKey = null; 1846 if (aid.getIsRelative()) { 1847 areaDirectoryKey = getKey(src, "POS"); 1848 } else { 1849 String keyDate = getKey(src, "DAY"); 1850 String keyTime = getKey(src, "TIME"); 1851 areaDirectoryKey = aid.getImageTime().toString(); 1852 // areaDirectoryKey = getKey(src, "TIME"); 1853 } 1854 AreaDirectory hacked = requestIdToDirectory.get(areaDirectoryKey); 1855 1856 // it only makes sense to set the following properties for things 1857 // coming from an ADDE server 1858 if (!isFromFile(aid)) { 1859 if (props.containsKey("PLACE")) { 1860 src = replaceKey(src, "PLACE", props.get("PLACE")); 1861 } 1862 if (props.containsKey("LATLON")) { 1863 src = replaceKey(src, "LINELE", "LATLON", props.get("LATLON")); 1864 } 1865 if (props.containsKey("LINELE")) { 1866 src = removeKey(src, "LATLON"); 1867 src = replaceKey(src, "LINELE", props.get("LINELE")); 1868 } 1869 if (props.containsKey("MAG")) { 1870 src = replaceKey(src, "MAG", props.get("MAG")); 1871 } 1872 } 1873 if (hacked != null) { 1874 logger.trace("adjusted src={} areaDirectoryKey='{}' hacked lat={} lon={}", new Object[] { src, areaDirectoryKey, hacked.getCenterLatitude(), hacked.getCenterLongitude() }); 1875 } 1876 aid.setSource(src); 1877 1878 SingleBandedImage result; 1879 result = (SingleBandedImage)getCache(src); 1880 if (result != null) { 1881 setDisplaySource(src, props); 1882 return result; 1883 } 1884 1885 //For now handle non adde urls here 1886 try { 1887 AddeImageInfo aii = aid.getImageInfo(); 1888 AreaDirectory areaDir = null; 1889 try { 1890 if (aii != null) { 1891 logger.trace("imageinfo={}", aii.toString()); 1892 if (currentDirs != null) { 1893 int pos = Math.abs(aii.getDatasetPosition()); 1894 int band = 0; 1895 String bandString = aii.getBand(); 1896 if ((bandString != null) && !aii.ALL.equals(bandString)) { 1897 band = new Integer(bandString).intValue(); 1898 } 1899 // TODO: even though the band is non-zero we might only 1900 // get back one band 1901 band = 0; 1902 areaDir = currentDirs[currentDirs.length - pos - 1][band]; 1903 } else { 1904 // If its absolute time then just use the AD from the descriptor 1905 if ((aii.getStartDate() != null) || (aii.getEndDate() != null)) { 1906 areaDir = aid.getDirectory(); 1907 } else { 1908 } 1909 } 1910 } else { 1911 logger.trace("uh oh"); 1912 } 1913 } catch (Exception exc) { 1914 LogUtil.printMessage("error looking up area dir"); 1915 logger.error("error looking up area dir", exc); 1916 return null; 1917 } 1918 1919 if (areaDir == null) { 1920 areaDir = aid.getDirectory(); 1921 } 1922 1923 if (!getCacheDataToDisk()) { 1924 areaDir = null; 1925 } 1926 1927 if (!fromSequence || (aid.getIsRelative() && (currentDirs == null))) { 1928 areaDir = null; 1929 } 1930 1931 if (areaDir != null) { 1932 if (isFromFile(aid)) { 1933 int hash = ((aii != null) 1934 ? aii.getURLString().hashCode() 1935 : areaDir.hashCode()); 1936 if (rangeType == null) { 1937 result = AreaImageFlatField.createImmediate(aid, readLabel); 1938 } else { 1939 //Else, pass in the already created range type 1940 result = AreaImageFlatField.create(aid, areaDir, rangeType, readLabel); 1941 } 1942 } 1943 1944 } else { 1945 src = aid.getSource(); 1946 try { 1947 savePlace = this.laLoSel.getPlace(); 1948 saveLat = this.laLoSel.getLatitude(); 1949 saveLon = this.laLoSel.getLongitude(); 1950 saveNumLine = this.laLoSel.getNumLines(); 1951 saveNumEle = this.laLoSel.getNumEles(); 1952 saveLineMag = this.laLoSel.getLineMag(); 1953 saveEleMag = this.laLoSel.getElementMag(); 1954 } catch (Exception e) { 1955 logger.error("error reading from laLoSel", e); 1956 // savePlace = getSavePlace(); 1957 // this.laLoSel.setPlace(savePlace); 1958 // saveLat = getSaveLat(); 1959 // this.laLoSel.setLatitude(saveLat); 1960 // saveLon = getSaveLon(); 1961 // this.laLoSel.setLongitude(saveLon); 1962 // saveNumLine = getSaveNumLine(); 1963 // this.laLoSel.setNumLines(saveNumLine); 1964 // saveNumEle = getSaveNumEle(); 1965 // this.laLoSel.setNumEles(saveNumEle); 1966 // saveLineMag = getSaveLineMag(); 1967 // this.laLoSel.setLineMag(saveLineMag); 1968 // saveEleMag = getSaveEleMag(); 1969 // this.laLoSel.setElementMag(saveEleMag); 1970 this.laLoSel.setPlace(savePlace); 1971 this.laLoSel.setLatitude(saveLat); 1972 this.laLoSel.setLongitude(saveLon); 1973 this.laLoSel.setNumLines(saveNumLine); 1974 this.laLoSel.setNumEles(saveNumEle); 1975 this.laLoSel.setLineMag(saveLineMag); 1976 this.laLoSel.setElementMag(saveEleMag); 1977 } 1978 1979 src = replaceKey(src, PLACE_KEY, savePlace); 1980 src = removeKey(src, LINELE_KEY); 1981 if (getKey(src, LATLON_KEY).length() != 0) { 1982 String latStr = Double.toString(saveLat); 1983 if (latStr.length() > 8) { 1984 latStr = latStr.substring(0,7); 1985 } 1986 String lonStr = Double.toString(saveLon); 1987 if (lonStr.length() > 9) { 1988 lonStr = lonStr.substring(0,8); 1989 } 1990 src = replaceKey(src, LATLON_KEY, latStr + ' ' + lonStr); 1991 } 1992 src = replaceKey(src, SIZE_KEY, saveNumLine + ' ' + saveNumEle); 1993 src = replaceKey(src, MAG_KEY, saveLineMag + ' ' + saveEleMag); 1994 } 1995 1996 // try { 1997 // AreaAdapter aa = new AreaAdapter(src, false); 1998 // logger.trace("Getting a new aa={} for src=: {}", aa, src); 1999 // areaDir = previewDir; 2000 // result = aa.getImage(); 2001 // } catch (VisADException e) { 2002 // logger.error("attempting to swallow non-fatal visad exception: ", e); 2003 // } catch (java.io.IOException e) { 2004 // logger.error("attempting to swallow non-fatal I/O exception: ", e); 2005 // } finally { 2006 // putCache(src, result); 2007 // aid.setSource(src); 2008 // iml.add(aid); 2009 // setImageList(iml); 2010 // setDisplaySource(src, props); 2011 // return result; 2012 // } 2013 2014 AreaAdapter aa = new AreaAdapter(src, false); 2015 logger.trace("Getting a new aa={} for src=: {}", aa, src); 2016 areaDir = previewDir; 2017 result = aa.getImage(); 2018 2019 putCache(src, result); 2020 aid.setSource(src); 2021 iml.add(aid); 2022 setImageList(iml); 2023 setDisplaySource(src, props); 2024 return result; 2025 2026 } catch (java.io.IOException ioe) { 2027 throw new VisADException("Creating AreaAdapter - " + ioe); 2028 } 2029 } 2030 2031 /** 2032 * Make a parmeter name for the BandInfo 2033 * 2034 * @param bi the BandInfo in question 2035 * 2036 * @return a name for the parameter 2037 */ 2038 private static String makeBandParam(BandInfo bi) { 2039 return new StringBuilder() 2040 .append(bi.getSensor()) 2041 .append("_Band") 2042 .append(bi.getBandNumber()) 2043 .append('_') 2044 .append(bi.getPreferredUnit()).toString(); 2045 } 2046 2047 private static String makeBandParam(AddeImageDescriptor descriptor) { 2048 AreaDirectory areaDir = descriptor.getDirectory(); 2049 if (areaDir == null) { 2050 throw new NullPointerException("No AREA directory!"); 2051 } 2052 return new StringBuilder() 2053 .append(areaDir.getSensorID()) 2054 .append("_Band") 2055 .append(areaDir.getBands()[0]) 2056 .append('_') 2057 .append(areaDir.getCalibrationType()).toString(); 2058 } 2059 2060 /** 2061 * Get the object that we use to display relative time. Relative time is defined 2062 * using an integer index, 0...n. We don't want to show the actual integer. 2063 * Rather we want to show "Third most recent", "Fourth most recent", etc. 2064 * 2065 * @param aid The image descriptor 2066 * @return The object that represents the relative time index of the aid 2067 */ 2068 private Object getRelativeTimeObject(AddeImageDescriptor aid) { 2069 return new TwoFacedObject(aid.toString(), 2070 new Integer(aid.getRelativeIndex())); 2071 } 2072 2073 /** 2074 * Sort the list of data choices on their time 2075 * 2076 * @param choices The data choices 2077 * 2078 * @return The data choices sorted 2079 */ 2080 private List sortChoices(List choices) { 2081 Object[] choicesArray = choices.toArray(); 2082 Comparator comp = new Comparator() { 2083 public int compare(Object o1, Object o2) { 2084 AddeImageDescriptor aid1 = getDescriptor(o1); 2085 AddeImageDescriptor aid2 = getDescriptor(o2); 2086 if ((aid1 == null) || (aid2 == null)) { 2087 return -1; 2088 } 2089 if (aid1.getIsRelative()) { 2090 if (aid1.getRelativeIndex() < aid2.getRelativeIndex()) { 2091 return 0; 2092 } else if (aid1.getRelativeIndex() 2093 == aid2.getRelativeIndex()) { 2094 return 1; 2095 } 2096 return -1; 2097 } 2098 return aid1.getImageTime().compareTo(aid2.getImageTime()); 2099 } 2100 }; 2101 Arrays.sort(choicesArray, comp); 2102 return new ArrayList(Arrays.asList(choicesArray)); 2103 2104 } 2105 2106 /** 2107 * Get a list of descriptors from the choice and subset 2108 * 2109 * @param dataChoice Data choice 2110 * @param subset subsetting info 2111 * 2112 * @return list of descriptors matching the selection 2113 */ 2114 public List getDescriptors(DataChoice dataChoice, DataSelection subset) { 2115 // logger.trace("choice={} subset props={} geo={}", new Object[] { dataChoice, subset.getProperties(), subset.getGeoSelection() }); 2116 int linRes = this.lineResolution; 2117 int eleRes = this.elementResolution; 2118 int newLinRes = linRes; 2119 int newEleRes = eleRes; 2120 // List<TwoFacedObject> times = getTimesFromDataSelection(subset, dataChoice); 2121 List times = getTimesFromDataSelection(subset, dataChoice); 2122 // if (dataChoice.getDataSelection() == null) { 2123 // logger.trace("setting datasel!"); 2124 // dataChoice.setDataSelection(subset); 2125 // } 2126 if ((times == null) || times.isEmpty()) { 2127 times = imageTimes; 2128 } 2129 // List<AddeImageDescriptor> descriptors = new ArrayList<AddeImageDescriptor>(times.size()); 2130 List descriptors = new ArrayList(); 2131 Object choiceId = dataChoice.getId(); 2132 // if (choiceId instanceof BandInfo) { 2133 // 2134 // } 2135 int choiceBandNum = ((BandInfo)dataChoice.getId()).getBandNumber(); 2136 int choiceSensorId = ((BandInfo)dataChoice.getId()).getSensor(); 2137 String choicePrefUnit = ((BandInfo)dataChoice.getId()).getPreferredUnit(); 2138 for (Iterator iter = times.iterator(); iter.hasNext(); ) { 2139 Object time = iter.next(); 2140 AddeImageDescriptor found = null; 2141 AddeImageDescriptor foundTimeMatch = null; 2142 if (saveImageList.isEmpty()) { 2143 saveImageList = getImageList(); 2144 } 2145 for (Iterator iter2 = saveImageList.iterator(); iter2.hasNext(); ) { 2146 AddeImageDescriptor aid = getDescriptor(iter2.next()); 2147 if (aid != null) { 2148 if (aid.getIsRelative()) { 2149 Object id; 2150 if (time instanceof TwoFacedObject) { 2151 id = ((TwoFacedObject)time).getId(); 2152 } else { 2153 id = time; 2154 } 2155 if ((id instanceof Integer) && ((Integer)id).intValue() == aid.getRelativeIndex()) { 2156 found = aid; 2157 break; 2158 } 2159 } else { 2160 int aidBand = aid.getDirectory().getBands()[0]; 2161 int aidSensorId = aid.getDirectory().getSensorID(); 2162 String calType = aid.getDirectory().getCalibrationType(); 2163 if (foundTimeMatch == null && aid.getImageTime().equals(time)) { 2164 logger.trace("found time match {}", time); 2165 foundTimeMatch = aid; 2166 } 2167 if (aid.getImageTime().equals(time) && choiceBandNum == aidBand && choiceSensorId == aidSensorId && choicePrefUnit.equals(calType)) { 2168 // the problem is here! 2169 logger.trace("found aid={} src={}", makeBandParam(aid), aid.getSource()); 2170 logger.trace("target info: param={}", dataChoice.getName()); 2171 found = aid; 2172 break; 2173 } 2174 } 2175 } 2176 } 2177 2178 if (found == null && foundTimeMatch != null) { 2179 logger.trace("good enough!?"); 2180 found = foundTimeMatch; 2181 } 2182 2183 if (found != null) { 2184 try { 2185 AddeImageDescriptor desc = new AddeImageDescriptor(found); 2186 //Sometimes we might have a null imageinfo 2187 if(desc.getImageInfo()!=null) { 2188 AddeImageInfo aii = 2189 (AddeImageInfo) desc.getImageInfo().clone(); 2190 BandInfo bi = (BandInfo) dataChoice.getId(); 2191 List<BandInfo> bandInfos = 2192 (List<BandInfo>) getProperty(PROP_BANDINFO, (Object) null); 2193 boolean hasBand = true; 2194 //If this data source has been changed after we have create a display 2195 //then the possibility exists that the bandinfo contained by the incoming 2196 //data choice might not be valid. If it isn't then default to the first 2197 //one in the list 2198 if(bandInfos != null) { 2199 hasBand = bandInfos.contains(bi); 2200 if(!hasBand) { 2201 } 2202 if(!hasBand && bandInfos.size() > 0) { 2203 bi = bandInfos.get(0); 2204 } else { 2205 //Not sure what to do here. 2206 } 2207 } 2208 aii.setBand("" + bi.getBandNumber()); 2209 aii.setPlaceValue("ULEFT"); 2210 2211 try { 2212 AddeImageDescriptor newAid = new AddeImageDescriptor(aii.getURLString()); 2213 AreaDirectory newAd = newAid.getDirectory(); 2214 // newLinRes = newAd.getValue(11); 2215 // newEleRes = newAd.getValue(12); 2216 newLinRes = newAd.getValue(AreaFile.AD_LINERES); 2217 newEleRes = newAd.getValue(AreaFile.AD_ELEMRES); 2218 } catch (Exception e) { 2219 logger.error("resetting resolution", e); 2220 } 2221 2222 double[][] projCoords = new double[2][2]; 2223 try { 2224 AreaDirectory ad = desc.getDirectory(); 2225 // double lin = (double)ad.getValue(5); 2226 // double ele = (double)ad.getValue(6); 2227 double lin = (double)ad.getValue(AreaFile.AD_STLINE); 2228 double ele = (double)ad.getValue(AreaFile.AD_STELEM); 2229 aii.setLocateKey("LINELE"); 2230 aii.setLocateValue((int)lin + " " + (int)ele); 2231 projCoords[0][0] = lin; 2232 projCoords[1][0] = ele; 2233 // lin += (double)ad.getValue(8); 2234 // ele += (double)ad.getValue(9); 2235 lin += (double)ad.getValue(AreaFile.AD_NUMLINES); 2236 ele += (double)ad.getValue(AreaFile.AD_NUMELEMS); 2237 projCoords[0][1] = lin; 2238 projCoords[1][1] = ele; 2239 } catch (Exception e) { 2240 logger.error("problem with adjusting projCoords?", e); 2241 return descriptors; 2242 } 2243 int lins = Math.abs((int)(projCoords[1][1] - projCoords[1][0])); 2244 int eles = Math.abs((int)(projCoords[0][1] - projCoords[0][0])); 2245 lins = lins*linRes/newLinRes; 2246 if (this.lineMag > 0) { 2247 lins *= this.lineMag; 2248 } else { 2249 lins /= -this.lineMag; 2250 } 2251 2252 eles = eles*eleRes/newEleRes; 2253 2254 if (elementMag > 0) { 2255 eles *= elementMag; 2256 } else { 2257 eles /= -elementMag; 2258 } 2259 2260 aii.setLines(lins); 2261 aii.setElements(eles); 2262 desc.setImageInfo(aii); 2263 desc.setSource(aii.getURLString()); 2264 } 2265 descriptors.add(desc); 2266 } catch (CloneNotSupportedException cnse) {} 2267 } 2268 } 2269 return descriptors; 2270 } 2271 2272 /** 2273 * Get the subset of the composite based on the selection 2274 * 2275 * @param choice composite choice 2276 * @param subset time selection 2277 * 2278 * @return subset list 2279 */ 2280 private List getChoicesFromSubset(CompositeDataChoice choice, 2281 DataSelection subset) { 2282 List choices = choice.getDataChoices(); 2283 if (subset == null) { 2284 return choices; 2285 } 2286 List times = subset.getTimes(); 2287 if (times == null) { 2288 return choices; 2289 } 2290 times = TwoFacedObject.getIdList(times); 2291 List subChoices = new ArrayList(); 2292 Object firstTime = times.get(0); 2293 if (firstTime instanceof Integer) { 2294 for (Iterator iter = times.iterator(); iter.hasNext(); ) { 2295 subChoices.add( 2296 choices.get(((Integer) iter.next()).intValue())); 2297 } 2298 } else { // TODO: what if they are DateTimes? 2299 subChoices.addAll(choices); 2300 } 2301 return subChoices; 2302 } 2303 2304 private List<AreaDirectory> getPreviewDirectories(final AddeImageDescriptor imageDescriptor) { 2305 List<AreaDirectory> directories = new ArrayList<AreaDirectory>(imageTimes.size()); 2306 2307 return directories; 2308 } 2309 2310 // private AreaDirectory getPreviewDirectory(AddeImageDescriptor aid) { 2311 // AreaDirectory directory = aid.getDirectory(); 2312 // AddeImageDescriptor descriptor = null; 2313 // int times = imageTimes.size(); 2314 // if (times == 1) { 2315 // logger.trace("only looking for a single time; returning AreaDirectory grabbed from incoming AddeImageDescriptor. directory={}", directory); 2316 // return directory; 2317 // } 2318 // String src = aid.getSource(); 2319 // logger.trace("URL for incoming AddeImageDescriptor: {}", src); 2320 // src = removeKey(src, LATLON_KEY); 2321 // src = removeKey(src, LINELE_KEY); 2322 // src = removeKey(src, PLACE_KEY); 2323 // src = removeKey(src, SIZE_KEY); 2324 // src = removeKey(src, UNIT_KEY); 2325 // src = removeKey(src, MAG_KEY); 2326 // src = removeKey(src, SPAC_KEY); 2327 // src = removeKey(src, NAV_KEY); 2328 // src = removeKey(src, AUX_KEY); 2329 // src = removeKey(src, DOC_KEY); 2330 // 2331 // int maxLine = 0; 2332 // int maxEle = 0; 2333 // int imageSize = 0; 2334 // src = src.replace("imagedata", "imagedir"); 2335 // boolean isRelative = aid.getIsRelative(); 2336 // for (int i=0; i<times; i++) { 2337 // if (isRelative) { 2338 // src = replaceKey(src, "POS", new Integer(i).toString()); 2339 // } else { 2340 // DateTime dt = (DateTime)imageTimes.get(i); 2341 // String timeStr = dt.timeString(); 2342 // timeStr = timeStr.replace("Z", " "); 2343 // src = removeKey(src, "POS"); 2344 // src = replaceKey(src, "TIME", timeStr + timeStr + "I"); 2345 // } 2346 // try { 2347 // logger.trace("attempting to create AreaDirectoryList using src={}", src); 2348 // AreaDirectoryList dirList = new AreaDirectoryList(src); 2349 // List ad = dirList.getDirs(); 2350 // AreaDirectory areaDir = (AreaDirectory)ad.get(0); 2351 // logger.trace("created AreaDirectory: {}", areaDir); 2352 // int lines = areaDir.getLines(); 2353 // int eles = areaDir.getElements(); 2354 // if (imageSize < lines*eles) { 2355 // imageSize = lines * eles; 2356 // maxLine = lines; 2357 // maxEle = eles; 2358 // directory = areaDir; 2359 // descriptor = new AddeImageDescriptor(src); 2360 // } 2361 // } catch (Exception e) { 2362 // logger.error("problem when dealing with AREA directory", e); 2363 // } 2364 // } 2365 // logger.trace("returning AreaDirectory: {}", directory); 2366 // logger.trace("could return AddeImageDescriptor:\nisRelative={}\nrelativeIndex={}\ntime={}\ndirectory={}\n", new Object[] { descriptor.getIsRelative(), descriptor.getRelativeIndex(), descriptor.getImageTime(), descriptor.getDirectory()}); 2367 // return directory; 2368 // } 2369 2370 private AddeImageDescriptor getPreviewDirectory(AddeImageDescriptor aid) { 2371 AreaDirectory directory = aid.getDirectory(); 2372 AddeImageDescriptor descriptor = null; 2373 int times = imageTimes.size(); 2374 if (times == 1) { 2375 logger.trace("only looking for a single time; returning AreaDirectory grabbed from incoming AddeImageDescriptor. directory={}", directory); 2376 // return directory; 2377 return aid; 2378 } 2379 2380 String src = aid.getSource(); 2381 logger.trace("URL for incoming AddeImageDescriptor: {}", src); 2382 2383 src = removeKey(src, LATLON_KEY); 2384 src = removeKey(src, LINELE_KEY); 2385 src = removeKey(src, PLACE_KEY); 2386 src = removeKey(src, SIZE_KEY); 2387 src = removeKey(src, UNIT_KEY); 2388 src = removeKey(src, MAG_KEY); 2389 src = removeKey(src, SPAC_KEY); 2390 src = removeKey(src, NAV_KEY); 2391 src = removeKey(src, AUX_KEY); 2392 src = removeKey(src, DOC_KEY); 2393 2394 int maxLine = 0; 2395 int maxEle = 0; 2396 int imageSize = 0; 2397 src = src.replace("imagedata", "imagedir"); 2398 boolean isRelative = aid.getIsRelative(); 2399 2400 List<String> previewUrls = new ArrayList<String>(times); 2401 2402 if (isRelative) { 2403 int maxIndex = Integer.MIN_VALUE; 2404 for (TwoFacedObject tfo : (List<TwoFacedObject>)getAllDateTimes()) { 2405 int relativeIndex = ((Integer)tfo.getId()).intValue(); 2406 if (relativeIndex > maxIndex) { 2407 maxIndex = relativeIndex; 2408 } 2409 } 2410 // TwoFacedObject tfo = (TwoFacedObject)this.getAllDateTimes().get(0); 2411 // negate maxIndex so we can get things like POS=0 or POS=-4 2412 maxIndex = 0 - maxIndex; 2413 logger.trace("using maxIndex={}", maxIndex); 2414 src = replaceKey(src, "POS", Integer.toString(maxIndex)); 2415 previewUrls.add(src); 2416 } else { 2417 for (int i = 0; i < times; i++) { 2418 DateTime dt = (DateTime)imageTimes.get(i); 2419 String timeStr = dt.timeString(); 2420 timeStr = timeStr.replace("Z", " "); 2421 src = removeKey(src, "POS"); 2422 src = replaceKey(src, "TIME", timeStr + timeStr + 'I'); 2423 logger.trace("using time value: ", timeStr + timeStr + 'I'); 2424 logger.trace("added absolute time preview url: {}", src); 2425 previewUrls.add(src); 2426 } 2427 } 2428 2429 logger.trace("preparing to examine previewUrls={}", previewUrls); 2430 2431 try { 2432 for (String previewUrl : previewUrls) { 2433 logger.trace("attempting to create AreaDirectoryList using previewUrl={}", previewUrl); 2434 AreaDirectoryList directoryList = new AreaDirectoryList(previewUrl); 2435 logger.trace("created directoryList! size={}\n{}", directoryList.getDirs().size(), directoryList); 2436 List<AreaDirectory> areaDirectories = (List<AreaDirectory>)directoryList.getDirs(); 2437 // if (isRelative) { 2438 // int requestedRelativePosition = Integer.valueOf(getKey(previewUrl, "POS")); 2439 // // remember, you're requesting the number of available AREA directories, 2440 // // not a position! 2441 // int availablePositions = 0 - (directoryList.getDirs().size() - 1); 2442 // 2443 // logger.trace("validating relative positions: requested position={}, available={}", requestedRelativePosition, availablePositions); 2444 // if (requestedRelativePosition != availablePositions) { 2445 // previewUrl = replaceKey(previewUrl, "POS", availablePositions); 2446 // } 2447 // } 2448 2449 // for (AreaDirectory areaDirectory : areaDirectories) { 2450 for (int i = 0; i < areaDirectories.size(); i++) { 2451 AreaDirectory areaDirectory = areaDirectories.get(i); 2452 String pos = Integer.toString(0 - i); 2453 int lines = areaDirectory.getLines(); 2454 int elements = areaDirectory.getElements(); 2455 int currentDimensions = lines * elements; 2456 logger.trace("image pos={} lines={} elements={} lat={} lon={} startTime='{}' nominalTime='{}' currentDimensions={} areaDirectory={}", new Object[] { pos, lines, elements, areaDirectory.getCenterLatitude(), areaDirectory.getCenterLongitude(), areaDirectory.getStartTime(), areaDirectory.getNominalTime(), currentDimensions, areaDirectory }); 2457 String key = null; 2458 if (isRelative) { 2459 key = pos; 2460 } else { 2461 try { 2462 DateTime reformatted = new DateTime(areaDirectory.getNominalTime()); 2463 key = reformatted.toString(); 2464 } catch (VisADException e) { 2465 logger.error("could not reformat time string='"+areaDirectory.getNominalTime().toString()+"'", e); 2466 key = areaDirectory.getNominalTime().toString(); 2467 } 2468 } 2469 requestIdToDirectory.put(key, areaDirectory); 2470 if (imageSize < currentDimensions) { 2471 2472 imageSize = currentDimensions; 2473 maxLine = lines; 2474 maxEle = elements; 2475 directory = areaDirectory; 2476 // TODO(jon): should be grabbing coord sys from chooser setting (HOW TO DO THAT!?) 2477 String latlonString = areaDirectory.getCenterLatitude() + " " + areaDirectory.getCenterLongitude() + " E"; 2478 String largestPreviewUrl = previewUrl.replace("imagedir", "imagedata"); 2479 largestPreviewUrl = replaceKey(largestPreviewUrl, "PLACE", "CENTER"); 2480 largestPreviewUrl = replaceKey(largestPreviewUrl, "LATLON", latlonString); 2481 Hashtable dataSourceProperties = this.getProperties(); 2482 if (dataSourceProperties.containsKey("navigation")) { 2483 largestPreviewUrl = replaceKey(largestPreviewUrl, "NAV", dataSourceProperties.get("navigation")); 2484 2485 } 2486 2487 if (isRelative) { 2488 largestPreviewUrl = replaceKey(largestPreviewUrl, "POS", pos); 2489 } else { 2490 logger.trace("need to set DAY and TIME keywords for absolute times!"); 2491 } 2492 // previewUrl = previewUrl.replace("imagedir", "imagedata"); 2493 // logger.trace("found new max size! old={} new={} url={}", new Object[] { imageSize, currentDimensions, previewUrl }); 2494 // descriptor = new AddeImageDescriptor(areaDirectory, previewUrl); 2495 logger.trace("found new max size! old={} new={} url={}", new Object[] { imageSize, currentDimensions, largestPreviewUrl }); 2496 descriptor = new AddeImageDescriptor(areaDirectory, largestPreviewUrl); 2497 // descriptor = new AddeImageDescriptor(previewUrl); 2498 // descriptor.setDirectory(areaDirectory); 2499 // descriptor = new AddeImageDescriptor(areaDirectory, previewUrl); 2500 } 2501 } 2502 } 2503 } catch (AreaFileException areaException) { 2504 logger.error("problem when dealing with AREA directory", areaException); 2505 } 2506 // for (int i = 0; i < times; i++) { 2507 // if (isRelative) { 2508 // src = replaceKey(src, "POS", new Integer(i).toString()); 2509 // } else { 2510 // DateTime dt = (DateTime)imageTimes.get(i); 2511 // String timeStr = dt.timeString(); 2512 // timeStr = timeStr.replace("Z", " "); 2513 // src = removeKey(src, "POS"); 2514 // src = replaceKey(src, "TIME", timeStr + timeStr + "I"); 2515 // } 2516 // // don't forget to NOT negate POS=0 2517 // try { 2518 // logger.trace("attempting to create AreaDirectoryList using src={}", src); 2519 // AreaDirectoryList dirList = new AreaDirectoryList(src); 2520 // List ad = dirList.getDirs(); 2521 // AreaDirectory areaDir = (AreaDirectory)ad.get(0); 2522 // logger.trace("created AreaDirectory: {}", areaDir); 2523 // int lines = areaDir.getLines(); 2524 // int eles = areaDir.getElements(); 2525 // logger.trace("image lines={} eles={} for src={}", new Object[] { lines, eles, src }); 2526 // if (imageSize < lines*eles) { 2527 // logger.trace("found new max size! old={} new={}", imageSize, lines*eles); 2528 // imageSize = lines * eles; 2529 // maxLine = lines; 2530 // maxEle = eles; 2531 // directory = areaDir; 2532 // descriptor = new AddeImageDescriptor(src); 2533 // } 2534 // } catch (Exception e) { 2535 // logger.error("problem when dealing with AREA directory", e); 2536 // } 2537 // } 2538 // 2539 2540 logger.trace("returning AreaDirectory: {}", directory); 2541 // logger.trace("could return AddeImageDescriptor:\nisRelative={}\nrelativeIndex={}\ntime={}\ndirectory={}\n", new Object[] { descriptor.getIsRelative(), descriptor.getRelativeIndex(), descriptor.getImageTime(), descriptor.getDirectory()}); 2542 return descriptor; 2543 } 2544 2545 private String getServer(String urlString) { 2546 int ix = urlString.indexOf("//") + 2; 2547 String temp = urlString.substring(ix); 2548 ix = temp.indexOf("/"); 2549 String retStr = temp.substring(0, ix); 2550 return retStr; 2551 } 2552 2553 public void setDisplaySource(String src, Hashtable props) { 2554 if (!props.isEmpty()) { 2555 Enumeration propEnum = props.keys(); 2556 for (int i=0; propEnum.hasMoreElements(); i++) { 2557 String key = propEnum.nextElement().toString(); 2558 Object val = props.get(key); 2559 if (getKey(src, key).length() != 0) { 2560 src = replaceKey(src, key, val); 2561 } 2562 } 2563 } 2564 this.displaySource = src; 2565 String unit = getKey(src, UNIT_KEY); 2566 if (unit.length() != 0) { 2567 sourceProps.put(UNIT_KEY.toUpperCase(), unit); 2568 } 2569 } 2570 2571 public String getDisplaySource() { 2572 return this.displaySource; 2573 } 2574 2575 2576 private float[] getLineEleResolution(AreaDirectory ad) { 2577 logger.trace("ad: {} sensor: {}", ad, ad.getSensorID()); 2578 float[] res = {(float)1.0, (float)1.0}; 2579 int sensor = ad.getSensorID(); 2580 List lines = null; 2581 try { 2582 String buff = getUrl(); 2583 2584 lines = readTextLines(buff); 2585 if (lines == null) { 2586 return res; 2587 } 2588 2589 int gotit = -1; 2590 String[] cards = StringUtil.listToStringArray(lines); 2591 logger.trace("cards: {}", cards); 2592 2593 for (int i=0; i<cards.length; i++) { 2594 if ( ! cards[i].startsWith("Sat ")) continue; 2595 StringTokenizer st = new StringTokenizer(cards[i]," "); 2596 String temp = st.nextToken(); // throw away the key 2597 int m = st.countTokens(); 2598 for (int k=0; k<m; k++) { 2599 int ss = Integer.parseInt(st.nextToken().trim()); 2600 if (ss == sensor) { 2601 gotit = i; 2602 break; 2603 } 2604 } 2605 2606 if (gotit != -1) { 2607 break; 2608 } 2609 } 2610 2611 if (gotit == -1) { 2612 return res; 2613 } 2614 2615 int gotSrc = -1; 2616 for (int i=gotit; i<cards.length; i++) { 2617 if (cards[i].startsWith("EndSat")) { 2618 return res; 2619 } 2620 if (!cards[i].startsWith("B") ) { 2621 continue; 2622 } 2623 StringTokenizer tok = new StringTokenizer(cards[i]); 2624 String str = tok.nextToken(); 2625 str = tok.nextToken(); 2626 Float flt = new Float(str); 2627 res[0] = flt.floatValue(); 2628 str = tok.nextToken(); 2629 flt = new Float(str); 2630 res[1] = flt.floatValue(); 2631 return res; 2632 } 2633 } catch (Exception e) { 2634 logger.error("problem getting the line+element rez", e); 2635 } 2636 return res; 2637 } 2638 2639 2640 /** 2641 * Read the adde text url and return the lines of text. 2642 * If unsuccessful return null. 2643 * 2644 * @param url adde url to a text file 2645 * 2646 * @return List of lines or {@code null} if in error. 2647 */ 2648 protected List readTextLines(String url) { 2649 AddeTextReader reader = new AddeTextReader(url); 2650 List lines = null; 2651 if ("OK".equals(reader.getStatus())) { 2652 lines = reader.getLinesOfText(); 2653 } 2654 return lines; 2655 } 2656 2657 /** 2658 * Create the first part of the ADDE request URL 2659 * 2660 * @return ADDE URL prefix 2661 */ 2662 protected String getUrl() { 2663 String str = source; 2664 str = str.replaceFirst("imagedata", "text"); 2665 int indx = str.indexOf("VERSION"); 2666 str = str.substring(0, indx); 2667 str = str.concat("file=SATBAND"); 2668 return str; 2669 } 2670 2671 public Hashtable getSourceProps() { 2672 return this.sourceProps; 2673 } 2674 2675 public void setSourceProps(Hashtable sourceProps) { 2676 this.sourceProps = sourceProps; 2677 } 2678 2679 // public MapProjection getSampleMapProjection() { 2680 // return this.sampleMapProjection; 2681 // } 2682 // 2683 // public void setSampleMapProjection(MapProjection sampleMapProjection) { 2684 // this.sampleMapProjection = sampleMapProjection; 2685 // } 2686 2687 public String getChoiceName() { 2688 return this.choiceName; 2689 } 2690 2691 public void setChoiceName(String choiceName) { 2692 this.choiceName = choiceName; 2693 } 2694 2695 // public MapProjection getPreviewProjection() { 2696 // return this.previewProjection; 2697 // } 2698 // 2699 // public void setPreviewProjection(MapProjection previewProjection) { 2700 // this.previewProjection = previewProjection; 2701 // } 2702 // 2703 // public AreaDirectory getPreviewDir() { 2704 // return this.previewDir; 2705 // } 2706 // 2707 // public void setPreviewDir(AreaDirectory previewDir) { 2708 // this.previewDir = previewDir; 2709 // } 2710 2711 public String getSavePlace() { 2712 return this.savePlace; 2713 } 2714 2715 public void setSavePlace(String savePlace) { 2716 this.savePlace = savePlace; 2717 } 2718 2719 public double getSaveLat() { 2720 return this.saveLat; 2721 } 2722 2723 public void setSaveLat(double saveLat) { 2724 this.saveLat = saveLat; 2725 } 2726 2727 public double getSaveLon() { 2728 return this.saveLon; 2729 } 2730 2731 public void setSaveLon(double saveLon) { 2732 this.saveLon = saveLon; 2733 } 2734 2735 public int getSaveNumLine() { 2736 return this.saveNumLine; 2737 } 2738 2739 public void setSaveNumLine(int saveNumLine) { 2740 this.saveNumLine = saveNumLine; 2741 } 2742 2743 public int getSaveNumEle() { 2744 return this.saveNumEle; 2745 } 2746 2747 public void setSaveNumEle(int saveNumEle) { 2748 this.saveNumEle = saveNumEle; 2749 } 2750 2751 public int getSaveLineMag() { 2752 return this.saveLineMag; 2753 } 2754 2755 public void setSaveLineMag(int saveLineMag) { 2756 this.saveLineMag = saveLineMag; 2757 } 2758 2759 public int getSaveEleMag() { 2760 return this.saveEleMag; 2761 } 2762 2763 public void setSaveEleMag(int saveEleMag) { 2764 this.saveEleMag = saveEleMag; 2765 } 2766 2767 public String getSource() { 2768 return this.source; 2769 } 2770 2771 public void setSource(String source) { 2772 this.source = source; 2773 } 2774 2775 public boolean getShowPreview() { 2776 return this.showPreview; 2777 } 2778 2779 public void setShowPreview(boolean showPreview) { 2780 this.showPreview = showPreview; 2781 } 2782 2783 public boolean getSaveShowPreview() { 2784 return this.saveShowPreview; 2785 } 2786 2787 public void setSaveShowPreview(boolean saveShowPreview) { 2788 this.saveShowPreview = saveShowPreview; 2789 } 2790 2791 private void getSaveComponents() { 2792 saveCoordType = this.laLoSel.getCoordinateType(); 2793 savePlace = this.laLoSel.getPlace(); 2794 if (saveCoordType.equals(this.laLoSel.getLatLonType())) { 2795 saveLat = this.laLoSel.getLatitude(); 2796 saveLon = this.laLoSel.getLongitude(); 2797 } 2798 saveNumLine = this.laLoSel.getNumLines(); 2799 saveNumEle = this.laLoSel.getNumEles(); 2800 saveLineMag = this.laLoSel.getLineMag(); 2801 saveEleMag = this.laLoSel.getElementMag(); 2802 } 2803 2804 public static class BundlePreviewSelection extends DataSelectionComponent { 2805 final String label; 2806 public BundlePreviewSelection(final String label) { 2807 super(label); 2808 this.label = label; 2809 } 2810 2811 @Override protected JComponent doMakeContents() { 2812 // TODO Auto-generated method stub 2813 JPanel panel = new JPanel(); 2814 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 2815 JLabel label1 = new JLabel("Area coverage has been defined by the data bundle;"); 2816 JLabel label2 = new JLabel("further subsetting is not currently supported."); 2817 label1.setAlignmentX(Component.CENTER_ALIGNMENT); 2818 label2.setAlignmentX(Container.CENTER_ALIGNMENT); 2819 panel.add(label1); 2820 panel.add(label2); 2821 return panel; 2822 } 2823 2824 @Override public void applyToDataSelection(DataSelection dataSelection) { 2825 } 2826 2827 /** 2828 * Overridden to disable these dummy tabs from showing up in properties 2829 * dialog. 2830 */ 2831 @Override public boolean getShowInControlProperties() { 2832 return false; 2833 } 2834 } 2835 }