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 }