001 /*
002 * $Id: AddeImageChooser.java,v 1.44 2012/02/19 17:35:35 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.chooser.adde;
032
033 import static javax.swing.GroupLayout.DEFAULT_SIZE;
034 import static javax.swing.GroupLayout.PREFERRED_SIZE;
035 import static javax.swing.GroupLayout.Alignment.BASELINE;
036 import static javax.swing.GroupLayout.Alignment.LEADING;
037 import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
038
039 import java.awt.Component;
040 import java.awt.IllegalComponentStateException;
041 import java.awt.Insets;
042 import java.awt.Point;
043 import java.awt.event.ActionEvent;
044 import java.awt.event.ActionListener;
045 import java.text.SimpleDateFormat;
046 import java.util.ArrayList;
047 import java.util.Arrays;
048 import java.util.Collections;
049 import java.util.Date;
050 import java.util.Hashtable;
051 import java.util.Iterator;
052 import java.util.List;
053 import java.util.StringTokenizer;
054 import java.util.Vector;
055 import java.util.regex.Matcher;
056 import java.util.regex.Pattern;
057
058 import javax.swing.GroupLayout;
059 import javax.swing.JButton;
060 import javax.swing.JCheckBox;
061 import javax.swing.JComboBox;
062 import javax.swing.JComponent;
063 import javax.swing.JDialog;
064 import javax.swing.JLabel;
065 import javax.swing.JPanel;
066 import javax.swing.JSlider;
067 import javax.swing.JTextField;
068 import javax.swing.JToggleButton;
069 import javax.swing.event.ChangeEvent;
070 import javax.swing.event.ChangeListener;
071
072 import org.slf4j.Logger;
073 import org.slf4j.LoggerFactory;
074 import org.w3c.dom.Element;
075
076 import edu.wisc.ssec.mcidas.AreaDirectory;
077 import edu.wisc.ssec.mcidas.AreaDirectoryList;
078 import edu.wisc.ssec.mcidas.AreaFileException;
079 import edu.wisc.ssec.mcidas.McIDASException;
080 import edu.wisc.ssec.mcidas.adde.AddeSatBands;
081 import edu.wisc.ssec.mcidas.adde.AddeURL;
082
083 import visad.DateTime;
084 import visad.Gridded1DSet;
085 import visad.VisADException;
086
087 import ucar.unidata.data.imagery.AddeImageDescriptor;
088 import ucar.unidata.data.imagery.AddeImageInfo;
089 import ucar.unidata.data.imagery.BandInfo;
090 import ucar.unidata.data.imagery.ImageDataSource;
091 import ucar.unidata.data.imagery.ImageDataset;
092 import ucar.unidata.idv.IdvResourceManager;
093 import ucar.unidata.idv.chooser.IdvChooserManager;
094 import ucar.unidata.idv.chooser.adde.AddeServer;
095 import ucar.unidata.ui.DateTimePicker;
096 import ucar.unidata.ui.LatLonWidget;
097 import ucar.unidata.util.Format;
098 import ucar.unidata.util.GuiUtils;
099 import ucar.unidata.util.LogUtil;
100 import ucar.unidata.util.Misc;
101 import ucar.unidata.util.StringUtil;
102 import ucar.unidata.util.TwoFacedObject;
103 import ucar.unidata.xml.XmlNodeList;
104 import ucar.unidata.xml.XmlResourceCollection;
105 import ucar.unidata.xml.XmlUtil;
106 import ucar.visad.UtcDate;
107
108 import edu.wisc.ssec.mcidasv.servermanager.EntryStore;
109 import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
110
111 /**
112 * Widget to select images from a remote ADDE server Displays a list of the
113 * descriptors (names) of the image datasets available for a particular ADDE
114 * group on the remote server.
115 *
116 * @author Don Murray
117 */
118 public class AddeImageChooser extends AddeChooser implements
119 ucar.unidata.ui.imagery.ImageSelector {
120
121 private static final Logger logger = LoggerFactory.getLogger(AddeImageChooser.class);
122
123 // TODO: get rid of this button right?
124 public static JToggleButton mineBtn = GuiUtils
125 .getToggleImageButton(
126 "/edu/wisc/ssec/mcidasv/resources/icons/toolbar/internet-web-browser16.png",
127 "/edu/wisc/ssec/mcidasv/resources/icons/toolbar/system-software-update16.png",
128 0, 0, true);
129
130 /** _more_ */
131 private static final int SIZE_THRESHOLD = 50;
132
133 /** default magnification */
134 private static final int DEFAULT_MAG = 0;
135
136 /** flag for center */
137 private static final String PLACE_CENTER = "CENTER";
138
139 /** flag for upper left */
140 private static final String PLACE_ULEFT = "ULEFT";
141
142 /** flag for lower left */
143 private static final String PLACE_LLEFT = "LLEFT";
144
145 /** flag for upper right */
146 private static final String PLACE_URIGHT = "URIGHT";
147
148 /** flag for lower right */
149 private static final String PLACE_LRIGHT = "LRIGHT";
150
151 /** Property for the satband file */
152 protected static final String FILE_SATBAND = "SATBAND";
153
154 /** Property for image default value band */
155 protected static final String PROP_BAND = "BAND";
156
157 /** Property for image default value id */
158 protected static final String PROP_ID = "ID";
159
160 /** Property for image default value key */
161 protected static final String PROP_KEY = "key";
162
163 /** Property for image default value lat/lon */
164 protected static final String PROP_LATLON = "LATLON";
165
166 /** Property for image default value line/ele */
167 protected static final String PROP_LINELE = "LINELE";
168
169 /** Property for image default value loc */
170 protected static final String PROP_LOC = "LOC";
171
172 /** Property for image default value mag */
173 protected static final String PROP_MAG = "MAG";
174
175 /** Property for num */
176 protected static final String PROP_NUM = "NUM";
177
178 /** Property for image default value place */
179 protected static final String PROP_PLACE = "PLACE";
180
181 /** Property for image default value size */
182 protected static final String PROP_SIZE = "SIZE";
183
184 /** Property for image default value spac */
185 protected static final String PROP_SPAC = "SPAC";
186
187 /** Property for image default value unit */
188 protected static final String PROP_UNIT = "UNIT";
189
190 /** Property for image default value unit */
191 protected static final String PROP_NAV = "NAV";
192
193 /** This is the list of properties that are used in the advanced gui */
194 private static final String[] ADVANCED_PROPS = { PROP_UNIT, PROP_BAND,
195 PROP_PLACE, PROP_LOC, PROP_SIZE, PROP_MAG, PROP_NAV };
196
197 /** This is the list of labels used for the advanced gui */
198 private static final String[] ADVANCED_LABELS = { "Data Type:", "Channel:",
199 "Placement:", "Location:", "Image Size:", "Magnification:",
200 "Navigation Type:" };
201
202 /** Xml tag name for the defaults */
203 protected static final String TAG_DEFAULT = "default";
204
205 /** identifiere for the default value */
206 protected static final String VALUE_DEFAULT = "default";
207
208 /** Xml attr name for the defaults */
209 protected static final String ATTR_NAME = "name";
210
211 /** Xml attr name for the defaults */
212 protected static final String ATTR_PATTERN = "pattern";
213
214 /** flag for setting properties */
215 private boolean amSettingProperties = false;
216
217 /** Are we currently reading times */
218 private Object readTimesTask;
219
220 /** archive date */
221 protected String archiveDay = null;
222
223 /** Holds the properties */
224 private JPanel propPanel;
225
226 /** archive day button and label */
227 protected JLabel archiveDayLabel;
228 protected JButton archiveDayBtn;
229
230 /** Maps the PROP_ property name to the gui component */
231 private Hashtable propToComps = new Hashtable();
232
233 /**
234 * This is a list of hashtables, one per imagedefaults resource. The
235 * Hashtables map the pattern to the xml node
236 */
237 private List resourceMaps;
238
239 /** Holds the subsetting defaults */
240 private XmlResourceCollection addeDefaults;
241
242 /** archive date formatter */
243 private SimpleDateFormat archiveDayFormatter;
244
245 /** Input for lat/lon center point */
246 protected LatLonWidget latLonWidget;
247
248 /** Widget for the line magnfication in the advanced section */
249 protected JSlider lineMagSlider;
250
251 /** Label for the line mag. in the advanced section */
252 protected JLabel lineMagLbl;
253
254 /** Widget for the element magnfication in the advanced section */
255 protected JSlider elementMagSlider;
256
257 /** Label for the element mag. in the advanced section */
258 protected JLabel elementMagLbl;
259
260 /** base number of lines */
261 private double baseNumLines = 0.0;
262
263 /** size label */
264 JLabel sizeLbl;
265
266 /** base number of lines */
267 private double baseNumElements = 0.0;
268
269 /** Widget to hold the number of elements in the advanced */
270 JTextField numElementsFld;
271
272 /** Widget to hold the number of lines in the advanced */
273 JTextField numLinesFld;
274
275 /** Widget for the line center point in the advanced section */
276 protected JTextField centerLineFld;
277
278 /** Widget for the element center point in the advanced section */
279 protected JTextField centerElementFld;
280
281 /** _more_ */
282 private JToggleButton lockBtn;
283
284 /** full resolution button */
285 private JButton fullResBtn;
286
287 /** Identifier for the maximum number of bands */
288 int MAX_BANDS = 100;
289
290 /** The last AreaDirectory we have seen. */
291 private AreaDirectory lastAD;
292
293 /** The current AreaDirectory used for properties */
294 private AreaDirectory propertiesAD;
295
296 /** The previous AreaDirectory used for properties */
297 private AreaDirectory prevPropertiesAD;
298
299 /** Mapping of area directory to list of BandInfos */
300 protected Hashtable bandTable;
301
302 /**
303 * The list of currently loaded AddeImageDescriptor-s
304 */
305 protected Vector imageDescriptors;
306
307 /** maximum size for the widget */
308 private static final int MAX_SIZE = 700;
309
310 /** Widget for selecting image units */
311 protected JComboBox unitComboBox;
312
313 /** place label */
314 private JLabel placeLbl;
315
316 /** the place string */
317 private String place;
318
319 /** location panel */
320 private GuiUtils.CardLayoutPanel locationPanel;
321
322 /** Widget for selecting image nav type */
323 protected JComboBox navComboBox;
324
325 /**
326 * Mapping of sensor id (String) to hashtable that maps Integer band number
327 * to name
328 */
329 private Hashtable sensorToBandToName;
330
331 /** A flag so we can debug the new way of processing sat band file */
332 private boolean useSatBandInfo = true;
333
334 /** Used to parse the sat band file */
335 private AddeSatBands satBandInfo;
336
337 /** Widget for selecting the band */
338 protected JComboBox bandComboBox;
339
340 /** string for ALL */
341 protected static final String ALL = "ALL";
342
343 /** object for selecting all bands */
344 protected static final TwoFacedObject ALLBANDS = new TwoFacedObject(
345 "All Bands", ALL);
346
347 /** object for selecting all calibrations */
348 protected static final TwoFacedObject ALLUNITS = new TwoFacedObject(
349 "All Types", ALL);
350
351 /**
352 * Keep track of the lines to element ratio
353 */
354 private double linesToElements = 1.0;
355
356 /**
357 * limit of slider
358 */
359 private static final int SLIDER_MAX = 29;
360
361 /**
362 * the list of band infos
363 */
364 private List<BandInfo> bandInfos;
365
366 /**
367 * Construct an Adde image selection widget
368 *
369 *
370 * @param mgr
371 * The chooser manager
372 * @param root
373 * The chooser.xml node
374 */
375 public AddeImageChooser(IdvChooserManager mgr, Element root) {
376 super(mgr, root);
377
378 addDescComp(loadButton);
379
380 archiveDayBtn = GuiUtils.makeImageButton(
381 "/auxdata/ui/icons/calendar_edit.png", this, "getArchiveDay", null,
382 true);
383 archiveDayBtn.setToolTipText("Select a day for archive datasets");
384 archiveDayLabel = new JLabel("Select day:");
385
386 this.addeDefaults = getImageDefaults();
387 }
388
389 /**
390 * Get the xml resource collection that defines the image default xml
391 *
392 * @return Image defaults resources
393 */
394 protected XmlResourceCollection getImageDefaults() {
395 return getIdv().getResourceManager().getXmlResources(
396 IdvResourceManager.RSC_IMAGEDEFAULTS);
397 }
398
399 /**
400 * Update labels, enable widgets, etc.
401 */
402 protected void updateStatus() {
403 super.updateStatus();
404 if (getDoAbsoluteTimes()) {
405 setPropertiesState(getASelectedTime());
406 } else {
407 setPropertiesState(lastAD);
408 }
409
410 if (readTimesTask != null) {
411 if (taskOk(readTimesTask)) {
412 setStatus("Reading available times from server");
413 }
414 } else if (getDoAbsoluteTimes() && !haveTimeSelected()) {
415 setStatus(MSG_TIMES);
416 }
417 enableWidgets();
418 }
419
420 /**
421 * Do we have times selected. Either we are doing absolute times and there
422 * are some selected in the list. Or we are doing relative times and we have
423 * done a connect to the server
424 *
425 * @return Do we have times
426 */
427 public boolean timesOk() {
428 if (getDoAbsoluteTimes() && !haveTimeSelected()) {
429 return false;
430 }
431 return (lastAD != null);
432 }
433
434 /**
435 * Get the list of advanced property names
436 *
437 * @return array of advanced property names
438 */
439 protected String[] getAdvancedProps() {
440 return ADVANCED_PROPS;
441 }
442
443 /**
444 * Get the list of advanced property labels
445 *
446 * @return list of advanced property labels
447 */
448 protected String[] getAdvancedLabels() {
449 return ADVANCED_LABELS;
450 }
451
452 /**
453 * Convenience method for lazy people who don't want to call
454 * {@link ucar.unidata.util.LogUtil#logException(String, Throwable)}.
455 *
456 * @param msg
457 * log message
458 * @param exc
459 * Exception to log
460 */
461 public void logException(String msg, Exception exc) {
462 LogUtil.logException(msg, exc);
463 }
464
465 /**
466 * This allows derived classes to provide their own name for labeling, etc.
467 *
468 * @return the dataset name
469 */
470 public String getDataName() {
471 return "Image Data";
472 }
473
474 /**
475 * Get the descriptor widget label
476 *
477 * @return label for the descriptor widget
478 */
479 public String getDescriptorLabel() {
480 return "Image Type";
481 }
482
483 /**
484 * Respond to a change in the descriptor list.
485 */
486 protected void checkSetNav() {
487 String descriptor = getDescriptor();
488 if (descriptor!=null) {
489 String[] suffixes = { "AMSU", "HIRS", "HRPT", "GAC", "LAC" };
490 for (int i=0; i<suffixes.length; i++) {
491 Pattern p = Pattern.compile("N\\d\\d" + suffixes[i]);
492 Matcher m = p.matcher(descriptor);
493 if (m.find()) {
494 navComboBox.setSelectedIndex(1);
495 break;
496 }
497 }
498 }
499 }
500
501 /**
502 * Get the name of the dataset.
503 *
504 * @return descriptive name of the dataset.
505 */
506 public String getDatasetName() {
507 StringBuffer buf = new StringBuffer();
508 buf.append(getSelectedDescriptor());
509 if (bandComboBox != null && bandComboBox.getItemCount() > 1) {
510 buf.append(" (");
511 buf.append(bandComboBox.getSelectedItem());
512 buf.append(")");
513 }
514 return buf.toString();
515 }
516
517 /**
518 * Check if we are ready to read times
519 *
520 * @return true if times can be read
521 */
522 protected boolean canReadTimes() {
523 return haveDescriptorSelected();
524 }
525
526 /**
527 * Handle when the user presses the update button
528 *
529 * @throws Exception
530 * On badness
531 */
532 public void handleUpdate() throws Exception {
533 if (getState() != STATE_CONNECTED) {
534 // If not connected then update the server list
535 updateServerList();
536 } else {
537 // If we are already connected then update the rest of the chooser
538 descriptorChanged();
539 }
540 updateStatus();
541 }
542
543 /**
544 * Do server connection stuff... override this with type-specific methods
545 */
546 protected void readFromServer() {
547 archiveDay = null;
548 if (archiveDayLabel != null) {
549 archiveDayLabel.setText("Select day:");
550 }
551 readSatBands();
552 super.readFromServer();
553 }
554
555 /**
556 * Overwrite base class method to clear out the lastAD member here.
557 */
558 protected void clearTimesList() {
559 lastAD = null;
560 super.clearTimesList();
561 }
562
563 /**
564 * Show the archive dialog. This method is not meant to be called but is
565 * public by reason of implementation (or insanity).
566 */
567 public void getArchiveDay() {
568 final JDialog dialog = GuiUtils.createDialog("Set Archive Day", true);
569 final DateTimePicker dtp = new DateTimePicker((Date) null, false);
570 if (archiveDay != null) {
571 if (archiveDayFormatter == null) {
572 archiveDayFormatter = new SimpleDateFormat(UtcDate.YMD_FORMAT);
573 }
574 Date d = null;
575 try {
576 d = archiveDayFormatter.parse(archiveDay);
577 dtp.setDate(d);
578 } catch (Exception e) {
579 logException("parsing archive day " + archiveDay, e);
580 }
581 }
582
583 ActionListener listener = new ActionListener() {
584 public void actionPerformed(ActionEvent ae) {
585 String cmd = ae.getActionCommand();
586 if (cmd.equals(GuiUtils.CMD_REMOVE)) {
587 archiveDay = null;
588 archiveDayLabel.setText("Select day:");
589 setDoAbsoluteTimes(true);
590 descriptorChanged();
591 } else if (cmd.equals(GuiUtils.CMD_OK)) {
592 try {
593 DateTime dt = new DateTime(dtp.getDate());
594 archiveDay = UtcDate.getYMD(dt);
595 // archiveDayLabel.setText(UtcDate.formatUtcDate(dt,
596 // "MMM dd, yyyy"));
597 archiveDayLabel.setText(archiveDay);
598 } catch (Exception e) {
599 }
600 // System.out.println("archiveDay = " + archiveDay);
601 setDoAbsoluteTimes(true);
602 descriptorChanged();
603 }
604 dialog.dispose();
605 }
606 };
607
608 JPanel buttons = GuiUtils.makeButtons(listener, new String[] {
609 GuiUtils.CMD_OK, GuiUtils.CMD_REMOVE, GuiUtils.CMD_CANCEL });
610
611 JComponent contents = GuiUtils.topCenterBottom(GuiUtils.inset(GuiUtils
612 .lLabel("Please select a day for this dataset:"), 10), GuiUtils
613 .inset(dtp, 10), buttons);
614 Point p = new Point(200, 200);
615 if (archiveDayBtn != null) {
616 try {
617 p = archiveDayBtn.getLocationOnScreen();
618 } catch (IllegalComponentStateException ice) {
619 }
620 }
621 dialog.setLocation(p);
622 dialog.getContentPane().add(contents);
623 dialog.pack();
624 dialog.setVisible(true);
625 }
626
627 /**
628 * Add the bottom advanced gui panel to the list
629 *
630 * @param bottomComps
631 * the bottom components
632 */
633 protected void getBottomComponents(List bottomComps) {
634
635 String[] propArray = getAdvancedProps();
636 String[] labelArray = getAdvancedLabels();
637 // List bottomComps = new ArrayList();
638 Insets dfltGridSpacing = new Insets(4, 0, 4, 0);
639 String dfltLblSpacing = " ";
640
641 boolean haveBand = Misc.toList(propArray).contains(PROP_BAND);
642 boolean haveNav = Misc.toList(propArray).contains(PROP_NAV);
643 for (int propIdx = 0; propIdx < propArray.length; propIdx++) {
644 JComponent propComp = null;
645 String prop = propArray[propIdx];
646 if (prop.equals(PROP_UNIT)) {
647 unitComboBox = new JComboBox();
648 addPropComp(PROP_UNIT, propComp = unitComboBox);
649 GuiUtils.setPreferredWidth(unitComboBox, 100);
650 if (haveBand) {
651 bandComboBox = new JComboBox();
652 bandComboBox.addActionListener(new ActionListener() {
653 public void actionPerformed(ActionEvent e) {
654 setAvailableUnits(propertiesAD, getSelectedBand());
655 }
656 });
657 addPropComp(PROP_BAND, bandComboBox);
658
659 propComp = GuiUtils.hbox(propComp, GuiUtils.inset(
660 new JLabel("Channel:"), new Insets(0, 10, 0, 5)),
661 bandComboBox, 5);
662 }
663 } else if (prop.equals(PROP_BAND)) {
664 // Moved to PROP_UNIT
665 } else if (prop.equals(PROP_PLACE)) {
666 // Moved to PROP_LOC
667 } else if (prop.equals(PROP_LOC)) {
668 placeLbl = GuiUtils.getFixedWidthLabel("");
669 changePlace(PLACE_CENTER);
670 addPropComp(PROP_PLACE, placeLbl);
671
672 latLonWidget = new LatLonWidget();
673 centerLineFld = new JTextField("", 3);
674 centerElementFld = new JTextField("", 3);
675
676 fullResBtn = GuiUtils.makeImageButton(
677 "/auxdata/ui/icons/arrow_out.png", this,
678 "setToFullResolution");
679 fullResBtn.setContentAreaFilled(false);
680 fullResBtn.setToolTipText("Set to full resolution");
681
682 // lockBtn =
683 // GuiUtils.getToggleImageButton(IdvUIManager.ICON_UNLOCK,
684 // IdvUIManager.ICON_LOCK, 0, 0, true);
685 // lockBtn.setContentAreaFilled(false);
686 // lockBtn.setSelected(true);
687 // lockBtn.setToolTipText(
688 // "Unlock to automatically change size when changing magnification");
689
690 final JButton centerPopupBtn = GuiUtils.getImageButton(
691 "/auxdata/ui/icons/MapIcon16.png", getClass());
692 centerPopupBtn.setToolTipText("Center on current displays");
693 centerPopupBtn.addActionListener(new ActionListener() {
694 public void actionPerformed(ActionEvent ae) {
695 getIdv().getIdvUIManager().popupCenterMenu(
696 centerPopupBtn, latLonWidget);
697 }
698 });
699 JComponent centerPopup = GuiUtils.inset(centerPopupBtn,
700 new Insets(0, 0, 0, 4));
701
702 GuiUtils.tmpInsets = dfltGridSpacing;
703 final JPanel latLonPanel = GuiUtils.hbox(new Component[] {
704 GuiUtils.rLabel(" Lat:" + dfltLblSpacing),
705 latLonWidget.getLatField(),
706 GuiUtils.rLabel(" Lon:" + dfltLblSpacing),
707 latLonWidget.getLonField(), new JLabel(" "),
708 centerPopup });
709
710 final JPanel lineElementPanel = GuiUtils.hbox(new Component[] {
711 GuiUtils.rLabel(" Line:" + dfltLblSpacing),
712 centerLineFld,
713 GuiUtils.rLabel(" Element:" + dfltLblSpacing),
714 centerElementFld });
715
716 locationPanel = new GuiUtils.CardLayoutPanel();
717 locationPanel.addCard(latLonPanel);
718 locationPanel.addCard(lineElementPanel);
719
720 JButton locPosButton = GuiUtils.makeImageButton(
721 "/auxdata/ui/icons/Refresh16.gif", this, "cyclePlace",
722 null, true);
723
724 locPosButton.setToolTipText("Change place type");
725
726 JButton locTypeButton = GuiUtils.makeImageButton(
727 "/auxdata/ui/icons/Refresh16.gif", locationPanel,
728 "flip", null, true);
729 locTypeButton
730 .setToolTipText("Toggle between Latitude/Longitude and Line/Element");
731
732 propComp = GuiUtils.hbox(new Component[] { locPosButton,
733 placeLbl, locTypeButton, locationPanel }, 5);
734 addPropComp(PROP_LOC, propComp);
735 } else if (prop.equals(PROP_MAG)) {
736 boolean oldAmSettingProperties = amSettingProperties;
737 amSettingProperties = true;
738 ChangeListener lineListener = new javax.swing.event.ChangeListener() {
739 public void stateChanged(ChangeEvent evt) {
740 if (amSettingProperties) {
741 return;
742 }
743 lineMagSliderChanged(!getLockButton().isSelected());
744 }
745 };
746 ChangeListener elementListener = new ChangeListener() {
747 public void stateChanged(javax.swing.event.ChangeEvent evt) {
748 if (amSettingProperties) {
749 return;
750 }
751 elementMagSliderChanged(true);
752 }
753 };
754 JComponent[] lineMagComps = GuiUtils.makeSliderPopup(
755 -SLIDER_MAX, SLIDER_MAX, 0, lineListener);
756 lineMagSlider = (JSlider) lineMagComps[1];
757 lineMagSlider.setMajorTickSpacing(1);
758 lineMagSlider.setSnapToTicks(true);
759 lineMagSlider.setExtent(1);
760 lineMagComps[0].setToolTipText("Change the line magnification");
761 JComponent[] elementMagComps = GuiUtils.makeSliderPopup(
762 -SLIDER_MAX, SLIDER_MAX, 0, elementListener);
763 elementMagSlider = (JSlider) elementMagComps[1];
764 elementMagSlider.setExtent(1);
765 elementMagSlider.setMajorTickSpacing(1);
766 elementMagSlider.setSnapToTicks(true);
767 elementMagComps[0]
768 .setToolTipText("Change the element magnification");
769 lineMagSlider
770 .setToolTipText("Slide to set line magnification factor");
771 lineMagLbl = GuiUtils.getFixedWidthLabel(StringUtil.padLeft(
772 "1", 4));
773 elementMagSlider
774 .setToolTipText("Slide to set element magnification factor");
775 elementMagLbl = GuiUtils.getFixedWidthLabel(StringUtil.padLeft(
776 "1", 4));
777 amSettingProperties = oldAmSettingProperties;
778
779 GuiUtils.tmpInsets = dfltGridSpacing;
780 /*
781 * JPanel magPanel = GuiUtils.doLayout(new Component[] {
782 * GuiUtils.rLabel("Line:" + dfltLblSpacing), lineMagLbl,
783 * GuiUtils.inset(lineMagComps[0], new Insets(0, 4, 0, 0)),
784 * GuiUtils.rLabel(" Element:" + dfltLblSpacing),
785 * elementMagLbl, GuiUtils.inset(elementMagComps[0], new
786 * Insets(0, 4, 0, 0)), }, 6, GuiUtils.WT_N, GuiUtils.WT_N);
787 */
788 /*
789 * JPanel magPanel = GuiUtils.doLayout(new Component[] {
790 * lineMagLbl, GuiUtils.inset(lineMagComps[0], new Insets(0, 4,
791 * 0, 0)), new JLabel(" X "), elementMagLbl,
792 * GuiUtils.inset(elementMagComps[0], new Insets(0, 4, 0, 0)),
793 * }, 6, GuiUtils.WT_N, GuiUtils.WT_N);
794 */
795
796 JPanel magPanel = GuiUtils.doLayout(
797 new Component[] {
798 lineMagLbl,
799 GuiUtils.inset(lineMagComps[0], new Insets(0,
800 4, 0, 0)),
801 new JLabel(" X"),
802 elementMagLbl,
803 GuiUtils.inset(elementMagComps[0], new Insets(
804 0, 4, 0, 0)),
805 GuiUtils.inset(getLockButton(), new Insets(0,
806 10, 0, 0)) }, 7, GuiUtils.WT_N,
807 GuiUtils.WT_N);
808
809 addPropComp(PROP_MAG, propComp = magPanel);
810 if (haveNav) {
811 navComboBox = new JComboBox();
812 GuiUtils.setListData(navComboBox, Misc.newList(
813 new TwoFacedObject("Default", "X"),
814 new TwoFacedObject("Lat/Lon", "LALO")));
815 addPropComp(PROP_NAV, navComboBox);
816 boolean showNav = false;
817 showNav = getProperty("includeNavComp", false);
818 if (showNav) {
819 propComp = GuiUtils.hbox(propComp, GuiUtils.inset(
820 new JLabel("Navigation Type:"), new Insets(0,
821 10, 0, 5)), navComboBox, 5);
822 }
823 }
824 } else if (prop.equals(PROP_SIZE)) {
825 numLinesFld = new JTextField("", 4);
826 numElementsFld = new JTextField("", 4);
827 numLinesFld.setToolTipText("Number of lines");
828 numElementsFld.setToolTipText("Number of elements");
829 GuiUtils.tmpInsets = dfltGridSpacing;
830 sizeLbl = GuiUtils.lLabel("");
831
832 /*
833 * JPanel sizePanel = GuiUtils.left(GuiUtils.doLayout(new
834 * Component[] { GuiUtils.rLabel("Lines:" + dfltLblSpacing),
835 * numLinesFld, GuiUtils.rLabel(" Elements:" + dfltLblSpacing),
836 * numElementsFld, new JLabel(" "), sizeLbl }, 6, GuiUtils.WT_N,
837 * GuiUtils.WT_N));
838 */
839
840 JPanel sizePanel = GuiUtils.left(GuiUtils.doLayout(
841 new Component[] { numLinesFld, new JLabel(" X "),
842 numElementsFld, fullResBtn, /* new JLabel(" "), */
843 sizeLbl }, 5, GuiUtils.WT_N, GuiUtils.WT_N));
844 addPropComp(PROP_SIZE, propComp = sizePanel);
845 }
846
847 if (propComp != null) {
848 bottomComps.add(GuiUtils.rLabel(labelArray[propIdx]));
849 bottomComps.add(GuiUtils.left(propComp));
850 }
851
852 }
853
854 GuiUtils.tmpInsets = new Insets(3, 4, 0, 4);
855 propPanel = GuiUtils.doLayout(bottomComps, 2, GuiUtils.WT_N,
856 GuiUtils.WT_N);
857 enableWidgets();
858 }
859
860 /**
861 * Get the "lock" button
862 *
863 * @return the lock button
864 */
865 private JToggleButton getLockButton() {
866 if (lockBtn == null) {
867 lockBtn = GuiUtils.getToggleImageButton(
868 "/auxdata/ui/icons/Linked.gif",
869 "/auxdata/ui/icons/Unlinked.gif", 0, 0, true);
870 lockBtn.setContentAreaFilled(false);
871 lockBtn.setSelected(true);
872 lockBtn
873 .setToolTipText("Unlock to automatically change size when changing magnification");
874 }
875 return lockBtn;
876
877 }
878
879 /**
880 * Set to full resolution
881 */
882 public void setToFullResolution() {
883
884 if (propertiesAD == null) {
885 return;
886 }
887 amSettingProperties = true;
888 numLinesFld.setText("" + propertiesAD.getLines());
889 numElementsFld.setText("" + propertiesAD.getElements());
890 changePlace(PLACE_CENTER);
891 if (useLatLon()) {
892 locationPanel.flip();
893 }
894 centerLineFld.setText("" + (propertiesAD.getLines() / 2));
895 centerElementFld.setText("" + (propertiesAD.getElements() / 2));
896
897 setMagSliders(1, 1);
898 amSettingProperties = false;
899
900 }
901
902 /**
903 * Cycle the place
904 */
905 public void cyclePlace() {
906 if (place.equals(PLACE_CENTER)) {
907 changePlace(PLACE_ULEFT);
908 } else {
909 changePlace(PLACE_CENTER);
910 }
911 }
912
913 /**
914 * Change the place
915 *
916 * @param newPlace
917 * new place
918 */
919 public void changePlace(String newPlace) {
920 this.place = newPlace;
921 String s = translatePlace(place) + "=";
922 placeLbl.setText(StringUtil.padRight(s, 12));
923 }
924
925 /**
926 * _more_
927 *
928 * @param recomputeLineEleRatio
929 * _more_
930 */
931 protected void elementMagSliderChanged(boolean recomputeLineEleRatio) {
932 int value = getElementMagValue();
933 if ((Math.abs(value) < SLIDER_MAX)) {
934 int lineMag = getLineMagValue();
935 if (lineMag > value) {
936 linesToElements = Math.abs(lineMag / (double) value);
937 } else {
938 linesToElements = Math.abs((double) value / lineMag);
939 }
940 }
941 // System.out.println(" changelistener: linesToElements = " +
942 // linesToElements);
943 elementMagLbl.setText(StringUtil.padLeft("" + value, 4));
944 if (!getLockButton().isSelected()) {
945 if (value > 0) {
946 numElementsFld.setText("" + (int) (baseNumElements * value));
947 } else {
948 numElementsFld.setText(""
949 + (int) (baseNumElements / (double) -value));
950 }
951 }
952 }
953
954 /**
955 * Handle the line mag slider changed event
956 *
957 *
958 * @param autoSetSize
959 * _more_
960 */
961 protected void lineMagSliderChanged(boolean autoSetSize) {
962 try {
963 int value = getLineMagValue();
964 lineMagLbl.setText(StringUtil.padLeft("" + value, 4));
965 if (autoSetSize) {
966 if (value > 0) {
967 numLinesFld.setText("" + (int) (baseNumLines * value));
968 } else {
969 numLinesFld.setText(""
970 + (int) (baseNumLines / (double) -value));
971 }
972 }
973
974 if (value == 1) { // special case
975 if (linesToElements < 1.0) {
976 value = (int) (-value / linesToElements);
977 } else {
978 value = (int) (value * linesToElements);
979 }
980
981 } else if (value > 1) {
982 value = (int) (value * linesToElements);
983
984 } else {
985 value = (int) (value / linesToElements);
986 }
987
988 value = (value > 0) ? value - 1 : value + 1; // since slider is one
989 // off
990 amSettingProperties = true;
991 elementMagSlider.setValue(value);
992 amSettingProperties = false;
993 elementMagSliderChanged(false);
994 } catch (Exception exc) {
995 logException("Setting line magnification", exc);
996 }
997 // amSettingProperties = false;
998 }
999
1000 /**
1001 * Get the value of the line magnification slider.
1002 *
1003 * @return The magnification value for the line
1004 */
1005 protected int getLineMagValue() {
1006 return getMagValue(lineMagSlider);
1007 }
1008
1009 /**
1010 * Get the value of the element magnification slider.
1011 *
1012 * @return The magnification value for the element
1013 */
1014 protected int getElementMagValue() {
1015 return getMagValue(elementMagSlider);
1016 }
1017
1018 /**
1019 * Handle the absolute time selection changing
1020 */
1021 protected void absoluteTimesSelectionChanged() {
1022 if (!getDoAbsoluteTimes()) {
1023 return;
1024 }
1025 if (getIdv().getProperty("idv.chooser.addeimage.updateontimechange",
1026 true)) {
1027 setPropertiesState(getASelectedTime(), false);
1028 }
1029 }
1030
1031 /**
1032 * Set the relative and absolute extra components
1033 */
1034 protected JPanel makeTimesPanel() {
1035 JComponent extra = getExtraTimeComponent();
1036 JPanel timesPanel = super.makeTimesPanel(null, extra);
1037 return timesPanel;
1038 }
1039
1040 /**
1041 * Get the time popup widget
1042 *
1043 * @return a widget for selecing the day
1044 */
1045 protected JComponent getExtraTimeComponent() {
1046 return McVGuiUtils.makeLabeledComponent(archiveDayLabel, archiveDayBtn);
1047 }
1048
1049 /**
1050 * Associates the given JComponent with the PROP_ property identified by the
1051 * given propId
1052 *
1053 * @param propId
1054 * The property
1055 * @param comp
1056 * The gui component that allows the user to set the property
1057 *
1058 * @return Just returns the given comp
1059 */
1060 protected JComponent addPropComp(String propId, JComponent comp) {
1061 Object oldComp = propToComps.get(propId);
1062 if (oldComp != null) {
1063 throw new IllegalStateException("Already have a component defined:"
1064 + propId);
1065 }
1066 propToComps.put(propId, comp);
1067 return comp;
1068 }
1069
1070 /**
1071 * Should we use the user supplied property
1072 *
1073 * @param propId
1074 * The property
1075 *
1076 * @return Should use the value from the advanced widget
1077 */
1078 protected boolean usePropFromUser(String propId) {
1079 if (propToComps.get(propId) == null) {
1080 return false;
1081 }
1082 return true;
1083 }
1084
1085 /**
1086 * Get one of the selected times.
1087 *
1088 * @return One of the selected times.
1089 */
1090 protected AreaDirectory getASelectedTime() {
1091 if (haveTimeSelected()) {
1092 List selected = getSelectedAbsoluteTimes();
1093 if (selected.size() > 0) {
1094 AddeImageDescriptor aid = (AddeImageDescriptor) selected.get(0);
1095 if (aid != null) {
1096 return aid.getDirectory();
1097 }
1098 }
1099 }
1100 return null;
1101 }
1102
1103 /**
1104 * Enable or disable the GUI widgets based on what has been selected.
1105 */
1106 protected void enableWidgets() {
1107 boolean descriptorState = ((getState() == STATE_CONNECTED) && canReadTimes());
1108
1109 for (int i = 0; i < compsThatNeedDescriptor.size(); i++) {
1110 JComponent comp = (JComponent) compsThatNeedDescriptor.get(i);
1111 GuiUtils.enableTree(comp, descriptorState);
1112 }
1113
1114 boolean timesOk = timesOk();
1115 if (propPanel != null) {
1116 GuiUtils.enableTree(propPanel, timesOk);
1117 }
1118
1119 // Require times to be selected
1120 GuiUtils.enableTree(loadButton, descriptorState && timesOk);
1121
1122 if (timesOk) {
1123 checkCenterEnabled();
1124 }
1125 checkTimesLists();
1126
1127 // TODO: This is temporary... absolute times on Windows makes the local
1128 // servers choke
1129 // Update: this works now, but leave it here as a reminder
1130 // boolean localWindowsServer = isLocalServer() &&
1131 // System.getProperty("os.name").startsWith("Windows");
1132 // setDoAbsoluteTimes(getDoAbsoluteTimes() && !localWindowsServer);
1133
1134 enableAbsoluteTimesList(getDoAbsoluteTimes() && descriptorState);
1135
1136 getRelativeTimesChooser().setEnabled(
1137 !getDoAbsoluteTimes() && descriptorState);
1138
1139 revalidate();
1140 }
1141
1142 /**
1143 * Check if we are using the lat/lon widget
1144 *
1145 * @return true if we are using the lat/lon widget
1146 */
1147 protected boolean useLatLon() {
1148 return locationPanel.getVisibleIndex() == 0;
1149 }
1150
1151 /**
1152 * Enable or disable the center lat/lon and line/element widgets
1153 */
1154 protected void checkCenterEnabled() {
1155 // NOT NOW
1156 if (true) {
1157 return;
1158 }
1159
1160 boolean usingLatLon = useLatLon();
1161
1162 latLonWidget.getLatField().setEnabled(usingLatLon);
1163 latLonWidget.getLonField().setEnabled(usingLatLon);
1164 // centerLatLbl.setEnabled(usingLatLon);
1165 // centerLonLbl.setEnabled(usingLatLon);
1166
1167 centerLineFld.setEnabled(!usingLatLon);
1168 centerElementFld.setEnabled(!usingLatLon);
1169 // centerLineLbl.setEnabled( !usingLatLon);
1170 // centerElementLbl.setEnabled( !usingLatLon);
1171
1172 }
1173
1174 /**
1175 * Get the selected calibration unit.
1176 *
1177 * @return the selected calibration unit
1178 */
1179 protected String getSelectedUnit() {
1180 if (unitComboBox==null || unitComboBox.getSelectedItem()==null) return "";
1181 String selection = (String) ((TwoFacedObject) unitComboBox.getSelectedItem()).getId();
1182 return selection;
1183 }
1184
1185 /**
1186 * Get the data type for this chooser
1187 *
1188 * @return the data type
1189 */
1190 public String getDataType() {
1191 return "IMAGE";
1192 }
1193
1194 /**
1195 * Get a description of the currently selected dataset
1196 *
1197 * @return a description of the currently selected dataset
1198 * @deprecated use #getDatasetName()
1199 */
1200 public String getDatasetDescription() {
1201 return getDatasetName();
1202 }
1203
1204 /**
1205 * Read the set of image times available for the current server/group/type
1206 * This method is a wrapper, setting the wait cursor and wrapping the call
1207 * to {@link #readTimesInner()}; in a try/catch block
1208 */
1209 public void readTimes() {
1210 clearTimesList();
1211 if (!canReadTimes()) {
1212 return;
1213 }
1214 Misc.run(new Runnable() {
1215 public void run() {
1216 updateStatus();
1217 showWaitCursor();
1218 try {
1219 readTimesInner();
1220 checkSetNav();
1221 } catch (Exception e) {
1222 handleConnectionError(e);
1223 }
1224 showNormalCursor();
1225 updateStatus();
1226 }
1227 });
1228 }
1229
1230 /**
1231 * _more_
1232 */
1233 public void doCancel() {
1234 readTimesTask = null;
1235 setState(STATE_UNCONNECTED);
1236 super.doCancel();
1237 }
1238
1239 /** locking mutex */
1240 private Object MUTEX = new Object();
1241
1242 /**
1243 * Set the list of dates/times based on the image selection
1244 *
1245 */
1246 protected void readTimesInner() {
1247 String descriptor = getDescriptor();
1248 String pos = (getDoAbsoluteTimes() || (archiveDay != null)) ? "all" : "0";
1249
1250 StringBuffer addeCmdBuff = getGroupUrl(REQ_IMAGEDIR, getGroup());
1251 String id = getSelectedStation();
1252 if (id != null) {
1253 appendKeyValue(addeCmdBuff, PROP_ID, id);
1254 }
1255 appendKeyValue(addeCmdBuff, PROP_DESCR, descriptor);
1256 appendKeyValue(addeCmdBuff, PROP_POS, "" + pos);
1257 if (archiveDay != null) {
1258 appendKeyValue(addeCmdBuff, PROP_DAY, archiveDay);
1259 }
1260 String url = addeCmdBuff.toString();
1261 readTimesTask = startTask();
1262 updateStatus();
1263 Object task = readTimesTask;
1264 try {
1265 AreaDirectoryList adir = new AreaDirectoryList(url);
1266 // Make sure no other loads are occurred
1267 boolean ok = stopTaskAndIsOk(task);
1268 if (!Misc.equals(readTimesTask, task) || !ok) {
1269 return;
1270 }
1271 readTimesTask = null;
1272
1273 synchronized (MUTEX) {
1274 // Array of AreaDirectory-s sorted by time
1275 AreaDirectory[][] dirs = adir.getSortedDirs();
1276 int numImages = dirs.length;
1277 imageDescriptors = new Vector();
1278 // TODO: Add a setBands method to AreaDirectory to replace bandtable
1279 bandTable = new Hashtable(numImages);
1280 lastAD = null;
1281 for (int i = 0; i < numImages; i++) {
1282 int bandIndex = 0;
1283 lastAD = (AreaDirectory) dirs[i][0];
1284 int[] allBands = new int[MAX_BANDS];
1285 Vector[] allCals = new Vector[MAX_BANDS];
1286 for (int j = 0; j < dirs[i].length; j++) {
1287 int nbands = dirs[i][j].getNumberOfBands();
1288 int[] abands = dirs[i][j].getBands();
1289 Vector[] vb = dirs[i][j].getCalInfo();
1290 for (int k = 0; k < nbands; k++) {
1291 allBands[bandIndex] = abands[k];
1292 allCals[bandIndex++] = vb[k];
1293 }
1294 }
1295 int[] bands = new int[bandIndex];
1296 System.arraycopy(allBands, 0, bands, 0, bandIndex);
1297 Vector[] cals = new Vector[bandIndex];
1298 System.arraycopy(allCals, 0, cals, 0, bandIndex);
1299 lastAD.setCalInfo(cals);
1300 bandTable.put(lastAD, bands);
1301 AddeImageDescriptor aid = new AddeImageDescriptor(lastAD, null);
1302 imageDescriptors.add(aid);
1303 }
1304
1305 Collections.sort(imageDescriptors);
1306 if (getDoAbsoluteTimes()) {
1307 setAbsoluteTimes(imageDescriptors);
1308 }
1309 // revalidate();
1310 }
1311 setState(STATE_CONNECTED);
1312 } catch (McIDASException e) {
1313 logger.warn("Exception from loadImages", e);
1314 stopTask(task);
1315 readTimesTask = null;
1316 handleConnectionError(e);
1317 }
1318 }
1319
1320 /**
1321 * Set the selected times in the times list based on the input times
1322 *
1323 * @param times
1324 * input times
1325 */
1326 protected void setSelectedTimes(DateTime[] times) {
1327 if ((times == null) || (times.length == 0)) {
1328 return;
1329 }
1330 DateTime[] imageTimes = new DateTime[times.length];
1331
1332 if (imageDescriptors != null) {
1333 imageTimes = new DateTime[imageDescriptors.size()];
1334 for (int idIdx = 0; idIdx < imageDescriptors.size(); idIdx++) {
1335 AddeImageDescriptor aid = (AddeImageDescriptor) imageDescriptors.get(idIdx);
1336 imageTimes[idIdx] = aid.getImageTime();
1337 }
1338 } else {
1339 imageTimes = times;
1340 }
1341 if (imageTimes.length > 0) {
1342 try {
1343 Gridded1DSet imageSet = DateTime.makeTimeSet(imageTimes);
1344 int numTimes = times.length;
1345 double[][] timesValues = new double[1][numTimes];
1346 for (int i = 0; i < times.length; i++) {
1347 timesValues[0][i] = times[i].getValue(imageSet.getSetUnits()[0]);
1348 }
1349 setSelectedAbsoluteTimes(imageSet.doubleToIndex(timesValues));
1350 absoluteTimesSelectionChanged();
1351 } catch (VisADException ve) {
1352 logException("Unable to set times from display", ve);
1353 }
1354 }
1355 }
1356
1357 /**
1358 * Set the center location portion of the request. If the input from the
1359 * widget is null, use the centerpoint from the image descriptor.
1360 *
1361 * @param aid
1362 * image descriptor for the image
1363 */
1364 protected void setCenterLocation(AddeImageDescriptor aid) {
1365 String latPoint = "";
1366 String lonPoint = "";
1367 if (aid != null) {
1368 AreaDirectory ad = aid.getDirectory();
1369 latPoint = "" + ad.getCenterLatitude();
1370 lonPoint = "" + ad.getCenterLongitude();
1371 }
1372 if (!latPoint.trim().equals("")) {
1373 latLonWidget.setLat(latPoint);
1374 }
1375 if (!lonPoint.trim().equals("")) {
1376 latLonWidget.setLon(lonPoint);
1377 }
1378 }
1379
1380 /**
1381 * get the adde server grup type to use
1382 *
1383 * @return group type
1384 */
1385 @Override
1386 protected String getGroupType() {
1387 return AddeServer.TYPE_IMAGE;
1388 }
1389
1390 /**
1391 * Does this selector have all of its state set to load in data
1392 *
1393 * @return Has the user chosen everything they need to choose to load data
1394 */
1395 protected boolean getGoodToGo() {
1396 // if(!super.getGoodToGo()) return false;
1397 if (getDoAbsoluteTimes()) {
1398 return getHaveAbsoluteTimesSelected();
1399 } else {
1400 return canReadTimes() && (lastAD != null);
1401 }
1402 }
1403
1404 /**
1405 * Returns a list of the images to load or null if none have been selected.
1406 *
1407 * @return list get the list of image descriptors
1408 */
1409 public List getImageList() {
1410 if (!timesOk()) {
1411 return null;
1412 }
1413 List images = new ArrayList();
1414 String defaultBand = getDefault(PROP_BAND, ALL);
1415 try {
1416 if (getDoRelativeTimes()) {
1417 AddeImageDescriptor firstDescriptor = (AddeImageDescriptor) imageDescriptors.get(0);
1418 AreaDirectory ad = firstDescriptor.getDirectory();
1419 int[] bands = (int[]) bandTable.get(ad);
1420 bandInfos = makeBandInfos(ad, bands);
1421 int[] relativeTimesIndices = getRelativeTimeIndices();
1422 for (int i = 0; i < relativeTimesIndices.length; i++) {
1423 AddeImageDescriptor aid = new AddeImageDescriptor(relativeTimesIndices[i], firstDescriptor);
1424 AddeImageInfo aii = makeImageInfo(aid.getDirectory(), true, relativeTimesIndices[i]);
1425 aii.setDebug(EntryStore.isAddeDebugEnabled(false));
1426 if (aii.getBand() == null) aii.setBand(defaultBand);
1427 aid.setImageInfo(aii);
1428 aid.setSource(aii.getURLString());
1429 images.add(aid);
1430 }
1431 } else {
1432 List selectedTimes = getSelectedAbsoluteTimes();
1433 for (int i = 0; i < selectedTimes.size(); i++) {
1434 AddeImageDescriptor aid = new AddeImageDescriptor((AddeImageDescriptor) selectedTimes.get(i));
1435 AddeImageInfo aii = makeImageInfo(aid.getDirectory(), false, i);
1436 aii.setDebug(EntryStore.isAddeDebugEnabled(false));
1437 if (aii.getBand() == null) aii.setBand(defaultBand);
1438 aid.setImageInfo(aii);
1439 aid.setSource(aii.getURLString());
1440 images.add(aid);
1441 }
1442 }
1443 } catch (Exception exc) {
1444 logException("Error occured", exc);
1445 return null;
1446 }
1447 return images;
1448 }
1449
1450 /**
1451 * Process the image defaults resources
1452 */
1453 protected void initializeAddeDefaults() {
1454 resourceMaps = new ArrayList();
1455 if (addeDefaults == null) {
1456 return;
1457 }
1458 for (int resourceIdx = 0; resourceIdx < addeDefaults.size(); resourceIdx++) {
1459 Element root = addeDefaults.getRoot(resourceIdx);
1460 if (root == null) {
1461 continue;
1462 }
1463 Hashtable resourceMap = new Hashtable();
1464 resourceMaps.add(resourceMap);
1465
1466 XmlNodeList defaultNodes = XmlUtil.getElements(root, TAG_DEFAULT);
1467 for (int nodeIdx = 0; nodeIdx < defaultNodes.size(); nodeIdx++) {
1468 Element dfltNode = (Element) defaultNodes.item(nodeIdx);
1469 String pattern = XmlUtil.getAttribute(dfltNode, ATTR_PATTERN,
1470 (String) null);
1471 if (pattern == null) {
1472 pattern = XmlUtil.getAttribute(dfltNode, ATTR_NAME);
1473 }
1474 if (pattern != null) {
1475 pattern = pattern.toLowerCase();
1476 }
1477 resourceMap.put(pattern, dfltNode);
1478 }
1479 }
1480 }
1481
1482 /**
1483 * Get the default value for a key
1484 *
1485 * @param property
1486 * property (key type)
1487 * @param dflt
1488 * default value
1489 * @return value for key or dflt if not found
1490 */
1491 protected String getDefault(String property, String dflt) {
1492 if (resourceMaps == null) {
1493 initializeAddeDefaults();
1494 }
1495 property = property.toLowerCase();
1496
1497 String userDefault = null;
1498 String server = getServer();
1499 String group = getGroup();
1500 String descriptor = getDescriptor();
1501 String[] keys = { userDefault, server + ":" + group + "/" + descriptor,
1502 group + "/" + descriptor, server + ":" + group + "/*",
1503 group + "/*", server + ":*/" + descriptor, "*/" + descriptor,
1504 descriptor, server + ":*/*", server, "*" };
1505
1506 if (server != null) {
1507 if (PROP_USER.equals(property))
1508 return getLastAddedUser();
1509 if (PROP_PROJ.equals(property))
1510 return getLastAddedProj();
1511 }
1512
1513 for (int resourceIdx = 0; resourceIdx < resourceMaps.size(); resourceIdx++) {
1514 Hashtable resourceMap = (Hashtable) resourceMaps.get(resourceIdx);
1515 for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
1516 String key = keys[keyIdx];
1517 if (key == null) {
1518 continue;
1519 }
1520 key = key.toLowerCase();
1521 Element defaultNode = (Element)resourceMap.get(key);
1522 if (defaultNode == null) {
1523 continue;
1524 }
1525 String value = XmlUtil.getAttribute(defaultNode, property, (String)null);
1526 if (value == null) {
1527 continue;
1528 }
1529 if (value.equals(VALUE_DEFAULT)) {
1530 return dflt;
1531 } else {
1532 return value;
1533 }
1534 }
1535 }
1536 return dflt;
1537 }
1538
1539 /**
1540 * Get the image size string from the directory and defaults
1541 *
1542 * @param ad
1543 * image directory
1544 * @return request size
1545 */
1546 protected String getSizeString(AreaDirectory ad) {
1547 String retString = MAX_SIZE + " " + MAX_SIZE;
1548 if (ad != null) {
1549 int x = ad.getElements();
1550 int y = ad.getLines();
1551 if ((x < MAX_SIZE) && (y < MAX_SIZE)) {
1552 retString = x + " " + y;
1553 } else if ((x >= MAX_SIZE) && (y >= MAX_SIZE)) {
1554 retString = MAX_SIZE + " " + MAX_SIZE;
1555 } else if ((x >= MAX_SIZE) && (y < MAX_SIZE)) {
1556 retString = MAX_SIZE + " " + y;
1557 } else if ((x < MAX_SIZE) && (y >= MAX_SIZE)) {
1558 retString = x + " " + MAX_SIZE;
1559 }
1560 }
1561 return retString;
1562 }
1563
1564 /**
1565 * Check for valid lat/lon values
1566 *
1567 * @return true if values are valid
1568 */
1569 protected boolean checkForValidValues() {
1570 if (usePropFromUser(PROP_LOC)) {
1571 if (useLatLon()) {
1572 String msg = latLonWidget.isValidValues();
1573 if ((msg != null) && (msg.length() > 0)) {
1574 LogUtil.userMessage(msg);
1575 return false;
1576 }
1577 }
1578 }
1579 return true;
1580 }
1581
1582 /**
1583 * Get the list of properties for the base URL
1584 *
1585 * @return list of properties
1586 */
1587 protected String[] getBaseUrlProps() {
1588 return new String[] { PROP_DESCR, PROP_UNIT, PROP_SPAC, PROP_BAND,
1589 PROP_NAV, PROP_USER, PROP_PROJ, };
1590 }
1591
1592 /**
1593 * A utility that creates the url argument line for the given set of
1594 * properties.
1595 *
1596 * @param props
1597 * The PROP_ properties to make the request string for
1598 * @param ad
1599 * The area directory.
1600 *
1601 * @return The adde request string
1602 */
1603 protected String makeProps(String[] props, AreaDirectory ad) {
1604 StringBuffer buf = new StringBuffer();
1605 for (int propIdx = 0; propIdx < props.length; propIdx++) {
1606 appendKeyValue(buf, props[propIdx],
1607 getPropValue(props[propIdx], ad));
1608 }
1609 return buf.toString();
1610 }
1611
1612 /**
1613 * Get the value for the given property. This can either be the value
1614 * supplied by the end user through the advanced GUI or is the default
1615 *
1616 * @param prop
1617 * The property
1618 * @param ad
1619 * The AreaDirectory
1620 *
1621 * @return The value of the property to use in the request string
1622 */
1623 protected String getPropValue(String prop, AreaDirectory ad) {
1624 if (usePropFromUser(prop)) {
1625 return getUserPropValue(prop, ad);
1626 }
1627
1628 // Handle size specially because we really want to get the minimum of
1629 // the default and the ad size
1630 if (PROP_SIZE.equals(prop)) {
1631 int[] size = getSize(ad);
1632 return size[0] + " " + size[1];
1633 }
1634
1635 return getDefault(prop, getDefaultPropValue(prop, ad, false));
1636 }
1637
1638 /**
1639 * Get the user supplied property value for the adde request string
1640 *
1641 * @param prop
1642 * The property
1643 * @param ad
1644 * The AreaDirectory
1645 *
1646 * @return The value, supplied by the user, of the property to use in the
1647 * request string
1648 */
1649 protected String getUserPropValue(String prop, AreaDirectory ad) {
1650 if (PROP_LATLON.equals(prop) && (latLonWidget != null)) {
1651 // apparently the ADDE server can't handle long numbers
1652 return Format.dfrac(latLonWidget.getLat(), 5) + " "
1653 + Format.dfrac(latLonWidget.getLon(), 5);
1654 }
1655 if (PROP_PLACE.equals(prop) && (placeLbl != null)) {
1656 return place;
1657 }
1658
1659 if (PROP_LINELE.equals(prop) && (centerLineFld != null)) {
1660 return centerLineFld.getText().trim() + " "
1661 + centerElementFld.getText().trim();
1662 }
1663
1664 if (PROP_SIZE.equals(prop) && (numLinesFld != null)) {
1665 return numLinesFld.getText().trim() + " "
1666 + numElementsFld.getText().trim();
1667 }
1668 if (PROP_MAG.equals(prop) && (lineMagSlider != null)) {
1669 return getLineMagValue() + " " + getElementMagValue();
1670 }
1671 if (PROP_BAND.equals(prop) && (bandComboBox != null)) {
1672
1673 Object selected = bandComboBox.getSelectedItem();
1674 if (selected != null) {
1675 if (selected.equals(ALLBANDS)) {
1676 return ALLBANDS.toString();
1677 } else {
1678 return "" + ((BandInfo) selected).getBandNumber();
1679 }
1680 }
1681 }
1682 if (PROP_UNIT.equals(prop)) {
1683 return getSelectedUnit();
1684 }
1685 if (PROP_NAV.equals(prop)) {
1686 return TwoFacedObject.getIdString(navComboBox.getSelectedItem());
1687 }
1688
1689 if (PROP_USER.equals(prop))
1690 return getLastAddedUser();
1691 if (PROP_PROJ.equals(prop))
1692 return getLastAddedProj();
1693
1694 return null;
1695 }
1696
1697 /**
1698 * Get the default property value for the adde request string
1699 *
1700 * @param prop
1701 * The property
1702 * @param ad
1703 * The AreaDirectory
1704 * @param forDisplay
1705 * Is this to display to the user in the gui
1706 *
1707 * @return The default of the property to use in the request string
1708 */
1709 protected String getDefaultPropValue(String prop, AreaDirectory ad,
1710 boolean forDisplay) {
1711 if (PROP_USER.equals(prop)) {
1712 return DEFAULT_USER;
1713 }
1714 if (PROP_USER.equals(prop)) {
1715 return PLACE_CENTER;
1716 }
1717 if (PROP_PROJ.equals(prop)) {
1718 return DEFAULT_PROJ;
1719 }
1720 if (PROP_DESCR.equals(prop)) {
1721 return getDescriptor();
1722 }
1723 if (PROP_VERSION.equals(prop)) {
1724 return DEFAULT_VERSION;
1725 }
1726 if (PROP_COMPRESS.equals(prop)) {
1727 return "gzip";
1728 }
1729 if (PROP_PORT.equals(prop)) {
1730 return DEFAULT_PORT;
1731 }
1732 if (PROP_DEBUG.equals(prop)) {
1733 // return DEFAULT_DEBUG;
1734 Boolean.toString(EntryStore.isAddeDebugEnabled(false));
1735 }
1736 if (PROP_SIZE.equals(prop)) {
1737 if (ad != null) {
1738 return ad.getLines() + " " + ad.getElements();
1739 }
1740 return MAX_SIZE + " " + MAX_SIZE;
1741 }
1742 if (PROP_MAG.equals(prop)) {
1743 return "1 1";
1744 }
1745 // if (prop.equals(PROP_LOC) || prop.equals(PROP_LINELE)) {
1746 if (PROP_MAG.equals(prop)) {
1747 if (ad == null) {
1748 return "0 0";
1749 }
1750 return ad.getLines() / 2 + " " + ad.getElements() / 2;
1751 }
1752 // if (prop.equals(PROP_LATLON)) {
1753 if (PROP_LOC.equals(prop) || PROP_LATLON.equals(prop)) {
1754 if (ad == null) {
1755 return "0 0";
1756 }
1757 return ad.getCenterLatitude() + " " + ad.getCenterLongitude();
1758 }
1759 if (PROP_BAND.equals(prop)) {
1760 if (bandTable==null) return "";
1761 if (forDisplay) {
1762 return getBandName(ad, ((int[]) bandTable.get(ad))[0]);
1763 }
1764 return "" + ((int[]) bandTable.get(ad))[0];
1765 }
1766 if (PROP_SPAC.equals(prop)) {
1767 return getSelectedUnit().equalsIgnoreCase("BRIT") ? "1" : "4";
1768 }
1769 if (PROP_UNIT.equals(prop)) {
1770 return "X";
1771 }
1772 if (PROP_NAV.equals(prop)) {
1773 return "X";
1774 }
1775 return "";
1776 }
1777
1778 /**
1779 * Set the properties on the AddeImageInfo from the list of properties
1780 *
1781 * @param aii
1782 * The AddeImageInfo
1783 * @param props
1784 * list of props to set
1785 * @param ad
1786 * The AreaDirectory
1787 */
1788 protected void setImageInfoProps(AddeImageInfo aii, String[] props, AreaDirectory ad) {
1789 for (int i = 0; i < props.length; i++) {
1790 String prop = props[i];
1791 String value = getPropValue(prop, ad);
1792 if (prop.equals(PROP_USER)) {
1793 aii.setUser(value);
1794 } else if (prop.equals(PROP_PROJ)) {
1795 aii.setProject(Integer.parseInt(value));
1796 } else if (prop.equals(PROP_DESCR)) {
1797 aii.setDescriptor(value);
1798 } else if (prop.equals(PROP_VERSION)) {
1799 aii.setVersion(value);
1800 } else if (prop.equals(PROP_COMPRESS)) {
1801 int compVal = AddeURL.GZIP;
1802 if (value.equals("none") || value.equals("1")) {
1803 compVal = AddeURL.NO_COMPRESS;
1804 } else if (value.equals("compress") || value.equals("2") || value.equals("true")) {
1805 compVal = AddeURL.COMPRESS;
1806 }
1807 aii.setCompression(compVal);
1808 } else if (prop.equals(PROP_PORT)) {
1809 aii.setPort(Integer.parseInt(value));
1810 } else if (prop.equals(PROP_DEBUG)) {
1811 // aii.setDebug(Boolean.getBoolean(value));
1812 aii.setDebug(EntryStore.isAddeDebugEnabled(false));
1813 } else if (prop.equals(PROP_SPAC)) {
1814 aii.setSpacing(Integer.parseInt(value));
1815 } else if (prop.equals(PROP_UNIT)) {
1816 if (value.equals(ALLUNITS.getId())) {
1817 value = getDefault(prop, getDefaultPropValue(prop, ad, false));
1818 }
1819 aii.setUnit(value);
1820 } else if (prop.equals(PROP_BAND)) {
1821 if (value.equals(ALLBANDS.toString())) {
1822 value = getDefault(prop, getDefaultPropValue(prop, ad, false));
1823 }
1824 aii.setBand(value);
1825 } else if (prop.equals(PROP_NAV)) {
1826 aii.setNavType(value);
1827 } else if (prop.equals(PROP_ID)) {
1828 aii.setId(value);
1829 }
1830 }
1831 }
1832
1833 /**
1834 * Get the name of the selected band
1835 *
1836 * @return the name of the band
1837 */
1838 public String getSelectedBandName() {
1839 return getBandName(propertiesAD, getSelectedBand());
1840 }
1841
1842 /**
1843 * Clear the properties widgets
1844 */
1845 protected void clearPropertiesWidgets() {
1846 if (latLonWidget != null) {
1847 latLonWidget.getLatField().setText("");
1848 latLonWidget.getLonField().setText("");
1849 }
1850 if (centerLineFld != null) {
1851 centerLineFld.setText("");
1852 centerElementFld.setText("");
1853 }
1854 if (numLinesFld != null) {
1855 if (sizeLbl != null) {
1856 sizeLbl.setText("");
1857 }
1858 numLinesFld.setText("");
1859 numElementsFld.setText("");
1860 }
1861 if (unitComboBox != null) {
1862 GuiUtils.setListData(unitComboBox, new Vector());
1863 }
1864 if (bandComboBox != null) {
1865 GuiUtils.setListData(bandComboBox, new Vector());
1866 }
1867
1868 setMagSliders(DEFAULT_MAG, DEFAULT_MAG);
1869
1870 if (placeLbl != null) {
1871 changePlace(PLACE_CENTER);
1872 }
1873
1874 if (navComboBox != null) {
1875 checkSetNav();
1876 // navComboBox.setSelectedIndex(0);
1877 }
1878 baseNumLines = 0.0;
1879 baseNumElements = 0.0;
1880 }
1881
1882 /**
1883 * Set the widgets with the state from the given AreaDirectory
1884 *
1885 * @param ad
1886 * AreaDirectory for the image
1887 */
1888 protected void setPropertiesState(AreaDirectory ad) {
1889 setPropertiesState(ad, false);
1890 }
1891
1892 /**
1893 * _more_
1894 *
1895 * @param ad
1896 * _more_
1897 *
1898 * @return _more_
1899 */
1900 protected int[] getSize(AreaDirectory ad) {
1901 baseNumLines = ad.getLines();
1902 baseNumElements = ad.getElements();
1903
1904 String sizeDefault = getDefault(PROP_SIZE, (String) null);
1905 List toks = ((sizeDefault != null) ? StringUtil.split(sizeDefault, " ",
1906 true, true) : null);
1907 if ((toks == null) || (toks.size() == 0)) {
1908 return new int[] { (int) baseNumLines, (int) baseNumElements };
1909 } else {
1910 String lines = "" + toks.get(0);
1911 if (lines.equalsIgnoreCase(ALL)) {
1912 lines = "" + (int) baseNumLines;
1913 }
1914 int numLines = new Integer(lines.trim()).intValue();
1915
1916 String elems = (toks.size() > 1) ? "" + toks.get(1) : ""
1917 + (int) baseNumElements;
1918 if (elems.equalsIgnoreCase(ALL)) {
1919 elems = "" + baseNumElements;
1920 }
1921 int numElements = new Integer(elems.trim()).intValue();
1922 return new int[] { (int) Math.min(numLines, baseNumLines),
1923 (int) Math.min(numElements, baseNumElements) };
1924 }
1925
1926 }
1927
1928 /**
1929 * Set the widgets with the state from the given AreaDirectory
1930 *
1931 * @param ad
1932 * AreaDirectory for the image
1933 * @param force
1934 * force an update regardless of the previous invocation
1935 */
1936 protected void setPropertiesState(AreaDirectory ad, boolean force) {
1937 if (amSettingProperties)
1938 return;
1939
1940 prevPropertiesAD = propertiesAD;
1941 propertiesAD = ad;
1942 if (!force && checkPropertiesEqual(prevPropertiesAD, propertiesAD))
1943 return;
1944
1945 amSettingProperties = true;
1946
1947 if (ad == null) {
1948 clearPropertiesWidgets();
1949 amSettingProperties = false;
1950 return;
1951 }
1952
1953 String[] propArray = getAdvancedProps();
1954
1955 if (numLinesFld != null) {
1956 int[] size = getSize(ad);
1957 numLinesFld.setText("" + size[0]);
1958 numElementsFld.setText("" + size[1]);
1959 if (sizeLbl != null) {
1960 String label = " Raw size: " + ad.getLines() + " X "
1961 + ad.getElements();
1962 sizeLbl.setText(label);
1963 }
1964 }
1965 if (latLonWidget != null) {
1966 latLonWidget.getLatField().setText("" + ad.getCenterLatitude());
1967 latLonWidget.getLonField().setText("" + ad.getCenterLongitude());
1968 }
1969 if (centerLineFld != null) {
1970 centerLineFld.setText("" + ad.getLines() / 2);
1971 centerElementFld.setText("" + ad.getElements() / 2);
1972 }
1973
1974 List<BandInfo> bandList = null;
1975 int[] bands = (int[]) bandTable.get(ad);
1976 if (bands != null)
1977 bandList = makeBandInfos(ad, bands);
1978 bandInfos = bandList;
1979
1980 if (bandComboBox != null) {
1981 List comboList = bandList;
1982 if (bandList.size() > 1) {
1983 comboList = new ArrayList();
1984 comboList.addAll(bandList);
1985 comboList.add(ALLBANDS);
1986 }
1987 GuiUtils.setListData(bandComboBox, comboList);
1988 }
1989
1990 setAvailableUnits(ad, getSelectedBand());
1991
1992 for (int propIdx = 0; propIdx < propArray.length; propIdx++) {
1993 String prop = propArray[propIdx];
1994 String value = getDefault(prop, getDefaultPropValue(prop, ad, false));
1995 if (value == null)
1996 value = "";
1997
1998 value = value.trim();
1999 if (prop.equals(PROP_LOC)) {
2000 String key = getDefault(PROP_KEY, PROP_LATLON);
2001
2002 boolean usingLineElement = key.equals(PROP_LINELE);
2003 if (usingLineElement) {
2004 locationPanel.show(1);
2005 } else {
2006 locationPanel.show(0);
2007 }
2008 if (usingLineElement) {
2009 value = getDefault(PROP_LOC, getDefaultPropValue(
2010 PROP_LINELE, ad, false));
2011 } else {
2012 value = getDefault(PROP_LOC, getDefaultPropValue(
2013 PROP_LATLON, ad, false));
2014 }
2015 String[] pair = getPair(value);
2016 if (pair != null) {
2017 if (usingLineElement) {
2018 centerLineFld.setText(pair[0]);
2019 centerElementFld.setText(pair[1]);
2020 } else {
2021 latLonWidget.setLat(pair[0]);
2022 latLonWidget.setLon(pair[1]);
2023 }
2024 }
2025 } else if (prop.equals(PROP_BAND)) {
2026 if (value.equalsIgnoreCase((String) ALLBANDS.getId())) {
2027 bandComboBox.setSelectedItem(ALLBANDS);
2028 } else {
2029 int bandNum = 0;
2030 try {
2031 bandNum = Integer.parseInt(value);
2032 } catch (NumberFormatException nfe) {
2033 }
2034 int index = BandInfo.findIndexByNumber(bandNum, bandList);
2035 if (index != -1) {
2036 bandComboBox.setSelectedIndex(index);
2037 }
2038 }
2039 } else if (prop.equals(PROP_PLACE)) {
2040 changePlace(value);
2041 } else if (prop.equals(PROP_MAG)) {
2042 String[] pair = getPair(value);
2043 if (pair != null) {
2044 setMagSliders(new Integer(pair[0]).intValue(), new Integer(
2045 pair[1]).intValue());
2046 } else {
2047 setMagSliders(DEFAULT_MAG, DEFAULT_MAG);
2048 }
2049 } else if (prop.equals(PROP_NAV)) {
2050 if (navComboBox != null) {
2051 navComboBox.setSelectedIndex((value
2052 .equalsIgnoreCase("LALO") ? 1 : 0));
2053 }
2054 checkSetNav();
2055 }
2056 }
2057 amSettingProperties = false;
2058
2059 }
2060
2061 /**
2062 * Set the mag slider values
2063 *
2064 * @param lineValue
2065 * the line value
2066 * @param elementValue
2067 * the element value
2068 */
2069 protected void setMagSliders(int lineValue, int elementValue) {
2070 if (lineMagSlider != null) {
2071 if (lineValue > 0) {
2072 lineValue--;
2073 } else if (lineValue < 0) {
2074 lineValue++;
2075 }
2076 if (elementValue > 0) {
2077 elementValue--;
2078 } else if (elementValue < 0) {
2079 elementValue++;
2080 }
2081
2082 lineMagSlider.setValue(lineValue);
2083 elementMagSlider.setValue(elementValue);
2084 lineMagLbl.setText(StringUtil.padLeft("" + getLineMagValue(), 4));
2085 elementMagLbl.setText(StringUtil.padLeft("" + getElementMagValue(),
2086 4));
2087 linesToElements = Math.abs(lineValue / (double) elementValue);
2088 if (Double.isNaN(linesToElements)) {
2089 linesToElements = 1.0;
2090 }
2091 }
2092 }
2093
2094 /**
2095 * Get the value of the given magnification slider.
2096 *
2097 * @param slider
2098 * The slider to get the value from
2099 * @return The magnification value
2100 */
2101 protected int getMagValue(JSlider slider) {
2102 // Value is [-SLIDER_MAX,SLIDER_MAX]. We change 0 and -1 to 1
2103 int value = slider.getValue();
2104 if (value >= 0) {
2105 return value + 1;
2106 }
2107 return value - 1;
2108 }
2109
2110 /**
2111 * Get a pair of properties
2112 *
2113 * @param v
2114 * a space separated string
2115 *
2116 * @return an array of the two strings
2117 */
2118 protected String[] getPair(String v) {
2119 if (v == null) {
2120 return null;
2121 }
2122 v = v.trim();
2123 List toks = StringUtil.split(v, " ", true, true);
2124 if ((toks == null) || (toks.size() == 0)) {
2125 return null;
2126 }
2127 String tok1 = toks.get(0).toString();
2128 return new String[] { tok1,
2129 ((toks.size() > 1) ? toks.get(1).toString() : tok1) };
2130
2131 }
2132
2133 /**
2134 * Get the selected band from the advanced chooser
2135 *
2136 * @return selected band number
2137 */
2138 protected int getSelectedBand() {
2139
2140 Object bi = (bandComboBox == null) ? null : bandComboBox
2141 .getSelectedItem();
2142 if ((bi == null) || bi.equals(ALLBANDS)) {
2143 return 0;
2144 }
2145 return ((BandInfo) bi).getBandNumber();
2146 }
2147
2148 /**
2149 * Translate a place name into a human readable form
2150 *
2151 * @param place
2152 * raw name
2153 *
2154 * @return human readable name
2155 */
2156 protected String translatePlace(String place) {
2157 place = place.toUpperCase();
2158 if (place.equals(PLACE_ULEFT)) {
2159 return "Upper left";
2160 }
2161 if (place.equals(PLACE_LLEFT)) {
2162 return "Lower left";
2163 }
2164 if (place.equals(PLACE_URIGHT)) {
2165 return "Upper right";
2166 }
2167 if (place.equals(PLACE_LRIGHT)) {
2168 return "Lower right";
2169 }
2170 if (place.equals(PLACE_CENTER)) {
2171 return "Center";
2172 }
2173 return place;
2174 }
2175
2176 /**
2177 * Get the band name for a particular area
2178 *
2179 * @param ad
2180 * AreaDirectory
2181 * @param band
2182 * band number
2183 *
2184 * @return name of the band
2185 */
2186 protected String getBandName(AreaDirectory ad, int band) {
2187 // if (band== 0) return ALLBANDS.toString();
2188
2189 if (useSatBandInfo) {
2190 if (satBandInfo == null) {
2191 return "Band: " + band;
2192 }
2193 String[] descrs = satBandInfo.getBandDescr(ad.getSensorID(), ad
2194 .getSourceType());
2195 if (descrs != null) {
2196 if ((band >= 0) && (band < descrs.length)) {
2197 return descrs[band];
2198 }
2199 }
2200 return "Band: " + band;
2201 }
2202
2203 if (sensorToBandToName == null) {
2204 return "Band: " + band;
2205 }
2206 Hashtable bandToName = (Hashtable) sensorToBandToName.get(new Integer(
2207 ad.getSensorID()));
2208 String name = null;
2209 Integer bandInteger = new Integer(band);
2210
2211 if (bandToName != null) {
2212 name = (String) bandToName.get(bandInteger);
2213 }
2214 if (name == null) {
2215 name = "Band: " + band;
2216 }
2217 /*
2218 * else { name = band + " - " + name.trim(); }
2219 */
2220 return name;
2221 }
2222
2223 /**
2224 * Set the available units in the unit selector
2225 *
2226 * @param ad
2227 * AreaDirectory for the image
2228 * @param band
2229 * band to use for units
2230 */
2231 protected void setAvailableUnits(AreaDirectory ad, int band) {
2232 List l = getAvailableUnits(ad, band);
2233 l.add(ALLUNITS);
2234 GuiUtils.setListData(unitComboBox, l);
2235 TwoFacedObject tfo = null;
2236 if ((bandComboBox != null) && (getSelectedBand() == 0)) {
2237 tfo = ALLUNITS;
2238 } else {
2239 String preferredUnit = getDefault(PROP_UNIT, "BRIT");
2240 tfo = TwoFacedObject.findId(preferredUnit, l);
2241 }
2242 if (tfo != null) {
2243 unitComboBox.setSelectedItem(tfo);
2244 }
2245 }
2246
2247 /**
2248 * Set the available units in the unit selector
2249 *
2250 * @param ad
2251 * AreaDirectory for the image
2252 * @param band
2253 * band to use for units
2254 *
2255 * @return List of available units
2256 */
2257 protected List<TwoFacedObject> getAvailableUnits(AreaDirectory ad, int band) {
2258 // get Vector array of Calibration types. Layout is
2259 // v[i] = band[i] and for each band, it is a vector of
2260 // strings of calibration names and descriptions
2261 // n = name, n+1 = desc.
2262 // for radar, we only have one band
2263 if (ad == null) {
2264 return new ArrayList<TwoFacedObject>();
2265 }
2266 int[] bands = (int[]) bandTable.get(ad);
2267 int index = (bands == null) ? 0 : Arrays.binarySearch(bands, band);
2268 if (index < 0) index = 0;
2269 Vector<TwoFacedObject> l = new Vector<TwoFacedObject>();
2270 Vector v = ad.getCalInfo()[index];
2271 TwoFacedObject tfo = null;
2272 int preferredUnitIndex = 0;
2273 String preferredUnit = getDefault(PROP_UNIT, "BRIT");
2274 if ((v != null) && (v.size() / 2 > 0)) {
2275 for (int i = 0; i < v.size() / 2; i++) {
2276 String name = (String) v.get(2 * i);
2277 String desc = (String) v.get(2 * i + 1);
2278 desc = StringUtil.camelCase(desc);
2279 tfo = new TwoFacedObject(desc, name);
2280 l.add(tfo);
2281 if (name.equalsIgnoreCase(preferredUnit)) {
2282 preferredUnitIndex = i;
2283 }
2284 }
2285 } else {
2286 l.add(new TwoFacedObject("Raw Value", "RAW"));
2287 }
2288 return l;
2289 }
2290
2291 /**
2292 * Get the band name information from the server
2293 */
2294 protected void readSatBands() {
2295 satBandInfo = null;
2296 sensorToBandToName = null;
2297 List lines = null;
2298 try {
2299 StringBuffer buff = getUrl(REQ_TEXT);
2300 appendKeyValue(buff, PROP_FILE, FILE_SATBAND);
2301 lines = readTextLines(buff.toString());
2302 if (lines == null) {
2303 return;
2304 }
2305 if (useSatBandInfo) {
2306 satBandInfo = new AddeSatBands(StringUtil.listToStringArray(lines));
2307 return;
2308 }
2309 } catch (Exception e) {
2310 return;
2311 }
2312
2313 if (lines == null) {
2314 return;
2315 }
2316
2317 sensorToBandToName = new Hashtable();
2318
2319 for (int i = 0; i < lines.size(); i++) {
2320 if (!lines.get(i).toString().startsWith("Sat")) {
2321 continue;
2322 }
2323 List satIds = StringUtil.split(lines.get(i).toString(), " ", true,
2324 true);
2325 satIds.remove(0);
2326 Hashtable bandToName = new Hashtable();
2327 for (int j = i + 1; j < lines.size(); j++, i++) {
2328 String line = lines.get(i).toString();
2329 line = line.trim();
2330 if (line.startsWith("EndSat")) {
2331 break;
2332 }
2333
2334 int idx = line.indexOf(" ");
2335 if (idx < 0) {
2336 continue;
2337 }
2338 String bandTok = line.substring(0, idx);
2339 try {
2340 bandToName.put(Integer.decode(bandTok.trim()), line
2341 .substring(idx).trim());
2342 } catch (NumberFormatException nfe) {
2343 }
2344 }
2345 for (int j = 0; j < satIds.size(); j++) {
2346 Integer sensorId = new Integer(satIds.get(j).toString());
2347 sensorToBandToName.put(sensorId, bandToName);
2348 }
2349 }
2350 }
2351
2352 /**
2353 * Make an AddeImageInfo from a URL and an AreaDirectory
2354 *
2355 * @param dir
2356 * AreaDirectory
2357 * @param isRelative
2358 * true if is relative
2359 * @param num
2360 * number (for relative images)
2361 *
2362 * @return corresponding AddeImageInfo
2363 */
2364 protected AddeImageInfo makeImageInfo(AreaDirectory dir,
2365 boolean isRelative, int num) {
2366 AddeImageInfo info = new AddeImageInfo(getAddeServer().getName(),
2367 AddeImageInfo.REQ_IMAGEDATA, getGroup(), getDescriptor());
2368 if (isRelative) {
2369 info.setDatasetPosition((num == 0) ? 0 : -num);
2370 } else {
2371 info.setStartDate(dir.getNominalTime());
2372 }
2373 setImageInfoProps(info, getMiscKeyProps(), dir);
2374 setImageInfoProps(info, getBaseUrlProps(), dir);
2375
2376 String locKey = getDefault(PROP_KEY, PROP_LINELE);
2377 String locValue = null;
2378 if (usePropFromUser(PROP_LOC)) {
2379 if (useLatLon()) {
2380 locKey = PROP_LATLON;
2381 locValue = getUserPropValue(PROP_LATLON, dir);
2382 } else {
2383 locKey = PROP_LINELE;
2384 locValue = getUserPropValue(PROP_LINELE, dir);
2385 }
2386 } else {
2387 locValue = getPropValue(PROP_LOC, dir);
2388 }
2389 info.setLocateKey(locKey);
2390 info.setLocateValue(locValue);
2391
2392 String placeKey = getPropValue(PROP_PLACE, dir);
2393 info.setPlaceValue(placeKey);
2394
2395 String magKey = getPropValue(PROP_MAG, dir);
2396 int lmag = 1;
2397 int emag = 1;
2398 StringTokenizer tok = new StringTokenizer(magKey);
2399 lmag = (int) Misc.parseNumber((String) tok.nextElement());
2400 if (tok.hasMoreTokens()) {
2401 emag = (int) Misc.parseNumber((String) tok.nextElement());
2402 } else {
2403 emag = lmag;
2404 }
2405 info.setLineMag(lmag);
2406 info.setElementMag(emag);
2407
2408 int lines = dir.getLines();
2409 int elems = dir.getElements();
2410 String sizeKey = getPropValue(PROP_SIZE, dir);
2411 tok = new StringTokenizer(sizeKey);
2412 String size = (String) tok.nextElement();
2413 if (!size.equalsIgnoreCase("all")) {
2414 lines = (int) Misc.parseNumber(size);
2415 if (tok.hasMoreTokens()) {
2416 elems = (int) Misc.parseNumber((String) tok.nextElement());
2417 } else {
2418 elems = lines;
2419 }
2420 }
2421 info.setLines(lines);
2422 info.setElements(elems);
2423 /*
2424 * System.out.println("url = " + info.getURLString().toLowerCase() +
2425 * "\n");
2426 */
2427 return info;
2428 }
2429
2430 /**
2431 * Check to see if the two Area directories are equal
2432 *
2433 * @param ad1
2434 * first AD (may be null)
2435 * @param ad2
2436 * second AD (may be null)
2437 *
2438 * @return true if they are equal
2439 */
2440 protected boolean checkPropertiesEqual(AreaDirectory ad1, AreaDirectory ad2) {
2441 if (ad1 == null) {
2442 return false;
2443 }
2444 if (ad2 == null) {
2445 return false;
2446 }
2447 return Misc.equals(ad1, ad2)
2448 || ((ad1.getLines() == ad2.getLines())
2449 && (ad1.getElements() == ad2.getElements()) && Arrays
2450 .equals(ad1.getBands(), ad2.getBands()));
2451 }
2452
2453 /**
2454 * Get a description of the properties
2455 *
2456 * @return a description
2457 */
2458 protected String getPropertiesDescription() {
2459 StringBuffer buf = new StringBuffer();
2460 String[] propArray = getAdvancedProps();
2461 List list = Misc.toList(propArray);
2462 if (list.contains(PROP_BAND)) {
2463 buf.append(getSelectedBandName());
2464 buf.append(", ");
2465 }
2466 if (list.contains(PROP_SIZE)) {
2467 buf.append("Size: ");
2468 String sizeKey = getUserPropValue(PROP_SIZE, propertiesAD);
2469 StringTokenizer tok = new StringTokenizer(sizeKey);
2470 if (tok.hasMoreTokens()) {
2471 String size = ((String) tok.nextElement()).trim();
2472 buf.append(size);
2473 buf.append("x");
2474 if (!size.equalsIgnoreCase("all")) {
2475 if (tok.hasMoreTokens()) {
2476 buf.append(((String) tok.nextElement()).trim());
2477 } else {
2478 buf.append(size);
2479 }
2480 }
2481 }
2482 }
2483 return buf.toString();
2484 }
2485
2486 /**
2487 * Show the given error to the user. If it was an Adde exception that was a
2488 * bad server error then print out a nice message.
2489 *
2490 * @param excp
2491 * The exception
2492 */
2493 protected void handleConnectionError(Exception e) {
2494 if (e != null && e.getMessage() != null) {
2495 String msg = e.getMessage().toLowerCase();
2496 if ((e instanceof AreaFileException)
2497 && (msg.indexOf("must be used with archived datasets") >= 0)) {
2498 getArchiveDay();
2499 return;
2500 }
2501 }
2502 super.handleConnectionError(e);
2503 }
2504
2505 /**
2506 * Get the list of bands for the images
2507 *
2508 * @param ad
2509 * AreaDirectory
2510 * @param bands
2511 * list of bands
2512 * @return list of BandInfos for the selected images
2513 */
2514 protected List<BandInfo> makeBandInfos(AreaDirectory ad, int[] bands) {
2515 // readSatBands();
2516 List<BandInfo> l = new ArrayList<BandInfo>();
2517 if (ad != null) {
2518 if (bands != null) {
2519 for (int i = 0; i < bands.length; i++) {
2520 int band = bands[i];
2521 if (band > 0) {
2522 BandInfo bi = new BandInfo(ad.getSensorID(), band);
2523 bi.setBandDescription(getBandName(ad, band));
2524 bi.setCalibrationUnits(getAvailableUnits(ad, band));
2525 bi.setPreferredUnit(getDefault(PROP_UNIT, "BRIT"));
2526 l.add(bi);
2527 }
2528 }
2529 }
2530 }
2531 return l;
2532 }
2533
2534 /**
2535 * Get the pregenerated bandInfos
2536 */
2537 protected List<BandInfo> getBandInfos() {
2538 return bandInfos;
2539 }
2540
2541 /**
2542 * Get the list of BandInfos for the current selected images
2543 *
2544 * @return list of BandInfos
2545 */
2546 public List<BandInfo> getSelectedBandInfos() {
2547 // update the BandInfo list based on what has been chosen
2548 List selectedBandInfos = new ArrayList<BandInfo>();
2549 List selectedUnits = null;
2550 if (unitComboBox != null) {
2551 TwoFacedObject tfo = (TwoFacedObject) unitComboBox.getSelectedItem();
2552 if (!(tfo.equals(ALLUNITS))) { // specific unit requested
2553 selectedUnits = new ArrayList<TwoFacedObject>();
2554 selectedUnits.add(tfo);
2555 }
2556 }
2557 if (getSelectedBand() == 0) { // All bands selected
2558 if (selectedUnits != null) {
2559 for (Iterator iter = bandInfos.iterator(); iter.hasNext();) {
2560 BandInfo newBI = new BandInfo((BandInfo) iter.next());
2561 newBI.setCalibrationUnits(selectedUnits);
2562 newBI.setPreferredUnit((String) ((TwoFacedObject) selectedUnits.get(0)).getId());
2563 selectedBandInfos.add(newBI);
2564 }
2565 } else { // else All Bands, AllUnits
2566 selectedBandInfos = bandInfos;
2567 }
2568 } else { // not All selected;
2569 int index = BandInfo.findIndexByNumber(getSelectedBand(), bandInfos);
2570 BandInfo selectedBandInfo = null;
2571 if (index != -1) {
2572 selectedBandInfo = bandInfos.get(index);
2573 }
2574 if (selectedBandInfo != null) {
2575 if (selectedUnits != null) {
2576 BandInfo newBI = new BandInfo(selectedBandInfo);
2577 newBI.setCalibrationUnits(selectedUnits);
2578 newBI.setPreferredUnit((String) ((TwoFacedObject) selectedUnits.get(0)).getId());
2579 selectedBandInfos.add(newBI);
2580 } else {
2581 selectedBandInfos.add(selectedBandInfo);
2582 }
2583 }
2584 }
2585 return selectedBandInfos;
2586 }
2587
2588 /**
2589 * Get the id for the default display type
2590 *
2591 * @return the display id
2592 */
2593 protected String getDefaultDisplayType() {
2594 return "imagedisplay";
2595 }
2596
2597 /**
2598 * User said go, we go. Simply get the list of images from the imageChooser
2599 * and create the ADDE.IMAGE DataSource
2600 *
2601 */
2602 public void doLoadInThread() {
2603 if (!checkForValidValues()) {
2604 return;
2605 }
2606 if (!getGoodToGo()) {
2607 updateStatus();
2608 return;
2609 }
2610
2611 List imageList = getImageList();
2612 if ((imageList == null) || (imageList.size() == 0)) {
2613 return;
2614 }
2615
2616 // Check for size threshold
2617 final int[] dim = { 0, 0 };
2618 AddeImageDescriptor aid = (AddeImageDescriptor) imageList.get(0);
2619 dim[0] = aid.getImageInfo().getElements();
2620 dim[1] = aid.getImageInfo().getLines();
2621 // System.err.println("dim:" + dim[0] + " x " + dim[1] + " # images:"
2622 // + imageList.size());
2623 int numPixels = dim[0] * dim[1] * imageList.size();
2624 double megs = (4 * numPixels) / (double) 1000000;
2625
2626 //DAVEP: take this out--it should be warning in the data source, not the chooser
2627 boolean doSizeCheck = false;
2628 if (megs > SIZE_THRESHOLD && doSizeCheck) {
2629 final JCheckBox maintainSize = new JCheckBox(
2630 "Maintain spatial extent", false);
2631 final JLabel sizeLbl = new JLabel(StringUtil.padRight(" "
2632 + ((double) ((int) megs * 100)) / 100.0 + " MB", 14));
2633 GuiUtils.setFixedWidthFont(sizeLbl);
2634 final List[] listHolder = { imageList };
2635 final JSlider slider = new JSlider(2, (int) megs, (int) megs);
2636 slider.setMajorTickSpacing((int) (megs - 2) / 10);
2637 slider.setMinorTickSpacing((int) (megs - 2) / 10);
2638 // slider.setPaintTicks(true);
2639 slider.setSnapToTicks(true);
2640 final long timeNow = System.currentTimeMillis();
2641 ChangeListener sizeListener = new javax.swing.event.ChangeListener() {
2642 public void stateChanged(ChangeEvent evt) {
2643 // A hack so we don't respond to the first event that we get
2644 // from the slider when
2645 // the dialog is first shown
2646 if (System.currentTimeMillis() - timeNow < 500)
2647 return;
2648 JSlider slider = (JSlider) evt.getSource();
2649 int pixelsPerImage = 1000000 * slider.getValue()
2650 / listHolder[0].size() / 4;
2651 double aspect = dim[1] / (double) dim[0];
2652 int nx = (int) Math.sqrt(pixelsPerImage / aspect);
2653 int ny = (int) (aspect * nx);
2654 if (maintainSize.isSelected()) {
2655 // doesn't work
2656 lineMagSlider.setValue(getLineMagValue() - 1);
2657 lineMagSliderChanged(true);
2658 } else {
2659 numElementsFld.setText("" + nx);
2660 numLinesFld.setText("" + ny);
2661 }
2662 listHolder[0] = getImageList();
2663 AddeImageDescriptor aid = (AddeImageDescriptor) listHolder[0]
2664 .get(0);
2665 dim[0] = aid.getImageInfo().getElements();
2666 dim[1] = aid.getImageInfo().getLines();
2667 int numPixels = dim[0] * dim[1] * listHolder[0].size();
2668 double nmegs = (4 * numPixels) / (double) 1000000;
2669 sizeLbl.setText(StringUtil.padRight(" "
2670 + ((double) ((int) nmegs * 100)) / 100.0 + " MB",
2671 14));
2672 }
2673 };
2674 slider.addChangeListener(sizeListener);
2675
2676 JComponent msgContents = GuiUtils
2677 .vbox(
2678 new JLabel(
2679 "<html>You are about to load "
2680 + megs
2681 + " MB of imagery.<br>Are you sure you want to do this?<p><hr><p></html>"),
2682 GuiUtils.inset(GuiUtils.leftCenterRight(new JLabel(
2683 "Change Size: "),
2684 GuiUtils.inset(slider, 5), sizeLbl), 5));
2685
2686 if (!GuiUtils.askOkCancel("Image Size", msgContents)) {
2687 return;
2688 }
2689 imageList = listHolder[0];
2690 }
2691
2692 ImageDataset ids = new ImageDataset(getDatasetName(), imageList);
2693 // make properties Hashtable to hand the station name
2694 // to the AddeImageDataSource
2695 Hashtable ht = new Hashtable();
2696 getDataSourceProperties(ht);
2697 Object bandName = getSelectedBandName();
2698 if (bandName != null && !(bandName.equals(ALLBANDS.toString()))) {
2699 ht.put(DATA_NAME_KEY, bandName);
2700 }
2701
2702 makeDataSource(ids, getDataSourceId(), ht);
2703 saveServerState();
2704 }
2705
2706 /**
2707 * Return the data source ID. Used by extending classes.
2708 */
2709 protected String getDataSourceId() {
2710 return "ADDE.IMAGE";
2711 }
2712
2713 /**
2714 * Get the DataSource properties
2715 *
2716 * @param ht
2717 * Hashtable of properties
2718 */
2719 protected void getDataSourceProperties(Hashtable ht) {
2720 super.getDataSourceProperties(ht);
2721 ht.put(DATASET_NAME_KEY, getDatasetName());
2722 ht.put(ImageDataSource.PROP_BANDINFO, getSelectedBandInfos());
2723 }
2724
2725 /**
2726 * _more_
2727 *
2728 * @return _more_
2729 */
2730 protected List processPropertyComponents() {
2731 List bottomComps = new ArrayList();
2732 getBottomComponents(bottomComps);
2733 for (int i = 0; i < bottomComps.size(); i++) {
2734 addDescComp((JComponent) bottomComps.get(i));
2735 }
2736 return bottomComps;
2737 }
2738
2739 /**
2740 * Make the UI for this selector.
2741 *
2742 * @return The gui
2743 */
2744 public JComponent doMakeContents() {
2745 JPanel myPanel = new JPanel();
2746
2747 JLabel timesLabel = McVGuiUtils.makeLabelRight("Times:");
2748 addDescComp(timesLabel);
2749
2750 JPanel timesPanel = makeTimesPanel();
2751 timesPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
2752 addDescComp(timesPanel);
2753
2754 JLabel imageLabel = McVGuiUtils.makeLabelRight("Other:");
2755 addDescComp(imageLabel);
2756
2757 List comps = new ArrayList();
2758 comps.addAll(processPropertyComponents());
2759 GuiUtils.tmpInsets = GRID_INSETS;
2760 JPanel imagePanel = GuiUtils.doLayout(comps, 2, GuiUtils.WT_NY, GuiUtils.WT_N);
2761 imagePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
2762
2763 GroupLayout layout = new GroupLayout(myPanel);
2764 myPanel.setLayout(layout);
2765 layout.setHorizontalGroup(layout.createParallelGroup(LEADING)
2766 .addGroup(layout.createSequentialGroup()
2767 .addGroup(layout.createParallelGroup(LEADING)
2768 .addGroup(layout.createSequentialGroup()
2769 .addComponent(descriptorLabel)
2770 .addGap(GAP_RELATED)
2771 .addComponent(descriptorComboBox))
2772 .addGroup(layout.createSequentialGroup()
2773 .addComponent(timesLabel)
2774 .addGap(GAP_RELATED)
2775 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))
2776 .addGroup(layout.createSequentialGroup()
2777 .addComponent(imageLabel)
2778 .addGap(GAP_RELATED)
2779 .addComponent(imagePanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)))));
2780
2781 layout.setVerticalGroup(layout.createParallelGroup(LEADING)
2782 .addGroup(layout.createSequentialGroup()
2783 .addGroup(layout.createParallelGroup(BASELINE)
2784 .addComponent(descriptorLabel)
2785 .addComponent(descriptorComboBox))
2786 .addPreferredGap(RELATED)
2787 .addGroup(layout.createParallelGroup(LEADING)
2788 .addComponent(timesLabel)
2789 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))
2790 .addPreferredGap(RELATED)
2791 .addGroup(layout.createParallelGroup(LEADING)
2792 .addComponent(imageLabel)
2793 .addComponent(imagePanel))));
2794
2795 setInnerPanel(myPanel);
2796 return super.doMakeContents();
2797 }
2798
2799 public JComponent doMakeContents(boolean doesOverride) {
2800 if (doesOverride)
2801 return super.doMakeContents();
2802 else
2803 return doMakeContents();
2804 }
2805
2806 }