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