14#include <QStackedWidget> 
   16#include <QTableWidget> 
   19#include "QnetDeletePointDialog.h" 
   20#include "QnetNewMeasureDialog.h" 
   21#include "NewControlPointDialog.h" 
   22#include "QnetFixedPointDialog.h" 
   25#include "Application.h" 
   28#include "CameraFactory.h" 
   29#include "ControlMeasure.h" 
   30#include "ControlMeasureLogData.h" 
   31#include "ControlNet.h" 
   32#include "ControlPoint.h" 
   33#include "ControlPointEdit.h" 
   36#include "IException.h" 
   39#include "MainWindow.h" 
   40#include "MdiCubeViewport.h" 
   41#include "Projection.h" 
   42#include "ProjectionFactory.h" 
   44#include "PvlEditDialog.h" 
   45#include "SerialNumber.h" 
   46#include "SpecialPixel.h" 
   48#include "SurfacePoint.h" 
   51#include "UniversalGroundMap.h" 
   52#include "ViewportMainWindow.h" 
   71    m_serialNumberList = NULL;
 
   72    m_templateModified = 
false;
 
   77    if (qobject_cast<Workspace *>(parent)) {
 
   78      m_workspace = qobject_cast<Workspace *>(parent);
 
   80    else if (qobject_cast<ViewportMainWindow *>(parent)) {
 
   81      m_workspace = qobject_cast<ViewportMainWindow *>(parent)->workspace();
 
   85          tr(
"Could not find the workspace with the given parent, expected a Workspace or " 
   86             "ViewportMainWindow."),
 
 
   94  QnetTool::~QnetTool () {
 
   99    delete m_rightMeasure;
 
  100    delete m_measureTable;
 
  101    delete m_measureWindow;
 
  133    m_qnetTool = 
new MainWindow(
"Qnet Tool", parent);
 
  134    m_qnetTool->setObjectName(
"QnetTool");
 
  143    connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
 
  144        m_pointEditor, SIGNAL(newControlNetwork(
ControlNet *)));
 
  150    connect(
this, SIGNAL(measureChanged()),
 
  153    QPushButton *
addMeasure = 
new QPushButton(
"Add Measure(s) to Point");
 
  155    addMeasure->setToolTip(
"Add a new measure to the edit control point. " 
  156                           "<strong>Shortcut: A</strong>");
 
  157    addMeasure->setWhatsThis(
"This allows a new control measure to be added " 
  158                         "to the currently edited control point.  A selection " 
  159                         "box with all cubes from the input list will be " 
  160                         "displayed with those that intersect with the " 
  161                         "control point highlighted.");
 
  164    m_savePoint = 
new QPushButton (
"Save Point");
 
  165    m_savePoint->setShortcut(Qt::Key_P);
 
  166    m_savePoint->setToolTip(
"Save the edit control point to the control network. " 
  167                            "<strong>Shortcut: P</strong>");
 
  168    m_savePoint->setWhatsThis(
"Save the edit control point to the control " 
  169                    "network which is loaded into memory in its entirety. " 
  170                    "When a control point is selected for editing, " 
  171                    "a copy of the point is made so that the original control " 
  172                    "point remains in the network.");
 
  173    m_saveDefaultPalette = m_savePoint->palette();
 
  174    connect (m_savePoint,SIGNAL(clicked()),
this,SLOT(
savePoint()));
 
  176    QHBoxLayout * addMeasureLayout = 
new QHBoxLayout;
 
  178    addMeasureLayout->addWidget(m_savePoint);
 
  181    m_templateFileNameLabel = 
new QLabel(
"Template File: " +
 
  182        m_pointEditor->templateFileName());
 
  183    m_templateFileNameLabel->setToolTip(
"Sub-pixel registration template File.");
 
  187    m_templateFileNameLabel->setWhatsThis(
"FileName of the sub-pixel " 
  188                  "registration template.  Refer to $ISISROOT/doc/documents/" 
  189                  "PatternMatch/PatternMatch.html for a description of the " 
  190                  "contents of this file.");
 
  192    m_groundFileNameLabel = 
new QLabel(
"Ground Source File: ");
 
  193    m_groundFileNameLabel->setToolTip(
"Cube used to create ground control " 
  194                               "points, either Fixed or Constrained.");
 
  195    m_groundFileNameLabel->setWhatsThis(
"This cube is used to create ground " 
  196                             "control points, Fixed or Constrained.  This may " 
  197                             "be a Dem, a shaded relief version of a Dem, " 
  198                             "a projected basemap or an unprojected cube with " 
  199                             "corrected camera pointing.  This will be used " 
  200                             "to set the apriori latitude, longitude.");
 
  201    m_radiusFileNameLabel = 
new QLabel(
"Radius Source: ");
 
  202    m_radiusFileNameLabel->setToolTip(
"Dem used to set the radius of ground " 
  203                             "control points, Fixed or Constrained.  This must " 
  204                             "be a Dem and is strictly used to set the apriori " 
  205                             "radius for ground control points.");
 
  207    QVBoxLayout * centralLayout = 
new QVBoxLayout;
 
  209    centralLayout->addWidget(m_templateFileNameLabel);
 
  210    centralLayout->addWidget(m_groundFileNameLabel);
 
  211    centralLayout->addWidget(m_radiusFileNameLabel);
 
  213    centralLayout->addStretch();
 
  214    centralLayout->addWidget(m_pointEditor);
 
  215    centralLayout->addLayout(addMeasureLayout);
 
  217    centralWidget->setLayout(centralLayout);
 
  219    QScrollArea *scrollArea = 
new QScrollArea();
 
  220    scrollArea->setObjectName(
"QnetToolScroll");
 
  221    scrollArea->setWidget(centralWidget);
 
  222    scrollArea->setWidgetResizable(
true);
 
  223    centralWidget->adjustSize();
 
  224    m_qnetTool->setCentralWidget(scrollArea);
 
  228    connect(
this, SIGNAL(editPointChanged(QString)),
 
 
  238    QHBoxLayout * measureLayout = 
new QHBoxLayout;
 
  242    QVBoxLayout * groupBoxesLayout = 
new QVBoxLayout;
 
  244    groupBoxesLayout->addStretch();
 
  245    groupBoxesLayout->addLayout(measureLayout);
 
  248    groupBoxesWidget->setLayout(groupBoxesLayout);
 
  252    QSplitter * topSplitter = 
new QSplitter;
 
  253    topSplitter->addWidget(groupBoxesWidget);
 
  254    topSplitter->addWidget(m_templateEditorWidget);
 
  255    topSplitter->setStretchFactor(0, 4);
 
  256    topSplitter->setStretchFactor(1, 3);
 
  258    m_templateEditorWidget->hide();
 
 
  268    m_ptIdValue = 
new QLabel;
 
  270    for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
 
  274    QHBoxLayout *pointTypeLayout = 
new QHBoxLayout;
 
  275    QLabel *pointTypeLabel = 
new QLabel(
"PointType:");
 
  276    pointTypeLayout->addWidget(pointTypeLabel);
 
  277    pointTypeLayout->addWidget(m_pointType);
 
  278    connect(m_pointType, SIGNAL(activated(
int)),
 
  280    m_numMeasures = 
new QLabel;
 
  281    m_pointAprioriLatitude = 
new QLabel;
 
  282    m_pointAprioriLongitude = 
new QLabel;
 
  283    m_pointAprioriRadius = 
new QLabel;
 
  284    m_pointAprioriLatitudeSigma = 
new QLabel;
 
  285    m_pointAprioriLongitudeSigma = 
new QLabel;
 
  286    m_pointAprioriRadiusSigma = 
new QLabel;
 
  287    QVBoxLayout * leftLayout = 
new QVBoxLayout;
 
  288    leftLayout->addWidget(m_ptIdValue);
 
  289    leftLayout->addLayout(pointTypeLayout);
 
  290    leftLayout->addWidget(m_pointAprioriLatitude);
 
  291    leftLayout->addWidget(m_pointAprioriLongitude);
 
  292    leftLayout->addWidget(m_pointAprioriRadius);
 
  293    leftLayout->addWidget(m_pointAprioriLatitudeSigma);
 
  294    leftLayout->addWidget(m_pointAprioriLongitudeSigma);
 
  295    leftLayout->addWidget(m_pointAprioriRadiusSigma);
 
  298    m_lockPoint = 
new QCheckBox(
"Edit Lock Point");
 
  299    connect(m_lockPoint, SIGNAL(clicked(
bool)), 
this, SLOT(
setLockPoint(
bool)));
 
  300    m_ignorePoint = 
new QCheckBox(
"Ignore Point");
 
  301    connect(m_ignorePoint, SIGNAL(clicked(
bool)),
 
  303    connect(
this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
 
  304    m_pointLatitude = 
new QLabel;
 
  305    m_pointLongitude = 
new QLabel;
 
  306    m_pointRadius = 
new QLabel;
 
  308    QVBoxLayout * rightLayout = 
new QVBoxLayout;
 
  309    rightLayout->addWidget(m_numMeasures);
 
  310    rightLayout->addWidget(m_lockPoint);
 
  311    rightLayout->addWidget(m_ignorePoint);
 
  312    rightLayout->addWidget(m_pointLatitude);
 
  313    rightLayout->addWidget(m_pointLongitude);
 
  314    rightLayout->addWidget(m_pointRadius);
 
  317    QHBoxLayout * mainLayout = 
new QHBoxLayout;
 
  318    mainLayout->addLayout(leftLayout);
 
  319    mainLayout->addStretch();
 
  320    mainLayout->addLayout(rightLayout);
 
  323    QGroupBox * groupBox = 
new QGroupBox(
"Control Point");
 
  324    groupBox->setLayout(mainLayout);
 
 
  334    m_leftCombo->setEditable(
true);
 
  335    m_leftCombo->setInsertPolicy(QComboBox::NoInsert);
 
  336    m_leftCombo->setToolTip(
"Choose left control measure");
 
  337    m_leftCombo->setWhatsThis(
"Choose left control measure identified by " 
  339    connect(m_leftCombo, SIGNAL(activated(
int)),
 
  341    m_lockLeftMeasure = 
new QCheckBox(
"Edit Lock Measure");
 
  342    connect(m_lockLeftMeasure, SIGNAL(clicked(
bool)),
 
  344    m_ignoreLeftMeasure = 
new QCheckBox(
"Ignore Measure");
 
  345    connect(m_ignoreLeftMeasure, SIGNAL(clicked(
bool)),
 
  347    connect(
this, SIGNAL(ignoreLeftChanged()),
 
  348            m_ignoreLeftMeasure, SLOT(toggle()));
 
  349    m_leftReference = 
new QLabel();
 
  350    m_leftMeasureType = 
new QLabel();
 
  351    m_leftSampError = 
new QLabel();
 
  352    m_leftSampError->setToolTip(
"<strong>Jigsaw</strong> sample residual.");
 
  353    m_leftSampError->setWhatsThis(
"This is the sample residual for the left " 
  354                          "measure calculated by the application, " 
  355                          "<strong>jigsaw</strong>.");
 
  356    m_leftLineError = 
new QLabel();
 
  357    m_leftLineError->setToolTip(
"<strong>Jigsaw</strong> line residual.");
 
  358    m_leftLineError->setWhatsThis(
"This is the line residual for the left " 
  359                          "measure calculated by the application, " 
  360                          "<strong>jigsaw</strong>.");
 
  361    m_leftSampShift = 
new QLabel();
 
  362    m_leftSampShift->setToolTip(
"Sample shift between apriori and current");
 
  363    m_leftSampShift->setWhatsThis(
"The shift between the apriori sample and " 
  364                           "the current sample.  The apriori sample is set " 
  365                           "when creating a new measure.");
 
  366    m_leftLineShift = 
new QLabel();
 
  367    m_leftLineShift->setToolTip(
"Line shift between apriori and current");
 
  368    m_leftLineShift->setWhatsThis(
"The shift between the apriori line and " 
  369                           "the current line.  The apriori line is set " 
  370                           "when creating a new measure.");
 
  371    m_leftGoodness = 
new QLabel();
 
  372    m_leftGoodness->setToolTip(
"Goodness of Fit result from sub-pixel " 
  374    m_leftGoodness->setWhatsThis(
"Resulting Goodness of Fit from sub-pixel " 
  376    QVBoxLayout * leftLayout = 
new QVBoxLayout;
 
  377    leftLayout->addWidget(m_leftCombo);
 
  378    leftLayout->addWidget(m_lockLeftMeasure);
 
  379    leftLayout->addWidget(m_ignoreLeftMeasure);
 
  380    leftLayout->addWidget(m_leftReference);
 
  381    leftLayout->addWidget(m_leftMeasureType);
 
  382    leftLayout->addWidget(m_leftSampError);
 
  383    leftLayout->addWidget(m_leftLineError);
 
  384    leftLayout->addWidget(m_leftSampShift);
 
  385    leftLayout->addWidget(m_leftLineShift);
 
  386    leftLayout->addWidget(m_leftGoodness);
 
  388    QGroupBox * leftGroupBox = 
new QGroupBox(
"Left Measure");
 
  389    leftGroupBox->setLayout(leftLayout);
 
 
  408    m_rightCombo->setEditable(
true);
 
  409    m_rightCombo->setInsertPolicy(QComboBox::NoInsert);
 
  413    QShortcut *nextMeasure = 
new QShortcut(Qt::Key_PageDown, m_qnetTool);
 
  415    QShortcut *prevMeasure = 
new QShortcut(Qt::Key_PageUp, m_qnetTool);
 
  418    m_rightCombo->setToolTip(
"Choose right control measure. " 
  419                             "<strong>Shortcuts: PageUp/PageDown</strong>");
 
  420    m_rightCombo->setWhatsThis(
"Choose right control measure identified by " 
  422                               "Note: PageUp selects previous measure; " 
  423                               "PageDown selects next meausure.");
 
  424    connect(m_rightCombo, SIGNAL(activated(
int)),
 
  426    m_lockRightMeasure = 
new QCheckBox(
"Edit Lock Measure");
 
  427    connect(m_lockRightMeasure, SIGNAL(clicked(
bool)),
 
  429    m_ignoreRightMeasure = 
new QCheckBox(
"Ignore Measure");
 
  430    connect(m_ignoreRightMeasure, SIGNAL(clicked(
bool)),
 
  432    connect(
this, SIGNAL(ignoreRightChanged()),
 
  433            m_ignoreRightMeasure, SLOT(toggle()));
 
  434    m_rightReference = 
new QLabel();
 
  435    m_rightMeasureType = 
new QLabel();
 
  436    m_rightSampError = 
new QLabel();
 
  437    m_rightSampError->setToolTip(
"<strong>Jigsaw</strong> sample residual.");
 
  438    m_rightSampError->setWhatsThis(
"This is the sample residual for the right " 
  439                          "measure which was calculated by the application, " 
  440                          "<strong>jigsaw</strong>.");
 
  441    m_rightLineError = 
new QLabel();
 
  442    m_rightLineError->setToolTip(
"<strong>Jigsaw</strong> line residual.");
 
  443    m_rightLineError->setWhatsThis(
"This is the line residual for the right " 
  444                          "measure which was calculated by the application, " 
  445                          "<strong>jigsaw</strong>.");
 
  446    m_rightSampShift = 
new QLabel();
 
  447    m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
 
  448    m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
 
  449    m_rightLineShift = 
new QLabel();
 
  450    m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
 
  451    m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
 
  452    m_rightGoodness = 
new QLabel();
 
  453    m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
 
  454    m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
 
  457    QVBoxLayout * rightLayout = 
new QVBoxLayout;
 
  458    rightLayout->addWidget(m_rightCombo);
 
  459    rightLayout->addWidget(m_lockRightMeasure);
 
  460    rightLayout->addWidget(m_ignoreRightMeasure);
 
  461    rightLayout->addWidget(m_rightReference);
 
  462    rightLayout->addWidget(m_rightMeasureType);
 
  463    rightLayout->addWidget(m_rightSampError);
 
  464    rightLayout->addWidget(m_rightLineError);
 
  465    rightLayout->addWidget(m_rightSampShift);
 
  466    rightLayout->addWidget(m_rightLineShift);
 
  467    rightLayout->addWidget(m_rightGoodness);
 
  469    QGroupBox * rightGroupBox = 
new QGroupBox(
"Right Measure");
 
  470    rightGroupBox->setLayout(rightLayout);
 
  472    return rightGroupBox;
 
 
  481    toolBar->addAction(m_openTemplateFile);
 
  482    toolBar->addSeparator();
 
  483    toolBar->addAction(m_saveTemplateFile);
 
  484    toolBar->addAction(m_saveTemplateFileAs);
 
  486    m_templateEditor = 
new QTextEdit;
 
  487    connect(m_templateEditor, SIGNAL(textChanged()), 
this,
 
  490    QVBoxLayout *mainLayout = 
new QVBoxLayout;
 
  491    mainLayout->addWidget(toolBar);
 
  492    mainLayout->addWidget(m_templateEditor);
 
  494    m_templateEditorWidget = 
new QWidget;
 
  495    m_templateEditorWidget->setLayout(mainLayout);
 
 
  508    m_openGround = 
new QAction(m_qnetTool);
 
  509    m_openGround->setText(
"Open &Ground Source");
 
  510    m_openGround->setToolTip(
"Open a ground source for choosing ground control " 
  512    m_openGround->setStatusTip(
"Open a ground source for choosing ground " 
  515      "<b>Function:</b> Open and display a ground source for choosing " 
  516      "ground control points, both Fixed and Constrained." 
  517      "This cube can be a level1, level2 or dem cube.";
 
  518    m_openGround->setWhatsThis(whatsThis);
 
  519    connect (m_openGround,SIGNAL(triggered()),
this,SLOT(
openGround()));
 
  521    m_openDem = 
new QAction(m_qnetTool);
 
  522    m_openDem->setText(
"Open &Radius Source");
 
  523    m_openDem->setToolTip(
"Open radius source file for ground control points");
 
  524    m_openDem->setStatusTip(
"Open radius source file for ground control points");
 
  526      "<b>Function:</b> Open a DEM for determining the radius when " 
  527      "choosing ground control points.  This is not the file that will be " 
  528      "displayed for visually picking points.  This is strictly used to " 
  529      "determine the radius value for ground control points.";
 
  530    m_openDem->setWhatsThis(whatsThis);
 
  531    connect (m_openDem,SIGNAL(triggered()),
this,SLOT(
openDem()));
 
  533    m_saveNet = 
new QAction(QIcon(
toolIconDir() + 
"/filesave.png"), 
"Save Control Network ...",
 
  535    m_saveNet->setShortcut(Qt::CTRL + Qt::Key_S);
 
  536    m_saveNet->setToolTip(
"Save current control network");
 
  537    m_saveNet->setStatusTip(
"Save current control network");
 
  538    whatsThis = 
"<b>Function:</b> Saves the current <i>" 
  539        "control network</i>";
 
  540    m_saveNet->setWhatsThis(whatsThis);
 
  541    connect(m_saveNet, SIGNAL(triggered()), 
this, SLOT(
saveNet()));
 
  543    m_saveAsNet = 
new QAction(QIcon(
toolIconDir() + 
"/filesaveas.png"), 
"Save Control Network &As...",
 
  545    m_saveAsNet->setToolTip(
"Save current control network to chosen file");
 
  546    m_saveAsNet->setStatusTip(
"Save current control network to chosen file");
 
  547    whatsThis = 
"<b>Function:</b> Saves the current <i>" 
  548        "control network</i> under chosen filename";
 
  549    m_saveAsNet->setWhatsThis(whatsThis);
 
  550    connect(m_saveAsNet, SIGNAL(triggered()), 
this, SLOT(
saveAsNet()));
 
  552    m_closeQnetTool = 
new QAction(QIcon(
toolIconDir() + 
"/fileclose.png"), 
"&Close", m_qnetTool);
 
  553    m_closeQnetTool->setToolTip(
"Close this window");
 
  554    m_closeQnetTool->setStatusTip(
"Close this window");
 
  555    m_closeQnetTool->setShortcut(Qt::ALT + Qt::Key_F4);
 
  556    whatsThis = 
"<b>Function:</b> Closes the Qnet Tool window for this point " 
  557        "<p><b>Shortcut:</b> Alt+F4 </p>";
 
  558    m_closeQnetTool->setWhatsThis(whatsThis);
 
  559    connect(m_closeQnetTool, SIGNAL(triggered()), m_qnetTool, SLOT(close()));
 
  562        "&View/edit registration template", m_qnetTool);
 
  563    m_showHideTemplateEditor->setCheckable(
true);
 
  564    m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration " 
  566    m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration " 
  568    whatsThis = 
"<b>Function:</b> Displays the curent registration template.  " 
  569       "The user may edit and save changes under a chosen filename.";
 
  570    m_showHideTemplateEditor->setWhatsThis(whatsThis);
 
  571    connect(m_showHideTemplateEditor, SIGNAL(triggered()), 
this,
 
  572        SLOT(showHideTemplateEditor()));
 
  574    m_saveChips = 
new QAction(QIcon(
toolIconDir() + 
"/savechips.png"), 
"Save registration chips",
 
  576    m_saveChips->setToolTip(
"Save registration chips");
 
  577    m_saveChips->setStatusTip(
"Save registration chips");
 
  578    whatsThis = 
"<b>Function:</b> Save registration chips to file.  " 
  579       "Each chip: pattern, search, fit will be saved to a separate file.";
 
  580    m_saveChips->setWhatsThis(whatsThis);
 
  581    connect(m_saveChips, SIGNAL(triggered()), 
this, SLOT(
saveChips()));
 
  583    m_openTemplateFile = 
new QAction(QIcon(
toolIconDir() + 
"/fileopen.png"), 
"&Open registration " 
  584        "template", m_qnetTool);
 
  585    m_openTemplateFile->setToolTip(
"Set registration template");
 
  586    m_openTemplateFile->setStatusTip(
"Set registration template");
 
  587    whatsThis = 
"<b>Function:</b> Allows user to select a new file to set as " 
  588        "the registration template";
 
  589    m_openTemplateFile->setWhatsThis(whatsThis);
 
  590    connect(m_openTemplateFile, SIGNAL(triggered()), 
this, SLOT(
openTemplateFile()));
 
  592    m_saveTemplateFile = 
new QAction(QIcon(
toolIconDir() + 
"/filesave.png"), 
"&Save template file",
 
  594    m_saveTemplateFile->setToolTip(
"Save the template file");
 
  595    m_saveTemplateFile->setStatusTip(
"Save the template file");
 
  596    m_saveTemplateFile->setWhatsThis(
"Save the registration template file");
 
  597    connect(m_saveTemplateFile, SIGNAL(triggered()), 
this,
 
  600    m_saveTemplateFileAs = 
new QAction(QIcon(
toolIconDir() + 
"/filesaveas.png"), 
"&Save template as...",
 
  602    m_saveTemplateFileAs->setToolTip(
"Save the template file as");
 
  603    m_saveTemplateFileAs->setStatusTip(
"Save the template file as");
 
  604    m_saveTemplateFileAs->setWhatsThis(
"Save the registration template file as");
 
  605    connect(m_saveTemplateFileAs, SIGNAL(triggered()), 
this,
 
  609      "$ISISROOT/appdata/images/icons/contexthelp.png").expanded()),
"&Whats's This", m_qnetTool);
 
  610    m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
 
  611    m_whatsThis->setToolTip(
"Activate What's This and click on items on " 
  612        "user interface to see more information.");
 
  613    connect(m_whatsThis, SIGNAL(triggered()), 
this, SLOT(enterWhatsThisMode()));
 
 
  630    QMenu *fileMenu = m_qnetTool->menuBar()->addMenu(
"&File");
 
  631    fileMenu->addAction(m_openGround);
 
  632    fileMenu->addAction(m_openDem);
 
  633    fileMenu->addAction(m_saveNet);
 
  634    fileMenu->addAction(m_saveAsNet);
 
  635    fileMenu->addAction(m_closeQnetTool);
 
  637    QMenu * regMenu = m_qnetTool->menuBar()->addMenu(
"&Registration");
 
  638    regMenu->addAction(m_openTemplateFile);
 
  639    regMenu->addAction(m_showHideTemplateEditor);
 
  640    regMenu->addAction(m_saveChips);
 
  642    QMenu *helpMenu = m_qnetTool->menuBar()->addMenu(
"&Help");
 
  643    helpMenu->addAction(m_whatsThis);
 
 
  647  void QnetTool::createToolBars() {
 
  650    toolBar->setObjectName(
"TemplateEditorToolBar");
 
  651    toolBar->setFloatable(
false);
 
  652    toolBar->addAction(m_saveNet);
 
  653    toolBar->addSeparator();
 
  654    toolBar->addAction(m_showHideTemplateEditor);
 
  655    toolBar->addAction(m_saveChips);
 
  656    toolBar->addAction(m_whatsThis);
 
  658    m_qnetTool->addToolBar(Qt::TopToolBarArea, toolBar);
 
  730                m_editPoint->GetMeasure(m_leftMeasure->GetCubeSerialNumber());
 
  732                m_editPoint->GetMeasure(m_rightMeasure->GetCubeSerialNumber());
 
  734    if (m_editPoint->IsIgnored()) {
 
  735      QString message = 
"You are saving changes to a measure on an ignored ";
 
  736      message += 
"point.  Do you want to set Ignore = False on the point and ";
 
  737      message += 
"both measures?";
 
  738      switch (QMessageBox::question(m_qnetTool, 
"Qnet Tool Save Measure",
 
  739                                    message, 
"&Yes", 
"&No", 0, 0)) {
 
  742          m_editPoint->SetIgnored(
false);
 
  743          emit ignorePointChanged();
 
  744          if (m_leftMeasure->IsIgnored()) {
 
  745            m_leftMeasure->SetIgnored(
false);
 
  746            emit ignoreLeftChanged();
 
  748          if (m_rightMeasure->IsIgnored()) {
 
  749            m_rightMeasure->SetIgnored(
false);
 
  750            emit ignoreRightChanged();
 
  758    if (origRightMeasure->IsIgnored() && m_rightMeasure->IsIgnored()) {
 
  759      QString message = 
"You are saving changes to an ignored measure.  ";
 
  760      message += 
"Do you want to set Ignore = False on the right measure?";
 
  761      switch(QMessageBox::question(m_qnetTool, 
"Qnet Tool Save Measure",
 
  762                                   message, 
"&Yes", 
"&No", 0, 0)){
 
  765            m_rightMeasure->SetIgnored(
false);
 
  766            emit ignoreRightChanged();
 
  775    if (m_editPoint->IsReferenceExplicit()) {
 
  776      if (m_editPoint->IsEditLocked()) {
 
  777        QString message = 
"This control point is edit locked.  The Apriori latitude, longitude and ";
 
  778        message += 
"radius cannot be updated.  You must first unlock the point by clicking the ";
 
  779        message += 
"check box above labeled \"Edit Lock Point\".";
 
  780        QMessageBox::warning(m_qnetTool, 
"Point Locked", message);
 
  788    else if (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) {
 
  789      m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
 
  799        m_rightMeasure->GetCubeSerialNumber() == m_groundSN)) {
 
  800      if (m_editPoint->IsEditLocked() && m_controlNet->ContainsPoint(m_editPoint->GetId())) {
 
  801        QString message = 
"This control point is edit locked.  The Apriori latitude, longitude and ";
 
  802        message += 
"radius cannot be updated.  You must first unlock the point by clicking the ";
 
  803        message += 
"check box above labeled \"Edit Lock Point\".";
 
  804        QMessageBox::warning(m_qnetTool, 
"Point Locked", message);
 
  807      if (m_leftMeasure->IsIgnored()) {
 
  808        QString message = 
"This is a Constrained or Fixed point and the reference measure is ";
 
  809        message += 
"Ignored.  Unset the Ignore flag on the reference measure before saving.";
 
  810        QMessageBox::warning(m_qnetTool, 
"Point Locked", message);
 
  813      updateGroundPosition();
 
  820    *origRightMeasure = *m_rightMeasure;
 
  823    if (m_leftMeasure->IsIgnored() != origLeftMeasure->IsIgnored() ||
 
  824        m_leftMeasure->IsEditLocked() != origLeftMeasure->IsEditLocked()) {
 
  826      *origLeftMeasure = *m_leftMeasure;
 
  830    if (m_leftMeasure->GetCubeSerialNumber() ==
 
  831        m_rightMeasure->GetCubeSerialNumber()) {
 
  832      *m_leftMeasure = *m_rightMeasure;
 
  834      m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
 
  835                                     m_editPoint->GetId());
 
  841    editPointChanged(m_editPoint->GetId());
 
 
  872    if ( (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) &&
 
  873         (refMeasure->GetCubeSerialNumber() != m_leftMeasure->GetCubeSerialNumber()) ) {
 
  874      QString message = 
"This point already contains a reference measure.  ";
 
  875      message += 
"Would you like to replace it with the measure on the left?";
 
  876      int  response = QMessageBox::question(m_qnetTool,
 
  877                                "Qnet Tool Save Measure", message,
 
  878                                QMessageBox::Yes | QMessageBox::No,
 
  881      if (response == QMessageBox::Yes) {
 
  884        QString file = m_serialNumberList->
fileName(m_leftMeasure->GetCubeSerialNumber());
 
  886        int iref = m_leftCombo->findText(fname);
 
  889        QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
 
  890        m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
 
  891        iref = m_rightCombo->findText(fname);
 
  892        m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
 
  894        file = m_serialNumberList->
fileName(refMeasure->GetCubeSerialNumber());
 
  896        iref = m_leftCombo->findText(fname);
 
  897        m_leftCombo->setItemData(iref,font,Qt::FontRole);
 
  898        iref = m_rightCombo->findText(fname);
 
  899        m_rightCombo->setItemData(iref,font,Qt::FontRole);
 
  901        m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
 
  903        refMeasure = m_editPoint->GetRefMeasure();
 
  910    if (refMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
 
  911      QString message = 
"You are making a change to the reference measure.  You ";
 
  912      message += 
"may need to move all of the other measures to match the new ";
 
  913      message += 
" coordinate of the reference measure.  Do you really want to ";
 
  914      message += 
" change the reference measure? ";
 
  915      switch(QMessageBox::question(m_qnetTool, 
"Qnet Tool Save Measure",
 
  916                                   message, 
"&Yes", 
"&No", 0, 0)){
 
 
  940  void QnetTool::updateGroundPosition() {
 
  948    if (!m_groundGmap->SetImage(groundMeasure->GetSample(),
 
  949                                groundMeasure->GetLine())) {
 
  954    double lat = m_groundGmap->UniversalLatitude();
 
  955    double lon = m_groundGmap->UniversalLongitude();
 
  966      if (radius == 
Null) {
 
  967        QString msg = 
"Could not read radius from DEM, will default to " 
  968          "local radius of reference measure.";
 
  969        QMessageBox::warning(m_qnetTool, 
"Warning", msg);
 
  970        if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
 
  973            m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
 
  974            m_editPoint->SetAprioriRadiusSource(
 
  975                ControlPoint::RadiusSource::None);
 
  979          QString message = 
"Error trying to get radius at this pt.  " 
  980              "Lat/Lon does not fall on the reference measure.  " 
  981              "Cannot save this measure.";
 
  982          QMessageBox::critical(m_qnetTool,
"Error",message);
 
  986      m_editPoint->SetAprioriRadiusSource(m_groundRadiusSource);
 
  987      m_editPoint->SetAprioriRadiusSourceFile(m_radiusSourceFile);
 
  991      if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
 
  994            m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
 
 1001        QString message = 
"Error trying to get radius at this pt.  " 
 1002            "Lat/Lon does not fall on the reference measure.  " 
 1003            "Cannot save this measure.";
 
 1004        QMessageBox::critical(m_qnetTool,
"Error",message);
 
 1013      if (m_editPoint->HasAprioriCoordinates()) {
 
 1014        SurfacePoint aprioriPt = m_editPoint->GetAprioriSurfacePoint();
 
 1015        Distance latSigma = aprioriPt.GetLatSigmaDistance();
 
 1016        Distance lonSigma = aprioriPt.GetLonSigmaDistance();
 
 1017        Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
 
 1021        aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
 
 1022        m_editPoint->SetAprioriSurfacePoint(aprioriPt);
 
 1025        m_editPoint->SetAprioriSurfacePoint(SurfacePoint(
 
 1031    catch (IException &e) {
 
 1032      QString message = 
"Unable to set Apriori Surface Point.\n";
 
 1033      message += 
"Latitude = " + QString::number(lat);
 
 1034      message += 
"  Longitude = " + QString::number(lon);
 
 1035      message += 
"  Radius = " + QString::number(radius) + 
"\n";
 
 1036      message += e.toString();
 
 1037      QMessageBox::critical(m_qnetTool,
"Error",message);
 
 1039    m_editPoint->SetAprioriSurfacePointSource(m_groundSurfacePointSource);
 
 1040    m_editPoint->SetAprioriSurfacePointSourceFile(m_groundSourceFile);
 
 1067    *updatePoint = *m_editPoint;
 
 1075      updatePoint->
Delete(m_groundSN);
 
 1080    if (m_controlNet->ContainsPoint(updatePoint->
GetId())) {
 
 1082      p = m_controlNet->GetPoint(QString(updatePoint->
GetId()));
 
 1088      m_controlNet->AddPoint(updatePoint);
 
 1092    m_savePoint->setPalette(m_saveDefaultPalette);
 
 1096    emit refreshNavList();
 
 1098    emit editPointChanged(m_editPoint->GetId());
 
 1102    m_pointEditor->refreshChips();
 
 
 1122    if (m_editPoint == NULL) 
return;
 
 1125    if (m_editPoint->GetType() == pointType) 
return;
 
 1128      m_pointType->setCurrentIndex((
int) m_editPoint->GetType());
 
 1129      QString message = 
"The reference measure is Ignored.  Unset the Ignore flag on the ";
 
 1130      message += 
"reference measure before setting the point type to Constrained or Fixed.";
 
 1131      QMessageBox::warning(m_qnetTool, 
"Ignored Reference Measure", message);
 
 1135    bool unloadGround = 
false;
 
 1137      unloadGround = 
true;
 
 1140    int temp = m_editPoint->GetType();
 
 1144      m_pointType->setCurrentIndex((
int) m_editPoint->GetType());
 
 1145      QString message = 
"This control point is edit locked.  The point type cannot be changed.  You ";
 
 1146      message += 
"must first unlock the point by clicking the check box above labeled ";
 
 1147      message += 
"\"Edit Lock Point\".";
 
 1148      QMessageBox::warning(m_qnetTool, 
"Point Locked", message);
 
 1157      m_pointEditor->colorizeSaveButton();
 
 1160    else if (unloadGround) {
 
 1163      if (m_editPoint->HasSerialNumber(m_groundSN)) {
 
 1164          m_editPoint->Delete(m_groundSN);
 
 1168      m_pointEditor->colorizeSaveButton();
 
 
 1189    if (!m_groundOpen) 
return;
 
 1195      QString file = m_serialNumberList->
fileName(groundMeasure->GetCubeSerialNumber());
 
 1199      m_leftCombo->addItem(tempFileName);
 
 1200      m_rightCombo->addItem(tempFileName);
 
 1201      int rightIndex = m_rightCombo->findText((QString)m_groundFile);
 
 1202      m_rightCombo->setCurrentIndex(rightIndex);
 
 
 1223    if (m_editPoint == NULL) 
return;
 
 1225    m_editPoint->SetEditLock(lock);
 
 
 1242    if (m_editPoint == NULL) 
return;
 
 1246      m_ignorePoint->setChecked(m_editPoint->IsIgnored());
 
 1247      QString message = 
"This control point is edit locked.  The Ignored status cannot be ";
 
 1248      message += 
"changed.  You must first unlock the point by clicking the check box above ";
 
 1249      message += 
"labeled \"Edit Lock Point\".";
 
 1250      QMessageBox::warning(m_qnetTool, 
"Point Locked", message);
 
 
 1276    if (m_editPoint->IsEditLocked()) {
 
 1277      m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
 
 1278      QMessageBox::warning(m_qnetTool, 
"Point Locked",
"Point is Edit Locked.  You must un-lock point" 
 1279        " before changing a measure.");
 
 1280      m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
 
 1284    if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
 
 1288    if (m_rightMeasure != NULL) {
 
 1289      if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
 
 1290        m_rightMeasure->SetEditLock(lock);
 
 1291        m_lockRightMeasure->setChecked(lock);
 
 1294    emit measureChanged();
 
 
 1316    if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
 
 1320    if (m_rightMeasure != NULL) {
 
 1321      if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
 
 1322        m_rightMeasure->SetIgnored(ignore);
 
 1323        m_ignoreRightMeasure->setChecked(ignore);
 
 1326    emit measureChanged();
 
 
 1347    if (m_editPoint->IsEditLocked()) {
 
 1348      m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
 
 1349      QMessageBox::warning(m_qnetTool, 
"Point Locked",
"Point is Edit Locked.  You must un-lock point" 
 1350        " before changing a measure.");
 
 1351      m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
 
 1355    if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
 
 1358    if (m_leftMeasure != NULL) {
 
 1359      if (m_leftMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
 
 1360        m_leftMeasure->SetEditLock(lock);
 
 1361        m_lockLeftMeasure->setChecked(lock);
 
 1364    emit measureChanged();
 
 
 1386    if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
 
 1390    if (m_leftMeasure != NULL) {
 
 1391      if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
 
 1392        m_leftMeasure->SetIgnored(ignore);
 
 1393        m_ignoreLeftMeasure->setChecked(ignore);
 
 1396    emit measureChanged();
 
 
 1407    if (m_cnetFileName.isEmpty()) {
 
 1408      QString message = 
"This is a new network, you must select " 
 1409                        "\"Save As\" under the File Menu.";
 
 1410      QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 1413    emit qnetToolSave();
 
 
 1423    emit qnetToolSaveAs();
 
 
 1432  void QnetTool::updateList() {
 
 1456    m_cnetFileName = cNetFileName;
 
 1457    m_qnetTool->setWindowTitle(
"Qnet Tool - Control Network File: " +
 
 
 1478    action->setIcon(QPixmap(
toolIconDir()+
"/stock_draw-connector-with-arrows.png"));
 
 1479    action->setToolTip(
"Control Point Editor (T)");
 
 1480    action->setShortcut(Qt::Key_T);
 
 1481    QObject::connect(action,SIGNAL(triggered(
bool)),
this,SLOT(
showNavWindow(
bool)));
 
 
 1523    if (cvp  == NULL) 
return;
 
 1525    QString file = cvp->cube()->fileName();
 
 1531      QString message = 
"Cannot get serial number for " + file + 
".  Is file contained in the ";
 
 1532      message += 
"cube list?\n";
 
 1533      message += e.toString();
 
 1534      QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 1539    cvp->viewportToCube(p.x(),p.y(),samp,line);
 
 1543    if (s == Qt::LeftButton) {
 
 1544      if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
 
 1545        QString message = 
"No points exist for editing.  Create points ";
 
 1546        message += 
"using the right mouse button.";
 
 1547        QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 1551      if (sn == m_groundSN) {
 
 1552        QString message = 
"Cannot select point for editing on ground source.  Select ";
 
 1553        message += 
"point using un-projected images or the Navigator Window.";
 
 1554        QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 1563        ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
 
 1567        QString message = 
"No points exist for editing. Create points using the right mouse";
 
 1568        message += 
" button.";
 
 1569        QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 1574    else if (s == Qt::MiddleButton) {
 
 1575      if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
 
 1576        QString message = 
"No points exist for deleting.  Create points ";
 
 1577        message += 
"using the right mouse button.";
 
 1578        QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 1582      if (m_groundOpen && file == m_groundCube->fileName()) {
 
 1583        QString message = 
"Cannot select point for deleting on ground source.  Select ";
 
 1584        message += 
"point using un-projected images or the Navigator Window.";
 
 1585        QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 1591        point = m_controlNet->FindClosest(sn, samp, line);
 
 1593        if (point == NULL) {
 
 1594          QString message = 
"No points exist for deleting.  Create points ";
 
 1595          message += 
"using the right mouse button.";
 
 1596          QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 1601        QString message = 
"Cannot find point on this image for deleting.";
 
 1602        QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 1608    else if (s == Qt::RightButton) {
 
 1611      if (!gmap->SetImage(samp,line)) {
 
 1612        QString message = 
"Invalid latitude or longitude at this point. ";
 
 1613        QMessageBox::critical(m_qnetTool,
"Error", message);
 
 1616      double lat = gmap->UniversalLatitude();
 
 1617      double lon = gmap->UniversalLongitude();
 
 1618      if (m_groundOpen && file == m_groundCube->fileName()) {
 
 
 1682    for(
int i = 0; i < m_serialNumberList->
size(); i++) {
 
 1683      if (m_serialNumberList->
serialNumber(i) == m_groundSN) 
continue;
 
 1684      cam = m_controlNet->Camera(i);
 
 1685      if(cam->SetUniversalGround(lat, lon)) {
 
 1687        double samp = cam->Sample();
 
 1688        double line = cam->Line();
 
 1689        if (samp >= 1 && samp <= cam->Samples() &&
 
 1690            line >= 1 && line <= cam->Lines()) {
 
 1691          pointFiles<<m_serialNumberList->
fileName(i);
 
 1698    newPointDialog->setFiles(pointFiles);
 
 1699    if (newPointDialog->exec()) {
 
 1700      m_lastUsedPointId = newPointDialog->pointId();
 
 1706      if (m_controlNet->ContainsPoint(newPoint->
GetId())) {
 
 1707        QString message = 
"A ControlPoint with Point Id = [" + newPoint->
GetId();
 
 1708        message += 
"] already exists.  Re-enter Point Id for this ControlPoint.";
 
 1709        QMessageBox::warning(m_qnetTool, 
"New Point Id", message);
 
 1719      QStringList selectedFiles = newPointDialog->selectedFiles();
 
 1720      foreach (QString selectedFile, selectedFiles) {
 
 1726        m->SetCubeSerialNumber(sn);
 
 1729        cam = m_controlNet->Camera(camIndex);
 
 1730        cam->SetUniversalGround(lat,lon);
 
 1731        m->SetCoordinate(cam->Sample(),cam->Line());
 
 1732        m->SetAprioriSample(cam->Sample());
 
 1733        m->SetAprioriLine(cam->Line());
 
 1739      if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
 
 1743      m_editPoint = newPoint;
 
 1747      if (!m_leftFile.isEmpty()) {
 
 1748        if (selectedFiles.indexOf(m_leftFile) == -1) {
 
 1755      m_qnetTool->setVisible(
true);
 
 1756      m_qnetTool->raise();
 
 1759          m_pointEditor->templateFileName());
 
 1763      emit refreshNavList();
 
 1765      emit editPointChanged(m_editPoint->GetId());
 
 1767      delete newPointDialog;
 
 
 1797    for (
int i=0; i<m_serialNumberList->
size(); i++) {
 
 1798      if (m_serialNumberList->
serialNumber(i) == m_groundSN) 
continue;
 
 1799      cam = m_controlNet->Camera(i);
 
 1800      if (cam->SetUniversalGround(lat,lon)) {
 
 1802        double samp = cam->Sample();
 
 1803        double line = cam->Line();
 
 1804        if (samp >= 1 && samp <= cam->Samples() &&
 
 1805            line >= 1 && line <= cam->Lines()) {
 
 1806          pointFiles<<m_serialNumberList->
fileName(i);
 
 1811    if (pointFiles.count() == 0) {
 
 1812      QString message = 
"Point does not intersect any images.";
 
 1813      QMessageBox::critical(m_qnetTool, 
"No intersection", message);
 
 1818    fixedPointDialog->setFiles(pointFiles);
 
 1819    if (fixedPointDialog->exec()) {
 
 1823      if (fixedPointDialog->isFixed()) {
 
 1832      if (m_controlNet->ContainsPoint(fixedPoint->GetId())) {
 
 1833        QString message = 
"A ControlPoint with Point Id = [" + fixedPoint->GetId();
 
 1834        message += 
"] already exists.  Re-enter Point Id for this ControlPoint.";
 
 1835        QMessageBox::warning(m_qnetTool, 
"New Point Id", message);
 
 1845      QStringList selectedFiles = fixedPointDialog->selectedFiles();
 
 1846      foreach (QString selectedFile, selectedFiles) {
 
 1854        if (sn == m_groundSN) 
continue;
 
 1856        m->SetCubeSerialNumber(sn);
 
 1859        cam = m_controlNet->Camera(camIndex);
 
 1860        cam->SetUniversalGround(lat,lon);
 
 1861        m->SetCoordinate(cam->Sample(),cam->Line());
 
 1872        if (radius == 
Null) {
 
 1873          QString msg = 
"Could not read radius from DEM, will default to the " 
 1874            "local radius of the first measure in the control point.  This " 
 1875            "will be updated to the local radius of the chosen reference " 
 1877          QMessageBox::warning(m_qnetTool, 
"Warning", msg);
 
 1878          if ((*fixedPoint)[0]->
Camera()->SetGround(
 
 1880            radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
 
 1883            QString msg = 
"Error trying to get radius at this pt.  " 
 1884                "Lat/Lon does not fall on the reference measure.  " 
 1885                "Cannot create this point.";
 
 1886            QMessageBox::critical(m_qnetTool, 
"Error", msg);
 
 1889            delete fixedPointDialog;
 
 1890            fixedPointDialog = NULL;
 
 1896        if ((*fixedPoint)[0]->
Camera()->SetGround(
 
 1898          radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
 
 1901          QString msg = 
"Error trying to get radius at this pt.  " 
 1902              "Lat/Lon does not fall on the reference measure.  " 
 1903              "Cannot create this point.";
 
 1904          QMessageBox::critical(m_qnetTool, 
"Error", msg);
 
 1907          delete fixedPointDialog;
 
 1908          fixedPointDialog = NULL;
 
 1918      if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
 
 1922      m_editPoint = fixedPoint;
 
 1926      m_qnetTool->setVisible(
true);
 
 1927      m_qnetTool->raise();
 
 1929      delete fixedPointDialog;
 
 1930      fixedPointDialog = NULL;
 
 1933      emit refreshNavList();
 
 1935      emit editPointChanged(m_editPoint->GetId());
 
 
 1966    if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
 
 1971    *m_editPoint = *point;
 
 1977    emit editPointChanged(m_editPoint->GetId());
 
 1980    QString CPId = m_editPoint->GetId();
 
 1981    deletePointDialog->pointIdValue->setText(CPId);
 
 1984    for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
 
 1986      QString file = m_serialNumberList->
fileName(m.GetCubeSerialNumber());
 
 1987      deletePointDialog->fileList->addItem(file);
 
 1990    if (deletePointDialog->exec()) {
 
 1992      int numDeleted = deletePointDialog->fileList->selectedItems().count();
 
 1995      if (deletePointDialog->deleteAllCheckBox->isChecked() ||
 
 1996          numDeleted == m_editPoint->GetNumMeasures()) {
 
 1999        if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
 
 2000          QString message = 
"You have selected all measures in this point to be deleted.  This " 
 2001            "control point will be deleted.  Do you want to delete this control point?";
 
 2002          int  response = QMessageBox::question(m_qnetTool,
 
 2003                                    "Delete control point", message,
 
 2004                                    QMessageBox::Yes | QMessageBox::No,
 
 2007          if (response == QMessageBox::No) {
 
 2016        m_qnetTool->setVisible(
false);
 
 2018        if (m_controlNet->DeletePoint(m_editPoint->GetId()) ==
 
 2020          QMessageBox::information(m_qnetTool, 
"EditLocked Point",
 
 2021              "This point is EditLocked and cannot be deleted.");
 
 2024        if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
 
 2029        emit refreshNavList();
 
 2035        int lockedMeasures = 0;
 
 2036        for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
 
 2037          QListWidgetItem *item = deletePointDialog->fileList->item(i);
 
 2038          if (!item->isSelected()) 
continue;
 
 2041          if (m_editPoint->IsReferenceExplicit() &&
 
 2042                (m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
 
 2043                (*m_editPoint)[i]->GetCubeSerialNumber())) {
 
 2044            QString message = 
"You are trying to delete the Reference measure." 
 2045                "  Do you really want to delete the Reference measure?";
 
 2046            switch (QMessageBox::question(m_qnetTool,
 
 2047                                          "Delete Reference measure?", message,
 
 2048                                          "&Yes", 
"&No", 0, 0)) {
 
 2056                if (numDeleted == 1) {
 
 2063          if (m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
 
 2068        if (lockedMeasures > 0) {
 
 2069          QMessageBox::information(m_qnetTool,
"EditLocked Measures",
 
 2070                QString::number(lockedMeasures) + 
" / " 
 2072                  deletePointDialog->fileList->selectedItems().size()) +
 
 2073                " measures are EditLocked and were not deleted.");
 
 2077        m_qnetTool->setVisible(
true);
 
 2078        m_qnetTool->raise();
 
 2087      if (m_editPoint != NULL) {
 
 2088        emit editPointChanged(m_editPoint->GetId());
 
 2096        emit editPointChanged(
"");
 
 
 2114    if (point->GetNumMeasures() == 0) {
 
 2115      QString message = 
"This point has no measures.";
 
 2116      QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 2118      if (m_editPoint != NULL) {
 
 2120        emit editPointChanged(m_editPoint->GetId());
 
 2125        emit editPointChanged(
"");
 
 2131    if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
 
 2136    *m_editPoint = *point;
 
 2140    if (sender() != 
this) m_leftFile.clear();
 
 2142    m_qnetTool->setVisible(
true);
 
 2143    m_qnetTool->raise();
 
 2147    emit editPointChanged(m_editPoint->GetId());
 
 2150    m_savePoint->setPalette(m_saveDefaultPalette);
 
 
 2164    bool located = 
true;
 
 2170      if (m_editPoint->HasAprioriCoordinates()) {
 
 2171        SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
 
 2172        lat = sPt.GetLatitude().degrees();
 
 2173        lon = sPt.GetLongitude().degrees();
 
 2179        cam = m_controlNet->Camera(camIndex);
 
 2180        cam->SetImage(m.GetSample(),m.GetLine());
 
 2181        lat = cam->UniversalLatitude();
 
 2182        lon = cam->UniversalLongitude();
 
 2187      if (!m_groundGmap->SetUniversalGround(lat,lon)) {
 
 2189        QString message = 
"This point does not exist on the ground source.\n";
 
 2190        message += 
"Latitude = " + QString::number(lat);
 
 2191        message += 
"  Longitude = " + QString::number(lon);
 
 2192        message += 
"\n A ground measure will not be created.";
 
 2193        QMessageBox::warning(m_qnetTool, 
"Warning", message);
 
 
 2216     groundMeasure->SetCoordinate(m_groundGmap->Sample(),m_groundGmap->Line());
 
 2217     m_editPoint->Add(groundMeasure);
 
 2219     return groundMeasure;
 
 
 2249    QString CPId = m_editPoint->GetId();
 
 2250    QString ptId(
"Point ID:  ");
 
 2251    ptId += (QString) CPId;
 
 2252    m_ptIdValue->setText(ptId);
 
 2258    m_pointType->setCurrentIndex((
int) m_editPoint->GetType());
 
 2261    QString ptsize = 
"Number of Measures:  " +
 
 2262                   QString::number(m_editPoint->GetNumMeasures());
 
 2263    m_numMeasures->setText(ptsize);
 
 2266    m_lockPoint->setChecked(m_editPoint->IsEditLocked());
 
 2269    m_ignorePoint->setChecked(m_editPoint->IsIgnored());
 
 2272    m_leftCombo->clear();
 
 2273    m_rightCombo->clear();
 
 2274    m_pointFiles.clear();
 
 2278    if (m_editPoint->HasSerialNumber(m_groundSN)) {
 
 2279        m_editPoint->Delete(m_groundSN);
 
 2296    if (m_groundOpen && !m_demOpen) {
 
 2302    for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
 
 2304      QString file = m_serialNumberList->
fileName(m.GetCubeSerialNumber());
 
 2307      m_leftCombo->addItem(tempFileName);
 
 2308      m_rightCombo->addItem(tempFileName);
 
 2309      if (m_editPoint->IsReferenceExplicit() &&
 
 2310          (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
 
 2311          m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
 
 2312          m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
 
 2328    if (m_editPoint->IsReferenceExplicit()) {
 
 2329      leftIndex = m_editPoint->IndexOfRefMeasure();
 
 2334        leftIndex = m_leftCombo->findText(baseFileName);
 
 2336        if (leftIndex < 0 ) leftIndex = 0;
 
 2344      rightIndex = m_rightCombo->findText((QString)m_groundFile);
 
 2346    if (rightIndex <= 0) {
 
 2347      if (leftIndex == 0) {
 
 2357    if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
 
 2358    m_rightCombo->setCurrentIndex(rightIndex);
 
 2359    m_leftCombo->setCurrentIndex(leftIndex);
 
 
 2381    if (m_measureWindow == NULL) {
 
 2383      m_measureTable = 
new QTableWidget();
 
 2384      m_measureTable->setMinimumWidth(1600);
 
 2385      m_measureTable->setAlternatingRowColors(
true);
 
 2386      m_measureWindow->setCentralWidget(m_measureTable);
 
 2389      m_measureTable->clear();
 
 2390      m_measureTable->setSortingEnabled(
false);
 
 2392    m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
 
 2393    m_measureTable->setColumnCount(NUMCOLUMNS);
 
 2396    for (
int i=0; i<NUMCOLUMNS; i++) {
 
 2397      labels<<measureColumnToString((MeasureColumns)i);
 
 2399    m_measureTable->setHorizontalHeaderLabels(labels);
 
 2402    for (
int row=0; row<m_editPoint->GetNumMeasures(); row++) {
 
 2406      QString file = m_serialNumberList->
fileName(m.GetCubeSerialNumber());
 
 2407      QTableWidgetItem *tableItem = 
new QTableWidgetItem(QString(file));
 
 2408      m_measureTable->setItem(row,column++,tableItem);
 
 2410      tableItem = 
new QTableWidgetItem(QString(m.GetCubeSerialNumber()));
 
 2411      m_measureTable->setItem(row,column++,tableItem);
 
 2413      tableItem = 
new QTableWidgetItem();
 
 2414      tableItem->setData(0,m.GetSample());
 
 2415      m_measureTable->setItem(row,column++,tableItem);
 
 2417      tableItem = 
new QTableWidgetItem();
 
 2418      tableItem->setData(0,m.GetLine());
 
 2419      m_measureTable->setItem(row,column++,tableItem);
 
 2421      if (m.GetAprioriSample() == 
Null) {
 
 2422        tableItem = 
new QTableWidgetItem(
"Null");
 
 2425        tableItem = 
new QTableWidgetItem();
 
 2426        tableItem->setData(0,m.GetAprioriSample());
 
 2428      m_measureTable->setItem(row,column++,tableItem);
 
 2430      if (m.GetAprioriLine() == 
Null) {
 
 2431        tableItem = 
new QTableWidgetItem(
"Null");
 
 2434        tableItem = 
new QTableWidgetItem();
 
 2435        tableItem->setData(0,m.GetAprioriLine());
 
 2437      m_measureTable->setItem(row,column++,tableItem);
 
 2439      if (m.GetSampleResidual() == 
Null) {
 
 2440        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2443        tableItem = 
new QTableWidgetItem();
 
 2444        tableItem->setData(0,m.GetSampleResidual());
 
 2446      m_measureTable->setItem(row,column++,tableItem);
 
 2448      if (m.GetLineResidual() == 
Null) {
 
 2449        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2452        tableItem = 
new QTableWidgetItem();
 
 2453        tableItem->setData(0,m.GetLineResidual());
 
 2455      m_measureTable->setItem(row,column++,tableItem);
 
 2457      if (m.GetResidualMagnitude() == 
Null) {
 
 2458        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2461        tableItem = 
new QTableWidgetItem();
 
 2462        tableItem->setData(0,m.GetResidualMagnitude());
 
 2464      m_measureTable->setItem(row,column++,tableItem);
 
 2466      double sampleShift = m.GetSampleShift();
 
 2467      if (sampleShift == 
Null) {
 
 2468        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2471        tableItem = 
new QTableWidgetItem();
 
 2472        tableItem->setData(0,sampleShift);
 
 2474      m_measureTable->setItem(row,column++,tableItem);
 
 2476      double lineShift = m.GetLineShift();
 
 2477      if (lineShift == 
Null) {
 
 2478        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2481        tableItem = 
new QTableWidgetItem();
 
 2482        tableItem->setData(0,lineShift);
 
 2484      m_measureTable->setItem(row,column++,tableItem);
 
 2486      double pixelShift = m.GetPixelShift();
 
 2487      if (pixelShift == 
Null) {
 
 2488        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2491        tableItem = 
new QTableWidgetItem();
 
 2492        tableItem->setData(0,pixelShift);
 
 2494      m_measureTable->setItem(row,column++,tableItem);
 
 2496      double goodnessOfFit = m.GetLogData(
 
 2498      if (goodnessOfFit == 
Null) {
 
 2499        tableItem = 
new QTableWidgetItem(QString(
"Null"));
 
 2502        tableItem = 
new QTableWidgetItem();
 
 2503        tableItem->setData(0,goodnessOfFit);
 
 2505      m_measureTable->setItem(row,column++,tableItem);
 
 2507      if (m.IsIgnored()) tableItem = 
new QTableWidgetItem(
"True");
 
 2508      if (!m.IsIgnored()) tableItem = 
new QTableWidgetItem(
"False");
 
 2509      m_measureTable->setItem(row,column++,tableItem);
 
 2512        tableItem = 
new QTableWidgetItem(
"True");
 
 2514        tableItem = 
new QTableWidgetItem(
"False");
 
 2515      m_measureTable->setItem(row,column++,tableItem);
 
 2517      tableItem = 
new QTableWidgetItem(
 
 2519      m_measureTable->setItem(row,column,tableItem);
 
 2522      if (m_editPoint->IsReferenceExplicit() &&
 
 2523          (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
 
 2527        for (
int col=0; col<m_measureTable->columnCount(); col++)
 
 2528          m_measureTable->item(row, col)->setFont(font);
 
 2533    m_measureTable->resizeColumnsToContents();
 
 2534    m_measureTable->resizeRowsToContents();
 
 2535    m_measureTable->setSortingEnabled(
true);
 
 2536    m_measureWindow->show();
 
 
 2541  QString QnetTool::measureColumnToString(QnetTool::MeasureColumns column) {
 
 2551      case SAMPLERESIDUAL:
 
 2552        return "Sample Residual";
 
 2554        return "Line Residual";
 
 2555      case RESIDUALMAGNITUDE:
 
 2556        return "Residual Magnitude";
 
 2558        return "Sample Shift";
 
 2560        return "Line Shift";
 
 2562        return "Pixel Shift";
 
 2564        return "Goodness of Fit";
 
 2570        return "Measure Type";
 
 2572        return "Apriori Sample";
 
 2574        return "Apriori Line";
 
 2577        "Invalid measure column passed to measureColumnToString", _FILEINFO_);
 
 2581  ControlNet *QnetTool::controlNet() {
 
 2582    return m_controlNet;
 
 2586  const ControlNet *QnetTool::controlNet()
 const {
 
 2587    return m_controlNet;
 
 2591  SerialNumberList *QnetTool::serialNumberList() {
 
 2592    return m_serialNumberList;
 
 2596  const SerialNumberList *QnetTool::serialNumberList()
 const {
 
 2597    return m_serialNumberList;
 
 2601  Workspace *QnetTool::workspace()
 const {
 
 2621    SurfacePoint aprioriPoint = m_editPoint->GetAprioriSurfacePoint();
 
 2622    if (aprioriPoint.GetLatitude().degrees() == 
Null) {
 
 2623      s = 
"Apriori Latitude:  Null";
 
 2626      s = 
"Apriori Latitude:  " +
 
 2627          QString::number(aprioriPoint.GetLatitude().degrees());
 
 2629    m_pointAprioriLatitude->setText(s);
 
 2630    if (aprioriPoint.GetLongitude().degrees() == 
Null) {
 
 2631      s = 
"Apriori Longitude:  Null";
 
 2634      s = 
"Apriori Longitude:  " +
 
 2635          QString::number(aprioriPoint.GetLongitude().degrees());
 
 2637    m_pointAprioriLongitude->setText(s);
 
 2638    if (aprioriPoint.GetLocalRadius().meters() == 
Null) {
 
 2639      s = 
"Apriori Radius:  Null";
 
 2642      s = 
"Apriori Radius:  " +
 
 2643          QString::number(aprioriPoint.GetLocalRadius().meters(),
'f',2) +
 
 2646    m_pointAprioriRadius->setText(s);
 
 2648    if (aprioriPoint.Valid()) {
 
 2649      if (aprioriPoint.GetLatSigmaDistance().meters() == 
Null) {
 
 2650        s = 
"Apriori Latitude Sigma:  Null";
 
 2653        s = 
"Apriori Latitude Sigma:  " +
 
 2654            QString::number(aprioriPoint.GetLatSigmaDistance().meters()) +
 
 2657      m_pointAprioriLatitudeSigma->setText(s);
 
 2658      if (aprioriPoint.GetLonSigmaDistance().meters() == 
Null) {
 
 2659        s = 
"Apriori Longitude Sigma:  Null";
 
 2662        s = 
"Apriori Longitude Sigma:  " +
 
 2663            QString::number(aprioriPoint.GetLonSigmaDistance().meters()) +
 
 2666      m_pointAprioriLongitudeSigma->setText(s);
 
 2667      if (aprioriPoint.GetLocalRadiusSigma().meters() == 
Null) {
 
 2668        s = 
"Apriori Radius Sigma:  Null";
 
 2671        s = 
"Apriori Radius Sigma:  " +
 
 2672            QString::number(aprioriPoint.GetLocalRadiusSigma().meters()) +
 
 2675      m_pointAprioriRadiusSigma->setText(s);
 
 2678      s = 
"Apriori Latitude Sigma:  Null";
 
 2679      m_pointAprioriLatitudeSigma->setText(s);
 
 2680      s = 
"Apriori Longitude Sigma:  Null";
 
 2681      m_pointAprioriLongitudeSigma->setText(s);
 
 2682      s = 
"Apriori Radius Sigma:  Null";
 
 2683      m_pointAprioriRadiusSigma->setText(s);
 
 2687    SurfacePoint point = m_editPoint->GetAdjustedSurfacePoint();
 
 2689      s = 
"Adjusted Latitude:  Null";
 
 2694    m_pointLatitude->setText(s);
 
 2696      s = 
"Adjusted Longitude:  Null";
 
 2701    m_pointLongitude->setText(s);
 
 2703      s = 
"Adjusted Radius:  Null";
 
 2706      s = 
"Adjusted Radius:  " +
 
 2709    m_pointRadius->setText(s);
 
 
 2727    int curIndex = m_rightCombo->currentIndex();
 
 2728    if (curIndex < m_rightCombo->count() - 1) {
 
 2730      m_rightCombo->setCurrentIndex(curIndex + 1);
 
 
 2746    int curIndex = m_rightCombo->currentIndex();
 
 2749      m_rightCombo->setCurrentIndex(curIndex - 1);
 
 
 2768    QString file = m_pointFiles[index];
 
 2770    QString serial = m_serialNumberList->
serialNumber(file);
 
 2774    if (m_leftMeasure != NULL) {
 
 2775      delete m_leftMeasure;
 
 2776      m_leftMeasure = NULL;
 
 2780    *m_leftMeasure = *((*m_editPoint)[serial]);
 
 2783    m_leftCube.reset(
new Cube(file, 
"r"));
 
 2786    m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
 
 2787                                   m_editPoint->GetId());
 
 
 2803    QString file = m_pointFiles[index];
 
 2805    QString serial = m_serialNumberList->
serialNumber(file);
 
 2809    if (m_rightMeasure != NULL) {
 
 2810      delete m_rightMeasure;
 
 2811      m_rightMeasure = NULL;
 
 2815    *m_rightMeasure = *((*m_editPoint)[serial]);
 
 2818    m_rightCube.reset(
new Cube(file, 
"r"));
 
 2821    m_pointEditor->setRightMeasure (m_rightMeasure, m_rightCube.data(),
 
 2822                                    m_editPoint->GetId());
 
 
 2849                                       m_leftMeasure->GetCubeSerialNumber()));
 
 2851    m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
 
 2853    QString s = 
"Reference: ";
 
 2854    if (m_editPoint->IsReferenceExplicit() &&
 
 2855        (QString(m_leftMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
 
 2861    m_leftReference->setText(s);
 
 2863    s = 
"Measure Type: ";
 
 2868    m_leftMeasureType->setText(s);
 
 2870    if (m_leftMeasure->GetSampleResidual() == 
Null) {
 
 2871      s = 
"Sample Residual: Null";
 
 2874      s = 
"Sample Residual: " + QString::number(m_leftMeasure->GetSampleResidual());
 
 2876    m_leftSampError->setText(s);
 
 2877    if (m_leftMeasure->GetLineResidual() == 
Null) {
 
 2878      s = 
"Line Residual: Null";
 
 2881      s = 
"Line Residual: " + QString::number(m_leftMeasure->GetLineResidual());
 
 2883    m_leftLineError->setText(s);
 
 2885    if (m_leftMeasure->GetSampleShift() == 
Null) {
 
 2886      s = 
"Sample Shift: Null";
 
 2889      s = 
"Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
 
 2891    m_leftSampShift->setText(s);
 
 2893    if (m_leftMeasure->GetLineShift() == 
Null) {
 
 2894      s = 
"Line Shift: Null";
 
 2897      s = 
"Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
 
 2899    m_leftLineShift->setText(s);
 
 2901    double goodnessOfFit = m_leftMeasure->GetLogData(
 
 2903    if (goodnessOfFit == 
Null) {
 
 2904      s = 
"Goodness of Fit: Null";
 
 2907      s = 
"Goodness of Fit: " + QString::number(goodnessOfFit);
 
 2909    m_leftGoodness->setText(s);
 
 
 2937                                        m_rightMeasure->GetCubeSerialNumber()));
 
 2939    m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
 
 2941    QString s = 
"Reference: ";
 
 2942    if (m_editPoint->IsReferenceExplicit() &&
 
 2943        (QString(m_rightMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
 
 2950    m_rightReference->setText(s);
 
 2952    s = 
"Measure Type: ";
 
 2957    m_rightMeasureType->setText(s);
 
 2959    if (m_rightMeasure->GetSampleResidual() == 
Null) {
 
 2960      s = 
"Sample Residual: Null";
 
 2963      s = 
"Sample Residual: " + QString::number(m_rightMeasure->GetSampleResidual());
 
 2965    m_rightSampError->setText(s);
 
 2966    if (m_rightMeasure->GetLineResidual() == 
Null) {
 
 2967      s = 
"Line Residual: Null";
 
 2970      s = 
"Line Residual: " + QString::number(m_rightMeasure->GetLineResidual());
 
 2972    m_rightLineError->setText(s);
 
 2974    if (m_rightMeasure->GetSampleShift() == 
Null) {
 
 2975      s = 
"Sample Shift: Null";
 
 2978      s = 
"Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
 
 2980    m_rightSampShift->setText(s);
 
 2982    if (m_rightMeasure->GetLineShift() == 
Null) {
 
 2983      s = 
"Line Shift: Null";
 
 2986      s = 
"Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
 
 2988    m_rightLineShift->setText(s);
 
 2990    double goodnessOfFit = m_rightMeasure->GetLogData(
 
 2992    if (goodnessOfFit == 
Null) {
 
 2993      s = 
"Goodness of Fit: Null";
 
 2996      s = 
"Goodness of Fit: " + QString::number(goodnessOfFit);
 
 2998    m_rightGoodness->setText(s);
 
 
 3033    cam = m_controlNet->Camera(camIndex);
 
 3035    cam->SetImage(m.GetSample(),m.GetLine());
 
 3036    lat = cam->UniversalLatitude();
 
 3037    lon = cam->UniversalLongitude();
 
 3039    for (
int i=0; i<m_serialNumberList->
size(); i++) {
 
 3040      cam = m_controlNet->Camera(i);
 
 3041      if (m_serialNumberList->
serialNumber(i) == m_groundSN) 
continue;
 
 3042      if (cam->SetUniversalGround(lat,lon)) {
 
 3044        double samp = cam->Sample();
 
 3045        double line = cam->Line();
 
 3046        if (samp >= 1 && samp <= cam->Samples() &&
 
 3047            line >= 1 && line <= cam->Lines()) {
 
 3048          pointFiles<<m_serialNumberList->
fileName(i);
 
 3054    newMeasureDialog->setFiles(*m_editPoint,pointFiles);
 
 3055    if (newMeasureDialog->exec()) {
 
 3056      QStringList selectedFiles = newMeasureDialog->selectedFiles();
 
 3057      foreach (QString selectedFile, selectedFiles) {
 
 3061        QString sn = m_serialNumberList->
serialNumber(selectedFile);
 
 3062        m->SetCubeSerialNumber(sn);
 
 3065        cam = m_controlNet->Camera(camIndex);
 
 3066        cam->SetUniversalGround(lat,lon);
 
 3067        m->SetCoordinate(cam->Sample(),cam->Line());
 
 3068        m->SetAprioriSample(cam->Sample());
 
 3069        m->SetAprioriLine(cam->Line());
 
 3072        m_editPoint->Add(m);
 
 3075      m_qnetTool->setVisible(
true);
 
 3076      m_qnetTool->raise();
 
 3079          m_pointEditor->templateFileName());
 
 3083      emit editPointChanged(m_editPoint->GetId());
 
 
 3100    if(e->type() != QEvent::Leave) 
return false;
 
 3101    if(o == m_leftCombo->view()) {
 
 3103      m_leftCombo->hidePopup();
 
 3105    if (o == m_rightCombo->view()) {
 
 3107      m_rightCombo->hidePopup();
 
 
 3147       vp->viewport()->update();
 
 
 3175    if (m_controlNet == 0 || m_controlNet->GetNumPoints() == 0) 
return;
 
 3182    if (serialNumber == m_groundSN) {
 
 3186    if (!m_controlNet->GetCubeSerials().contains(
 
 3187                      serialNumber)) 
return;
 
 3189    QList<ControlMeasure *> measures =
 
 3190        m_controlNet->GetMeasuresInCube(serialNumber);
 
 3192    for (
int i = 0; i < measures.count(); i++) {
 
 3195      double samp = m->GetSample();
 
 3196      double line = m->GetLine();
 
 3198      vp->cubeToViewport(samp, line, x, y);
 
 3200      if (m->Parent()->IsIgnored()) {
 
 3201        painter->setPen(QColor(255, 255, 0)); 
 
 3204      else if (m->IsIgnored()) {
 
 3205        painter->setPen(QColor(255, 255, 0)); 
 
 3209        painter->setPen(Qt::magenta);
 
 3212        painter->setPen(Qt::green); 
 
 3215      painter->drawLine(x - 5, y, x + 5, y);
 
 3216      painter->drawLine(x, y - 5, x, y + 5);
 
 3219    if (m_editPoint != NULL) {
 
 3221      if (m_editPoint->HasSerialNumber(serialNumber)) {
 
 3223        double samp = (*m_editPoint)[serialNumber]->GetSample();
 
 3224        double line = (*m_editPoint)[serialNumber]->GetLine();
 
 3226        vp->cubeToViewport(samp, line, x, y);
 
 3228        QBrush brush(Qt::red);
 
 3232        painter->setPen(pen);
 
 3233        painter->drawLine(x - 5, y, x + 5, y);
 
 3234        painter->drawLine(x, y - 5, x, y + 5);
 
 
 3254    for (
int i = 0; i < m_controlNet->GetNumPoints(); i++) {
 
 3257      if (!p.HasAprioriCoordinates()) 
continue;
 
 3260      if (m_groundGmap->SetGround(p.GetAprioriSurfacePoint().GetLatitude(),
 
 3261                                  p.GetAprioriSurfacePoint().GetLongitude())) {
 
 3262        double samp = m_groundGmap->Sample();
 
 3263        double line = m_groundGmap->Line();
 
 3265        vp->cubeToViewport(samp, line, x, y);
 
 3267        if (p.IsIgnored()) {
 
 3268          painter->setPen(QColor(255, 255, 0)); 
 
 3271          painter->setPen(Qt::magenta);
 
 3273        else if (&p == m_editPoint) {
 
 3275          QBrush brush(Qt::red);
 
 3280          painter->setPen(Qt::green); 
 
 3283        painter->drawLine(x - 5, y, x + 5, y);
 
 3284        painter->drawLine(x, y - 5, x, y + 5);
 
 
 3305    if (m_templateModified) {
 
 3306      int r = QMessageBox::warning(m_qnetTool, tr(
"OK to continue?"),
 
 3307          tr(
"The currently opened registration template has been modified.\n" 
 3309          QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
 
 3312      if (r == QMessageBox::Yes)
 
 3314      else if (r == QMessageBox::Cancel)
 
 
 3332    QString filename = QFileDialog::getOpenFileName(m_qnetTool,
 
 3333        "Select a registration template", 
".",
 
 3334        "Registration template files (*.def *.pvl);;All files (*)");
 
 3336    if (filename.isEmpty())
 
 3339    if (m_pointEditor->setTemplateFile(filename)) {
 
 
 3352    QFile file(
FileName(fn).expanded());
 
 3353    if (!file.open(QIODevice::ReadOnly)) {
 
 3354      QString msg = 
"Failed to open template file \"" + fn + 
"\"";
 
 3355      QMessageBox::warning(m_qnetTool, 
"IO Error", msg);
 
 3359    QTextStream stream(&file);
 
 3360    m_templateEditor->setText(stream.readAll());
 
 3363    QScrollBar * sb = m_templateEditor->verticalScrollBar();
 
 3364    sb->setValue(sb->minimum());
 
 3366    m_templateModified = 
false;
 
 3367    m_saveTemplateFile->setEnabled(
false);
 
 3368    m_templateFileNameLabel->setText(
"Template File: " + fn);
 
 
 3374    m_templateModified = 
true;
 
 3375    m_saveTemplateFile->setEnabled(
true);
 
 
 3382    if (!m_templateModified)
 
 3385    QString filename = m_pointEditor->templateFileName();
 
 
 3394    QString filename = QFileDialog::getSaveFileName(m_qnetTool,
 
 3395        "Save registration template", 
".",
 
 3396        "Registration template files (*.def *.pvl);;All files (*)");
 
 3398    if (filename.isEmpty())
 
 
 3412    QString contents = m_templateEditor->toPlainText();
 
 3422      QString message = e.toString();
 
 3423      QMessageBox::warning(m_qnetTool, 
"Error", message);
 
 3427    QString expandedFileName(
FileName(fn).expanded());
 
 3429    QFile file(expandedFileName);
 
 3431    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
 
 3432      QString msg = 
"Failed to save template file to \"" + fn + 
"\"\nDo you " 
 3434      QMessageBox::warning(m_qnetTool, 
"IO Error", msg);
 
 3439    QTextStream stream(&file);
 
 3443    if (m_pointEditor->setTemplateFile(fn)) {
 
 3444      m_templateModified = 
false;
 
 3445      m_saveTemplateFile->setEnabled(
false);
 
 3446      m_templateFileNameLabel->setText(
"Template File: " + fn);
 
 
 3467      Pvl templatePvl(m_pointEditor->templateFileName());
 
 3471      registrationDialog.setWindowTitle(
"View or Edit Template File: " 
 3472                                         + templatePvl.fileName());
 
 3473      registrationDialog.resize(550,360);
 
 3474      registrationDialog.exec();
 
 3477      QString message = e.toString();
 
 3478      QMessageBox::information(m_qnetTool, 
"Error", message);
 
 
 3491    m_pointEditor->saveChips();
 
 
 3495  void QnetTool::showHideTemplateEditor() {
 
 3497    if (!m_templateEditorWidget)
 
 3500    m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
 
 3518    if (m_editPoint == NULL) 
return;
 
 3519    if (pointId != m_editPoint->GetId()) 
return;
 
 3524    ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
 
 3525    m_editPoint->SetEditLock(updatedPoint->IsEditLocked());
 
 3526    m_editPoint->SetIgnored(updatedPoint->IsIgnored());
 
 3527    m_editPoint->SetAprioriSurfacePoint(updatedPoint->GetAprioriSurfacePoint());
 
 3530    m_lockPoint->setChecked(m_editPoint->IsEditLocked());
 
 3533    m_ignorePoint->setChecked(m_editPoint->IsIgnored());
 
 
 3562    if (m_editPoint != NULL) {
 
 3564        QString 
id = m_ptIdValue->text().remove(
"Point ID:  ");
 
 3565        m_controlNet->GetPoint(
id);
 
 3570        emit editPointChanged(
"");
 
 3571        m_qnetTool->setVisible(
false);
 
 3572        m_measureWindow->setVisible(
false);
 
 3576    if (m_editPoint == NULL) {
 
 
 3612    QToolButton *showNavToolButton = 
new QToolButton();
 
 3613    showNavToolButton->setText(
"Show Nav Tool");
 
 3614    showNavToolButton->setToolTip(
"Shows the Navigation Tool Window");
 
 3616    "<b>Function:</b> This button will bring up the Navigation Tool window that allows \ 
 3617     the user to view, modify, ignore, delete, or filter points and cubes.";
 
 3618    showNavToolButton->setWhatsThis(text);
 
 3619    connect(showNavToolButton,SIGNAL(clicked(
bool)),
this,SLOT(
showNavWindow(
bool)));
 
 3621    QHBoxLayout *layout = 
new QHBoxLayout(hbox);
 
 3622    layout->setMargin(0);
 
 3623    layout->addWidget(showNavToolButton);
 
 3624    layout->addStretch(1);
 
 3625    hbox->setLayout(layout);
 
 
 3652    QString filter = 
"Isis cubes (*.cub *.cub.*);;";
 
 3653    filter += 
"Detached labels (*.lbl);;";
 
 3654    filter += 
"All (*)";
 
 3656    QString ground = QFileDialog::getOpenFileName((
QWidget*)parent(),
 
 3657                                                  "Open ground source",
 
 3660    if (ground.isEmpty()) 
return;
 
 3666    if (m_groundOpen && m_groundFile == 
FileName(ground).name()) {
 
 3672        if (vp->cube()->fileName() == ground) {
 
 3673          m_workspace->mdiArea()->setActiveSubWindow(
 
 3682    if (newGroundSN != m_groundSN && m_serialNumberList->
hasSerialNumber(newGroundSN)) {
 
 3685      QString message = 
"A cube in the cube list has the same serial number as this ground file.  ";
 
 3686      message += 
"If this ground source is a level 1, un-projected cube, it is probably included ";
 
 3687      message += 
"in the cube list.  If the ground source is a projected version of a cube in ";
 
 3688      message += 
"the list and has the Instrument Group in the labels, the un-projected and ";
 
 3689      message += 
"projected cube will have the same serial number. \n";
 
 3690      message += 
"Because of duplicate serial numbers this cube cannot be used as a ground ";
 
 3691      message += 
"source.\n\n";
 
 3692      message += 
"NOTE:  If this cube is the reference cube you can select points in ";
 
 3693      message += 
"the Navigator window, then select the Set Apriori button to use this cube to ";
 
 3694      message += 
"set the apriori latitude, longitude and radius.";
 
 3695      QMessageBox::critical(m_qnetTool, 
"Cannot set ground source", message);
 
 3704      clearGroundSource ();
 
 3707    QApplication::setOverrideCursor(Qt::WaitCursor);
 
 3712    m_groundCube.reset(NULL);
 
 3713    m_groundGmap.reset(NULL);
 
 3716      QScopedPointer<Cube> newGroundCube(
new Cube(ground, 
"r"));
 
 3717      QScopedPointer<UniversalGroundMap> newGroundGmap(
new UniversalGroundMap(*newGroundCube));
 
 3719      m_groundFile = 
FileName(newGroundCube->fileName()).
name();
 
 3720      m_groundCube.reset(newGroundCube.take());
 
 3721      m_groundGmap.reset(newGroundGmap.take());
 
 3723      m_serialNumberList->
add(ground, 
true);
 
 3726      QApplication::restoreOverrideCursor();
 
 3727      QMessageBox::critical(m_qnetTool, 
"Error", e.toString());
 
 3729      m_groundFile.clear();
 
 3736      emit refreshNavList();
 
 3740    m_groundSN = newGroundSN;
 
 3741    m_groundSourceFile = ground;
 
 3742    m_groundOpen = 
true;
 
 3744    m_workspace->addCubeViewport(m_groundCube.data());
 
 3751      if (vp->cube()->fileName() == ground) {
 
 3759      if (m_editPoint != NULL) {
 
 3765      else if (m_groundCube->hasTable(
"ShapeModelStatistics")) {
 
 3766        m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
 
 3768          m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
 
 3769          m_radiusSourceFile = ground;
 
 3776          m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
 
 3778            m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
 
 3779            m_radiusSourceFile = 
"";
 
 3785            m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Reference;
 
 3787              PvlGroup kernels = m_groundCube->group(
"Kernels");
 
 3788              QString shapeFile = kernels [
"ShapeModel"];
 
 3789              if (shapeFile.contains(
"dem")) {
 
 3790                m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
 
 3791                m_radiusSourceFile = shapeFile;
 
 3794                m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
 
 3796                m_radiusSourceFile = (QString) kernels[
"TargetAttitudeShape"];
 
 3801            QString message = 
"Cannot create either Camera or Projections ";
 
 3802            message += 
"for the ground source file.  Check the validity of the ";
 
 3803            message += 
" cube labels.  The cube must either be projected or ";
 
 3804            message += 
" run through spiceinit.";
 
 3805            QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 3807            clearGroundSource ();
 
 3808            QApplication::restoreOverrideCursor();
 
 3809            emit refreshNavList();
 
 3816    if (m_editPoint != NULL &&
 
 3820    emit refreshNavList();
 
 3821    QApplication::restoreOverrideCursor();
 
 
 3834      if (m_groundFile.isEmpty()) {
 
 3835        QString message = 
"You must enter a ground source before opening a Dem.";
 
 3836        QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 3840      QString filter = 
"Isis cubes (*.cub *.cub.*);;";
 
 3841      filter += 
"Detached labels (*.lbl);;";
 
 3842      filter += 
"All (*)";
 
 3843      QString dem = QFileDialog::getOpenFileName((
QWidget*)parent(),
 
 3847      if (dem.isEmpty()) 
return;
 
 
 3862    QString referenceSN = m_editPoint->GetReferenceSN();
 
 3863    QString referenceFileName = m_serialNumberList->
fileName(referenceSN);
 
 3864    QScopedPointer<Cube> referenceCube(
new Cube(referenceFileName, 
"r"));
 
 3865    PvlGroup kernels = referenceCube->group(
"Kernels");
 
 3866    QString shapeFile = kernels[
"ShapeModel"];
 
 3871    if (shapeFile.contains(
".cub")) {
 
 3872      if (shapeFile.contains(
"dem")) {
 
 3873        m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
 
 3876        m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
 
 3879      m_radiusSourceFile = shapeFile;
 
 3887      m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
 
 3890      refSpice->radii(refRadii);
 
 3891      m_demFile = QString::number(refRadii[0].meters()) + 
", " +
 
 3892                  QString::number(refRadii[1].meters()) + 
", " +
 
 3893                  QString::number(refRadii[2].meters());
 
 3895      m_radiusSourceFile = 
"";
 
 3898      m_groundFileNameLabel->setText(
"Ground Source File:  " + m_groundFile);
 
 3899      m_radiusFileNameLabel->setText(
"Radius Source:  " + m_demFile);
 
 
 3903  void QnetTool::initDem (QString demFile) {
 
 3907      QApplication::setOverrideCursor(Qt::WaitCursor);
 
 3909        if (m_demFile == demFile) {
 
 3910          QApplication::restoreOverrideCursor();
 
 3914        m_demCube.reset(NULL);
 
 3919        QScopedPointer<Cube> newDemCube(
new Cube(demFile, 
"r"));
 
 3921        m_demFile = FileName(newDemCube->fileName()).name();
 
 3922        m_demCube.reset(newDemCube.take());
 
 3924      catch (IException &e) {
 
 3925        QMessageBox::critical(m_qnetTool, 
"Error", e.toString());
 
 3926        QApplication::restoreOverrideCursor();
 
 3932      if (!m_demCube->hasTable(
"ShapeModelStatistics")) {
 
 3933        QString message = m_demFile + 
" is not a DEM.";
 
 3934        QMessageBox::critical(m_qnetTool, 
"Error", message);
 
 3935        m_demCube.reset(NULL);
 
 3938        QApplication::restoreOverrideCursor();
 
 3941      m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
 
 3942      m_groundFileNameLabel->setText(
"Ground Source File:  " + m_groundFile);
 
 3943      m_radiusFileNameLabel->setText(
"Radius Source File:  " + m_demFile);
 
 3944      m_radiusSourceFile = demFile;
 
 3946      QApplication::restoreOverrideCursor();
 
 3961    clearGroundSource();
 
 
 3966  void QnetTool::clearGroundSource () {
 
 3968    m_leftCombo->removeItem(m_leftCombo->findText(m_groundFile));
 
 3969    m_rightCombo->removeItem(m_rightCombo->findText(m_groundFile));
 
 3975      if (vp->cube() == m_groundCube.data()) {
 
 3980        vp->parentWidget()->parentWidget()->close();
 
 3981        QApplication::processEvents();
 
 3987    m_groundOpen = 
false;
 
 3988    m_groundCube.take();
 
 3989    m_groundFile.clear();
 
 3990    m_groundGmap.reset(NULL);
 
 3992    m_groundFileNameLabel->setText(
"Ground Source File:  ");
 
 3994      m_radiusFileNameLabel->setText(
"Radius Source File:  " + m_demFile);
 
 3998    m_serialNumberList->
remove(m_groundSN);
 
 4004        m_editPoint->HasSerialNumber(m_groundSN)) {
 
 4005      m_editPoint->Delete(m_groundSN);
 
 4027    if (!m_demOpen) 
return Null;
 
 4030    if (!demMap->SetUniversalGround(latitude, longitude)) {
 
 4041    Portal *portal = 
new Portal(interp->Samples(), interp->Lines(),
 
 4042                                m_demCube->pixelType(),
 
 4043                                interp->HotSample(), interp->HotLine());
 
 4044    portal->SetPosition(demMap->Sample(), demMap->Line(), 1);
 
 4045    m_demCube->read(*portal);
 
 4046    double radius = interp->Interpolate(demMap->Sample(), demMap->Line(),
 
 4047                                        portal->DoubleBuffer());
 
 
 4070    QColor qc = Qt::red;
 
 4071    QPalette p = m_savePoint->palette();
 
 4072    p.setColor(QPalette::ButtonText,qc);
 
 4073    m_savePoint->setPalette(p);
 
 
 4093    if (m_editPoint == NULL) 
return false;
 
 4096    if (m_editPoint->IsEditLocked() && m_editPoint->IsReferenceExplicit() &&
 
 4097        (m_editPoint->GetReferenceSN() == serialNumber)) {
 
 4102      return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
 
 
 4115    FileName config(
"$HOME/.Isis/qnet/QnetTool.config");
 
 4116    QSettings settings(config.expanded(), QSettings::NativeFormat);
 
 4117    QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
 
 4118    QSize size = settings.value(
"size", QSize(900, 500)).toSize();
 
 4119    m_qnetTool->resize(size);
 
 4120    m_qnetTool->move(pos);
 
 
 4133    if(!m_qnetTool->isVisible()) 
return;
 
 4134    FileName config(
"$HOME/.Isis/qnet/QnetTool.config");
 
 4135    QSettings settings(config.expanded(), QSettings::NativeFormat);
 
 4136    settings.setValue(
"pos", m_qnetTool->pos());
 
 4137    settings.setValue(
"size", m_qnetTool->size());
 
 
 4142  void QnetTool::enterWhatsThisMode() {
 
 4143    QWhatsThis::enterWhatsThisMode();
 
double degrees() const
Get the angle in units of Degrees.
 
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
 
static QString UserName()
Returns the user name.
 
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
 
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
 
static QString MeasureTypeToString(MeasureType type)
Return the String Control Measure type.
 
@ Manual
Hand Measured (e.g., qnet)
 
@ Candidate
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
 
@ RegisteredSubPixel
Registered to sub-pixel (e.g., pointreg)
 
@ RegisteredPixel
Registered to whole pixel (e.g.,pointreg)
 
@ GoodnessOfFit
GoodnessOfFit is pointreg information for reference measures.
 
Status
This is a return status for many of the mutating (setter) method calls.
 
@ PointLocked
This is returned when the operation requires Edit Lock to be false but it is currently true.
 
Status SetChooserName(QString name)
Set the point's chooser name.
 
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
 
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
 
PointType GetType() const
 
PointType
These are the valid 'types' of point.
 
@ Constrained
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
 
@ Free
A Free point is a Control Point that identifies common measurements between two or more cubes.
 
@ Fixed
A Fixed point is a Control Point whose lat/lon is well established and should not be changed.
 
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
 
QString GetId() const
Return the Id of the control point.
 
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
 
IO Handler for Isis Cubes.
 
Widget to display Isis cubes for qt apps.
 
Distance measurement, usually in meters.
 
@ Meters
The distance is being specified in meters.
 
double meters() const
Get the distance in meters.
 
File name manipulation and expansion.
 
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
 
@ Programmer
This error is for when a programmer made an API call that was illegal.
 
This class is designed to encapsulate the concept of a Latitude.
 
This class is designed to encapsulate the concept of a Longitude.
 
Base class for the Qisis main windows.
 
Cube display widget for certain Isis MDI applications.
 
Buffer for containing a two dimensional section of an image.
 
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
 
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file.
 
Contains multiple PvlContainers.
 
Container for cube-like labels.
 
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
 
Serial Number list generator.
 
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
 
void remove(const QString &sn)
Remove the specified serial number from the list.
 
QString serialNumber(const QString &filename)
Return a serial number given a filename.
 
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
 
int size() const
How many serial number / filename combos are in the list.
 
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
 
int fileNameIndex(const QString &filename)
Return a list index given a filename.
 
QString fileName(const QString &sn)
Return a filename given a serial number.
 
Obtain SPICE information for a spacecraft.
 
This class defines a body-fixed surface point.
 
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
 
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
 
Distance GetLocalRadius() const
Return the radius of the surface point.
 
This is free and unencumbered software released into the public domain.
 
const double Null
Value for an Isis Null pixel.
 
Namespace for the standard library.