001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
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 https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.data;
030
031import java.awt.Component;
032import java.awt.Dimension;
033import java.awt.Insets;
034import java.awt.event.ActionEvent;
035import java.awt.event.ActionListener;
036import java.awt.event.FocusEvent;
037import java.awt.event.FocusListener;
038import java.awt.geom.Rectangle2D;
039import java.rmi.RemoteException;
040import java.util.ArrayList;
041import java.util.Hashtable;
042import java.util.List;
043
044import javax.swing.JButton;
045import javax.swing.JComboBox;
046import javax.swing.JComponent;
047import javax.swing.JLabel;
048import javax.swing.JMenuItem;
049import javax.swing.JPanel;
050import javax.swing.JSlider;
051import javax.swing.JTextField;
052import javax.swing.JToggleButton;
053import javax.swing.event.ChangeEvent;
054import javax.swing.event.ChangeListener;
055
056import org.slf4j.Logger;
057import org.slf4j.LoggerFactory;
058
059import ucar.unidata.data.DataChoice;
060import ucar.unidata.data.DataSelection;
061import ucar.unidata.data.DataSelectionComponent;
062import ucar.unidata.data.DataSourceImpl;
063import ucar.unidata.data.GeoLocationInfo;
064import ucar.unidata.data.GeoSelection;
065import ucar.unidata.geoloc.LatLonPoint;
066import ucar.unidata.idv.ui.IdvUIManager;
067import ucar.unidata.ui.LatLonWidget;
068import ucar.unidata.util.GuiUtils;
069import ucar.unidata.util.Misc;
070import ucar.unidata.util.StringUtil;
071
072import visad.VisADException;
073import visad.data.mcidas.AREACoordinateSystem;
074import visad.georef.EarthLocationTuple;
075import visad.georef.MapProjection;
076
077import edu.wisc.ssec.mcidas.AREAnav;
078import edu.wisc.ssec.mcidas.AreaDirectory;
079import edu.wisc.ssec.mcidasv.Constants;
080
081
082public class GeoLatLonSelection extends DataSelectionComponent implements Constants {
083
084    private static final Logger logger = LoggerFactory.getLogger(GeoLatLonSelection.class);
085    
086      private GeoLocationInfo geoLocInfo;
087
088      /** The spacing used in the grid layout */
089      protected static final int GRID_SPACING = 3;
090
091      /** Used by derived classes when they do a GuiUtils.doLayout */
092      protected static final Insets GRID_INSETS = new Insets(GRID_SPACING,
093                                                      GRID_SPACING,
094                                                      GRID_SPACING,
095                                                      GRID_SPACING);
096
097      DataChoice dataChoice;
098      MapProjection sampleProjection;
099
100      /** earth coordinates */
101      protected static final String TYPE_LATLON = "Latitude/Longitude";
102
103      /** image */
104      protected static final String TYPE_IMAGE = "Image Coordinates";
105
106      /** area */
107      protected static final String TYPE_AREA = "Area Coordinates";
108
109      /** flag for center */
110      protected static final String PLACE_CENTER = "CENTER";
111
112      /** flag for upper left */
113      protected static final String PLACE_ULEFT = "ULEFT";
114
115      /** Property for image default value lat/lon */
116      protected static final String PROP_LATLON = "LATLON";
117
118      /** Property for image default value line/ele */
119      protected static final String PROP_LINEELE = "LINELE";
120
121      /** Property for image default value loc */
122      protected static final String PROP_LOC = "LOC";
123
124      /** Property for image default value mag */
125      protected static final String PROP_MAG = "MAG";
126      protected static final String PROP_LMAG = "LMAG";
127      protected static final String PROP_EMAG = "EMAG";
128
129      /** Property for image default value place */
130      protected static final String PROP_PLACE = "PLACE";
131
132      /** Property for image default value size */
133      protected static final String PROP_SIZE = "SIZE";
134
135      /** Property for image default value unit */
136      protected static final String PROP_TYPE = "TYPE";
137
138      /** Property for line resolution */
139      protected static final String PROP_LRES = "LRES";
140      protected static final String PROP_PLRES = "PLRES";
141
142      /** Property for element resolution */
143      protected static final String PROP_ERES = "ERES";
144      protected static final String PROP_PERES = "PERES";
145
146      protected static final String PROP_READOUT = "READOUT";
147
148      /** This is the list of properties that are used in the advanced gui */
149      private static final String[] ADVANCED_PROPS = {
150          PROP_TYPE, PROP_PLACE, PROP_LOC, PROP_SIZE,  PROP_MAG,
151          PROP_LMAG, PROP_EMAG, PROP_READOUT
152      };
153
154      /** This is the list of labels used for the advanced gui */
155      private static final String[] ADVANCED_LABELS = {
156        "Coordinate Type:", "Placement:", "Location:", "   Image Size:",
157        "Magnification:", "", "", "Approx. Area: "
158      };
159
160      private static final String[] readoutLabels = {
161          "Center     ",
162          "Upper Left ",
163          "Upper Right",
164          "Lower Left ",
165          "Lower Right"
166      };
167
168      private String kmLbl = " km";
169
170      /** Input for lat/lon center point */
171      protected LatLonWidget latLonWidget = new LatLonWidget();
172
173      /** Widget to hold the number of elements in the advanced */
174      JTextField numElementsFld = new JTextField();
175
176      /** Widget to hold  the number of lines   in the advanced */
177      JTextField numLinesFld = new JTextField();
178
179      /** Widget for the line  center point in the advanced section */
180      JTextField centerLineFld = new JTextField();
181
182      /** Widget for the element  center point in the advanced section */
183      JTextField centerElementFld = new JTextField();
184
185      JTextField lineMagFld = new JTextField();
186      JTextField eleMagFld = new JTextField();
187
188      /** _more_ */
189      private JToggleButton lockBtn;
190      private JButton fullResBtn;
191
192      private JPanel lMagPanel;
193      private JPanel eMagPanel;
194
195      /** Widget for the line magnfication in the advanced section */
196      protected JSlider lineMagSlider;
197
198      /** Label for the line mag. in the advanced section */
199      JLabel lineMagLbl = new JLabel();
200      JLabel lineResLbl = new JLabel();
201
202       JLabel rawSizeLbl = new JLabel();
203
204      /** Widget for the element magnfication in the advanced section */
205      protected JSlider elementMagSlider;
206
207      /** Label for the element mag. in the advanced section */
208      JLabel elementMagLbl = new JLabel();
209      JLabel elementResLbl = new JLabel();
210
211      /** location panel */
212      protected GuiUtils.CardLayoutPanel locationPanel;
213
214      /** flag for setting properties */
215      private boolean amSettingProperties = false;
216
217      JComboBox coordinateTypeComboBox;
218      JComboBox locationComboBox;
219
220      String[] coordinateTypes = { TYPE_LATLON, TYPE_IMAGE, TYPE_AREA };
221      String[] locations = {"Center", "Upper Left"};
222
223      /** the place string */
224      private String defaultType = TYPE_LATLON;
225      private String place;
226      private String defaultPlace = PLACE_CENTER;
227      private int defaultNumLines = 1000;
228      private int defaultNumEles = 1000;
229      private int numLines = defaultNumLines;
230      private int numEles = defaultNumEles;
231      private double latitude;
232      private double defaultLat = Double.NaN;
233      private double longitude;
234      private double defaultLon = Double.NaN;
235      private  boolean resetLatLon = true;
236      private int imageLine;
237      private int areaLine;
238      private int imageElement;
239      private int areaElement;
240      private int lineMag;
241      private double dLineMag;
242      private int defaultLineMag;
243      private int elementMag;
244      private double dElementMag;
245      private int defaultElementMag;
246      private boolean isLineEle = false;
247      private double lRes;
248      protected double baseLRes = 0.0;
249      private double eRes;
250      protected double baseERes = 0.0;
251
252      private Hashtable properties;
253      protected boolean amUpdating = false;
254
255
256      /** Maps the PROP_ property name to the gui component */
257      private Hashtable propToComps = new Hashtable();
258
259      /** size label */ JLabel sizeLbl;
260
261      /** base number of lines */
262      private double baseNumLines;
263
264      /** base number of elements */
265      private double baseNumElements;
266
267      private DataSourceImpl dataSource;
268      private static DataSourceImpl lastDataSource;
269      private AreaDirectory previewDir;
270      private AREAnav previewNav;
271      private AREAnav areaNav;
272
273      private List latLonLbls = new ArrayList();
274      private List linEleImageLbls = new ArrayList();
275      private List linEleAreaLbls = new ArrayList();
276      private JPanel latLonPanel;
277      private JPanel lineElementPanel;
278
279      /**
280       * limit of slider
281       */
282      private static final int SLIDER_MAX = 1;
283      private static final int SLIDER_MIN = -29;
284      private static final int SLIDER_WIDTH = 150;
285      private static final int SLIDER_HEIGHT = 16;
286
287      /**
288       *  Keep track of the lines to element ratio
289       */
290      private double linesToElements = 1.0;
291 
292      double[][] imageEL = new double[2][5];
293      double[][] areaEL = new double[2][5];
294      double[][] displayEL = new double[2][5];
295      double[][] latLon = new double[2][5];
296
297      private int[] previewDirBlk;
298
299      private int previewLineRes = 1;
300      private int previewEleRes = 1;
301      private int maxLines = 0;
302      private int maxEles = 0;
303
304      private double bLRes = 0.0;
305      private double bERes = 0.0;
306
307      private JPanel latLonReadoutPanel;
308      private JPanel lineElementImageReadoutPanel;
309      private JPanel lineElementAreaReadoutPanel;
310      private GuiUtils.CardLayoutPanel readoutPanel;
311
312      public GeoLatLonSelection(DataSourceImpl dataSource,
313             DataChoice dataChoice, Hashtable initProps, MapProjection sample,
314             AreaDirectory dir, AREAnav nav) 
315              throws VisADException, RemoteException {
316          super("Advanced");
317
318          if (dataSource != lastDataSource) {
319              this.resetLatLon = true;
320          }
321          lastDataSource = dataSource;
322
323          this.properties = initProps;
324          this.dataSource = dataSource;
325          this.dataChoice = dataChoice;
326          this.sampleProjection = sample;
327          this.previewDir = dir;
328
329          setBaseNumLines(dir.getLines());
330          setBaseNumElements(dir.getElements());
331          this.previewNav = nav;
332          previewDirBlk = this.previewDir.getDirectoryBlock();
333          int areaLinRes = previewDirBlk[11];
334          int areaEleRes = previewDirBlk[12];
335          this.areaNav = this.previewNav;
336          this.areaNav.setRes(areaLinRes, areaEleRes);
337          this.areaNav.setImageStart(previewDirBlk[5], previewDirBlk[6]);
338
339          int numberOfLines;
340          int numberOfElements;
341          if (properties.containsKey(PROP_SIZE)) {
342              String str = (String)properties.get(PROP_SIZE);
343              String[] strs = StringUtil.split(str, " ", 2);
344              numberOfLines = Integer.parseInt(strs[0]);
345              numberOfElements = Integer.parseInt(strs[1]);
346          } else {
347              try {
348                  numberOfLines = this.previewDir.getLines();
349                  numberOfElements = this.previewDir.getElements();
350                  if (numberOfLines < defaultNumLines)
351                      defaultNumLines = numberOfLines;
352                  if (numberOfElements < defaultNumEles)
353                      defaultNumEles = numberOfElements;
354                  numberOfLines = defaultNumLines;
355                  numberOfElements = defaultNumEles;
356              } catch (Exception e) {
357                  logger.error("no directory", e);
358                  return;
359              }
360          }
361          setNumLines(numberOfLines);
362          setNumEles(numberOfElements);
363          if (properties.containsKey(PROP_MAG)) {
364              String str = (String)properties.get(PROP_MAG);
365              String[] strs = StringUtil.split(str, " ", 2);
366              this.defaultLineMag = Integer.parseInt(strs[0]);
367              this.defaultElementMag = Integer.parseInt(strs[1]);
368              this.dLineMag = (double)this.defaultLineMag;
369              this.dElementMag = (double)this.defaultElementMag;
370          } else {
371              this.dLineMag = -(double)this.previewDir.getLines()/(double)numberOfLines;
372              this.dElementMag = -(double)this.previewDir.getElements()/(double)numberOfElements;
373              this.defaultLineMag = (int)(Math.floor(dLineMag));
374              this.defaultElementMag = (int)(Math.floor(dElementMag));
375          }
376          setLineMag(this.defaultLineMag);
377          setElementMag(this.defaultElementMag);
378
379          try {
380              if (properties.containsKey(PROP_LRES)) {
381                  this.bLRes = Double.parseDouble((String)properties.get(PROP_LRES));
382                  //if (dir.getValue(11) == 1) this.bLRes = this.previewDir.getCenterLatitudeResolution();
383                  this.baseLRes = this.bLRes * (double)(dir.getValue(11));
384                  setLRes(this.baseLRes * Math.abs(this.defaultLineMag));
385              }
386              if (properties.containsKey(PROP_ERES)) {
387                  this.bERes = Double.parseDouble((String)properties.get(PROP_ERES));
388                  //if (dir.getValue(12) == 1) this.bERes = this.previewDir.getCenterLongitudeResolution();
389                  this.baseERes = this.bERes * (double)(dir.getValue(12));
390                  setERes(this.baseERes * Math.abs(this.defaultElementMag));
391              }
392          } catch (Exception e) {
393              logger.error("unable to get resolution", e);
394             
395          }
396          setBLRes(this.bLRes);
397          setBERes(this.bERes);
398          if (this.baseLRes == 0.0)
399              this.baseLRes = this.previewDir.getCenterLatitudeResolution();
400          if (this.baseERes == 0.0)
401              this.baseERes = this.previewDir.getCenterLongitudeResolution();
402
403          this.place = getPlace();
404          if (properties.containsKey(PROP_PLACE)) {
405              setPlace((String)properties.get(PROP_PLACE));
406          }
407
408          if (properties.containsKey(PROP_PLRES)) {
409              this.previewLineRes = Integer.parseInt((String)properties.get(PROP_PLRES));
410          }
411          if (properties.containsKey(PROP_PERES)) {
412              this.previewEleRes = Integer.parseInt((String)properties.get(PROP_PERES));
413          }
414
415          if (this.resetLatLon) {
416              if (this.previewDir != null) {
417                  setLatitude(this.previewDir.getCenterLatitude());
418                  setLongitude(this.previewDir.getCenterLongitude());
419              }
420          } else {
421              setLatitude(this.latitude);
422              setLongitude(this.longitude);
423          }
424          convertToLineEle();
425
426          if (properties.containsKey(PROP_LATLON)) {
427              String str = (String)properties.get(PROP_LATLON);
428              String[] strs = StringUtil.split(str, " ", 2);
429              setLatitude(Double.parseDouble(strs[0]));
430              setLongitude(Double.parseDouble(strs[1]));
431              convertToLineEle();
432              this.isLineEle = false;
433          } else if (properties.containsKey(PROP_LINEELE)) {
434              String str = (String)properties.get(PROP_LINEELE);
435              String[] strs = StringUtil.split(str, " ", 3);
436              setLine(Integer.parseInt(strs[0]));
437              setElement(Integer.parseInt(strs[1]));
438              convertToLatLon();
439              this.isLineEle = true;
440          }
441
442          if (this.defaultLineMag > 1) {
443              numberOfLines = numberOfLines * this.defaultLineMag;
444              setNumLines(numberOfLines);
445              setLRes(lRes/this.defaultLineMag);
446              this.defaultLineMag = 1;
447              setLineMag(this.defaultLineMag);
448          }
449          if (this.defaultElementMag > 1) {
450              numberOfElements = numberOfElements * this.defaultElementMag;
451              setNumEles(numberOfElements);
452              setERes(lRes/this.defaultElementMag);
453              this.defaultElementMag = 1;
454              setElementMag(this.defaultElementMag);
455          }
456      }
457
458      protected JComponent doMakeContents() {
459          String[] propArray  = getAdvancedProps();
460          String[] labelArray = getAdvancedLabels();
461          Insets  dfltGridSpacing = new Insets(4, 0, 4, 0);
462          String  dfltLblSpacing  = " ";
463          List allComps = new ArrayList();
464
465          for (int propIdx = 0; propIdx < propArray.length; propIdx++) {
466              JComponent propComp = null;
467              String     prop     = propArray[propIdx];
468              if (prop.equals(PROP_TYPE)) {
469                  allComps.add(new JLabel(" "));
470                  allComps.add(new JLabel(" "));
471                  coordinateTypeComboBox = new JComboBox(coordinateTypes);
472                  coordinateTypeComboBox.addActionListener(new ActionListener() {
473                      public void actionPerformed(ActionEvent ae) {
474                          int selectedIndex = coordinateTypeComboBox.getSelectedIndex();
475                          flipLocationPanel(selectedIndex);
476                          flipReadoutPanel(selectedIndex);
477                      }
478                  });
479                  propComp = (JComponent)coordinateTypeComboBox;
480              }
481              else if (prop.equals(PROP_LOC)) {
482                  locationComboBox = new JComboBox(locations);
483                  setPlace(this.place);
484                  locationComboBox.addActionListener(new ActionListener() {
485                      public void actionPerformed(ActionEvent ae) {
486                          String selected = getPlace();
487                          cyclePlace();
488                      }
489                  });
490                  propComp = (JComponent)locationComboBox;
491                  addPropComp(PROP_LOC, propComp);
492
493                  ActionListener latLonChange =new ActionListener() {
494                      public void actionPerformed(ActionEvent ae) {
495                          String type = getCoordinateType();
496                          if (type.equals(TYPE_LATLON)) {
497                              setLatitude();
498                              setLongitude();
499                              convertToLineEle();
500                              getGeoLocationInfo();
501                          } else {
502                              setLineElement();
503                              convertToLatLon();
504                              getGeoLocationInfo();
505                          }
506                      }
507                  };
508
509                  FocusListener linEleFocusChange = new FocusListener() {
510                      public void focusGained(FocusEvent fe) {
511                      }
512                      public void focusLost(FocusEvent fe) {
513                          setLineElement();
514                          convertToLatLon();
515                          getGeoLocationInfo();
516                      }
517                  };
518
519                  if (latLonWidget == null)
520                      latLonWidget     = new LatLonWidget(latLonChange);
521
522                  FocusListener latLonFocusChange = new FocusListener() {
523                      public void focusGained(FocusEvent fe) {
524                          JTextField latFld = latLonWidget.getLatField();
525                          latFld.setCaretPosition(latFld.getText().length());
526                          JTextField lonFld = latLonWidget.getLonField();
527                          lonFld.setCaretPosition(lonFld.getText().length());
528                      }
529                      public void focusLost(FocusEvent fe) {
530                          setLatitude();
531                          setLongitude();
532                          convertToLineEle();
533                          getGeoLocationInfo();
534                      }
535                  };
536
537                  if (!this.isLineEle) {
538                      latLonWidget.setLatLon(this.latitude, this.longitude);
539                  }
540                  String lineStr = "";
541                  String eleStr = "";
542                  setLine(this.imageLine);
543                  setElement(this.imageElement);
544                  if ((this.imageLine >= 0) && (this.imageElement >= 0)) {
545                      lineStr =Integer.toString(this.imageLine);
546                      eleStr =Integer.toString(this.imageElement);
547                  }
548                  centerLineFld    = new JTextField(lineStr, 3);
549                  centerLineFld.addActionListener(latLonChange);
550                  centerLineFld.addFocusListener(linEleFocusChange);
551                  final String lineField = "";
552                  centerElementFld = new JTextField(eleStr, 3);
553                  centerElementFld.addActionListener(latLonChange);
554                  centerElementFld.addFocusListener(linEleFocusChange);
555                  final JButton centerPopupBtn =
556                      GuiUtils.getImageButton(
557                        "/auxdata/ui/icons/MapIcon16.png", getClass());
558                  centerPopupBtn.setToolTipText("Center on current displays");
559
560                  centerPopupBtn.addActionListener(new ActionListener() {
561                      public void actionPerformed(ActionEvent ae) {
562                          dataSource.getDataContext().getIdv().getIdvUIManager().popupCenterMenu(
563                              centerPopupBtn, latLonWidget);
564                      }
565                  });
566
567                  JComponent centerPopup = GuiUtils.inset(centerPopupBtn,
568                                             new Insets(0, 0, 0, 4));
569
570
571                  GuiUtils.tmpInsets = dfltGridSpacing;
572                  JTextField latFld = latLonWidget.getLatField();
573                  JTextField lonFld = latLonWidget.getLonField();
574                  latFld.addFocusListener(latLonFocusChange);
575                  lonFld.addFocusListener(latLonFocusChange);
576                  latLonPanel = GuiUtils.hbox(new Component[] {
577                      GuiUtils.rLabel(" Lat:" + dfltLblSpacing),
578                      latFld,
579                      GuiUtils.rLabel(" Lon:" + dfltLblSpacing),
580                      lonFld,
581                      new JLabel(" "), centerPopup
582                  });
583
584                  lineElementPanel =
585                      GuiUtils.hbox(new Component[] {
586                          GuiUtils.rLabel(" Line:" + dfltLblSpacing),
587                          centerLineFld,
588                          GuiUtils.rLabel(" Element:" + dfltLblSpacing),
589                          centerElementFld });
590
591                  locationPanel = new GuiUtils.CardLayoutPanel();
592                  locationPanel.addCard(latLonPanel);
593                  locationPanel.addCard(lineElementPanel);
594
595                  if (propComp != null) {
596                      allComps.add(GuiUtils.rLabel(labelArray[propIdx]));
597                      allComps.add(GuiUtils.left(propComp));
598                  }
599                  propComp = GuiUtils.hbox(new Component[] { locationPanel }, 1);
600                  if (propComp != null) {
601                      allComps.add(GuiUtils.rLabel("  "));
602                      allComps.add(GuiUtils.left(propComp));
603                  }
604                  propComp = null;
605              } else if (prop.equals(PROP_SIZE)) {
606                  ActionListener sizeChange =new ActionListener() {
607                      public void actionPerformed(ActionEvent ae) {
608                          int lines = getNumLines() * Math.abs(getLineMag());
609                          if (lines > maxLines) lines = maxLines;
610                          setBaseNumLines(lines);
611                          int eles = getNumEles() * Math.abs(getElementMag());
612                          if (eles > maxEles) eles = maxEles;
613                          setBaseNumElements(eles);
614                          getGeoLocationInfo();
615                      }
616                  };
617                  FocusListener sizeFocusChange = new FocusListener() {
618                      public void focusGained(FocusEvent fe) {
619                      }
620                      public void focusLost(FocusEvent fe) {
621                          int lines = getNumLines() * Math.abs(getLineMag());
622                          if (lines > maxLines) lines = maxLines;
623                          setBaseNumLines(lines);
624                          int eles = getNumEles() * Math.abs(getElementMag());
625                          if (eles > maxEles) eles = maxEles;
626                          setBaseNumElements(eles);
627                          getGeoLocationInfo();
628                      }
629                  };
630                  
631                  this.maxLines = this.previewDir.getLines();
632                  this.maxEles = this.previewDir.getElements();
633                  
634                  int lmag = getLineMag();
635                  int emag = getElementMag();
636                  if (lmag < 0) this.numLines = this.maxLines / Math.abs(lmag);
637                  if (emag < 0) this.numEles = this.maxEles / Math.abs(emag);
638
639                  setNumLines(this.numLines);
640                  numLinesFld    = new JTextField(Integer.toString(this.numLines), 4);
641                  numLinesFld.addActionListener(sizeChange);
642                  numLinesFld.addFocusListener(sizeFocusChange);
643                  setNumEles(this.numEles);
644                  numElementsFld = new JTextField(Integer.toString(this.numEles), 4);
645                  numElementsFld.addActionListener(sizeChange);
646                  numElementsFld.addFocusListener(sizeFocusChange);
647                  numLinesFld.setToolTipText("Number of lines");
648                  numElementsFld.setToolTipText("Number of elements");
649                  GuiUtils.tmpInsets = dfltGridSpacing;
650                  sizeLbl            = GuiUtils.lLabel("");
651
652                  fullResBtn = GuiUtils.makeImageButton(
653                      "/auxdata/ui/icons/arrow_out.png", this,
654                      "setToFullResolution");
655                  fullResBtn.setContentAreaFilled(false);
656                  fullResBtn.setToolTipText("Set fields to retrieve full image");
657
658                  lockBtn =
659                          GuiUtils.getToggleImageButton(IdvUIManager.ICON_UNLOCK,
660                                          IdvUIManager.ICON_LOCK, 0, 0, true);
661                  lockBtn.setContentAreaFilled(false);
662                  lockBtn.setSelected(true);
663                  lockBtn.setToolTipText(
664                                  "Unlock to automatically change size when changing magnification");
665
666                  rawSizeLbl = new JLabel(" Raw size: " + this.maxLines + " X " + 
667                                                          this.maxEles);
668                  JPanel sizePanel =
669                      GuiUtils.left(GuiUtils.doLayout(new Component[] {
670                          numLinesFld,
671                          new JLabel(" X "), numElementsFld, sizeLbl, new JLabel(" "),
672                          fullResBtn, new JLabel("  "), lockBtn,
673                          rawSizeLbl }, 9, GuiUtils.WT_N, GuiUtils.WT_N));
674                  addPropComp(PROP_SIZE, propComp = sizePanel);
675              } else if (prop.equals(PROP_MAG)) {
676                  propComp = GuiUtils.hbox(new Component[] { new JLabel("") }, 1);
677                  addPropComp(PROP_MAG, propComp);
678              } else if (prop.equals(PROP_LMAG)) {
679                  boolean oldAmSettingProperties = amSettingProperties;
680                  amSettingProperties = true;
681                  ChangeListener lineListener =
682                      new javax.swing.event.ChangeListener() {
683                      public void stateChanged(ChangeEvent evt) {
684                          if (amSettingProperties) {
685                              return;
686                          }
687                          int val = getMagValue(lineMagSlider);
688                          setLineMag(val);
689                          amUpdating = true;
690                          lineMagSliderChanged(!lockBtn.isSelected());
691                          amUpdating = false;
692                          getGeoLocationInfo();
693                      }
694                  };
695                  ActionListener lineMagChange =new ActionListener() {
696                      public void actionPerformed(ActionEvent ae) {
697                          if (amSettingProperties) {
698                              return;
699                          }
700                          setLineMag();
701                          changeLineMagSlider(!lockBtn.isSelected());
702                          getGeoLocationInfo();
703                      }
704                  };
705                  FocusListener lineMagFocusChange = new FocusListener() {
706                      public void focusGained(FocusEvent fe) {
707                      }
708                      public void focusLost(FocusEvent fe) {
709                          if (amSettingProperties) {
710                              return;
711                          }
712                          setLineMag();
713                          changeLineMagSlider(!lockBtn.isSelected());
714                          getGeoLocationInfo();
715                      }
716                  };
717                  JComponent[] lineMagComps =
718                      GuiUtils.makeSliderPopup(SLIDER_MIN, SLIDER_MAX, 0,
719                                               lineListener);
720                  lineMagSlider = (JSlider) lineMagComps[1];
721                  lineMagSlider.setPreferredSize(new Dimension(SLIDER_WIDTH,SLIDER_HEIGHT));
722                  lineMagSlider.setMajorTickSpacing(1);
723                  lineMagSlider.setSnapToTicks(true);
724                  lineMagSlider.setExtent(1);
725                  int mag = getLineMag();
726                  setLineMagSlider(mag);
727                  lineMagComps[0].setToolTipText(
728                      "Change the line magnification");
729                  lineMagSlider.setToolTipText(
730                      "Slide to set line magnification factor");
731                  String str = "Line Mag=";
732                  lineMagFld = new JTextField(Integer.toString(mag),3);
733                  lineMagFld.addFocusListener(lineMagFocusChange);
734                  lineMagFld.addActionListener(lineMagChange);
735                  lineMagLbl =
736                      GuiUtils.getFixedWidthLabel(StringUtil.padLeft(str, 4));
737                  str = truncateNumericString(Double.toString(this.baseLRes*Math.abs(getLineMag())), 1);
738                  str = " Res=" + str + kmLbl;
739                  lineResLbl =
740                      GuiUtils.getFixedWidthLabel(StringUtil.padLeft(str, 4));
741                  amSettingProperties = oldAmSettingProperties;
742
743                  GuiUtils.tmpInsets  = dfltGridSpacing;
744                  lMagPanel = GuiUtils.doLayout(new Component[] {
745                                        lineMagLbl, lineMagFld,
746                                        GuiUtils.inset(lineMagComps[1],
747                                            new Insets(0, 4, 0, 0)), lineResLbl, }, 5,
748                                                GuiUtils.WT_N, GuiUtils.WT_N);
749                  propComp = GuiUtils.hbox(new Component[] { new JLabel(" "), lMagPanel }, 2);
750                  addPropComp(PROP_LMAG, propComp = lMagPanel);
751              } else if (prop.equals(PROP_EMAG)) {
752                  boolean oldAmSettingProperties = amSettingProperties;
753                  amSettingProperties = true;
754                  ChangeListener elementListener = new ChangeListener() {
755                      public void stateChanged(
756                              javax.swing.event.ChangeEvent evt) {
757                          if (amSettingProperties) {
758                              return;
759                          }
760                          int val = getMagValue(elementMagSlider);
761                          setElementMag(val);
762                          amUpdating = true;
763                          elementMagSliderChanged(true);
764                          amUpdating = false;
765                          getGeoLocationInfo();
766                      }
767                  };
768                  ActionListener eleMagChange =new ActionListener() {
769                      public void actionPerformed(ActionEvent ae) {
770                          if (amSettingProperties) {
771                              return;
772                          }
773                          setElementMag();
774                          changeEleMagSlider(!lockBtn.isSelected());
775                          getGeoLocationInfo();
776                      }
777                  };
778                  FocusListener eleMagFocusChange = new FocusListener() {
779                      public void focusGained(FocusEvent fe) {
780                      }
781                      public void focusLost(FocusEvent fe) {
782                          if (amSettingProperties) {
783                              return;
784                          }
785                          setElementMag();
786                          changeEleMagSlider(!lockBtn.isSelected());
787                          getGeoLocationInfo();
788                      }
789                  };
790                  JComponent[] elementMagComps =
791                      GuiUtils.makeSliderPopup(SLIDER_MIN, SLIDER_MAX, 0,
792                                               elementListener);
793                  elementMagSlider = (JSlider) elementMagComps[1];
794                  elementMagSlider.setPreferredSize(new Dimension(SLIDER_WIDTH,SLIDER_HEIGHT));
795                  elementMagSlider.setExtent(1);
796                  elementMagSlider.setMajorTickSpacing(1);
797                  elementMagSlider.setSnapToTicks(true);
798                  int mag = getElementMag();
799                  setElementMagSlider(mag);
800                  elementMagComps[0].setToolTipText(
801                      "Change the element magnification");
802                  elementMagSlider.setToolTipText(
803                      "Slide to set element magnification factor");
804                  eleMagFld = new JTextField(Integer.toString(mag),3);
805                  eleMagFld.addFocusListener(eleMagFocusChange);
806                  eleMagFld.addActionListener(eleMagChange);
807                  String str = "Ele  Mag=";
808                  elementMagLbl =
809                      GuiUtils.getFixedWidthLabel(StringUtil.padLeft(str, 4));
810                  str = truncateNumericString(Double.toString(this.baseERes*Math.abs(getElementMag())), 1);
811                  str = " Res=" + str + kmLbl;
812                  elementResLbl =
813                      GuiUtils.getFixedWidthLabel(StringUtil.padLeft(str, 4));
814                  amSettingProperties = oldAmSettingProperties;
815
816                  GuiUtils.tmpInsets  = dfltGridSpacing;
817                  eMagPanel = GuiUtils.doLayout(new Component[] {
818                                        elementMagLbl, eleMagFld,
819                                        GuiUtils.inset(elementMagComps[1],
820                                            new Insets(0, 4, 0, 0)), elementResLbl, }, 5,
821                                                GuiUtils.WT_N, GuiUtils.WT_N);
822                  propComp = GuiUtils.hbox(new Component[] { new JLabel(" "), eMagPanel }, 2);
823                  addPropComp(PROP_EMAG, propComp = eMagPanel);
824              } else if (prop.equals(PROP_READOUT)) {
825                  allComps.add(new JLabel(" "));
826                  allComps.add(new JLabel(" "));
827                  for (int i=0; i<5; i++) {
828                      latLonLbls.add(GuiUtils.getFixedWidthLabel(" "));
829                      linEleImageLbls.add(GuiUtils.getFixedWidthLabel(" "));
830                      linEleAreaLbls.add(GuiUtils.getFixedWidthLabel(" "));
831                  }
832                  latLonReadoutPanel = GuiUtils.left(GuiUtils.doLayout(
833                      latLonLbls, 1, GuiUtils.WT_N, GuiUtils.WT_Y));
834                  lineElementImageReadoutPanel = GuiUtils.left(GuiUtils.doLayout(
835                      linEleImageLbls, 1, GuiUtils.WT_N, GuiUtils.WT_Y));
836                  lineElementAreaReadoutPanel = GuiUtils.left(GuiUtils.doLayout(
837                      linEleAreaLbls, 1, GuiUtils.WT_N, GuiUtils.WT_Y));
838
839                  readoutPanel = new GuiUtils.CardLayoutPanel();
840                  readoutPanel.addCard(latLonReadoutPanel);
841                  readoutPanel.addCard(lineElementImageReadoutPanel);
842                  readoutPanel.addCard(lineElementAreaReadoutPanel);
843
844                  propComp = GuiUtils.hbox(new Component[] { readoutPanel }, 1);
845                  addPropComp(PROP_READOUT, propComp);
846                  if (propComp != null) {
847                      allComps.add(GuiUtils.rLabel(labelArray[propIdx]));
848                      allComps.add(GuiUtils.left(propComp));
849                  }
850                  propComp = null;
851              }
852              if (propComp != null) {
853                  allComps.add(GuiUtils.rLabel(labelArray[propIdx]));
854                  allComps.add(GuiUtils.left(propComp));
855              }
856          }
857          GuiUtils.tmpInsets = GRID_INSETS;
858          JPanel imagePanel = GuiUtils.doLayout(allComps, 2, GuiUtils.WT_NY,
859                                  GuiUtils.WT_N);
860          getGeoLocationInfo();
861          return GuiUtils.top(imagePanel);
862      }
863
864      private void updateReadout() {
865          if ((readoutLabels.length == 0) || latLonLbls.isEmpty()) {
866              return;
867          }
868          int numCols = 7;
869          for (int i=0; i<5; i++) {
870              String str = readoutLabels[i] +
871                           " Lat: " + formatDoubleCoord(numCols, latLon[0][i]) +
872                           " Lon: " + formatDoubleCoord(numCols, latLon[1][i]);
873              ((JLabel)latLonLbls.get(i)).setText(str);
874
875              String lineStr = formatIntegerCoord(numCols, imageEL[1][i]);
876              String eleStr = formatIntegerCoord(numCols, imageEL[0][i]);
877              str = readoutLabels[i] + " Line: " + lineStr +
878                                       " Element: " + eleStr;
879              ((JLabel)linEleImageLbls.get(i)).setText(str);
880
881              lineStr = formatIntegerCoord(numCols, areaEL[1][i]);
882              eleStr = formatIntegerCoord(numCols, areaEL[0][i]);
883              str = readoutLabels[i] + " Line: " + lineStr +
884                                       " Element: " + eleStr;
885              ((JLabel)linEleAreaLbls.get(i)).setText(str);
886          }
887      }
888
889      private String formatIntegerCoord(int cols, double val) {
890          String outStr = Misc.MISSING;
891          Double dbl = new Double(val);
892          if (!dbl.isNaN()) {
893              int ival = (int)Math.floor(val + 0.5);
894              outStr = Integer.toString(ival);
895          }
896          int len = outStr.length() + 1;
897          while (len < cols) {
898              outStr = new String(" ").concat(outStr);
899              len++;
900          }
901          return outStr;
902      }
903
904      private String formatDoubleCoord(int cols, double val) {
905          String outStr = Misc.MISSING;
906          Double dbl = new Double(val);
907          if (!dbl.isNaN()) {
908              outStr = Double.toString(val);
909              if (outStr.length() > cols)
910                  outStr = outStr.substring(0, cols);
911          }
912          int len = outStr.length();
913          while (len < cols) {
914              outStr = new String(" ").concat(outStr);
915              len++;
916          }
917          return outStr;
918      }
919
920      /**
921       * Change coordinate type panel
922       */
923      protected void flipLocationPanel(int locPanel) {
924          int nowPlaying = locationPanel.getVisibleIndex();
925          if (locPanel > 0) {
926              if (nowPlaying == 0) {
927                  locationPanel.flip();
928              }
929              setIsLineEle(true);
930              String type = getCoordinateType();
931              int ele = this.imageElement;
932              int lin = this.imageLine;
933              if (type.equals(TYPE_AREA)) {
934                  ele = this.areaElement;
935                  lin = this.areaLine;
936              }
937              setElement(ele);
938              setLine(lin);
939          } else {
940              if (nowPlaying > 0) locationPanel.flip();
941              setIsLineEle(false);
942          }
943      }
944
945      /**
946       * Change readout type panel
947       */
948      protected void flipReadoutPanel(int roPanel) {
949          readoutPanel.show(roPanel);
950      }
951
952      /**
953       * Set to full resolution
954       */
955      public void setToFullResolution() {
956          setPlace(PLACE_CENTER);
957          setLatitude(this.previewDir.getCenterLatitude());
958          setLongitude(this.previewDir.getCenterLongitude());
959          convertToLinEle();
960          setNumLines(this.maxLines);
961          setNumEles(this.maxEles);
962          setBaseNumLines(this.maxLines);
963          setBaseNumElements(this.maxEles);
964          setLineMag(1);
965          setElementMag(1);
966          setLineMagSlider(1);
967          setLRes(this.baseLRes);
968          setElementMagSlider(1);
969          setERes(this.baseERes);
970          amUpdating = true;
971          lineMagSliderChanged(false);
972          elementMagSliderChanged(false);
973          amUpdating = false;
974          getGeoLocationInfo();
975      }
976
977      @Override public void applyToDataSelection(DataSelection dataSelection) {
978          logger.trace("dataSelection={}", dataSelection);
979
980         if (dataSelection == null) {
981             dataSelection = new DataSelection(true);
982         }
983
984         if (geoLocInfo == null) {
985             getGeoLocationInfo();
986         }
987         
988         GeoLocationInfo geoInfo = geoLocInfo;
989         if (geoInfo == null) {
990             logger.trace("err, wtf?");
991             dataSelection = null;
992             return;
993         }
994
995         String coordType = getCoordinateType();
996
997         if (!isLineEle) {
998             logger.trace("dealing with LALO coords for datasel={}", dataSelection);
999             double lat = getLatitude();
1000             double lon = getLongitude();
1001             if (lat > 90.0 && lon> 360.0) {
1002                 convertToLatLon();
1003                 lat = getLatitude();
1004                 lon = getLongitude();
1005             }
1006//             if ((lat == dNaN) || (lon == dNaN)) {
1007//                 return;
1008//             }
1009             if ((Double.isNaN(lat) || (Double.isNaN(lon)))) {
1010                 return;
1011             }
1012
1013             String latString = Double.toString(lat);
1014             if (latString.length() > 8) {
1015                 latString = latString.substring(0,7);
1016             }
1017             String lonString = Double.toString(lon);
1018             if (lonString.length() > 9) {
1019                 lonString = lonString.substring(0,8);
1020             }
1021             dataSelection.putProperty(PROP_LATLON, (latString + " " + lonString));
1022         } else {
1023             logger.trace("dealing with line-ele coords for datasel={}", dataSelection);
1024             int lin = getLine();
1025             int ele = getElement();
1026             if ((Double.isNaN(lin)) || (Double.isNaN(ele))) {
1027                 return;
1028             }
1029//             if ((lin == dNaN) || (ele == dNaN)) return;
1030
1031             String typeStr = " I";
1032             if (coordType.equals(TYPE_AREA)) typeStr = " F";
1033             String linString = Integer.toString(lin);
1034             String eleString = Integer.toString(ele);
1035             dataSelection.putProperty(PROP_LINEELE, (linString + " " + eleString + typeStr));
1036         }
1037
1038         dataSelection.putProperty(PROP_PLACE, getPlace());
1039         dataSelection.putProperty(PROP_MAG, (getLineMag() + " " + getElementMag()));
1040
1041         GeoSelection geoSelection = new GeoSelection(geoInfo);
1042         dataSelection.setGeoSelection(geoSelection);
1043
1044         int nlins = getNumLines();
1045         int neles = getNumEles();
1046         if (nlins > 0 && neles > 0) {
1047             dataSelection.putProperty(PROP_SIZE, (nlins + " " + neles));
1048         }
1049         logger.trace("dataChoice={} dataSelection={}", dataChoice, dataSelection);
1050         dataChoice.setDataSelection(dataSelection);
1051         
1052         this.dataSource.setDataSelection(dataSelection);
1053    }
1054
1055      @Override public boolean getShowInControlProperties() {
1056          return false;
1057      }
1058
1059    public GeoLocationInfo getGeoLocationInfo() {
1060        geoLocInfo = null;
1061        double[][] el = convertToDisplayCoords();
1062        int ele = (int)Math.floor(el[0][0] + 0.5);
1063        if (ele < 0) ele = 0;
1064        int lin = (int)Math.floor(el[1][0] + 0.5);
1065        if (lin < 0) lin = 0;
1066        geoLocInfo = getGeoLocationInfo(lin, ele);
1067        return geoLocInfo;
1068    }
1069
1070    protected GeoLocationInfo getGeoLocationInfo(int lin, int ele) {
1071        int nLin = getNumLines();
1072        if (nLin > 0) {
1073            int nEle = getNumEles();
1074            if (nEle > 0) {
1075                int lMag = getLineMag();
1076                if (lMag > 1) return geoLocInfo;
1077                int eMag = getElementMag();
1078                if (eMag > 1) return geoLocInfo;
1079                geoLocInfo = makeGeoLocationInfo(lin, ele, nLin, nEle,
1080                             lMag, eMag);
1081                return geoLocInfo;
1082            }
1083        }
1084        for (int i = 0; i < 2; i++) {
1085            for (int j = 0; j < 5; j++) {
1086                latLon[i][j] = Double.NaN;
1087                imageEL[i][j] = Double.NaN;
1088                areaEL[i][j] = Double.NaN;
1089                displayEL[i][j] = Double.NaN;
1090            }
1091        }
1092        updateReadout();
1093        setLine(-1);
1094        setElement(-1);
1095        return null;
1096    }
1097
1098    private GeoLocationInfo makeGeoLocationInfo(int lin, int ele, int nlins, int neles,
1099                            int linMag, int eleMag) {
1100         geoLocInfo = null;
1101
1102         String plc = getPlace();
1103         String type = getCoordinateType();
1104
1105         AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1106         Rectangle2D mapArea = macs.getDefaultMapArea();
1107         double previewXDim = mapArea.getWidth();
1108         double previewYDim = mapArea.getHeight();
1109
1110         double dLine = (double)nlins/(2.0*this.previewLineRes)*Math.abs(linMag);
1111         double dEle = (double)neles/(2.0*this.previewEleRes)*Math.abs(eleMag);
1112
1113         if (plc.equals(PLACE_CENTER)) {
1114             displayEL[0][0] = ele;
1115             displayEL[1][0] = lin;
1116             displayEL[0][1] = ele - dEle;
1117             if (displayEL[0][1] < 0) displayEL[0][1] = 0.0;
1118             displayEL[1][1] = lin + dLine;
1119             if (displayEL[1][1] > previewYDim) displayEL[1][1] = previewYDim;
1120         } else if (plc.equals(PLACE_ULEFT)) {
1121             displayEL[0][0] = ele + dEle;
1122             if (displayEL[0][0] > previewXDim) displayEL[0][0] = previewXDim;
1123             displayEL[1][0] = lin - dLine;
1124             if (displayEL[1][0] < 0) displayEL[1][0] = 0.0;
1125             displayEL[0][1] = ele;
1126             displayEL[1][1] = lin;
1127         }
1128         int cEle = (int)Math.ceil(displayEL[0][0]);
1129         int cLin = (int)Math.ceil(displayEL[1][0]);
1130         displayEL[0][2] = cEle + dEle;
1131         if (displayEL[0][2] > previewXDim) displayEL[0][2] = previewXDim;
1132         displayEL[1][2] = cLin + dLine;
1133         if (displayEL[1][2] > previewYDim) displayEL[1][2] = previewYDim;
1134         displayEL[0][3] = cEle - dEle;
1135         if (displayEL[0][3] < 0) displayEL[0][3] = 0.0;
1136         displayEL[1][3] = cLin - dLine;
1137         if (displayEL[1][3] < 0) displayEL[1][3] = 0.0;
1138         displayEL[0][4] = cEle + dEle;
1139         if (displayEL[0][4] > previewXDim) displayEL[0][4] = previewXDim;
1140         displayEL[1][4] = cLin - dLine;
1141         if (displayEL[1][4] < 0) displayEL[1][4] = 0.0;
1142/*
1143         System.out.println("\nDisplay:");
1144         System.out.println("    0: " + displayEL[1][0] + " " + displayEL[0][0]);
1145         System.out.println("    1: " + displayEL[1][1] + " " + displayEL[0][1]);
1146         System.out.println("    2: " + displayEL[1][2] + " " + displayEL[0][2]);
1147         System.out.println("    3: " + displayEL[1][3] + " " + displayEL[0][3]);
1148         System.out.println("    4: " + displayEL[1][4] + " " + displayEL[0][4]);
1149*/
1150         areaEL = displayCoordToAreaCoord(displayEL);
1151/*
1152         System.out.println("\nArea:");
1153         System.out.println("    0: " + areaEL[1][0] + " " + areaEL[0][0]);
1154         System.out.println("    1: " + areaEL[1][1] + " " + areaEL[0][1]);
1155         System.out.println("    2: " + areaEL[1][2] + " " + areaEL[0][2]);
1156         System.out.println("    3: " + areaEL[1][3] + " " + areaEL[0][3]);
1157         System.out.println("    4: " + areaEL[1][4] + " " + areaEL[0][4]);
1158*/
1159         for (int i=0; i<5; i++) {
1160             if (areaEL[0][i] < 0.0) areaEL[0][i] = 0.0;
1161             if (areaEL[0][i] > this.maxEles) areaEL[0][i] = (double)this.maxEles;
1162             if (areaEL[1][i] < 0.0) areaEL[1][i] = 0.0;
1163             if (areaEL[1][i] > this.maxLines) areaEL[1][i] = (double)this.maxLines;
1164         }
1165
1166         try {
1167             latLon = macs.toReference(displayEL);
1168         } catch (Exception e) {
1169             logger.error("converting input latitude/longitude", e);
1170         }
1171/*
1172         System.out.println("\nLat/Lon:");
1173         System.out.println("    0: " + latLon[0][0] + " " + latLon[1][0]);
1174         System.out.println("    1: " + latLon[0][1] + " " + latLon[1][1]);
1175         System.out.println("    2: " + latLon[0][2] + " " + latLon[1][2]);
1176         System.out.println("    3: " + latLon[0][3] + " " + latLon[1][3]);
1177         System.out.println("    4: " + latLon[0][4] + " " + latLon[1][4]);
1178*/
1179         double maxLat = latLon[0][1];
1180         if (latLon[0][2] > maxLat) maxLat = latLon[0][2];
1181         double minLat = latLon[0][3];
1182         if (latLon[0][4] < minLat) minLat = latLon[0][4];
1183         double maxLon = latLon[1][4];
1184         if (latLon[1][2] > maxLon) maxLon = latLon[1][2];
1185         double minLon = latLon[1][1];
1186         if (latLon[1][3] < minLon) minLon = latLon[1][3];
1187
1188         imageEL = this.previewNav.areaCoordToImageCoord(areaEL);
1189/*
1190         System.out.println("\nImage:");
1191         System.out.println("    0: " + imageEL[1][0] + " " + imageEL[0][0]);
1192         System.out.println("    1: " + imageEL[1][1] + " " + imageEL[0][1]);
1193         System.out.println("    2: " + imageEL[1][2] + " " + imageEL[0][2]);
1194         System.out.println("    3: " + imageEL[1][3] + " " + imageEL[0][3]);
1195         System.out.println("    4: " + imageEL[1][4] + " " + imageEL[0][4]);
1196*/
1197         updateReadout();
1198
1199         geoLocInfo = new GeoLocationInfo(maxLat, minLon, minLat, maxLon);
1200
1201         return geoLocInfo;
1202    }
1203
1204    /**
1205     * Get the list of advanced property names
1206     *
1207     * @return array of advanced property names
1208     */
1209    protected String[] getAdvancedProps() {
1210        return ADVANCED_PROPS;
1211    }
1212
1213    /**
1214     * Get the list of advanced property labels
1215     *
1216     * @return list of advanced property labels
1217     */
1218    protected String[] getAdvancedLabels() {
1219        return ADVANCED_LABELS;
1220    }
1221
1222
1223    /**
1224     * Cycle the place
1225     */
1226    public void cyclePlace() {
1227        
1228        String type = getCoordinateType();
1229        int dLine = getNumLines()/2 * Math.abs(getLineMag());
1230        int dEle = getNumEles()/2 * Math.abs(getElementMag());
1231        if (this.place.equals(PLACE_CENTER)) {
1232            int newVal = this.areaLine + dLine;
1233            if (newVal > this.maxLines/2) newVal = this.maxLines/2;
1234            this.areaLine = newVal;
1235            newVal = this.areaElement + dEle;
1236            if (newVal > this.maxEles/2) newVal = this.maxEles/2;
1237            this.areaElement = newVal;
1238        } else {
1239            int newVal = this.areaLine - dLine;
1240            if (newVal < 0) newVal = 0;
1241            this.areaLine = newVal;
1242            newVal = this.areaElement - dEle;
1243            if (newVal < 0) newVal = 0;
1244            this.areaElement = newVal;
1245        }
1246        double[][] el = new double[2][1];
1247        el[0][0] = this.areaElement;
1248        el[1][0] = this.areaLine;
1249        double[][] vals = this.areaNav.areaCoordToImageCoord(el);
1250        this.imageElement = (int)Math.floor(vals[0][0] + 0.5);
1251        this.imageLine = (int)Math.floor(vals[1][0] + 0.5);
1252
1253        if (type.equals(TYPE_AREA)) {
1254            setLine(this.areaLine);
1255            setElement(this.areaElement);
1256        } else if (type.equals(TYPE_IMAGE)) {
1257            setLine(this.imageLine);
1258            setElement(this.imageElement);
1259        }
1260        double[][] ll = this.areaNav.toLatLon(el);
1261        setLatitude(ll[0][0]);
1262        setLongitude(ll[1][0]);
1263    }
1264
1265
1266    /**
1267     * Associates the goven JComponent with the PROP_ property
1268     * identified  by the given propId
1269     *
1270     * @param propId The property
1271     * @param comp The gui component that allows the user to set the property
1272     *
1273     * @return Just returns the given comp
1274     */
1275    protected JComponent addPropComp(String propId, JComponent comp) {
1276        Object oldComp = propToComps.get(propId);
1277        if (oldComp != null) {
1278            throw new IllegalStateException(
1279                "Already have a component defined:" + propId);
1280        }
1281        propToComps.put(propId, comp);
1282        return comp;
1283    }
1284
1285    /**
1286     * Translate a place name into a human readable form
1287     *
1288     * @param thisPlace raw name
1289     *
1290     * @return human readable name
1291     */
1292    protected String translatePlace(String thisPlace) {
1293        if (thisPlace.equals("Upper Left")) {
1294            return PLACE_ULEFT;
1295        }
1296        if (thisPlace.equals("Center")) {
1297            return PLACE_CENTER;
1298        }
1299        return thisPlace;
1300    }
1301
1302    private void setNumberOfLines(int val) {
1303        numLinesFld.setText(Integer.toString(val));
1304    }
1305
1306    private void setNumberOfElements(int val) {
1307        numElementsFld.setText(Integer.toString(val));
1308    }
1309
1310    public String getPlace() {
1311        try {
1312            this.place = translatePlace((String)locationComboBox.getSelectedItem());
1313        } catch (Exception e) {
1314            this.place = defaultPlace;
1315        }
1316        return this.place;
1317    }
1318
1319    public void setPlace(String str) {
1320        if (str.equals("")) str = defaultPlace;
1321        this.place = str;
1322        if (str.equals(PLACE_CENTER))
1323            locationComboBox.setSelectedItem("Center");
1324        else
1325            locationComboBox.setSelectedItem("Upper Left");
1326    }
1327
1328    public int getNumLines() {
1329        int val = -1;
1330        try {
1331            val = Integer.parseInt(numLinesFld.getText().trim());
1332        } catch (Exception e) {
1333            logger.error("problem within getNumLines", e);
1334        }
1335        setNumLines(val);
1336        return this.numLines;
1337    }
1338
1339    public void setNumLines(int val) {
1340        this.numLines = val;
1341        if (val >= 0) setNumberOfLines(val);
1342    }
1343
1344    public int getNumEles() {
1345        int val = -1;
1346        try {
1347            val = Integer.parseInt(numElementsFld.getText().trim());
1348        } catch (Exception e) {
1349            logger.error("problem within getNumEles", e);
1350        }
1351        setNumEles(val);
1352        return this.numEles;
1353    }
1354
1355    public void setNumEles(int val) {
1356        val = (int)((double)val/4.0 + 0.5)*4;
1357        this.numEles = val;
1358        if (val >= 0) setNumberOfElements(val);
1359    }
1360
1361    public int getLine() {
1362        int val = -1;
1363        try {
1364            if (!(centerLineFld.getText().equals(Misc.MISSING)))
1365                val = Integer.parseInt(centerLineFld.getText().trim());
1366        } catch (Exception e) {
1367        }
1368        return val;
1369    }
1370
1371    protected void setLineElement() {
1372        double[][] el = getLineElement();
1373        String type = getCoordinateType();
1374        if (type.equals(TYPE_IMAGE)) {
1375            this.imageElement = (int)Math.floor(el[0][0] + 0.5);
1376            this.imageLine = (int)Math.floor(el[1][0] + 0.5);
1377            double[][] vals = this.areaNav.imageCoordToAreaCoord(el);
1378            this.areaElement = (int)Math.floor(vals[0][0] + 0.5);
1379            this.areaLine = (int)Math.floor(vals[1][0] + 0.5);
1380        } else {
1381            this.areaElement = (int)Math.floor(el[0][0] + 0.5);
1382            this.areaLine = (int)Math.floor(el[1][0] + 0.5);
1383            double[][] vals = this.areaNav.areaCoordToImageCoord(el);
1384            this.imageElement = (int)Math.floor(vals[0][0] + 0.5);
1385            this.imageLine = (int)Math.floor(vals[1][0] + 0.5);
1386        }
1387    }
1388
1389    public void setLine(int val) {
1390        if (val < 0)
1391            centerLineFld.setText(Misc.MISSING);
1392        else
1393            centerLineFld.setText(Integer.toString(val));
1394    }
1395
1396    public int getElement() {
1397        int val =-1;
1398        try {
1399            val = Integer.parseInt(centerElementFld.getText().trim());
1400        } catch (Exception e) {
1401        }
1402        return val;
1403    }
1404
1405    private double[][] getLineElement() {
1406        double[][] el = new double[2][1];
1407        el[0][0] = (double)getElement();
1408        el[1][0] = (double)getLine();
1409        return el;
1410    }
1411
1412    public void setElement(int val) {
1413        if (val < 0)
1414            centerElementFld.setText(Misc.MISSING);
1415        else
1416            centerElementFld.setText(Integer.toString(val));
1417    }
1418
1419    public int getLineMag() {
1420        return this.lineMag;
1421    }
1422
1423    private void setElementMag() {
1424        int val = 1;
1425        try {
1426            val = Integer.parseInt(eleMagFld.getText().trim());
1427        } catch (Exception e) {
1428            logger.error("problem setting element mag", e);
1429            return;
1430        }
1431        setElementMag(val);
1432    }
1433
1434    public void setLineMag(int val) {
1435        if (val > SLIDER_MAX) val = SLIDER_MAX;
1436        if (val < SLIDER_MIN-1) val = SLIDER_MIN-1;
1437        if (val == -1) val = 1;
1438        this.lineMag = val;
1439        setDLineMag((double)val);
1440    }
1441
1442    private void setLineMagSlider(int val) {
1443        if (val == 1) val = -1;
1444        if (val > SLIDER_MAX) val = -1;
1445        if (val < SLIDER_MIN) val = SLIDER_MIN-1;
1446        lineMagSlider.setValue(val + 1);
1447    }
1448
1449    public int getElementMag() {
1450        return this.elementMag;
1451    }
1452
1453    private void setLineMag() {
1454        int val = 1;
1455        try {
1456            val = Integer.parseInt(lineMagFld.getText().trim());
1457        } catch (Exception e) {
1458            logger.error("problem setting line mag", e);
1459        }
1460        setLineMag(val);
1461    }
1462
1463    public void setDLineMag(double val) {
1464        this.dLineMag = val;
1465    }
1466
1467    public double getDLineMag() {
1468        return this.dLineMag;
1469    }
1470
1471    public void setDElementMag(double val) {
1472        this.dElementMag = val;
1473    }
1474
1475    private void setElementMagSlider(int val) {
1476        if (val == 1) val = -1;
1477        if (val > SLIDER_MAX) val = -1;
1478        if (val < SLIDER_MIN) val = SLIDER_MIN-1;
1479        elementMagSlider.setValue(val + 1);
1480    }
1481
1482    public double getDElementMag() {
1483        return this.dElementMag;
1484    }
1485
1486    public void setElementMag(int val) {
1487        if (val > SLIDER_MAX) val = SLIDER_MAX;
1488        if (val < SLIDER_MIN-1) val = SLIDER_MIN-1;
1489        if (val == -1) val = 1;
1490        this.elementMag = val;
1491        setDElementMag((double)val);
1492    }
1493
1494    public double getLatitude() {
1495        double val = latLonWidget.getLat();
1496        if (Double.isNaN(val)) val = defaultLat;
1497        if (val < -90.0 || val > 90.0) val = defaultLat;
1498        setLatitude(val);
1499        return this.latitude;
1500    }
1501
1502    private void setLatitude() {
1503        this.latitude = latLonWidget.getLat();
1504    }
1505
1506    public void setLatitude(double val) {
1507        if (val < -90.0 || val > 90.0)
1508            val = defaultLat;
1509        latLonWidget.setLat(val);
1510        this.latitude = val;
1511        this.resetLatLon = false;
1512    }
1513
1514    private void setLongitude() {
1515        this.longitude = latLonWidget.getLon();
1516    }
1517
1518    public double getLongitude() {
1519        double val = latLonWidget.getLon();
1520        if (Double.isNaN(val)) val = defaultLon;
1521        if (val < -180.0 || val > 180.0) val = defaultLon;
1522        setLongitude(val);
1523        return this.longitude;
1524    }
1525
1526    public void setLongitude(double val) {
1527        if (val < -180.0 || val > 180.0)
1528            val = defaultLon;
1529        latLonWidget.setLon(val);
1530        this.longitude = val;
1531        this.resetLatLon = false;
1532    }
1533
1534    protected void convertToLineEle() {
1535        double[][] ll = new double[2][1];
1536        ll[0][0] = getLatitude();
1537        ll[1][0] = getLongitude();
1538        double[][] el = this.areaNav.toLinEle(ll);
1539        this.areaElement = (int)Math.floor(el[0][0] + 0.5);
1540        this.areaLine = (int)Math.floor(el[1][0] + 0.5);
1541        el = this.areaNav.areaCoordToImageCoord(el);
1542        this.imageElement = (int)Math.floor(el[0][0] + 0.5);
1543        this.imageLine = (int)Math.floor(el[1][0] + 0.5);
1544    }
1545
1546    protected void convertToLatLon() {
1547        double[][] el = getLineElement();
1548        double[][] ll = new double[2][1];
1549        String coordType = getCoordinateType();
1550        if (coordType.equals(TYPE_IMAGE))
1551            el = this.previewNav.imageCoordToAreaCoord(el);
1552
1553        try {
1554            AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1555            ll = macs.toReference(el);
1556            setLatitude(ll[0][0]);
1557            setLongitude(ll[1][0]);
1558            getGeoLocationInfo();
1559        } catch (Exception e) {
1560            logger.error("problem converting to latitude/longitude", e);
1561        }
1562    }
1563
1564    protected void convertToLatLon(int ele, int lin) {
1565        try {
1566            double[][] el = new double[2][1];
1567            double[][] ll = new double[2][1];
1568            AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1569            el[0][0] = (double)ele;
1570            el[1][0] = (double)lin;
1571            ll = macs.toReference(el);
1572            setLatitude(ll[0][0]);
1573            setLongitude(ll[1][0]);
1574            double[][] imageLE = new double[2][1];
1575            double[][] areaLE = new double[2][1];
1576            areaLE = this.previewNav.toLinEle(ll);
1577            imageLE = this.previewNav.areaCoordToImageCoord(areaLE);
1578            setCenterCoords((int)imageLE[0][0], (int)imageLE[1][0]);
1579            getGeoLocationInfo();
1580        } catch (Exception e) {
1581            logger.error("problem converting to latitude/longitude", e);
1582        }
1583    }
1584
1585    protected double[][] convertToDisplayCoords() {
1586        double[][] el = getLineElement();
1587        try {
1588            double[][] ll = new double[2][1];
1589            AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1590            String type = getCoordinateType();
1591            if (type.equals(TYPE_LATLON)) {
1592                ll[0][0] = getLatitude();
1593                ll[1][0] = getLongitude();
1594                el = macs.fromReference(ll);
1595            } else {
1596                int[] dirB = macs.getDirBlock();
1597                int previewLineMag = dirB[11];
1598                int previewEleMag = dirB[12];
1599                int dirLMag = this.previewDir.getValue(11);
1600                int dirEMag = this.previewDir.getValue(12);
1601                if (type.equals(TYPE_IMAGE))
1602                    el = this.areaNav.imageCoordToAreaCoord(el);
1603                Rectangle2D mapArea = macs.getDefaultMapArea();
1604                int previewXDim = new Long(new Double(mapArea.getMaxX() - mapArea.getMinX()).longValue()).intValue();
1605                int previewYDim = new Long(new Double(mapArea.getMaxY() - mapArea.getMinY()).longValue()).intValue();
1606                el[0][0] = el[0][0] * dirEMag / previewEleMag;
1607                el[1][0] = previewYDim - 1 - el[1][0] * dirLMag / previewLineMag;;
1608            }
1609        } catch (Exception e) {
1610            logger.error("problem converting to display coordinates", e);
1611        }
1612        return el;
1613    }
1614
1615    private double[][] displayCoordToAreaCoord(double[][] disp) {
1616        double[][] area = new double[2][disp[0].length];
1617        try {
1618            if (sampleProjection != null) {
1619                AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1620                double[][] ll = macs.toReference(disp);
1621                double[][] el = this.areaNav.toLinEle(ll);
1622                int midEle = (int)Math.floor(el[0][0] + 0.5);
1623                int midLin = (int)Math.floor(el[1][0] + 0.5);
1624
1625                int width = (int)Math.floor(Math.abs(disp[0][2] - disp[0][1])
1626                            * getPreviewEleRes() + 0.5);
1627
1628                int height = (int)Math.floor(Math.abs(disp[1][3] - disp[1][1]) 
1629                            * getPreviewLineRes() + 0.5);
1630                int deltaEle = width/2;
1631                int deltaLin = height/2;
1632
1633                area[0][0] = midEle;
1634                area[1][0] = midLin;
1635                area[0][1] = midEle - deltaEle;
1636                area[1][1] = midLin - deltaLin;
1637                area[0][2] = midEle + deltaEle;
1638                area[1][2] = midLin - deltaLin;
1639                area[0][3] = midEle - deltaEle;
1640                area[1][3] = midLin + deltaLin;
1641                area[0][4] = midEle + deltaEle;
1642                area[1][4] = midLin + deltaLin;
1643
1644            }
1645        } catch (Exception e) {
1646            logger.error("problem converting display coordinates to area coordinates", e);
1647        }
1648        return area;
1649    }
1650
1651    private double[][] areaCoordToDisplayCoord(double[][] area) {
1652        double[][] disp = new double[2][area[0].length];
1653        try {
1654            if (sampleProjection != null) {
1655                AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1656                int[] dirB = macs.getDirBlock();
1657                int previewLineMag = dirB[11];
1658                int previewEleMag = dirB[12];
1659                Rectangle2D mapArea = macs.getDefaultMapArea();
1660                int previewXDim = new Long(new Double(mapArea.getMaxX() - mapArea.getMinX()).longValue()).intValue();
1661                int previewYDim = new Long(new Double(mapArea.getMaxY() - mapArea.getMinY()).longValue()).intValue();
1662                for (int i=0; i<area[0].length; i++) {
1663                    disp[0][i] = area[0][i] / previewEleMag;
1664                    disp[1][i] = previewYDim - 1 - area[1][i] / previewLineMag;
1665                }
1666            }
1667        } catch (Exception e) {
1668            logger.error("problem converting area coordinates to display coordinates", e);
1669        }
1670        return disp;
1671    }
1672
1673    protected void convertToLinEle() {
1674        try {
1675            double[][] el = new double[2][1];
1676            double[][] ll = new double[2][1];
1677            AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
1678            ll[0][0] = getLatitude();
1679            ll[1][0] = getLongitude();
1680            String coordType = getCoordinateType();
1681            el = this.previewNav.toLinEle(ll);
1682            if (coordType.equals(TYPE_IMAGE))
1683                el = this.previewNav.areaCoordToImageCoord(el);
1684            setLine((int)el[1][0]);
1685            setElement((int)el[0][0]);
1686            getGeoLocationInfo();
1687        } catch (Exception e) {
1688            logger.error("problem converting to lines/elements", e);
1689        }
1690    }
1691
1692    public String getCoordinateType() {
1693        String ret = defaultType;
1694        try {
1695            ret = (String)coordinateTypeComboBox.getSelectedItem();
1696        } catch (Exception e) {
1697        }
1698        return ret;
1699    }
1700
1701    protected void setCoordinateType(String type) {
1702        if (!type.equals(TYPE_IMAGE)) {
1703            if (!type.equals(TYPE_AREA)) {
1704                type = TYPE_LATLON;
1705            }
1706        }
1707        coordinateTypeComboBox.setSelectedItem(type);
1708    }
1709
1710    protected void setLockOn(boolean val) {
1711        lockBtn.setSelected(val);
1712    }
1713
1714    public boolean getLockOn() {
1715        return lockBtn.isSelected();
1716    }
1717 
1718    protected void setCenterCoords(int x, int y) {
1719        setLine(y);
1720        setElement(x);
1721    }
1722
1723    protected void elementMagSliderChanged(boolean recomputeLineEleRatio) {
1724        int value = getElementMag();
1725        if (!amUpdating) {
1726          value = getElementMagValue();
1727          setElementMag(value);
1728        }
1729        if ((Math.abs(value) < SLIDER_MAX)) {
1730            int lineMag = getLineMagValue();
1731            if (lineMag > value) {
1732                linesToElements = Math.abs(lineMag
1733                                           / (double) value);
1734            } else {
1735                linesToElements = Math.abs((double) value
1736                                           / lineMag);
1737            }
1738        }
1739        elementMagLbl.setText("Ele  Mag=");
1740        eleMagFld.setText(new Integer(value).toString());
1741        String str = " Res=" +
1742            truncateNumericString(Double.toString(this.baseERes*Math.abs(value)), 1);
1743        elementResLbl.setText(StringUtil.padLeft(str, 4) + kmLbl);
1744
1745        if (!lockBtn.isSelected()) {
1746            if (value > 0) {
1747                setNumberOfElements((int)(this.baseNumElements * value));
1748            } else {
1749                setNumberOfElements((int)(this.baseNumElements
1750                                                / (double) -value));
1751            }
1752        }
1753    }
1754
1755    private void changeLineMagSlider(boolean autoSetSize) {
1756        int value = getLineMag();
1757        setLineMagSlider(value);
1758    }
1759
1760    private void changeEleMagSlider(boolean autoSetSize) {
1761        int value = getElementMag();
1762        setElementMagSlider(value);
1763    }
1764
1765    /**
1766     * Handle the line mag slider changed event.
1767     *
1768     * @param autoSetSize Whether or not the size is automatically set.
1769     */
1770    protected void lineMagSliderChanged(boolean autoSetSize) {
1771        try {
1772            int value = getLineMag();
1773            if (!amUpdating) {
1774                value = getLineMagValue();
1775                setLineMag(value);
1776            }
1777            lineMagLbl.setText("Line Mag=");
1778            lineMagFld.setText(new Integer(value).toString());
1779            String str = " Res=" +
1780                truncateNumericString(Double.toString(this.baseLRes*Math.abs(value)), 1);
1781            lineResLbl.setText(StringUtil.padLeft(str, 4) + kmLbl);
1782
1783            if (autoSetSize) {
1784                if (value > 0) {
1785                    setNumberOfLines((int)(this.baseNumLines * value));
1786                } else {
1787                    setNumberOfLines((int)(this.baseNumLines
1788                                                    / (double) -value));
1789                }
1790            }
1791
1792            if (value == 1) {                     // special case
1793                if (linesToElements < 1.0) {
1794                    value = (int) (-value / linesToElements);
1795                } else {
1796                    value = (int) (value * linesToElements);
1797                }
1798            } else if (value > 1) {
1799                value = (int) (value * linesToElements);
1800            } else {
1801                value = (int) (value / linesToElements);
1802            }
1803
1804            amSettingProperties = true;
1805            setElementMag(value);
1806            setElementMagSlider(value);
1807            amSettingProperties = false;
1808            elementMagSliderChanged(false);
1809        } catch (Exception exc) {
1810            logger.error("could not set line magnifiction", exc);
1811        }
1812    }
1813
1814    /**
1815     * Get the value of the line magnification slider.
1816     *
1817     * @return The magnification value for the line
1818     */
1819    protected int getLineMagValue() {
1820        int val = getMagValue(lineMagSlider);
1821        return val;
1822    }
1823
1824    /**
1825     * Get the value of the element magnification slider.
1826     *
1827     * @return The magnification value for the element
1828     */
1829    protected int getElementMagValue() {
1830        int val = getMagValue(elementMagSlider) - 1;
1831        setElementMag(val);
1832        return val;
1833    }
1834
1835    /**
1836     * Get the value of the given  magnification slider.
1837     *
1838     * @param slider The slider to get the value from
1839     * @return The magnification value
1840     */
1841    private int getMagValue(JSlider slider) {
1842        //Value is [-SLIDER_MAX,SLIDER_MAX]. We change 0 and -1 to 1
1843        int value = slider.getValue();
1844        if (value == 0) {
1845            value = SLIDER_MAX;
1846            return value;
1847        } else if (value < SLIDER_MIN) {
1848            value = SLIDER_MIN;
1849        }
1850        return value - 1;
1851    }
1852
1853    /**
1854     * Create a menu item based upon a given location.
1855     *
1856     * @param llp Location to use in the resulting menu item. Cannot be
1857     * {@code null}.
1858     * @param name Name of {@code location}. Cannot be {@code null}.
1859     *
1860     * @return Menu item based on {@code llp} and {@code name}.
1861     */
1862    private JMenuItem makeLocationMenuItem(final LatLonPoint llp,
1863                                           final String name) {
1864        JMenuItem mi = null;
1865        try {
1866            double alt = 0.0;
1867            EarthLocationTuple elt = 
1868                new EarthLocationTuple(llp.getLatitude(), llp.getLongitude(), alt);
1869            mi =
1870            new JMenuItem(
1871                StringUtil.padRight(name + ": ", 15, " ")
1872                + dataSource.getDataContext().getIdv().getDisplayConventions()
1873                .formatLatLonPoint(elt.getLatLonPoint()));
1874            GuiUtils.setFixedWidthFont(mi);
1875        } catch (Exception e) {
1876            logger.error("could not create location menu item", e);
1877        }
1878        return mi;
1879    }
1880
1881    public boolean getIsLineEle() {
1882        return this.isLineEle;
1883    }
1884
1885    public void setIsLineEle(boolean val) {
1886        this.isLineEle = val;
1887    }
1888
1889
1890    public double getLRes() {
1891        return this.lRes;
1892    }
1893
1894    public void setLRes(double val) {
1895        if (val < 1) val = this.baseLRes;
1896        this.lRes = val;
1897    }
1898
1899    public void setBLRes(double val) {
1900        this.bLRes = val;
1901    }
1902
1903    public void setBERes(double val) {
1904        this.bERes = val;
1905    }
1906
1907    public double getBLRes() {
1908        return this.bLRes;
1909    }
1910
1911    public double getBERes() {
1912        return this.bERes;
1913    }
1914
1915    public double getERes() {
1916        return this.eRes;
1917    }
1918
1919    public void setERes(double val) {
1920        if (val < 1) val = this.baseERes;
1921        this.eRes = val;
1922    }
1923
1924    public int getPreviewLineRes() {
1925        return this.previewLineRes;
1926    }
1927
1928    public void setPreviewLineRes(int val) {
1929        this.previewLineRes = val;
1930    }
1931
1932    public int getPreviewEleRes() {
1933        return this.previewEleRes;
1934    }
1935
1936    public void setPreviewEleRes(int val) {
1937        this.previewEleRes = val;
1938    }
1939
1940    private String truncateNumericString(String str, int numDec) {
1941        int indx = str.indexOf(".") + numDec + 1;
1942        if (indx >= str.length()) indx = str.length();
1943        return str.substring(0,indx);
1944    }
1945    
1946    public String getLatLonType() {
1947        return TYPE_LATLON;
1948    }
1949
1950    protected double[][] getLatLonPoints() {
1951        return latLon;
1952    }
1953
1954    protected double[][] getImagePoints() {
1955        return imageEL;
1956    }
1957
1958    protected double[][] getAreaPoints() {
1959        return areaEL;
1960    }
1961
1962    protected double[][] getDisplayELPoints() {
1963        return displayEL;
1964    }
1965
1966    protected double getBaseLRes() {
1967        return this.baseLRes;
1968    }
1969
1970    protected double getBaseERes() {
1971        return this.baseERes;
1972    }
1973
1974    protected void setBaseNumLines(int val) {
1975        this.baseNumLines = (double)val;
1976    }
1977
1978    public void setDataChoice(DataChoice choice) {
1979        logger.trace("oldChoice={} newChoice={}", this.dataChoice, choice);
1980        this.dataChoice = choice;
1981    }
1982
1983    public DataChoice getDataChoice() {
1984        return this.dataChoice;
1985    }
1986    
1987    protected void setBaseNumElements(int val) {
1988        this.baseNumElements = (double)val;
1989    }
1990
1991    public void update(AreaDirectory dir, MapProjection sample, AREAnav nav, 
1992                          String coordType, double[] coords) {
1993        boolean saveLock = getLockOn();
1994        setLockOn(true);
1995        this.maxLines = dir.getLines();
1996        this.maxEles = dir.getElements();
1997        sampleProjection = sample;
1998
1999        double baseLResOld = getBaseLRes();
2000        double baseEResOld = getBaseERes();
2001        double lDMagOld = getDLineMag();
2002        double eDMagOld = getDElementMag();
2003        int lMagOld = getLineMag();
2004        int eMagOld = getElementMag();
2005        int lSizeOld = getNumLines();
2006        int eSizeOld = getNumEles();
2007        
2008        double baseLResNew = getBLRes();
2009        double baseEResNew = getBERes();
2010        try {
2011            baseLResNew *= (double)(dir.getValue(11));
2012            baseEResNew *= (double)(dir.getValue(12));
2013        } catch (Exception e) {
2014        }
2015
2016        double lDMagNew = lDMagOld * baseLResOld / baseLResNew;
2017        int lMagNew = (int)Math.ceil(lDMagNew - 0.5);
2018        if (lMagNew > -2) lMagNew = 1;
2019        double eDMagNew = eDMagOld * baseEResOld / baseEResNew;
2020        int eMagNew = (int)Math.ceil(eDMagNew - 0.5);
2021        if (eMagNew > -2) eMagNew = 1;
2022
2023        double lResOld = Math.abs(lMagOld) * baseLResOld;
2024        double eResOld = Math.abs(eMagOld) * baseEResOld;
2025        double lResNew = Math.abs(lMagNew) * baseLResNew;
2026        double eResNew = Math.abs(eMagNew) * baseEResNew;
2027
2028        int lSizeNew = (int)Math.floor(((double)lSizeOld * lResOld / lResNew) + 0.5);
2029        if (lSizeNew > this.maxLines) lSizeNew = this.maxLines;
2030        int eSizeNew = (int)Math.floor(((double)eSizeOld * eResOld / eResNew) + 0.5);
2031        if (eSizeNew > this.maxEles) eSizeNew = this.maxEles;        
2032        setNumLines(lSizeNew);
2033        setNumEles(eSizeNew);
2034        
2035        this.baseLRes = baseLResNew;
2036        this.baseERes = baseEResNew;
2037
2038        amUpdating = true;
2039        amSettingProperties = true;
2040        int newVal = 0;
2041        try {
2042            this.defaultLineMag = lMagNew;
2043            setLRes(lResNew);
2044            newVal = lMagNew;
2045            if (newVal > -2)  newVal = 1;
2046            setLineMag(newVal);
2047            changeLineMagSlider(!lockBtn.isSelected());
2048        } catch (Exception e) {
2049            logger.error("error adjusting line mag slider", e);
2050        }
2051
2052        try {
2053            this.defaultElementMag = eMagNew;
2054            setERes(eResNew);
2055            newVal = eMagNew;
2056            if (newVal > -2) newVal = 1;
2057        } catch (Exception e) {
2058            logger.error("error adjusting element mag slider", e);
2059        }
2060        amUpdating = false;
2061        amSettingProperties = false;
2062
2063        int ele = 0;
2064        AREACoordinateSystem macs = (AREACoordinateSystem)sampleProjection;
2065        Rectangle2D mapArea = macs.getDefaultMapArea();
2066        double previewYDim = mapArea.getHeight();
2067        int line = (int)Math.floor(previewYDim);
2068        try {
2069            int lat = (int)Math.floor(getLatitude() + 0.5);
2070            if ((lat <= 90.0) && (lat >= -90.0)) {
2071                double[][] ll = new double[2][1];
2072                ll[0][0] = lat;
2073                ll[1][0] = getLongitude();
2074                double[][] el = sample.fromReference(ll);
2075                ele = (int)Math.floor(el[0][0] + 0.5);
2076                line = (int)Math.floor(el[1][0] + 0.5);
2077            }
2078            this.areaNav = nav;
2079            int areaLinRes = dir.getValue(11);
2080            int areaEleRes = dir.getValue(12);
2081            int startLine = dir.getValue(5);
2082            int startEle = dir.getValue(6);
2083            this.previewDir = dir;
2084            this.areaNav = this.previewNav;
2085            this.areaNav.setRes(areaLinRes, areaEleRes);
2086            this.areaNav.setImageStart(startLine, startEle);
2087            
2088            setCoordinateType(coordType);
2089            if (coordType.equals(TYPE_LATLON)) {
2090                setLatitude(coords[0]);
2091                setLongitude(coords[1]);
2092                convertToLineEle();
2093            } else if (coordType.equals(TYPE_AREA)) {
2094                double dCoord = coords[0] * baseLResOld/baseLResNew;
2095                setLine((int)Math.floor(dCoord+0.5));
2096                dCoord = coords[1] * baseEResOld/baseEResNew;
2097                setElement((int)Math.floor(dCoord+0.5));
2098                setLineElement();
2099                convertToLatLon();
2100            }
2101
2102        } catch (Exception e) {
2103            logger.error("error updating", e);
2104        }
2105
2106        try {
2107            rawSizeLbl.setText(" Raw size: " + this.maxLines + " X " + this.maxEles);
2108        } catch (Exception e) {
2109            logger.error("could not update raw size", e);
2110        }
2111
2112        amUpdating = true;
2113        lineMagSliderChanged(false);
2114        setElementMag(newVal);
2115        elementMagSliderChanged(false);
2116        amUpdating = false;
2117        changeEleMagSlider(!lockBtn.isSelected());
2118        setLockOn(saveLock);
2119        getGeoLocationInfo(line, ele);
2120    }
2121}