USGS

Isis 3.0 Object Programmers' Reference

Home

QnetTool.cpp
1 #include "QnetTool.h"
2 
3 #include <sstream>
4 #include <vector>
5 #include <iomanip>
6 
7 #include <QtGui>
8 
9 #include "QnetDeletePointDialog.h"
10 #include "QnetNewMeasureDialog.h"
11 #include "QnetNewPointDialog.h"
12 #include "QnetFixedPointDialog.h"
13 #include "Workspace.h"
14 
15 #include "Application.h"
16 #include "Brick.h"
17 #include "Camera.h"
18 #include "CameraFactory.h"
19 #include "ControlMeasure.h"
20 #include "ControlMeasureLogData.h"
21 #include "ControlNet.h"
22 #include "ControlPoint.h"
23 #include "ControlPointEdit.h"
24 #include "Distance.h"
25 #include "FileName.h"
26 #include "IException.h"
27 #include "Latitude.h"
28 #include "Longitude.h"
29 #include "MainWindow.h"
30 #include "MdiCubeViewport.h"
31 #include "Projection.h"
32 #include "ProjectionFactory.h"
33 #include "Pvl.h"
34 #include "PvlEditDialog.h"
35 #include "SerialNumber.h"
36 #include "SpecialPixel.h"
37 #include "SurfacePoint.h"
38 #include "ToolPad.h"
39 #include "UniversalGroundMap.h"
40 #include "ViewportMainWindow.h"
41 
42 using namespace std;
43 
44 namespace Isis {
45  const int VIEWSIZE = 301;
46  const int CHIPVIEWPORT_WIDTH = 310;
47 
48 
58  QnetTool::QnetTool (QWidget *parent) : Tool(parent) {
59  m_controlNet = NULL;
60  m_demOpen = false;
61  m_groundOpen = false;
62  m_serialNumberList = NULL;
63  m_templateModified = false;
64 
65  m_controlNet = new ControlNet;
66  m_serialNumberList = new SerialNumberList;
67 
68  if (qobject_cast<Workspace *>(parent)) {
69  m_workspace = qobject_cast<Workspace *>(parent);
70  }
71  else if (qobject_cast<ViewportMainWindow *>(parent)) {
72  m_workspace = qobject_cast<ViewportMainWindow *>(parent)->workspace();
73  }
74  else {
76  tr("Could not find the workspace with the given parent, expected a Workspace or "
77  "ViewportMainWindow."),
78  _FILEINFO_);
79  }
80 
81  createQnetTool(parent);
82  }
83 
84 
85  QnetTool::~QnetTool () {
86  writeSettings();
87 
88  delete m_editPoint;
89  delete m_leftMeasure;
90  delete m_rightMeasure;
91  delete m_measureTable;
92  delete m_measureWindow;
93  }
94 
95 
96 
121 
122  m_qnetTool = new MainWindow("Qnet Tool", parent);
123  m_qnetTool->setObjectName("QnetTool");
124 
125  createActions();
126  createMenus();
127  createToolBars();
128 
129  // create m_pointEditor first since we need to get its templateFileName
130  // later
131  m_pointEditor = new ControlPointEdit(m_controlNet, parent);
132  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
133  m_pointEditor, SIGNAL(newControlNetwork(ControlNet *)));
134  connect(this,
135  SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
136  m_pointEditor,
137  SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)));
138  connect(m_pointEditor, SIGNAL(measureSaved()), this, SLOT(measureSaved()));
139  connect(this, SIGNAL(measureChanged()),
140  m_pointEditor, SLOT(colorizeSaveButton()));
141 
142  QPushButton * addMeasure = new QPushButton("Add Measure(s) to Point");
143  addMeasure->setToolTip("Add a new measure to the edit control point.");
144  addMeasure->setWhatsThis("This allows a new control measure to be added "
145  "to the currently edited control point. A selection "
146  "box with all cubes from the input list will be "
147  "displayed with those that intersect with the "
148  "control point highlighted.");
149  connect(addMeasure, SIGNAL(clicked()), this, SLOT(addMeasure()));
150 
151  m_savePoint = new QPushButton ("Save Point");
152  m_savePoint->setToolTip("Save the edit control point to the control "
153  "network.");
154  m_savePoint->setWhatsThis("Save the edit control point to the control "
155  "network which is loaded into memory in its entirety. "
156  "When a control point is selected for editing, "
157  "a copy of the point is made so that the original control "
158  "point remains in the network.");
159  m_saveDefaultPalette = m_savePoint->palette();
160  connect (m_savePoint,SIGNAL(clicked()),this,SLOT(savePoint()));
161 
162  QHBoxLayout * addMeasureLayout = new QHBoxLayout;
163  addMeasureLayout->addWidget(addMeasure);
164  addMeasureLayout->addWidget(m_savePoint);
165 // addMeasureLayout->addStretch();
166 
167  m_templateFileNameLabel = new QLabel("Template File: " +
168  m_pointEditor->templateFileName());
169  m_templateFileNameLabel->setToolTip("Sub-pixel registration template File.");
170 // QString patternMatchDoc =
171 // FileName("$ISISROOT/doc/documents/PatternMatch/PatternMatch.html").fileName();
172 // m_templateFileNameLabel->setOpenExternalLinks(true);
173  m_templateFileNameLabel->setWhatsThis("FileName of the sub-pixel "
174  "registration template. Refer to $ISISROOT/doc/documents/"
175  "PatternMatch/PatternMatch.html for a description of the "
176  "contents of this file.");
177 
178  m_groundFileNameLabel = new QLabel("Ground Source File: ");
179  m_groundFileNameLabel->setToolTip("Cube used to create ground control "
180  "points, either Fixed or Constrained.");
181  m_groundFileNameLabel->setWhatsThis("This cube is used to create ground "
182  "control points, Fixed or Constrained. This may "
183  "be a Dem, a shaded relief version of a Dem, "
184  "a projected basemap or an unprojected cube with "
185  "corrected camera pointing. This will be used "
186  "to set the apriori latitude, longitude.");
187  m_radiusFileNameLabel = new QLabel("Radius Source File: ");
188  m_radiusFileNameLabel->setToolTip("Dem used to set the radius of ground "
189  "control points, Fixed or Constrained. This must "
190  "be a Dem and is strictly used to set the apriori "
191  "radius for ground control points.");
192 
193  QVBoxLayout * centralLayout = new QVBoxLayout;
194 
195  centralLayout->addWidget(m_templateFileNameLabel);
196  centralLayout->addWidget(m_groundFileNameLabel);
197  centralLayout->addWidget(m_radiusFileNameLabel);
198  centralLayout->addWidget(createTopSplitter());
199  centralLayout->addStretch();
200  centralLayout->addWidget(m_pointEditor);
201  centralLayout->addLayout(addMeasureLayout);
202  QWidget * centralWidget = new QWidget;
203  centralWidget->setLayout(centralLayout);
204 
205  QScrollArea *scrollArea = new QScrollArea();
206  scrollArea->setObjectName("QnetToolScroll");
207  scrollArea->setWidget(centralWidget);
208  scrollArea->setWidgetResizable(true);
209  centralWidget->adjustSize();
210  m_qnetTool->setCentralWidget(scrollArea);
211 // m_qnetTool->setCentralWidget(centralWidget);
212 
213 
214  connect(this, SIGNAL(editPointChanged(QString)),
215  this, SLOT(paintAllViewports(QString)));
216 
217  readSettings();
218  }
219 
220 
223 
224  QHBoxLayout * measureLayout = new QHBoxLayout;
225  measureLayout->addWidget(createLeftMeasureGroupBox());
226  measureLayout->addWidget(createRightMeasureGroupBox());
227 
228  QVBoxLayout * groupBoxesLayout = new QVBoxLayout;
229  groupBoxesLayout->addWidget(createControlPointGroupBox());
230  groupBoxesLayout->addStretch();
231  groupBoxesLayout->addLayout(measureLayout);
232 
233  QWidget * groupBoxesWidget = new QWidget;
234  groupBoxesWidget->setLayout(groupBoxesLayout);
235 
237 
238  QSplitter * topSplitter = new QSplitter;
239  topSplitter->addWidget(groupBoxesWidget);
240  topSplitter->addWidget(m_templateEditorWidget);
241  topSplitter->setStretchFactor(0, 4);
242  topSplitter->setStretchFactor(1, 3);
243 
244  m_templateEditorWidget->hide();
245 
246  return topSplitter;
247  }
248 
249 
252 
253  // create left vertical layout
254  m_ptIdValue = new QLabel;
255  m_pointType = new QComboBox;
256  for (int i=0; i<ControlPoint::PointTypeCount; i++) {
257  m_pointType->insertItem(i, ControlPoint::PointTypeToString(
259  }
260  QHBoxLayout *pointTypeLayout = new QHBoxLayout;
261  QLabel *pointTypeLabel = new QLabel("PointType:");
262  pointTypeLayout->addWidget(pointTypeLabel);
263  pointTypeLayout->addWidget(m_pointType);
264  connect(m_pointType, SIGNAL(activated(int)),
265  this, SLOT(setPointType(int)));
266  m_numMeasures = new QLabel;
267  m_pointAprioriLatitude = new QLabel;
268  m_pointAprioriLongitude = new QLabel;
269  m_pointAprioriRadius = new QLabel;
270  m_pointAprioriLatitudeSigma = new QLabel;
271  m_pointAprioriLongitudeSigma = new QLabel;
272  m_pointAprioriRadiusSigma = new QLabel;
273  QVBoxLayout * leftLayout = new QVBoxLayout;
274  leftLayout->addWidget(m_ptIdValue);
275  leftLayout->addLayout(pointTypeLayout);
276  leftLayout->addWidget(m_pointAprioriLatitude);
277  leftLayout->addWidget(m_pointAprioriLongitude);
278  leftLayout->addWidget(m_pointAprioriRadius);
279  leftLayout->addWidget(m_pointAprioriLatitudeSigma);
280  leftLayout->addWidget(m_pointAprioriLongitudeSigma);
281  leftLayout->addWidget(m_pointAprioriRadiusSigma);
282 
283  // create right vertical layout's top layout
284  m_lockPoint = new QCheckBox("Edit Lock Point");
285  connect(m_lockPoint, SIGNAL(clicked(bool)), this, SLOT(setLockPoint(bool)));
286  m_ignorePoint = new QCheckBox("Ignore Point");
287  connect(m_ignorePoint, SIGNAL(clicked(bool)),
288  this, SLOT(setIgnorePoint(bool)));
289  connect(this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
290  m_pointLatitude = new QLabel;
291  m_pointLongitude = new QLabel;
292  m_pointRadius = new QLabel;
293 
294  QVBoxLayout * rightLayout = new QVBoxLayout;
295  rightLayout->addWidget(m_numMeasures);
296  rightLayout->addWidget(m_lockPoint);
297  rightLayout->addWidget(m_ignorePoint);
298  rightLayout->addWidget(m_pointLatitude);
299  rightLayout->addWidget(m_pointLongitude);
300  rightLayout->addWidget(m_pointRadius);
301 
302 
303  QHBoxLayout * mainLayout = new QHBoxLayout;
304  mainLayout->addLayout(leftLayout);
305  mainLayout->addStretch();
306  mainLayout->addLayout(rightLayout);
307 
308  // create the groupbox
309  QGroupBox * groupBox = new QGroupBox("Control Point");
310  groupBox->setLayout(mainLayout);
311 
312  return groupBox;
313  }
314 
315 
318 
319  m_leftCombo = new QComboBox;
320  m_leftCombo->view()->installEventFilter(this);
321  m_leftCombo->setToolTip("Choose left control measure");
322  m_leftCombo->setWhatsThis("Choose left control measure identified by "
323  "cube filename.");
324  connect(m_leftCombo, SIGNAL(activated(int)),
325  this, SLOT(selectLeftMeasure(int)));
326  m_lockLeftMeasure = new QCheckBox("Edit Lock Measure");
327  connect(m_lockLeftMeasure, SIGNAL(clicked(bool)),
328  this, SLOT(setLockLeftMeasure(bool)));
329  m_ignoreLeftMeasure = new QCheckBox("Ignore Measure");
330  connect(m_ignoreLeftMeasure, SIGNAL(clicked(bool)),
331  this, SLOT(setIgnoreLeftMeasure(bool)));
332  connect(this, SIGNAL(ignoreLeftChanged()),
333  m_ignoreLeftMeasure, SLOT(toggle()));
334  m_leftReference = new QLabel();
335  m_leftMeasureType = new QLabel();
336  m_leftSampError = new QLabel();
337  m_leftSampError->setToolTip("<strong>Jigsaw</strong> sample residual.");
338  m_leftSampError->setWhatsThis("This is the sample residual for the left "
339  "measure calculated by the application, "
340  "<strong>jigsaw</strong>.");
341  m_leftLineError = new QLabel();
342  m_leftLineError->setToolTip("<strong>Jigsaw</strong> line residual.");
343  m_leftLineError->setWhatsThis("This is the line residual for the left "
344  "measure calculated by the application, "
345  "<strong>jigsaw</strong>.");
346  m_leftSampShift = new QLabel();
347  m_leftSampShift->setToolTip("Sample shift between apriori and current");
348  m_leftSampShift->setWhatsThis("The shift between the apriori sample and "
349  "the current sample. The apriori sample is set "
350  "when creating a new measure.");
351  m_leftLineShift = new QLabel();
352  m_leftLineShift->setToolTip("Line shift between apriori and current");
353  m_leftLineShift->setWhatsThis("The shift between the apriori line and "
354  "the current line. The apriori line is set "
355  "when creating a new measure.");
356  m_leftGoodness = new QLabel();
357  m_leftGoodness->setToolTip("Goodness of Fit result from sub-pixel "
358  "registration.");
359  m_leftGoodness->setWhatsThis("Resulting Goodness of Fit from sub-pixel "
360  "registration.");
361  QVBoxLayout * leftLayout = new QVBoxLayout;
362  leftLayout->addWidget(m_leftCombo);
363  leftLayout->addWidget(m_lockLeftMeasure);
364  leftLayout->addWidget(m_ignoreLeftMeasure);
365  leftLayout->addWidget(m_leftReference);
366  leftLayout->addWidget(m_leftMeasureType);
367  leftLayout->addWidget(m_leftSampError);
368  leftLayout->addWidget(m_leftLineError);
369  leftLayout->addWidget(m_leftSampShift);
370  leftLayout->addWidget(m_leftLineShift);
371  leftLayout->addWidget(m_leftGoodness);
372 
373  QGroupBox * leftGroupBox = new QGroupBox("Left Measure");
374  leftGroupBox->setLayout(leftLayout);
375 
376  return leftGroupBox;
377  }
378 
379 
382 
383  // create widgets for the right groupbox
384  m_rightCombo = new QComboBox;
385  m_rightCombo->view()->installEventFilter(this);
386  m_rightCombo->setToolTip("Choose right control measure");
387  m_rightCombo->setWhatsThis("Choose right control measure identified by "
388  "cube filename.");
389  connect(m_rightCombo, SIGNAL(activated(int)),
390  this, SLOT(selectRightMeasure(int)));
391  m_lockRightMeasure = new QCheckBox("Edit Lock Measure");
392  connect(m_lockRightMeasure, SIGNAL(clicked(bool)),
393  this, SLOT(setLockRightMeasure(bool)));
394  m_ignoreRightMeasure = new QCheckBox("Ignore Measure");
395  connect(m_ignoreRightMeasure, SIGNAL(clicked(bool)),
396  this, SLOT(setIgnoreRightMeasure(bool)));
397  connect(this, SIGNAL(ignoreRightChanged()),
398  m_ignoreRightMeasure, SLOT(toggle()));
399  m_rightReference = new QLabel();
400  m_rightMeasureType = new QLabel();
401  m_rightSampError = new QLabel();
402  m_rightSampError->setToolTip("<strong>Jigsaw</strong> sample residual.");
403  m_rightSampError->setWhatsThis("This is the sample residual for the right "
404  "measure which was calculated by the application, "
405  "<strong>jigsaw</strong>.");
406  m_rightLineError = new QLabel();
407  m_rightLineError->setToolTip("<strong>Jigsaw</strong> line residual.");
408  m_rightLineError->setWhatsThis("This is the line residual for the right "
409  "measure which was calculated by the application, "
410  "<strong>jigsaw</strong>.");
411  m_rightSampShift = new QLabel();
412  m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
413  m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
414  m_rightLineShift = new QLabel();
415  m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
416  m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
417  m_rightGoodness = new QLabel();
418  m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
419  m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
420 
421  // create right groupbox
422  QVBoxLayout * rightLayout = new QVBoxLayout;
423  rightLayout->addWidget(m_rightCombo);
424  rightLayout->addWidget(m_lockRightMeasure);
425  rightLayout->addWidget(m_ignoreRightMeasure);
426  rightLayout->addWidget(m_rightReference);
427  rightLayout->addWidget(m_rightMeasureType);
428  rightLayout->addWidget(m_rightSampError);
429  rightLayout->addWidget(m_rightLineError);
430  rightLayout->addWidget(m_rightSampShift);
431  rightLayout->addWidget(m_rightLineShift);
432  rightLayout->addWidget(m_rightGoodness);
433 
434  QGroupBox * rightGroupBox = new QGroupBox("Right Measure");
435  rightGroupBox->setLayout(rightLayout);
436 
437  return rightGroupBox;
438  }
439 
440 
443 
444  QToolBar *toolBar = new QToolBar("Template Editor ToolBar");
445 
446  toolBar->addAction(m_openTemplateFile);
447  toolBar->addSeparator();
448  toolBar->addAction(m_saveTemplateFile);
449  toolBar->addAction(m_saveTemplateFileAs);
450 
451  m_templateEditor = new QTextEdit;
452  connect(m_templateEditor, SIGNAL(textChanged()), this,
453  SLOT(setTemplateModified()));
454 
455  QVBoxLayout *mainLayout = new QVBoxLayout;
456  mainLayout->addWidget(toolBar);
457  mainLayout->addWidget(m_templateEditor);
458 
459  m_templateEditorWidget = new QWidget;
460  m_templateEditorWidget->setLayout(mainLayout);
461  }
462 
463 
464 
465  void QnetTool::createActions() {
466  m_openGround = new QAction(m_qnetTool);
467  m_openGround->setText("Open &Ground Source");
468  m_openGround->setToolTip("Open a ground source for choosing ground control "
469  "points");
470  m_openGround->setStatusTip("Open a ground source for choosing ground "
471  "control points");
472  QString whatsThis =
473  "<b>Function:</b> Open and display a ground source for choosing "
474  "ground control points, both Fixed and Constrained."
475  "This cube can be a level1, level2 or dem cube.";
476  m_openGround->setWhatsThis(whatsThis);
477  connect (m_openGround,SIGNAL(activated()),this,SLOT(openGround()));
478 
479  m_openDem = new QAction(m_qnetTool);
480  m_openDem->setText("Open &Radius Source");
481  m_openDem->setToolTip("Open radius source file for ground control points");
482  m_openDem->setStatusTip("Open radius source file for ground control points");
483  whatsThis =
484  "<b>Function:</b> Open a DEM for determining the radius when "
485  "choosing ground control points. This is not the file that will be "
486  "displayed for visually picking points. This is strictly used to "
487  "determine the radius value for ground control points.";
488  m_openDem->setWhatsThis(whatsThis);
489  connect (m_openDem,SIGNAL(activated()),this,SLOT(openDem()));
490 
491  m_saveNet = new QAction(QIcon(":save"), "Save Control Network ...",
492  m_qnetTool);
493  m_saveNet->setToolTip("Save current control network");
494  m_saveNet->setStatusTip("Save current control network");
495  whatsThis = "<b>Function:</b> Saves the current <i>"
496  "control network</i>";
497  m_saveNet->setWhatsThis(whatsThis);
498  connect(m_saveNet, SIGNAL(activated()), this, SLOT(saveNet()));
499 
500  m_saveAsNet = new QAction(QIcon(":saveAs"), "Save Control Network &As...",
501  m_qnetTool);
502  m_saveAsNet->setToolTip("Save current control network to chosen file");
503  m_saveAsNet->setStatusTip("Save current control network to chosen file");
504  whatsThis = "<b>Function:</b> Saves the current <i>"
505  "control network</i> under chosen filename";
506  m_saveAsNet->setWhatsThis(whatsThis);
507  connect(m_saveAsNet, SIGNAL(activated()), this, SLOT(saveAsNet()));
508 
509  m_closeQnetTool = new QAction(QIcon(":close"), "&Close", m_qnetTool);
510  m_closeQnetTool->setToolTip("Close this window");
511  m_closeQnetTool->setStatusTip("Close this window");
512  m_closeQnetTool->setShortcut(Qt::ALT + Qt::Key_F4);
513  whatsThis = "<b>Function:</b> Closes the Qnet Tool window for this point "
514  "<p><b>Shortcut:</b> Alt+F4 </p>";
515  m_closeQnetTool->setWhatsThis(whatsThis);
516  connect(m_closeQnetTool, SIGNAL(activated()), m_qnetTool, SLOT(close()));
517 
518  m_showHideTemplateEditor = new QAction(QIcon(":view_edit"),
519  "&View/edit registration template", m_qnetTool);
520  m_showHideTemplateEditor->setCheckable(true);
521  m_showHideTemplateEditor->setToolTip("View and/or edit the registration "
522  "template");
523  m_showHideTemplateEditor->setStatusTip("View and/or edit the registration "
524  "template");
525  whatsThis = "<b>Function:</b> Displays the curent registration template. "
526  "The user may edit and save changes under a chosen filename.";
527  m_showHideTemplateEditor->setWhatsThis(whatsThis);
528  connect(m_showHideTemplateEditor, SIGNAL(activated()), this,
529  SLOT(showHideTemplateEditor()));
530 
531  m_saveChips = new QAction(QIcon(":window_new"), "Save registration chips",
532  m_qnetTool);
533  m_saveChips->setToolTip("Save registration chips");
534  m_saveChips->setStatusTip("Save registration chips");
535  whatsThis = "<b>Function:</b> Save registration chips to file. "
536  "Each chip: pattern, search, fit will be saved to a separate file.";
537  m_saveChips->setWhatsThis(whatsThis);
538  connect(m_saveChips, SIGNAL(activated()), this, SLOT(saveChips()));
539 
540  m_openTemplateFile = new QAction(QIcon(":open"), "&Open registration "
541  "template", m_qnetTool);
542  m_openTemplateFile->setToolTip("Set registration template");
543  m_openTemplateFile->setStatusTip("Set registration template");
544  whatsThis = "<b>Function:</b> Allows user to select a new file to set as "
545  "the registration template";
546  m_openTemplateFile->setWhatsThis(whatsThis);
547  connect(m_openTemplateFile, SIGNAL(activated()), this, SLOT(openTemplateFile()));
548 
549  m_saveTemplateFile = new QAction(QIcon(":save"), "&Save template file",
550  m_qnetTool);
551  m_saveTemplateFile->setToolTip("Save the template file");
552  m_saveTemplateFile->setStatusTip("Save the template file");
553  m_saveTemplateFile->setWhatsThis("Save the registration template file");
554  connect(m_saveTemplateFile, SIGNAL(triggered()), this,
555  SLOT(saveTemplateFile()));
556 
557  m_saveTemplateFileAs = new QAction(QIcon(":saveAs"), "&Save template as...",
558  m_qnetTool);
559  m_saveTemplateFileAs->setToolTip("Save the template file");
560  m_saveTemplateFileAs->setStatusTip("Save the template file");
561  m_saveTemplateFileAs->setWhatsThis("Save the registration template file");
562  connect(m_saveTemplateFileAs, SIGNAL(triggered()), this,
563  SLOT(saveTemplateFileAs()));
564 
565  m_whatsThis = new QAction(QIcon(FileName(
566  "$base/icons/contexthelp.png").expanded()),"&Whats's This", m_qnetTool);
567  m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
568  m_whatsThis->setToolTip("Activate What's This and click on items on "
569  "user interface to see more information.");
570  connect(m_whatsThis, SIGNAL(activated()), this, SLOT(enterWhatsThisMode()));
571 
572  }
573 
574 
575 
586 
587  QMenu *fileMenu = m_qnetTool->menuBar()->addMenu("&File");
588  fileMenu->addAction(m_openGround);
589  fileMenu->addAction(m_openDem);
590  fileMenu->addAction(m_saveNet);
591  fileMenu->addAction(m_saveAsNet);
592  fileMenu->addAction(m_closeQnetTool);
593 
594  QMenu * regMenu = m_qnetTool->menuBar()->addMenu("&Registration");
595  regMenu->addAction(m_openTemplateFile);
596  regMenu->addAction(m_showHideTemplateEditor);
597  regMenu->addAction(m_saveChips);
598 
599  QMenu *helpMenu = m_qnetTool->menuBar()->addMenu("&Help");
600  helpMenu->addAction(m_whatsThis);
601  }
602 
603 
604  void QnetTool::createToolBars() {
605 
606  QToolBar * toolBar = new QToolBar;
607  toolBar->setObjectName("TemplateEditorToolBar");
608  toolBar->setFloatable(false);
609  toolBar->addAction(m_saveNet);
610  toolBar->addSeparator();
611  toolBar->addAction(m_showHideTemplateEditor);
612  toolBar->addAction(m_saveChips);
613  toolBar->addAction(m_whatsThis);
614 
615  m_qnetTool->addToolBar(Qt::TopToolBarArea, toolBar);
616  }
617 
618 
619 
682  // Read original measures from the network for comparison with measures
683  // that have been edited
684  ControlMeasure *origLeftMeasure =
685  m_editPoint->GetMeasure(m_leftMeasure->GetCubeSerialNumber());
686  ControlMeasure *origRightMeasure =
687  m_editPoint->GetMeasure(m_rightMeasure->GetCubeSerialNumber());
688 
689  if (m_editPoint->IsIgnored()) {
690  QString message = "You are saving changes to a measure on an ignored ";
691  message += "point. Do you want to set Ignore = False on the point and ";
692  message += "both measures?";
693  switch (QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
694  message, "&Yes", "&No", 0, 0)) {
695  // Yes: set Ignore=false for the point and measures and save point
696  case 0:
697  m_editPoint->SetIgnored(false);
698  emit ignorePointChanged();
699  if (m_leftMeasure->IsIgnored()) {
700  m_leftMeasure->SetIgnored(false);
701  emit ignoreLeftChanged();
702  }
703  if (m_rightMeasure->IsIgnored()) {
704  m_rightMeasure->SetIgnored(false);
705  emit ignoreRightChanged();
706  }
707  // No: keep Ignore=true and save measure
708  case 1:
709  break;
710 
711  }
712  }
713  if (origRightMeasure->IsIgnored() && m_rightMeasure->IsIgnored()) {
714  QString message = "You are saving changes to an ignored measure. ";
715  message += "Do you want to set Ignore = False on the right measure?";
716  switch(QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
717  message, "&Yes", "&No", 0, 0)){
718  // Yes: set Ignore=false for the right measure and save point
719  case 0:
720  m_rightMeasure->SetIgnored(false);
721  emit ignoreRightChanged();
722  // No: keep Ignore=true and save point
723  case 1:
724  break;
725  }
726  }
727 
728  // Only check reference if point contains explicit reference. Otherwise,
729  // there has not been a reference set, set the measure on the left as the reference.
730  if (m_editPoint->IsReferenceExplicit()) {
731  if (m_editPoint->IsEditLocked()) {
732  QString message = "This control point is edit locked. The Apriori latitude, longitude and ";
733  message += "radius cannot be updated. You must first unlock the point by clicking the ";
734  message += "check box above labeled \"Edit Lock Point\".";
735  QMessageBox::warning(m_qnetTool, "Point Locked", message);
736  return;
737  }
738  checkReference();
739  }
740  else if (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) {
741  m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
742  }
743 
744  // If this is a fixed or constrained point, and the right measure is the ground source,
745  // update the lat,lon,radius. Only the right measure can be moved, so only need to update
746  // position if the ground measure is loaded on the right.
747  //
748  // If point is locked and it is not a new point, print error
749  // TODO:: Only update if the measure moved
750  if (m_editPoint->GetType() != ControlPoint::Free && (m_groundOpen &&
751  m_rightMeasure->GetCubeSerialNumber() == m_groundSN)) {
752  if (m_editPoint->IsEditLocked() && m_controlNet->ContainsPoint(m_editPoint->GetId())) {
753  QString message = "This control point is edit locked. The Apriori latitude, longitude and ";
754  message += "radius cannot be updated. You must first unlock the point by clicking the ";
755  message += "check box above labeled \"Edit Lock Point\".";
756  QMessageBox::warning(m_qnetTool, "Point Locked", message);
757  return;
758  }
759  if (m_leftMeasure->IsIgnored()) {
760  QString message = "This is a Constrained or Fixed point and the reference measure is ";
761  message += "Ignored. Unset the Ignore flag on the reference measure before saving.";
762  QMessageBox::warning(m_qnetTool, "Point Locked", message);
763  return;
764  }
765  updateGroundPosition();
766  }
767 
768  // Save the right measure and left (if ignore or edit lock flag changed) to
769  // the editPoint The Ignore flag is the only thing that can change on the left
770  // measure.
771  m_rightMeasure->SetChooserName(Application::UserName());
772  *origRightMeasure = *m_rightMeasure;
773 
774  // Only save the left measure if the ignore flag or editLock has changed
775  if (m_leftMeasure->IsIgnored() != origLeftMeasure->IsIgnored() ||
776  m_leftMeasure->IsEditLocked() != origLeftMeasure->IsEditLocked()) {
777  m_leftMeasure->SetChooserName(Application::UserName());
778  *origLeftMeasure = *m_leftMeasure;
779  }
780 
781  // If left measure == right measure, update left
782  if (m_leftMeasure->GetCubeSerialNumber() ==
783  m_rightMeasure->GetCubeSerialNumber()) {
784  *m_leftMeasure = *m_rightMeasure;
785  // Update left measure of pointEditor
786  m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
787  m_editPoint->GetId());
788  }
789 
790  // Change Save Point button text to red
792 
793  editPointChanged(m_editPoint->GetId());
794 
795  // Update measure info
799  }
800 
801 
802 
803  /*
804  * Change which measure is the reference.
805  *
806  * @author 2012-04-26 Tracie Sucharski - moved funcitonality from measureSaved
807  *
808  * @internal
809  * @history 2012-06-12 Tracie Sucharski - Moved check for ground loaded on left from the
810  * measureSaved method.
811  */
812  void QnetTool::checkReference() {
813 
814  // Check if ControlPoint has reference measure, if reference Measure is
815  // not the same measure that is on the left chip viewport, set left
816  // measure as reference.
817  ControlMeasure *refMeasure = m_editPoint->GetRefMeasure();
818  if ( (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) &&
819  (refMeasure->GetCubeSerialNumber() != m_leftMeasure->GetCubeSerialNumber()) ) {
820  QString message = "This point already contains a reference measure. ";
821  message += "Would you like to replace it with the measure on the left?";
822  int response = QMessageBox::question(m_qnetTool,
823  "Qnet Tool Save Measure", message,
824  QMessageBox::Yes | QMessageBox::No,
825  QMessageBox::Yes);
826  // Replace reference measure
827  if (response == QMessageBox::Yes) {
828  // Update measure file combo boxes: old reference normal font,
829  // new reference bold font
830  QString file = m_serialNumberList->FileName(m_leftMeasure->GetCubeSerialNumber());
831  QString fname = FileName(file).name();
832  int iref = m_leftCombo->findText(fname);
833 
834  // Save normal font from new reference measure
835  QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
836  m_leftCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
837  iref = m_rightCombo->findText(fname);
838  m_rightCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
839 
840  file = m_serialNumberList->FileName(refMeasure->GetCubeSerialNumber());
841  fname = FileName(file).name();
842  iref = m_leftCombo->findText(fname);
843  m_leftCombo->setItemData(iref,font,Qt::FontRole);
844  iref = m_rightCombo->findText(fname);
845  m_rightCombo->setItemData(iref,font,Qt::FontRole);
846 
847  m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
848  // Update reference measure to new reference measure
849  refMeasure = m_editPoint->GetRefMeasure();
850  }
851  // ??? Need to set rest of measures to Candidate and add more warning. ???//
852  }
853 
854  // If the right measure is the reference, make sure they really want
855  // to move the reference.
856  if (refMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
857  QString message = "You are making a change to the reference measure. You ";
858  message += "may need to move all of the other measures to match the new ";
859  message += " coordinate of the reference measure. Do you really want to ";
860  message += " change the reference measure? ";
861  switch(QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
862  message, "&Yes", "&No", 0, 0)){
863  // Yes: Save measure
864  case 0:
865  break;
866  // No: keep original reference, return without saving
867  case 1:
868  loadPoint();
869  return;
870  }
871  }
872 
873  }
874 
875 
876 
877  /*
878  * Update the position of ground point
879  *
880  * @author 2012-04-26 Tracie Sucharski - moved functionality from measureSaved
881  *
882  * @internal
883  *
884  */
885  void QnetTool::updateGroundPosition() {
886 
887  // TODO: If groundSource file opened does not match the SurfacePoint Source
888  // file, print warning.
889 
890  // This method only called if ground measure is on the right. Use ground measure to update
891  // apriori surface point.
892  ControlMeasure *groundMeasure = m_rightMeasure;
893  if (!m_groundGmap->SetImage(groundMeasure->GetSample(),
894  groundMeasure->GetLine())) {
895  // TODO : should never happen, either add error check or
896  // get rid of
897  }
898 
899  double lat = m_groundGmap->UniversalLatitude();
900  double lon = m_groundGmap->UniversalLongitude();
901 // cout<<"lat = "<<setprecision(15)<<lat<<endl;
902 // cout<<"lon = "<<lon<<endl;
903  double radius;
904  // Update radius, order of precedence
905  // 1. If a dem has been opened, read radius from dem.
906  // 2. Get radius from reference measure
907  // If image has shape model, radius will come from shape model
908  //
909  if (m_demOpen) {
910  radius = demRadius(lat,lon);
911  if (radius == Null) {
912  QString msg = "Could not read radius from DEM, will default to "
913  "local radius of reference measure.";
914  QMessageBox::warning(m_qnetTool, "Warning", msg);
915  if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
916  Latitude(lat, Angle::Degrees), Longitude(lon, Angle::Degrees))) {
917  radius =
918  m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
919  m_editPoint->SetAprioriRadiusSource(
920  ControlPoint::RadiusSource::None);
921  //m_editPoint->SetAprioriRadiusSourceFile(m_radiusSourceFile);
922  }
923  else {
924  QString message = "Error trying to get radius at this pt. "
925  "Lat/Lon does not fall on the reference measure. "
926  "Cannot save this measure.";
927  QMessageBox::critical(m_qnetTool,"Error",message);
928  return;
929  }
930  }
931  m_editPoint->SetAprioriRadiusSource(m_groundRadiusSource);
932  m_editPoint->SetAprioriRadiusSourceFile(m_radiusSourceFile);
933  }
934  else {
935  // Get radius from reference image
936  if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
937  Latitude(lat, Angle::Degrees), Longitude(lon, Angle::Degrees))) {
938  radius =
939  m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
940 // cout.width(15);
941 // cout.precision(4);
942 // cout<<"Camera Radius = "<<fixed<<radius<<endl;
943  //radius = m_groundGmap->Projection()->LocalRadius();
944  }
945  else {
946  QString message = "Error trying to get radius at this pt. "
947  "Lat/Lon does not fall on the reference measure. "
948  "Cannot save this measure.";
949  QMessageBox::critical(m_qnetTool,"Error",message);
950  return;
951  }
952  }
953 
954  try {
955  // Read apriori surface point if it exists so that point is
956  // replaced, but sigmas are retained. Save sigmas because the
957  // SurfacePoint class will change them if the coordinates change.
958  vector<Distance> targetRadii = m_controlNet->GetTargetRadii();
959  if (m_editPoint->HasAprioriCoordinates()) {
960  SurfacePoint aprioriPt = m_editPoint->GetAprioriSurfacePoint();
961  aprioriPt.SetRadii(Distance(targetRadii[0]),
962  Distance(targetRadii[1]),
963  Distance(targetRadii[2]));
964  Distance latSigma = aprioriPt.GetLatSigmaDistance();
965  Distance lonSigma = aprioriPt.GetLonSigmaDistance();
966  Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
967  aprioriPt.SetSphericalCoordinates(Latitude(lat, Angle::Degrees),
968  Longitude(lon, Angle::Degrees),
969  Distance(radius, Distance::Meters));
970  aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
971  m_editPoint->SetAprioriSurfacePoint(aprioriPt);
972  }
973  else {
974  m_editPoint->SetAprioriSurfacePoint(SurfacePoint(
975  Latitude(lat, Angle::Degrees),
976  Longitude(lon, Angle::Degrees),
977  Distance(radius, Distance::Meters)));
978  }
979  }
980  catch (IException &e) {
981  QString message = "Unable to set Apriori Surface Point.\n";
982  message += "Latitude = " + QString::number(lat);
983  message += " Longitude = " + QString::number(lon);
984  message += " Radius = " + QString::number(radius) + "\n";
985  message += e.toString();
986  QMessageBox::critical(m_qnetTool,"Error",message);
987  }
988  m_editPoint->SetAprioriSurfacePointSource(m_groundSurfacePointSource);
989  m_editPoint->SetAprioriSurfacePointSourceFile(m_groundSourceFile);
990 
992 
993  }
994 
995 
996 
1012 
1013  // Make a copy of edit point for updating the control net since the edit
1014  // point is still loaded in the point editor.
1015  ControlPoint *updatePoint = new ControlPoint;
1016  *updatePoint = *m_editPoint;
1017 
1018  // If this is a fixed or constrained point, see if there is a temporary
1019  // measure holding the coordinate information from the ground source.
1020  // If so, delete this measure before saving point. Clear out the
1021  // fixed Measure variable (memory deleted in ControlPoint::Delete).
1022  if (updatePoint->GetType() != ControlPoint::Free &&
1023  updatePoint->HasSerialNumber(m_groundSN)) {
1024  updatePoint->Delete(m_groundSN);
1025  }
1026 
1027  // If edit point exists in the network, save the updated point. If it
1028  // does not exist, add it.
1029  if (m_controlNet->ContainsPoint(updatePoint->GetId())) {
1030  ControlPoint *p;
1031  p = m_controlNet->GetPoint(QString(updatePoint->GetId()));
1032  *p = *updatePoint;
1033  delete updatePoint;
1034  updatePoint = NULL;
1035  }
1036  else {
1037  m_controlNet->AddPoint(updatePoint);
1038  }
1039 
1040  // Change Save Measure button text back to default
1041  m_savePoint->setPalette(m_saveDefaultPalette);
1042 
1043  // ???? Why was this here??? loadPoint();
1044  // emit signal so the nav tool refreshes the list
1045  emit refreshNavList();
1046  // emit signal so the nav tool can update edit point
1047  emit editPointChanged(m_editPoint->GetId());
1048  // emit a signal to alert user to save when exiting
1049  emit netChanged();
1050  // Refresh chipViewports to show new positions of controlPoints
1051  m_pointEditor->refreshChips();
1052  }
1053 
1054 
1055 
1056 
1067  void QnetTool::setPointType (int pointType) {
1068  if (m_editPoint == NULL) return;
1069 
1070  // If pointType is equal to current type, nothing to do
1071  if (m_editPoint->GetType() == pointType) return;
1072 
1073  if (pointType != ControlPoint::Free && m_leftMeasure->IsIgnored()) {
1074  m_pointType->setCurrentIndex((int) m_editPoint->GetType());
1075  QString message = "The reference measure is Ignored. Unset the Ignore flag on the ";
1076  message += "reference measure before setting the point type to Constrained or Fixed.";
1077  QMessageBox::warning(m_qnetTool, "Ignored Reference Measure", message);
1078  return;
1079  }
1080 
1081  bool unloadGround = false;
1082  if (m_editPoint->GetType() != ControlPoint::Free && pointType == ControlPoint::Free)
1083  unloadGround = true;
1084 
1085  ControlPoint::Status status = m_editPoint->SetType((ControlPoint::PointType) pointType);
1086  if (status == ControlPoint::PointLocked) {
1087  m_pointType->setCurrentIndex((int) m_editPoint->GetType());
1088  QString message = "This control point is edit locked. The point type cannot be changed. You ";
1089  message += "must first unlock the point by clicking the check box above labeled ";
1090  message += "\"Edit Lock Point\".";
1091  QMessageBox::warning(m_qnetTool, "Point Locked", message);
1092  return;
1093  }
1094 
1095  // If ground loaded, read temporary ground measure to the point
1096  if (pointType != ControlPoint::Free && m_groundOpen) {
1098  m_pointEditor->colorizeSaveButton();
1099  }
1100  // If going from constrained or fixed to free, unload the ground measure.
1101  else if (unloadGround) {
1102  // Find in point and delete, it will be re-created with current
1103  // ground source if this is a fixed point
1104  if (m_editPoint->HasSerialNumber(m_groundSN)) {
1105  m_editPoint->Delete(m_groundSN);
1106  }
1107 
1108  loadPoint();
1109  m_pointEditor->colorizeSaveButton();
1110  }
1111 
1113  }
1114 
1115 
1116 
1127 
1128  if (!m_groundOpen) return;
1129 
1130  // Use apriori surface point to find location on ground source. If
1131  // apriori surface point does not exist use reference measure
1132  double lat = 0.;
1133  double lon = 0.;
1134  if (m_editPoint->HasAprioriCoordinates()) {
1135  SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
1136  lat = sPt.GetLatitude().degrees();
1137  lon = sPt.GetLongitude().degrees();
1138  }
1139  else {
1140  ControlMeasure m = *(m_editPoint->GetRefMeasure());
1141  int camIndex = m_serialNumberList->SerialNumberIndex(m.GetCubeSerialNumber());
1142  Camera *cam;
1143  cam = m_controlNet->Camera(camIndex);
1144  cam->SetImage(m.GetSample(),m.GetLine());
1145  lat = cam->UniversalLatitude();
1146  lon = cam->UniversalLongitude();
1147  }
1148 
1149  // Try to locate point position on current ground source,
1150  // TODO ???if doesn't exist,???
1151  if (!m_groundGmap->SetUniversalGround(lat,lon)) {
1152  QString message = "This point does not exist on the ground source.\n";
1153  message += "Latitude = " + QString::number(lat);
1154  message += " Longitude = " + QString::number(lon);
1155  message += "\n A ground measure will not be created.";
1156  QMessageBox::warning(m_qnetTool, "Warning", message);
1157  }
1158  else {
1159  // Create a temporary measure to hold the ground point info for ground source
1160  // This measure will be deleted when the ControlPoint is saved to the
1161  // ControlNet.
1162  ControlMeasure *groundMeasure = new ControlMeasure;
1163  groundMeasure->SetCubeSerialNumber(m_groundSN);
1164  groundMeasure->SetType(ControlMeasure::Candidate);
1165  groundMeasure->SetCoordinate(m_groundGmap->Sample(),m_groundGmap->Line());
1166  m_editPoint->Add(groundMeasure);
1167 
1168  // Add to measure combo boxes
1169  QString file = m_serialNumberList->FileName(groundMeasure->GetCubeSerialNumber());
1170  m_pointFiles<<file;
1171  QString tempFileName = FileName(file).name();
1172  m_leftCombo->addItem(tempFileName);
1173  m_rightCombo->addItem(tempFileName);
1174  int rightIndex = m_rightCombo->findText((QString)m_groundFile);
1175  m_rightCombo->setCurrentIndex(rightIndex);
1176  selectRightMeasure(rightIndex);
1177 
1179 
1180  loadMeasureTable();
1181  }
1182  }
1183 
1184 
1185 
1195  void QnetTool::setLockPoint (bool lock) {
1196  if (m_editPoint == NULL) return;
1197 
1198  m_editPoint->SetEditLock(lock);
1200  }
1201 
1202 
1203 
1214  void QnetTool::setIgnorePoint (bool ignore) {
1215  if (m_editPoint == NULL) return;
1216 
1217  ControlPoint::Status status = m_editPoint->SetIgnored(ignore);
1218  if (status == ControlPoint::PointLocked) {
1219  m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1220  QString message = "This control point is edit locked. The Ignored status cannot be ";
1221  message += "changed. You must first unlock the point by clicking the check box above ";
1222  message += "labeled \"Edit Lock Point\".";
1223  QMessageBox::warning(m_qnetTool, "Point Locked", message);
1224  return;
1225  }
1227  }
1228 
1229 
1230 
1231 
1247  void QnetTool::setLockLeftMeasure (bool lock) {
1248 
1249  if (m_editPoint->IsEditLocked()) {
1250  m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
1251  QMessageBox::warning(m_qnetTool, "Point Locked","Point is Edit Locked. You must un-lock point"
1252  " before changing a measure.");
1253  m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
1254  return;
1255  }
1256 
1257  if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
1258 
1259  // If the right chip is the same as the left chip , update the right editLock
1260  // box.
1261  if (m_rightMeasure != NULL) {
1262  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1263  m_rightMeasure->SetEditLock(lock);
1264  m_lockRightMeasure->setChecked(lock);
1265  }
1266  }
1267  emit measureChanged();
1268  }
1269 
1270 
1288  void QnetTool::setIgnoreLeftMeasure (bool ignore) {
1289  if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
1290 
1291  // If the right chip is the same as the left chip , update the right
1292  // ignore box.
1293  if (m_rightMeasure != NULL) {
1294  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1295  m_rightMeasure->SetIgnored(ignore);
1296  m_ignoreRightMeasure->setChecked(ignore);
1297  }
1298  }
1299  emit measureChanged();
1300  }
1301 
1302 
1319 
1320  if (m_editPoint->IsEditLocked()) {
1321  m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
1322  QMessageBox::warning(m_qnetTool, "Point Locked","Point is Edit Locked. You must un-lock point"
1323  " before changing a measure.");
1324  m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
1325  return;
1326  }
1327 
1328  if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
1329 
1330  // If the left chip is the same as the right chip , update the left editLock box.
1331  if (m_leftMeasure != NULL) {
1332  if (m_leftMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
1333  m_leftMeasure->SetEditLock(lock);
1334  m_lockLeftMeasure->setChecked(lock);
1335  }
1336  }
1337  emit measureChanged();
1338  }
1339 
1340 
1358  void QnetTool::setIgnoreRightMeasure (bool ignore) {
1359  if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
1360 
1361  // If the right chip is the same as the left chip , update the right
1362  // ignore blox.
1363  if (m_leftMeasure != NULL) {
1364  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1365  m_leftMeasure->SetIgnored(ignore);
1366  m_ignoreLeftMeasure->setChecked(ignore);
1367  }
1368  }
1369  emit measureChanged();
1370  }
1371 
1372 
1373 
1380  if (m_cnetFileName.isEmpty()) {
1381  QString message = "This is a new network, you must select "
1382  "\"Save As\" under the File Menu.";
1383  QMessageBox::critical(m_qnetTool, "Error", message);
1384  return;
1385  }
1386  emit qnetToolSave();
1387  //m_controlNet->Write(m_cnetFileName);
1388  }
1389 
1390 
1391 
1396  emit qnetToolSaveAs();
1397  }
1398 
1399 
1400 
1401 
1405  void QnetTool::updateList() {
1406 
1407  //m_pointEditor->setSerialList (*m_serialNumberList);
1408 
1409  }
1410 
1411 
1428  void QnetTool::updateNet(QString cNetFileName) {
1429  m_cnetFileName = cNetFileName;
1430  m_qnetTool->setWindowTitle("Qnet Tool - Control Network File: " +
1431  cNetFileName);
1432  //m_pointEditor->setControlNet(*m_controlNet);
1433 
1434  }
1435 
1436 
1437 
1450  QAction *action = new QAction(pad);
1451  action->setIcon(QPixmap(toolIconDir()+"/stock_draw-connector-with-arrows.png"));
1452  action->setToolTip("Control Point Editor (T)");
1453  action->setShortcut(Qt::Key_T);
1454  QObject::connect(action,SIGNAL(triggered(bool)),this,SLOT(showNavWindow(bool)));
1455  return action;
1456  }
1457 
1458 
1459 
1491  void QnetTool::mouseButtonRelease(QPoint p, Qt::MouseButton s) {
1492  MdiCubeViewport *cvp = cubeViewport();
1493  if (cvp == NULL) return;
1494 
1495  QString file = cvp->cube()->fileName();
1496  QString sn;
1497  try {
1498  sn = m_serialNumberList->SerialNumber(file);
1499  }
1500  catch (IException &e) {
1501  QString message = "Cannot get serial number for " + file + ". Is file contained in the ";
1502  message += "cube list?\n";
1503  message += e.toString();
1504  QMessageBox::critical(m_qnetTool, "Error", message);
1505  return;
1506  }
1507 
1508  double samp,line;
1509  cvp->viewportToCube(p.x(),p.y(),samp,line);
1510 
1511  m_leftFile.clear();
1512 
1513  if (s == Qt::LeftButton) {
1514  if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1515  QString message = "No points exist for editing. Create points ";
1516  message += "using the right mouse button.";
1517  QMessageBox::warning(m_qnetTool, "Warning", message);
1518  return;
1519  }
1520 
1521  if (sn == m_groundSN) {
1522  QString message = "Cannot select point for editing on ground source. Select ";
1523  message += "point using un-projected images or the Navigator Window.";
1524  QMessageBox::critical(m_qnetTool, "Error", message);
1525  return;
1526  }
1527 
1528  // Find closest control point in network
1529  QString sn = m_serialNumberList->SerialNumber(file);
1530  ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1531 
1532  modifyPoint(point);
1533  }
1534  else if (s == Qt::MidButton) {
1535  if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1536  QString message = "No points exist for deleting. Create points ";
1537  message += "using the right mouse button.";
1538  QMessageBox::warning(m_qnetTool, "Warning", message);
1539  return;
1540  }
1541 
1542  if (m_groundOpen && file == m_groundCube->fileName()) {
1543  QString message = "Cannot select point for deleting on ground source. Select ";
1544  message += "point using un-projected images or the Navigator Window.";
1545  QMessageBox::critical(m_qnetTool, "Error", message);
1546  return;
1547  }
1548  // Find closest control point in network
1549  ControlPoint *point = NULL;
1550  try {
1551  point = m_controlNet->FindClosest(sn, samp, line);
1552 
1553  if (point == NULL) {
1554  QString message = "No points exist for deleting. Create points ";
1555  message += "using the right mouse button.";
1556  QMessageBox::warning(m_qnetTool, "Warning", message);
1557  return;
1558  }
1559  }
1560  catch (IException &e) {
1561  QString message = "Cannot find point on this image for deleting.";
1562  QMessageBox::critical(m_qnetTool, "Error", message);
1563  return;
1564  }
1565 
1566  deletePoint(point);
1567  }
1568  else if (s == Qt::RightButton) {
1569  m_leftFile = file;
1570  UniversalGroundMap *gmap = cvp->universalGroundMap();
1571  if (!gmap->SetImage(samp,line)) {
1572  QString message = "Invalid latitude or longitude at this point. ";
1573  QMessageBox::critical(m_qnetTool,"Error", message);
1574  return;
1575  }
1576  double lat = gmap->UniversalLatitude();
1577  double lon = gmap->UniversalLongitude();
1578  if (m_groundOpen && file == m_groundCube->fileName()) {
1579  createFixedPoint (lat,lon);
1580  }
1581  else {
1582  createPoint(lat,lon);
1583  }
1584  }
1585  }
1586 
1587 
1588 
1633  void QnetTool::createPoint(double lat,double lon) {
1634 
1635  // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1636 
1637  // Create list box of all files highlighting those that
1638  // contain the point.
1639  QStringList pointFiles;
1640 
1641  Camera *cam;
1642  for(int i = 0; i < m_serialNumberList->Size(); i++) {
1643  if (m_serialNumberList->SerialNumber(i) == m_groundSN) continue;
1644  cam = m_controlNet->Camera(i);
1645  if(cam->SetUniversalGround(lat, lon)) {
1646  // Make sure point is within image boundary
1647  double samp = cam->Sample();
1648  double line = cam->Line();
1649  if (samp >= 1 && samp <= cam->Samples() &&
1650  line >= 1 && line <= cam->Lines()) {
1651  pointFiles<<m_serialNumberList->FileName(i);
1652  }
1653  }
1654  }
1655 
1656  QnetNewPointDialog *newPointDialog = new QnetNewPointDialog(this, m_lastUsedPointId);
1657  newPointDialog->setFiles(pointFiles);
1658  if (newPointDialog->exec()) {
1659  m_lastUsedPointId = newPointDialog->pointId();
1660  ControlPoint *newPoint =
1661  new ControlPoint(m_lastUsedPointId);
1662 
1663  // If this ControlPointId already exists, message box pops up and user is
1664  // asked to enter a new value.
1665  if (m_controlNet->ContainsPoint(newPoint->GetId())) {
1666  QString message = "A ControlPoint with Point Id = [" + newPoint->GetId();
1667  message += "] already exists. Re-enter Point Id for this ControlPoint.";
1668  QMessageBox::warning(m_qnetTool, "New Point Id", message);
1669  pointFiles.clear();
1670  delete newPoint;
1671  newPoint = NULL;
1672  createPoint(lat, lon);
1673  return;
1674  }
1675 
1677 
1678  QStringList selectedFiles = newPointDialog->selectedFiles();
1679  foreach (QString selectedFile, selectedFiles) {
1680  // Create measure for any file selected
1681  ControlMeasure *m = new ControlMeasure;
1682  // Find serial number for this file
1683  QString sn =
1684  m_serialNumberList->SerialNumber(selectedFile);
1685  m->SetCubeSerialNumber(sn);
1686  int camIndex =
1687  m_serialNumberList->FileNameIndex(selectedFile);
1688  cam = m_controlNet->Camera(camIndex);
1689  cam->SetUniversalGround(lat,lon);
1690  m->SetCoordinate(cam->Sample(),cam->Line());
1691  m->SetAprioriSample(cam->Sample());
1692  m->SetAprioriLine(cam->Line());
1695  m->SetCamera(cam);
1696  newPoint->Add(m);
1697  }
1698  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1699  delete m_editPoint;
1700  m_editPoint = NULL;
1701  }
1702  m_editPoint = newPoint;
1703 
1704  // If the image that the user clicked on to select the point is not
1705  // included, clear out the leftFile value.
1706  if (!m_leftFile.isEmpty()) {
1707  if (selectedFiles.indexOf(m_leftFile) == -1) {
1708  m_leftFile.clear();
1709  }
1710  }
1711 
1712  // Load new point in QnetTool
1713  loadPoint();
1714  m_qnetTool->setShown(true);
1715  m_qnetTool->raise();
1716 
1718  m_pointEditor->templateFileName());
1719 
1720 
1721  // emit signal so the nave tool refreshes the list
1722  emit refreshNavList();
1723  // emit signal so the nav tool can update edit point
1724  emit editPointChanged(m_editPoint->GetId());
1726 
1727  }
1728  }
1729 
1730 
1731 
1732 
1733 
1734 
1746  void QnetTool::createFixedPoint(double lat,double lon) {
1747 
1748  // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1749 
1750  // Create list of list box of all files highlighting those that
1751  // contain the point.
1752  QStringList pointFiles;
1753 
1754  Camera *cam;
1755  for (int i=0; i<m_serialNumberList->Size(); i++) {
1756  if (m_serialNumberList->SerialNumber(i) == m_groundSN) continue;
1757  cam = m_controlNet->Camera(i);
1758  if (cam->SetUniversalGround(lat,lon)) {
1759  // Make sure point is within image boundary
1760  double samp = cam->Sample();
1761  double line = cam->Line();
1762  if (samp >= 1 && samp <= cam->Samples() &&
1763  line >= 1 && line <= cam->Lines()) {
1764  pointFiles<<m_serialNumberList->FileName(i);
1765  }
1766  }
1767  }
1768 
1769  if (pointFiles.count() == 0) {
1770  QString message = "Point does not intersect any images.";
1771  QMessageBox::critical(m_qnetTool, "No intersection", message);
1772  return;
1773  }
1774 
1775  QnetFixedPointDialog *fixedPointDialog = new QnetFixedPointDialog(this, m_lastUsedPointId);
1776  fixedPointDialog->setFiles(pointFiles);
1777  if (fixedPointDialog->exec()) {
1778  ControlPoint *fixedPoint =
1779  new ControlPoint(fixedPointDialog->pointId());
1780 
1781  if (fixedPointDialog->isFixed()) {
1782  fixedPoint->SetType(ControlPoint::Fixed);
1783  }
1784  else {
1785  fixedPoint->SetType(ControlPoint::Constrained);
1786  }
1787 
1788  // If this ControlPointId already exists, message box pops up and user is
1789  // asked to enter a new value.
1790  if (m_controlNet->ContainsPoint(fixedPoint->GetId())) {
1791  QString message = "A ControlPoint with Point Id = [" + fixedPoint->GetId();
1792  message += "] already exists. Re-enter Point Id for this ControlPoint.";
1793  QMessageBox::warning(m_qnetTool, "New Point Id", message);
1794  pointFiles.clear();
1795  delete fixedPoint;
1796  fixedPoint = NULL;
1797  createFixedPoint(lat,lon);
1798  return;
1799  }
1800 
1801  fixedPoint->SetChooserName(Application::UserName());
1802 
1803  QStringList selectedFiles = fixedPointDialog->selectedFiles();
1804  foreach (QString selectedFile, selectedFiles) {
1805  // Create measure for any file selected
1806  ControlMeasure *m = new ControlMeasure;
1807  // Find serial number for this file
1808  QString sn =
1809  m_serialNumberList->SerialNumber(selectedFile);
1810 
1811  // If ground, do not add measure, it will be added in loadPoint
1812  if (sn == m_groundSN) continue;
1813 
1814  m->SetCubeSerialNumber(sn);
1815  int camIndex =
1816  m_serialNumberList->FileNameIndex(selectedFile);
1817  cam = m_controlNet->Camera(camIndex);
1818  cam->SetUniversalGround(lat,lon);
1819  m->SetCoordinate(cam->Sample(),cam->Line());
1822  m->SetCamera(cam);
1823  fixedPoint->Add(m);
1824  }
1825 
1826  // ?????? What radius , check for dem or shape model
1827  double radius = 0;
1828  if (m_demOpen) {
1829  radius = demRadius(lat,lon);
1830  if (radius == Null) {
1831  QString msg = "Could not read radius from DEM, will default to the "
1832  "local radius of the first measure in the control point. This "
1833  "will be updated to the local radius of the chosen reference "
1834  "measure.";
1835  QMessageBox::warning(m_qnetTool, "Warning", msg);
1836  if ((*fixedPoint)[0]->Camera()->SetGround(
1838  radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
1839  }
1840  else {
1841  QString msg = "Error trying to get radius at this pt. "
1842  "Lat/Lon does not fall on the reference measure. "
1843  "Cannot create this point.";
1844  QMessageBox::critical(m_qnetTool, "Error", msg);
1845  delete fixedPoint;
1846  fixedPoint = NULL;
1847  delete fixedPointDialog;
1848  fixedPointDialog = NULL;
1849  return;
1850  }
1851  }
1852  }
1853  else {
1854  if ((*fixedPoint)[0]->Camera()->SetGround(
1856  radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
1857  }
1858  else {
1859  QString msg = "Error trying to get radius at this pt. "
1860  "Lat/Lon does not fall on the reference measure. "
1861  "Cannot create this point.";
1862  QMessageBox::critical(m_qnetTool, "Error", msg);
1863  delete fixedPoint;
1864  fixedPoint = NULL;
1865  delete fixedPointDialog;
1866  fixedPointDialog = NULL;
1867  return;
1868  }
1869  }
1870 
1872  Latitude(lat, Angle::Degrees),
1873  Longitude(lon, Angle::Degrees),
1874  Distance(radius, Distance::Meters)));
1875 
1876  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1877  delete m_editPoint;
1878  m_editPoint = NULL;
1879  }
1880  m_editPoint = fixedPoint;
1881 
1882  // Load new point in QnetTool
1883  loadPoint();
1884  m_qnetTool->setShown(true);
1885  m_qnetTool->raise();
1886 
1887  delete fixedPointDialog;
1888  fixedPointDialog = NULL;
1889 
1890  // emit signal so the nave tool refreshes the list
1891  emit refreshNavList();
1892  // emit signal so the nav tool can update edit point
1893  emit editPointChanged(m_editPoint->GetId());
1895  }
1896  }
1897 
1898 
1899 
1921 
1922  // Make a copy and make sure editPoint is a copy (which means it does not
1923  // have a parent network.
1924  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1925  delete m_editPoint;
1926  m_editPoint = NULL;
1927  }
1928  m_editPoint = new ControlPoint;
1929  *m_editPoint = *point;
1930  loadPoint();
1931 
1932  // Change point in viewport to red so user can see what point they are
1933  // about to delete.
1934  // the nav tool will update edit point
1935  emit editPointChanged(m_editPoint->GetId());
1936 
1937  QnetDeletePointDialog *deletePointDialog = new QnetDeletePointDialog;
1938  QString CPId = m_editPoint->GetId();
1939  deletePointDialog->pointIdValue->setText(CPId);
1940 
1941  // Need all files for this point
1942  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1943  ControlMeasure &m = *(*m_editPoint)[i];
1944  QString file = m_serialNumberList->FileName(m.GetCubeSerialNumber());
1945  deletePointDialog->fileList->addItem(file);
1946  }
1947 
1948  if (deletePointDialog->exec()) {
1949 
1950  int numDeleted = deletePointDialog->fileList->selectedItems().count();
1951 
1952  // Delete entire control point, either through deleteAllCheckBox or all measures selected
1953  if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1954  numDeleted == m_editPoint->GetNumMeasures()) {
1955 
1956  // If all measures being deleted, let user know and give them the option to quit operation
1957  if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1958  QString message = "You have selected all measures in this point to be deleted. This "
1959  "control point will be deleted. Do you want to delete this control point?";
1960  int response = QMessageBox::question(m_qnetTool,
1961  "Delete control point", message,
1962  QMessageBox::Yes | QMessageBox::No,
1963  QMessageBox::Yes);
1964  // If No, do nothing
1965  if (response == QMessageBox::No) {
1966  return;
1967  }
1968  }
1969 
1970  // First get rid of deleted point from m_filteredPoints list
1971  // need index in control net for pt
1972  //int i = m_controlNet->
1973  //m_filteredPoints.
1974  m_qnetTool->setShown(false);
1975  // remove this point from the control network
1976  if (m_controlNet->DeletePoint(m_editPoint->GetId()) ==
1978  QMessageBox::information(m_qnetTool, "EditLocked Point",
1979  "This point is EditLocked and cannot be deleted.");
1980  return;
1981  }
1982  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1983  delete m_editPoint;
1984  m_editPoint = NULL;
1985  }
1986  // emit signal so the nav tool refreshes the list
1987  emit refreshNavList();
1988  }
1989 
1990  // Delete specific measures from control point
1991  else {
1992  // Keep track of editLocked measures for reporting
1993  int lockedMeasures = 0;
1994  for (int i=0; i<deletePointDialog->fileList->count(); i++) {
1995  QListWidgetItem *item = deletePointDialog->fileList->item(i);
1996  if (!deletePointDialog->fileList->isItemSelected(item)) continue;
1997 
1998  // Do not delete reference without asking user
1999  if (m_editPoint->IsReferenceExplicit() &&
2000  (m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
2001  (*m_editPoint)[i]->GetCubeSerialNumber())) {
2002  QString message = "You are trying to delete the Reference measure."
2003  " Do you really want to delete the Reference measure?";
2004  switch (QMessageBox::question(m_qnetTool,
2005  "Delete Reference measure?", message,
2006  "&Yes", "&No", 0, 0)) {
2007  // Yes: skip to end of switch todelete the measure
2008  case 0:
2009  break;
2010  // No: continue to next measure in the loop
2011  case 1:
2012  // if only a single measure and it's reference and user chooses not to delete,
2013  // simply return. The point has not changed.
2014  if (numDeleted == 1) {
2015  return;
2016  }
2017  continue;
2018  }
2019  }
2020 
2021  if (m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
2022  lockedMeasures++;
2023  }
2024  }
2025 
2026  if (lockedMeasures > 0) {
2027  QMessageBox::information(m_qnetTool,"EditLocked Measures",
2028  QString::number(lockedMeasures) + " / "
2029  + QString::number(
2030  deletePointDialog->fileList->selectedItems().size()) +
2031  " measures are EditLocked and were not deleted.");
2032  }
2033 
2034  loadPoint();
2035  m_qnetTool->setShown(true);
2036  m_qnetTool->raise();
2037 
2038  loadTemplateFile(m_pointEditor->templateFileName());
2039  }
2040 
2041  // emit a signal to alert user to save when exiting
2042  emit netChanged();
2043 
2044  // emit signal so the nav tool can update edit point
2045  if (m_editPoint != NULL) {
2046  emit editPointChanged(m_editPoint->GetId());
2047  // Change Save Point button text to red
2049  }
2050  else {
2051  // if the entire point is deleted, update with point Id = ""
2052  // this signal is connected to QnetTool::paintAllViewports
2053  // and QnetNavTool::updateEditPoint
2054  emit editPointChanged("");
2055  }
2056  }
2057  }
2058 
2059 
2060 
2070 
2071  // If no measures, print info and return
2072  if (point->GetNumMeasures() == 0) {
2073  QString message = "This point has no measures.";
2074  QMessageBox::warning(m_qnetTool, "Warning", message);
2075  // update nav list to re-highlight old point
2076  if (m_editPoint != NULL) {
2077  // emit signal so the nav tool can update edit point
2078  emit editPointChanged(m_editPoint->GetId());
2079  }
2080  else {
2081  // this signal is connected to QnetTool::paintAllViewports
2082  // and QnetNavTool::updateEditPoint
2083  emit editPointChanged("");
2084  }
2085  return;
2086  }
2087  // Make a copy of point for editing, first make sure memory not already
2088  // allocated
2089  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
2090  delete m_editPoint;
2091  m_editPoint = NULL;
2092  }
2093  m_editPoint = new ControlPoint;
2094  *m_editPoint = *point;
2095 
2096  // If navTool modfify button pressed, m_leftFile needs to be reset
2097  // TODO: better way - have 2 slots
2098  if (sender() != this) m_leftFile.clear();
2099  loadPoint();
2100  m_qnetTool->setShown(true);
2101  m_qnetTool->raise();
2102  loadTemplateFile(m_pointEditor->templateFileName());
2103 
2104  // emit signal so the nav tool can update edit point
2105  emit editPointChanged(m_editPoint->GetId());
2106 
2107  // New point loaded, make sure Save Measure Button text is default
2108  m_savePoint->setPalette(m_saveDefaultPalette);
2109  }
2110 
2131 
2132  // Write pointId
2133  QString CPId = m_editPoint->GetId();
2134  QString ptId("Point ID: ");
2135  ptId += (QString) CPId;
2136  m_ptIdValue->setText(ptId);
2137 
2138  // Write point type
2139 // QString ptType("Point Type: ");
2140 // ptType += (QString) m_editPoint->GetPointTypeString();
2141 // m_pointType->setText(ptType);
2142  m_pointType->setCurrentIndex((int) m_editPoint->GetType());
2143 
2144  // Write number of measures
2145  QString ptsize = "Number of Measures: " +
2146  QString::number(m_editPoint->GetNumMeasures());
2147  m_numMeasures->setText(ptsize);
2148 
2149  // Set EditLock box correctly
2150  m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2151 
2152  // Set ignore box correctly
2153  m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2154 
2155  // Clear combo boxes
2156  m_leftCombo->clear();
2157  m_rightCombo->clear();
2158  m_pointFiles.clear();
2159 
2160  // Find in point and delete, it will be re-created with current
2161  // ground source if this is a fixed point
2162  if (m_editPoint->HasSerialNumber(m_groundSN)) {
2163  m_editPoint->Delete(m_groundSN);
2164  }
2165 
2166  // If fixed, add ground source file to combos, create a measure for
2167  // the ground source, load reference on left, ground source on right
2168  if (m_groundOpen && (m_editPoint->GetType() != ControlPoint::Free)) {
2169 
2170  // TODO: Does open ground source match point ground source
2171 
2172 
2173  // Use apriori surface point to find location on ground source. If
2174  // apriori surface point does not exist use reference measure
2175  double lat = 0.;
2176  double lon = 0.;
2177  if (m_editPoint->HasAprioriCoordinates()) {
2178  SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
2179  lat = sPt.GetLatitude().degrees();
2180  lon = sPt.GetLongitude().degrees();
2181  }
2182  else {
2183  ControlMeasure m = *(m_editPoint->GetRefMeasure());
2184  int camIndex = m_serialNumberList->SerialNumberIndex(m.GetCubeSerialNumber());
2185  Camera *cam;
2186  cam = m_controlNet->Camera(camIndex);
2187  cam->SetImage(m.GetSample(),m.GetLine());
2188  lat = cam->UniversalLatitude();
2189  lon = cam->UniversalLongitude();
2190  }
2191 
2192  // Try to locate point position on current ground source,
2193  // TODO ???if doesn't exist,???
2194  if (!m_groundGmap->SetUniversalGround(lat,lon)) {
2195  QString message = "This point does not exist on the ground source.\n";
2196  message += "Latitude = " + QString::number(lat);
2197  message += " Longitude = " + QString::number(lon);
2198  message += "\n A ground measure will not be created.";
2199  QMessageBox::warning(m_qnetTool, "Warning", message);
2200  }
2201  else {
2202  // Create a temporary measure to hold the ground point info for ground source
2203  // This measure will be deleted when the ControlPoint is saved to the
2204  // ControlNet.
2205  ControlMeasure *groundMeasure = new ControlMeasure;
2206  groundMeasure->SetCubeSerialNumber(m_groundSN);
2207  groundMeasure->SetType(ControlMeasure::Candidate);
2208  groundMeasure->SetCoordinate(m_groundGmap->Sample(),m_groundGmap->Line());
2209  m_editPoint->Add(groundMeasure);
2210  }
2211  }
2212 
2213 
2214  // Need all files for this point
2215  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
2216  ControlMeasure &m = *(*m_editPoint)[i];
2217  QString file = m_serialNumberList->FileName(m.GetCubeSerialNumber());
2218  m_pointFiles<<file;
2219  QString tempFileName = FileName(file).name();
2220  m_leftCombo->addItem(tempFileName);
2221  m_rightCombo->addItem(tempFileName);
2222  if (m_editPoint->IsReferenceExplicit() &&
2223  (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
2224  m_leftCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2225  m_rightCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2226  }
2227  }
2228 
2229 
2230  // TODO: WHAT HAPPENS IF THERE IS ONLY ONE MEASURE IN THIS CONTROLPOINT??
2231  // Assuming combo loaded in same order as measures in the control point-is
2232  // this a safe assumption???
2233  //
2234  // Find the file from the cubeViewport that was originally used to select
2235  // the point, this will be displayed on the left ChipViewport, unless the
2236  // point was selected on the ground source image. In this case, simply
2237  // load the first measure on the left.
2238  int leftIndex = 0;
2239  int rightIndex = 0;
2240  // Check for reference
2241  if (m_editPoint->IsReferenceExplicit()) {
2242  leftIndex = m_editPoint->IndexOfRefMeasure();
2243  }
2244  else {
2245  if ((m_editPoint->GetType() == ControlPoint::Free) && !m_leftFile.isEmpty()) {
2246  QString baseFileName = FileName(m_leftFile).name();
2247  leftIndex = m_leftCombo->findText(baseFileName);
2248  // Sanity check
2249  if (leftIndex < 0 ) leftIndex = 0;
2250  }
2251  }
2252 
2253  // Determine index for right measure.
2254  // First, try to find correct ground. If no correct ground, set right index to either 0 or 1,
2255  // depending on value of the left index.
2256  if (m_groundOpen && (m_editPoint->GetType() != ControlPoint::Free)) {
2257  rightIndex = m_rightCombo->findText((QString)m_groundFile);
2258  }
2259  if (rightIndex <= 0) {
2260  if (leftIndex == 0) {
2261  rightIndex = 1;
2262  }
2263  else {
2264  rightIndex = 0;
2265  }
2266  }
2267 
2268  // Handle pts with a single measure, for now simply put measure on left/right
2269  // Evenutally put on left with black on right??
2270  if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
2271  m_rightCombo->setCurrentIndex(rightIndex);
2272  m_leftCombo->setCurrentIndex(leftIndex);
2273  // Initialize pointEditor with measures
2274  selectLeftMeasure(leftIndex);
2275  selectRightMeasure(rightIndex);
2276 
2278 
2279  loadMeasureTable();
2280  }
2281 
2282 
2283 
2284 
2285 
2294  if (m_measureWindow == NULL) {
2295  m_measureWindow = new QMainWindow();
2296  m_measureTable = new QTableWidget();
2297  m_measureTable->setMinimumWidth(1600);
2298  m_measureTable->setAlternatingRowColors(true);
2299  m_measureWindow->setCentralWidget(m_measureTable);
2300  }
2301  else {
2302  m_measureTable->clear();
2303  m_measureTable->setSortingEnabled(false);
2304  }
2305  m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
2306  m_measureTable->setColumnCount(NUMCOLUMNS);
2307 
2308  QStringList labels;
2309  for (int i=0; i<NUMCOLUMNS; i++) {
2310  labels<<measureColumnToString((MeasureColumns)i);
2311  }
2312  m_measureTable->setHorizontalHeaderLabels(labels);
2313 
2314  // Fill in values
2315  for (int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2316  int column = 0;
2317  ControlMeasure &m = *(*m_editPoint)[row];
2318 
2319  QString file = m_serialNumberList->FileName(m.GetCubeSerialNumber());
2320  QTableWidgetItem *tableItem = new QTableWidgetItem(QString(file));
2321  m_measureTable->setItem(row,column++,tableItem);
2322 
2323  tableItem = new QTableWidgetItem(QString(m.GetCubeSerialNumber()));
2324  m_measureTable->setItem(row,column++,tableItem);
2325 
2326  tableItem = new QTableWidgetItem();
2327  tableItem->setData(0,m.GetSample());
2328  m_measureTable->setItem(row,column++,tableItem);
2329 
2330  tableItem = new QTableWidgetItem();
2331  tableItem->setData(0,m.GetLine());
2332  m_measureTable->setItem(row,column++,tableItem);
2333 
2334  if (m.GetAprioriSample() == Null) {
2335  tableItem = new QTableWidgetItem("Null");
2336  }
2337  else {
2338  tableItem = new QTableWidgetItem();
2339  tableItem->setData(0,m.GetAprioriSample());
2340  }
2341  m_measureTable->setItem(row,column++,tableItem);
2342 
2343  if (m.GetAprioriLine() == Null) {
2344  tableItem = new QTableWidgetItem("Null");
2345  }
2346  else {
2347  tableItem = new QTableWidgetItem();
2348  tableItem->setData(0,m.GetAprioriLine());
2349  }
2350  m_measureTable->setItem(row,column++,tableItem);
2351 
2352  if (m.GetSampleResidual() == Null) {
2353  tableItem = new QTableWidgetItem(QString("Null"));
2354  }
2355  else {
2356  tableItem = new QTableWidgetItem();
2357  tableItem->setData(0,m.GetSampleResidual());
2358  }
2359  m_measureTable->setItem(row,column++,tableItem);
2360 
2361  if (m.GetLineResidual() == Null) {
2362  tableItem = new QTableWidgetItem(QString("Null"));
2363  }
2364  else {
2365  tableItem = new QTableWidgetItem();
2366  tableItem->setData(0,m.GetLineResidual());
2367  }
2368  m_measureTable->setItem(row,column++,tableItem);
2369 
2370  if (m.GetResidualMagnitude() == Null) {
2371  tableItem = new QTableWidgetItem(QString("Null"));
2372  }
2373  else {
2374  tableItem = new QTableWidgetItem();
2375  tableItem->setData(0,m.GetResidualMagnitude());
2376  }
2377  m_measureTable->setItem(row,column++,tableItem);
2378 
2379  double sampleShift = m.GetSampleShift();
2380  if (sampleShift == Null) {
2381  tableItem = new QTableWidgetItem(QString("Null"));
2382  }
2383  else {
2384  tableItem = new QTableWidgetItem();
2385  tableItem->setData(0,sampleShift);
2386  }
2387  m_measureTable->setItem(row,column++,tableItem);
2388 
2389  double lineShift = m.GetLineShift();
2390  if (lineShift == Null) {
2391  tableItem = new QTableWidgetItem(QString("Null"));
2392  }
2393  else {
2394  tableItem = new QTableWidgetItem();
2395  tableItem->setData(0,lineShift);
2396  }
2397  m_measureTable->setItem(row,column++,tableItem);
2398 
2399  double pixelShift = m.GetPixelShift();
2400  if (pixelShift == Null) {
2401  tableItem = new QTableWidgetItem(QString("Null"));
2402  }
2403  else {
2404  tableItem = new QTableWidgetItem();
2405  tableItem->setData(0,pixelShift);
2406  }
2407  m_measureTable->setItem(row,column++,tableItem);
2408 
2409  double goodnessOfFit = m.GetLogData(
2411  if (goodnessOfFit == Null) {
2412  tableItem = new QTableWidgetItem(QString("Null"));
2413  }
2414  else {
2415  tableItem = new QTableWidgetItem();
2416  tableItem->setData(0,goodnessOfFit);
2417  }
2418  m_measureTable->setItem(row,column++,tableItem);
2419 
2420  if (m.IsIgnored()) tableItem = new QTableWidgetItem("True");
2421  if (!m.IsIgnored()) tableItem = new QTableWidgetItem("False");
2422  m_measureTable->setItem(row,column++,tableItem);
2423 
2425  tableItem = new QTableWidgetItem("True");
2427  tableItem = new QTableWidgetItem("False");
2428  m_measureTable->setItem(row,column++,tableItem);
2429 
2430  tableItem = new QTableWidgetItem(
2432  m_measureTable->setItem(row,column,tableItem);
2433 
2434  // If reference measure set font on this row to bold
2435  if (m_editPoint->IsReferenceExplicit() &&
2436  (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
2437  QFont font;
2438  font.setBold(true);
2439 
2440  for (int col=0; col<m_measureTable->columnCount(); col++)
2441  m_measureTable->item(row, col)->setFont(font);
2442  }
2443 
2444  }
2445 
2446  m_measureTable->resizeColumnsToContents();
2447  m_measureTable->resizeRowsToContents();
2448  m_measureTable->setSortingEnabled(true);
2449  m_measureWindow->show();
2450  }
2451 
2452 
2453 
2454  QString QnetTool::measureColumnToString(QnetTool::MeasureColumns column) {
2455  switch (column) {
2456  case FILENAME:
2457  return "FileName";
2458  case CUBESN:
2459  return "Serial #";
2460  case SAMPLE:
2461  return "Sample";
2462  case LINE:
2463  return "Line";
2464  case SAMPLERESIDUAL:
2465  return "Sample Residual";
2466  case LINERESIDUAL:
2467  return "Line Residual";
2468  case RESIDUALMAGNITUDE:
2469  return "Residual Magnitude";
2470  case SAMPLESHIFT:
2471  return "Sample Shift";
2472  case LINESHIFT:
2473  return "Line Shift";
2474  case PIXELSHIFT:
2475  return "Pixel Shift";
2476  case GOODNESSOFFIT:
2477  return "Goodness of Fit";
2478  case IGNORED:
2479  return "Ignored";
2480  case EDITLOCK:
2481  return "Edit Lock";
2482  case TYPE:
2483  return "Measure Type";
2484  case APRIORISAMPLE:
2485  return "Apriori Sample";
2486  case APRIORILINE:
2487  return "Apriori Line";
2488  }
2489  throw IException(IException::Programmer,
2490  "Invalid measure column passed to measureColumnToString", _FILEINFO_);
2491  }
2492 
2493 
2494  ControlNet *QnetTool::controlNet() {
2495  return m_controlNet;
2496  }
2497 
2498 
2499  const ControlNet *QnetTool::controlNet() const {
2500  return m_controlNet;
2501  }
2502 
2503 
2504  SerialNumberList *QnetTool::serialNumberList() {
2505  return m_serialNumberList;
2506  }
2507 
2508 
2509  const SerialNumberList *QnetTool::serialNumberList() const {
2510  return m_serialNumberList;
2511  }
2512 
2513 
2514  Workspace *QnetTool::workspace() const {
2515  return m_workspace;
2516  }
2517 
2518 
2531 
2532  QString s;
2533 
2534  SurfacePoint aprioriPoint = m_editPoint->GetAprioriSurfacePoint();
2535  if (aprioriPoint.GetLatitude().degrees() == Null) {
2536  s = "AprioriLatitude: Null";
2537  }
2538  else {
2539  s = "Apriori Latitude: " +
2540  QString::number(aprioriPoint.GetLatitude().degrees());
2541  }
2542  m_pointAprioriLatitude->setText(s);
2543  if (aprioriPoint.GetLongitude().degrees() == Null) {
2544  s = "Apriori Longitude: Null";
2545  }
2546  else {
2547  s = "Apriori Longitude: " +
2548  QString::number(aprioriPoint.GetLongitude().degrees());
2549  }
2550  m_pointAprioriLongitude->setText(s);
2551  if (aprioriPoint.GetLocalRadius().meters() == Null) {
2552  s = "Apriori Radius: Null";
2553  }
2554  else {
2555  s = "Apriori Radius: " +
2556  QString::number(aprioriPoint.GetLocalRadius().meters(),'f',2) +
2557  " <meters>";
2558  }
2559  m_pointAprioriRadius->setText(s);
2560 
2561  if (aprioriPoint.Valid()) {
2562  vector<Distance> targRadii = m_controlNet->GetTargetRadii();
2563  aprioriPoint.SetRadii(targRadii[0],targRadii[1],targRadii[2]);
2564 
2565  if (aprioriPoint.GetLatSigmaDistance().meters() == Null) {
2566  s = "Apriori Latitude Sigma: Null";
2567  }
2568  else {
2569  s = "Apriori Latitude Sigma: " +
2570  QString::number(aprioriPoint.GetLatSigmaDistance().meters()) +
2571  " <meters>";
2572  }
2573  m_pointAprioriLatitudeSigma->setText(s);
2574  if (aprioriPoint.GetLonSigmaDistance().meters() == Null) {
2575  s = "Apriori Longitude Sigma: Null";
2576  }
2577  else {
2578  s = "Apriori Longitude Sigma: " +
2579  QString::number(aprioriPoint.GetLonSigmaDistance().meters()) +
2580  " <meters>";
2581  }
2582  m_pointAprioriLongitudeSigma->setText(s);
2583  if (aprioriPoint.GetLocalRadiusSigma().meters() == Null) {
2584  s = "Apriori Radius Sigma: Null";
2585  }
2586  else {
2587  s = "Apriori Radius Sigma: " +
2588  QString::number(aprioriPoint.GetLocalRadiusSigma().meters()) +
2589  " <meters>";
2590  }
2591  m_pointAprioriRadiusSigma->setText(s);
2592  }
2593  else {
2594  s = "Apriori Latitude Sigma: Null";
2595  m_pointAprioriLatitudeSigma->setText(s);
2596  s = "Apriori Longitude Sigma: Null";
2597  m_pointAprioriLongitudeSigma->setText(s);
2598  s = "Apriori Radius Sigma: Null";
2599  m_pointAprioriRadiusSigma->setText(s);
2600  }
2601 
2602 
2603  SurfacePoint point = m_editPoint->GetAdjustedSurfacePoint();
2604  if (point.GetLatitude().degrees() == Null) {
2605  s = "Adjusted Latitude: Null";
2606  }
2607  else {
2608  s = "Adjusted Latitude: " + QString::number(point.GetLatitude().degrees());
2609  }
2610  m_pointLatitude->setText(s);
2611  if (point.GetLongitude().degrees() == Null) {
2612  s = "Adjusted Longitude: Null";
2613  }
2614  else {
2615  s = "Adjusted Longitude: " + QString::number(point.GetLongitude().degrees());
2616  }
2617  m_pointLongitude->setText(s);
2618  if (point.GetLocalRadius().meters() == Null) {
2619  s = "Adjusted Radius: Null";
2620  }
2621  else {
2622  s = "Adjusted Radius: " +
2623  QString::number(point.GetLocalRadius().meters(),'f',2) + " <meters>";
2624  }
2625  m_pointRadius->setText(s);
2626 
2627 
2628 
2629  }
2630 
2631 
2632 
2633 
2646  QString file = m_pointFiles[index];
2647 
2648  QString serial = m_serialNumberList->SerialNumber(file);
2649 
2650  // Make sure to clear out leftMeasure before making a copy of the selected
2651  // measure.
2652  if (m_leftMeasure != NULL) {
2653  delete m_leftMeasure;
2654  m_leftMeasure = NULL;
2655  }
2656  m_leftMeasure = new ControlMeasure();
2657  // Find measure for each file
2658  *m_leftMeasure = *((*m_editPoint)[serial]);
2659 
2660  // If m_leftCube is not null, delete before creating new one
2661  m_leftCube.reset(new Cube(file, "r"));
2662 
2663  // Update left measure of pointEditor
2664  m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
2665  m_editPoint->GetId());
2667 
2668  }
2669 
2670 
2681 
2682  QString file = m_pointFiles[index];
2683 
2684  QString serial = m_serialNumberList->SerialNumber(file);
2685 
2686  // Make sure to clear out rightMeasure before making a copy of the selected
2687  // measure.
2688  if (m_rightMeasure != NULL) {
2689  delete m_rightMeasure;
2690  m_rightMeasure = NULL;
2691  }
2692  m_rightMeasure = new ControlMeasure();
2693  // Find measure for each file
2694  *m_rightMeasure = *((*m_editPoint)[serial]);
2695 
2696  // If m_leftCube is not null, delete before creating new one
2697  m_rightCube.reset(new Cube(file, "r"));
2698 
2699  // Update left measure of pointEditor
2700  m_pointEditor->setRightMeasure (m_rightMeasure, m_rightCube.data(),
2701  m_editPoint->GetId());
2703 
2704  }
2705 
2706 
2707 
2708 
2725 
2726  // Set editLock measure box correctly
2727  m_lockLeftMeasure->setChecked(IsMeasureLocked(
2728  m_leftMeasure->GetCubeSerialNumber()));
2729  // Set ignore measure box correctly
2730  m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2731 
2732  QString s = "Reference: ";
2733  if (m_editPoint->IsReferenceExplicit() &&
2734  (QString(m_leftMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2735  s += "True";
2736  }
2737  else {
2738  s += "False";
2739  }
2740  m_leftReference->setText(s);
2741 
2742  s = "Measure Type: ";
2743  if (m_leftMeasure->GetType() == ControlMeasure::Candidate) s+= "Candidate";
2744  if (m_leftMeasure->GetType() == ControlMeasure::Manual) s+= "Manual";
2745  if (m_leftMeasure->GetType() == ControlMeasure::RegisteredPixel) s+= "RegisteredPixel";
2746  if (m_leftMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s+= "RegisteredSubPixel";
2747  m_leftMeasureType->setText(s);
2748 
2749  if (m_leftMeasure->GetSampleResidual() == Null) {
2750  s = "Sample Residual: Null";
2751  }
2752  else {
2753  s = "Sample Residual: " + QString::number(m_leftMeasure->GetSampleResidual());
2754  }
2755  m_leftSampError->setText(s);
2756  if (m_leftMeasure->GetLineResidual() == Null) {
2757  s = "Line Residual: Null";
2758  }
2759  else {
2760  s = "Line Residual: " + QString::number(m_leftMeasure->GetLineResidual());
2761  }
2762  m_leftLineError->setText(s);
2763 
2764  if (m_leftMeasure->GetSampleShift() == Null) {
2765  s = "Sample Shift: Null";
2766  }
2767  else {
2768  s = "Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2769  }
2770  m_leftSampShift->setText(s);
2771 
2772  if (m_leftMeasure->GetLineShift() == Null) {
2773  s = "Line Shift: Null";
2774  }
2775  else {
2776  s = "Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2777  }
2778  m_leftLineShift->setText(s);
2779 
2780  double goodnessOfFit = m_leftMeasure->GetLogData(
2781  ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
2782  if (goodnessOfFit == Null) {
2783  s = "Goodness of Fit: Null";
2784  }
2785  else {
2786  s = "Goodness of Fit: " + QString::number(goodnessOfFit);
2787  }
2788  m_leftGoodness->setText(s);
2789 
2790  }
2791 
2792 
2793 
2813 
2814  // Set editLock measure box correctly
2815  m_lockRightMeasure->setChecked(IsMeasureLocked(
2816  m_rightMeasure->GetCubeSerialNumber()));
2817  // Set ignore measure box correctly
2818  m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2819 
2820  QString s = "Reference: ";
2821  if (m_editPoint->IsReferenceExplicit() &&
2822  (QString(m_rightMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2823  s += "True";
2824  }
2825  else {
2826  s += "False";
2827  }
2828 
2829  m_rightReference->setText(s);
2830 
2831  s = "Measure Type: ";
2832  if (m_rightMeasure->GetType() == ControlMeasure::Candidate) s+= "Candidate";
2833  if (m_rightMeasure->GetType() == ControlMeasure::Manual) s+= "Manual";
2834  if (m_rightMeasure->GetType() == ControlMeasure::RegisteredPixel) s+= "RegisteredPixel";
2835  if (m_rightMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s+= "RegisteredSubPixel";
2836  m_rightMeasureType->setText(s);
2837 
2838  if (m_rightMeasure->GetSampleResidual() == Null) {
2839  s = "Sample Residual: Null";
2840  }
2841  else {
2842  s = "Sample Residual: " + QString::number(m_rightMeasure->GetSampleResidual());
2843  }
2844  m_rightSampError->setText(s);
2845  if (m_rightMeasure->GetLineResidual() == Null) {
2846  s = "Line Residual: Null";
2847  }
2848  else {
2849  s = "Line Residual: " + QString::number(m_rightMeasure->GetLineResidual());
2850  }
2851  m_rightLineError->setText(s);
2852 
2853  if (m_rightMeasure->GetSampleShift() == Null) {
2854  s = "Sample Shift: Null";
2855  }
2856  else {
2857  s = "Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2858  }
2859  m_rightSampShift->setText(s);
2860 
2861  if (m_rightMeasure->GetLineShift() == Null) {
2862  s = "Line Shift: Null";
2863  }
2864  else {
2865  s = "Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2866  }
2867  m_rightLineShift->setText(s);
2868 
2869  double goodnessOfFit = m_rightMeasure->GetLogData(
2870  ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
2871  if (goodnessOfFit == Null) {
2872  s = "Goodness of Fit: Null";
2873  }
2874  else {
2875  s = "Goodness of Fit: " + QString::number(goodnessOfFit);
2876  }
2877  m_rightGoodness->setText(s);
2878 
2879  }
2880 
2881 
2894 
2895  // Create list of list box of all files highlighting those that
2896  // contain the point, but that do not already have a measure.
2897  QStringList pointFiles;
2898 
2899  // Initialize camera for all images in control network,
2900  // TODO:: Needs to be moved to QnetFileTool.cpp
2901  Camera *cam;
2902 
2903  // If no apriori or adjusted lat/lon for this point, use lat/lon of first measure
2904  double lat = m_editPoint->GetBestSurfacePoint().GetLatitude().degrees();
2905  double lon = m_editPoint->GetBestSurfacePoint().GetLongitude().degrees();
2906  if (lat == Null || lon == Null) {
2907  ControlMeasure m = *(m_editPoint->GetRefMeasure());
2908  int camIndex = m_serialNumberList->SerialNumberIndex(m.GetCubeSerialNumber());
2909  cam = m_controlNet->Camera(camIndex);
2910  //cam = m.Camera();
2911  cam->SetImage(m.GetSample(),m.GetLine());
2912  lat = cam->UniversalLatitude();
2913  lon = cam->UniversalLongitude();
2914  }
2915 
2916  for (int i=0; i<m_serialNumberList->Size(); i++) {
2917  cam = m_controlNet->Camera(i);
2918  if (m_serialNumberList->SerialNumber(i) == m_groundSN) continue;
2919  if (cam->SetUniversalGround(lat,lon)) {
2920  // Make sure point is within image boundary
2921  double samp = cam->Sample();
2922  double line = cam->Line();
2923  if (samp >= 1 && samp <= cam->Samples() &&
2924  line >= 1 && line <= cam->Lines()) {
2925  pointFiles<<m_serialNumberList->FileName(i);
2926  }
2927  }
2928  }
2929 
2930  QnetNewMeasureDialog *newMeasureDialog = new QnetNewMeasureDialog(this);
2931  newMeasureDialog->setFiles(*m_editPoint,pointFiles);
2932  if (newMeasureDialog->exec()) {
2933  QStringList selectedFiles = newMeasureDialog->selectedFiles();
2934  foreach (QString selectedFile, selectedFiles) {
2935  // Create measure for any file selected
2936  ControlMeasure *m = new ControlMeasure;
2937  // Find serial number for this file
2938  QString sn = m_serialNumberList->SerialNumber(selectedFile);
2939  m->SetCubeSerialNumber(sn);
2940  int camIndex =
2941  m_serialNumberList->FileNameIndex(selectedFile);
2942  cam = m_controlNet->Camera(camIndex);
2943  cam->SetUniversalGround(lat,lon);
2944  m->SetCoordinate(cam->Sample(),cam->Line());
2945  m->SetAprioriSample(cam->Sample());
2946  m->SetAprioriLine(cam->Line());
2949  m_editPoint->Add(m);
2950  }
2951  loadPoint();
2952  m_qnetTool->setShown(true);
2953  m_qnetTool->raise();
2954 
2956  m_pointEditor->templateFileName());
2957 
2958 
2959  // emit signal so the nav tool can update edit point
2960  emit editPointChanged(m_editPoint->GetId());
2962  }
2963  }
2964 
2965 
2976  bool QnetTool::eventFilter(QObject *o, QEvent *e) {
2977  if(e->type() != QEvent::Leave) return false;
2978  if(o == m_leftCombo->view()) {
2980  m_leftCombo->hidePopup();
2981  }
2982  if (o == m_rightCombo->view()) {
2984  m_rightCombo->hidePopup();
2985  }
2986  return true;
2987  }
2988 
2989 
2997  void QnetTool::paintViewport(MdiCubeViewport *vp, QPainter *painter) {
2998  drawAllMeasurments (vp,painter);
2999 
3000  }
3001 
3002 
3016  void QnetTool::paintAllViewports(QString pointId) {
3017 
3018  // Take care of drawing things on all viewPorts.
3019  // Calling update will cause the Tool class to call all registered tools
3020  // if point has been deleted, this will remove it from the main window
3021  MdiCubeViewport *vp;
3022  for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3023  vp = (*(cubeViewportList()))[i];
3024  vp->viewport()->update();
3025  }
3026  }
3027 
3050  void QnetTool::drawAllMeasurments(MdiCubeViewport *vp, QPainter *painter) {
3051  // Without a controlnetwork there are no points, or if new net, no points
3052  if (m_controlNet == 0 || m_controlNet->GetNumPoints() == 0) return;
3053 
3054  // Don't show the measurments on cubes not in the serial number list
3055  // TODO: Should we show them anyway
3056  // TODO: Should we add the SN to the viewPort
3057  QString serialNumber = SerialNumber::Compose(*vp->cube(), true);
3058 
3059  if (serialNumber == m_groundSN) {
3060  drawGroundMeasures(vp, painter);
3061  return;
3062  }
3063  if (!m_controlNet->GetCubeSerials().contains(
3064  serialNumber)) return;
3065  if (!m_serialNumberList->HasSerialNumber(serialNumber)) return;
3066  QList<ControlMeasure *> measures =
3067  m_controlNet->GetMeasuresInCube(serialNumber);
3068  // loop through all measures contained in this cube
3069  for (int i = 0; i < measures.count(); i++) {
3070  ControlMeasure *m = measures[i];
3071  // Find the measurments on the viewport
3072  double samp = m->GetSample();
3073  double line = m->GetLine();
3074  int x, y;
3075  vp->cubeToViewport(samp, line, x, y);
3076  // if the point is ignored,
3077  if (m->Parent()->IsIgnored()) {
3078  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3079  }
3080  // point is not ignored, but measure matching this image is ignored,
3081  else if (m->IsIgnored()) {
3082  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3083  }
3084  // Neither point nor measure is not ignored and the measure is fixed,
3085  else if (m->Parent()->GetType() != ControlPoint::Free) {
3086  painter->setPen(Qt::magenta);// set point marker magenta
3087  }
3088  else {
3089  painter->setPen(Qt::green); // set all other point markers green
3090  }
3091  // draw points
3092  painter->drawLine(x - 5, y, x + 5, y);
3093  painter->drawLine(x, y - 5, x, y + 5);
3094  }
3095  // if QnetTool is open,
3096  if (m_editPoint != NULL) {
3097  // and the selected point is in the image,
3098  if (m_editPoint->HasSerialNumber(serialNumber)) {
3099  // find the measurement
3100  double samp = (*m_editPoint)[serialNumber]->GetSample();
3101  double line = (*m_editPoint)[serialNumber]->GetLine();
3102  int x, y;
3103  vp->cubeToViewport(samp, line, x, y);
3104  // set point marker red
3105  QBrush brush(Qt::red);
3106  // set point marker bold - line width 2
3107  QPen pen(brush, 2);
3108  // draw the selected point in each image last so it's on top of the rest of the points
3109  painter->setPen(pen);
3110  painter->drawLine(x - 5, y, x + 5, y);
3111  painter->drawLine(x, y - 5, x, y + 5);
3112  }
3113  }
3114  }
3115 
3116 
3117 
3118 
3128  void QnetTool::drawGroundMeasures(MdiCubeViewport *vp, QPainter *painter) {
3129 
3130  // loop through control network looking for fixed and constrained points
3131  for (int i = 0; i < m_controlNet->GetNumPoints(); i++) {
3132  ControlPoint &p = *((*m_controlNet)[i]);
3133  if (p.GetType() == ControlPoint::Free) continue;
3134  if (!p.HasAprioriCoordinates()) continue;
3135 
3136  // Find the measure on the ground image
3137  if (m_groundGmap->SetGround(p.GetAprioriSurfacePoint().GetLatitude(),
3138  p.GetAprioriSurfacePoint().GetLongitude())) {
3139  double samp = m_groundGmap->Sample();
3140  double line = m_groundGmap->Line();
3141  int x, y;
3142  vp->cubeToViewport(samp, line, x, y);
3143  // if the point is ignored,
3144  if (p.IsIgnored()) {
3145  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3146  }
3147  else if (p.GetType() != ControlPoint::Free) {
3148  painter->setPen(Qt::magenta);// set point marker magenta
3149  }
3150  else if (&p == m_editPoint) {
3151  // set point marker red
3152  QBrush brush(Qt::red);
3153  // set point marker bold - line width 2
3154  QPen pen(brush, 2);
3155  }
3156  else {
3157  painter->setPen(Qt::green); // set all other point markers green
3158  }
3159  // draw points
3160  painter->drawLine(x - 5, y, x + 5, y);
3161  painter->drawLine(x, y - 5, x, y + 5);
3162  }
3163  }
3164  }
3165 
3166 
3167 
3181 
3182  if (m_templateModified) {
3183  int r = QMessageBox::warning(m_qnetTool, tr("OK to continue?"),
3184  tr("The currently opened registration template has been modified.\n"
3185  "Save changes?"),
3186  QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
3187  QMessageBox::Yes);
3188 
3189  if (r == QMessageBox::Yes)
3191  else if (r == QMessageBox::Cancel)
3192  return false;
3193  }
3194 
3195  return true;
3196  }
3197 
3198 
3205 
3206  if (!okToContinue())
3207  return;
3208 
3209  QString filename = QFileDialog::getOpenFileName(m_qnetTool,
3210  "Select a registration template", ".",
3211  "Registration template files (*.def *.pvl);;All files (*)");
3212 
3213  if (filename.isEmpty())
3214  return;
3215 
3216  if (m_pointEditor->setTemplateFile(filename)) {
3217  loadTemplateFile(filename);
3218  }
3219  }
3220 
3221 
3227  void QnetTool::loadTemplateFile(QString fn) {
3228 
3229  QFile file(FileName(fn).expanded());
3230  if (!file.open(QIODevice::ReadOnly)) {
3231  QString msg = "Failed to open template file \"" + fn + "\"";
3232  QMessageBox::warning(m_qnetTool, "IO Error", msg);
3233  return;
3234  }
3235 
3236  QTextStream stream(&file);
3237  m_templateEditor->setText(stream.readAll());
3238  file.close();
3239 
3240  QScrollBar * sb = m_templateEditor->verticalScrollBar();
3241  sb->setValue(sb->minimum());
3242 
3243  m_templateModified = false;
3244  m_saveTemplateFile->setEnabled(false);
3245  m_templateFileNameLabel->setText("Template File: " + fn);
3246  }
3247 
3248 
3251  m_templateModified = true;
3252  m_saveTemplateFile->setEnabled(true);
3253  }
3254 
3255 
3258 
3259  if (!m_templateModified)
3260  return;
3261 
3262  QString filename = m_pointEditor->templateFileName();
3263 
3264  writeTemplateFile(filename);
3265  }
3266 
3267 
3270 
3271  QString filename = QFileDialog::getSaveFileName(m_qnetTool,
3272  "Save registration template", ".",
3273  "Registration template files (*.def *.pvl);;All files (*)");
3274 
3275  if (filename.isEmpty())
3276  return;
3277 
3278  writeTemplateFile(filename);
3279  }
3280 
3281 
3287  void QnetTool::writeTemplateFile(QString fn) {
3288 
3289  QString contents = m_templateEditor->toPlainText();
3290 
3291  // catch errors in Pvl format when populating pvl object
3292  stringstream ss;
3293  ss << contents;
3294  try {
3295  Pvl pvl;
3296  ss >> pvl;
3297  }
3298  catch(IException &e) {
3299  QString message = e.toString();
3300  QMessageBox::warning(m_qnetTool, "Error", message);
3301  return;
3302  }
3303 
3304  QString expandedFileName(FileName(fn).expanded());
3305 
3306  QFile file(expandedFileName);
3307 
3308  if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
3309  QString msg = "Failed to save template file to \"" + fn + "\"\nDo you "
3310  "have permission?";
3311  QMessageBox::warning(m_qnetTool, "IO Error", msg);
3312  return;
3313  }
3314 
3315  // now save contents
3316  QTextStream stream(&file);
3317  stream << contents;
3318  file.close();
3319 
3320  if (m_pointEditor->setTemplateFile(fn)) {
3321  m_templateModified = false;
3322  m_saveTemplateFile->setEnabled(false);
3323  m_templateFileNameLabel->setText("Template File: " + fn);
3324  }
3325  }
3326 
3327 
3342  try{
3343  // Get the template file from the ControlPointEditor object
3344  Pvl templatePvl(m_pointEditor->templateFileName());
3345  // Create registration dialog window using PvlEditDialog class
3346  // to view and/or edit the template
3347  PvlEditDialog registrationDialog(templatePvl);
3348  registrationDialog.setWindowTitle("View or Edit Template File: "
3349  + templatePvl.fileName());
3350  registrationDialog.resize(550,360);
3351  registrationDialog.exec();
3352  }
3353  catch (IException &e) {
3354  QString message = e.toString();
3355  QMessageBox::information(m_qnetTool, "Error", message);
3356  }
3357  }
3358 
3359 
3360 
3368  m_pointEditor->saveChips();
3369  }
3370 
3371 
3372  void QnetTool::showHideTemplateEditor() {
3373 
3374  if (!m_templateEditorWidget)
3375  return;
3376 
3377  m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
3378  }
3379 
3380 
3381 
3394  void QnetTool::updatePointInfo(QString pointId) {
3395  if (m_editPoint == NULL) return;
3396  if (pointId != m_editPoint->GetId()) return;
3397  // The edit point has been changed by SetApriori, so m_editPoint needs
3398  // to possibly update some values. Need to retain measures from m_editPoint
3399  // because they might have been updated, but not yet saved to the network
3400  // ("Save Point").
3401  ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
3402  m_editPoint->SetEditLock(updatedPoint->IsEditLocked());
3403  m_editPoint->SetIgnored(updatedPoint->IsIgnored());
3404  m_editPoint->SetAprioriSurfacePoint(updatedPoint->GetAprioriSurfacePoint());
3405 
3406  // Set EditLock box correctly
3407  m_lockPoint->setChecked(m_editPoint->IsEditLocked());
3408 
3409  // Set ignore box correctly
3410  m_ignorePoint->setChecked(m_editPoint->IsIgnored());
3411 
3413 
3414  }
3415 
3416 
3417 
3418 
3435 
3436 
3437  // Check point being edited, make sure it still exists, if not ???
3438  // Update ignored checkbox??
3439  if (m_editPoint != NULL) {
3440  try {
3441  QString id = m_ptIdValue->text().remove("Point ID: ");
3442  m_controlNet->GetPoint(id);
3443  }
3444  catch (IException &) {
3445  delete m_editPoint;
3446  m_editPoint = NULL;
3447  emit editPointChanged("");
3448  m_qnetTool->setShown(false);
3449  m_measureWindow->setShown(false);
3450  }
3451  }
3452 
3453  if (m_editPoint == NULL) {
3454  paintAllViewports("");
3455  }
3456  else {
3457  paintAllViewports(m_editPoint->GetId());
3458  }
3459  }
3460 
3461 
3469  void QnetTool::showNavWindow(bool checked){
3470  emit showNavTool();
3471  }
3472 
3486  QWidget *QnetTool::createToolBarWidget (QStackedWidget *parent) {
3487  QWidget *hbox = new QWidget(parent);
3488 
3489  QToolButton *showNavToolButton = new QToolButton();
3490  showNavToolButton->setText("Show Nav Tool");
3491  showNavToolButton->setToolTip("Shows the Navigation Tool Window");
3492  QString text =
3493  "<b>Function:</b> This button will bring up the Navigation Tool window that allows \
3494  the user to view, modify, ignore, delete, or filter points and cubes.";
3495  showNavToolButton->setWhatsThis(text);
3496  connect(showNavToolButton,SIGNAL(clicked(bool)),this,SLOT(showNavWindow(bool)));
3497 
3498  QHBoxLayout *layout = new QHBoxLayout(hbox);
3499  layout->setMargin(0);
3500  layout->addWidget(showNavToolButton);
3501  layout->addStretch(1);
3502  hbox->setLayout(layout);
3503  return hbox;
3504  }
3505 
3506 
3507 
3508 
3526 
3527  QString filter = "Isis cubes (*.cub *.cub.*);;";
3528  filter += "Detached labels (*.lbl);;";
3529  filter += "All (*)";
3530  QString ground = QFileDialog::getOpenFileName((QWidget*)parent(),
3531  "Open ground source",
3532  ".",
3533  filter);
3534  if (ground.isEmpty()) return;
3535 
3536  // First off, find serial number of new ground, it is needed for a couple of error checks.
3537  QString newGroundSN = SerialNumber::Compose(ground, true);
3538 
3539  // If new ground same file as old ground file simply set as active window.
3540  if (m_groundOpen && m_groundFile == FileName(ground).name()) {
3541  // See if ground source is already opened in a cubeviewport. If so, simply
3542  // activate the viewport and return.
3543  MdiCubeViewport *vp;
3544  for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3545  vp = (*(cubeViewportList()))[i];
3546  if (vp->cube()->fileName() == ground) {
3547  m_workspace->mdiArea()->setActiveSubWindow(
3548  (QMdiSubWindow *)vp->parentWidget()->parent());
3549  return;
3550  }
3551  }
3552  }
3553 
3554  // Make sure there are not serial number conflicts. If there are serial number conflicts,
3555  // simply return, retaining current ground source.
3556  if (newGroundSN != m_groundSN && m_serialNumberList->HasSerialNumber(newGroundSN)) {
3557  // TODO If it already exists, are the files different? Now what?
3558  // For now, do not allow.
3559  QString message = "A cube in the cube list has the same serial number as this ground file. ";
3560  message += "If this ground source is a level 1, un-projected cube, it is probably included ";
3561  message += "in the cube list. If the ground source is a projected version of a cube in ";
3562  message += "the list and has the Instrument Group in the labels, the un-projected and ";
3563  message += "projected cube will have the same serial number. \n";
3564  message += "Because of duplicate serial numbers this cube cannot be used as a ground ";
3565  message += "source.\n\n";
3566  message += "NOTE: If this cube is the reference cube you can select points in ";
3567  message += "the Navigator window, then select the Set Apriori button to use this cube to ";
3568  message += "set the apriori latitude, longitude and radius.";
3569  QMessageBox::critical(m_qnetTool, "Cannot set ground source", message);
3570  return;
3571  }
3572 
3573  // So far, so good. If previous ground, clear out ground source info.
3574  if (m_groundOpen) {
3575  // ....otherwise if new ground source, close old. We only want a single
3576  // ground source opened at once. Delete old ground source from left/right
3577  // combo if it's there, and delete from serial number list.
3578  clearGroundSource ();
3579  }
3580 
3581  QApplication::setOverrideCursor(Qt::WaitCursor);
3582 
3583  // Create new ground cube, if failure, there will be not ground source, clear all ground
3584  // source data. (Cannot call clearGroundSource because it assumes a ground was successfully
3585  // loaded)
3586  m_groundCube.reset(NULL);
3587  m_groundGmap.reset(NULL);
3588 
3589  try {
3590  QScopedPointer<Cube> newGroundCube(new Cube(ground, "r"));
3591  QScopedPointer<UniversalGroundMap> newGroundGmap(new UniversalGroundMap(*newGroundCube));
3592 
3593  m_groundFile = FileName(newGroundCube->fileName()).name();
3594  m_groundCube.reset(newGroundCube.take());
3595  m_groundGmap.reset(newGroundGmap.take());
3596 
3597  m_serialNumberList->Add(ground, true);
3598  }
3599  catch (IException &e) {
3600  QApplication::restoreOverrideCursor();
3601  QMessageBox::critical(m_qnetTool, "Error", e.toString());
3602 
3603  m_groundFile.clear();
3604 
3605  // Re-load point w/o ground source
3606  if (m_editPoint) {
3607  loadPoint();
3608  }
3609 
3610  emit refreshNavList();
3611  return;
3612  }
3613 
3614  m_groundSN = newGroundSN;
3615  m_groundSourceFile = ground;
3616  m_groundOpen = true;
3617 
3618  m_workspace->addCubeViewport(m_groundCube.data());
3619  // Get viewport so connect can be made when ground source viewport closed to clean up
3620  // ground source
3621  MdiCubeViewport *vp;
3622  for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3623  vp = (*(cubeViewportList()))[i];
3624  if (vp->cube()->fileName() == ground) {
3625  connect(vp, SIGNAL(viewportClosed(CubeViewport *)),
3626  this, SLOT(groundViewportClosed(CubeViewport *)), Qt::UniqueConnection);
3627  }
3628  }
3629 
3630  // Determine file type of ground for setting AprioriSurfacePointSource
3631  // and AprioriRadiusSource.
3632  if (m_groundCube->hasTable("ShapeModelStatistics")) {
3633  m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
3634  if (!m_demOpen) {
3635  m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3636  m_radiusSourceFile = ground;
3637  }
3638  }
3639  // Is this a level 1 or level 2?
3640  else {
3641  try {
3642  ProjectionFactory::CreateFromCube(*m_groundCube);
3643  m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
3644  // TODO Add Basemap to ControlPoint::RadiusSource
3645  if (!m_demOpen) {
3646  // TODO m_groundRadiusSource = ControlPoint::RadiusSource::Basemap;
3647  m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3648  PvlGroup mapping = m_groundCube->group("Mapping");
3649  m_demFile = mapping ["EquatorialRadius"][0]
3650  + ", " + mapping ["PolarRadius"][0];
3651  //
3652  m_radiusSourceFile = "";
3653  }
3654  }
3655  catch (IException &) {
3656  try {
3657  CameraFactory::Create(*m_groundCube);
3658  m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Reference;
3659  if (!m_demOpen) {
3660  // If level 1, determine the shape model
3661  PvlGroup kernels = m_groundCube->group("Kernels");
3662  QString shapeFile = kernels ["ShapeModel"];
3663  if (shapeFile.contains("dem")) {
3664  m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3665  m_radiusSourceFile = shapeFile;
3666  // Open shape file for reading radius later
3667  initDem(shapeFile);
3668  }
3669  else {
3670  m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3671  m_demFile = "Ellipsoid";
3672  // Find pck file from Kernels group
3673  m_radiusSourceFile = (QString) kernels["TargetAttitudeShape"];
3674  }
3675  }
3676  }
3677  catch (IException &) {
3678  QString message = "Cannot create either Camera or Projections ";
3679  message += "for the ground source file. Check the validity of the ";
3680  message += " cube labels. The cube must either be projected or ";
3681  message += " run through spiceinit.";
3682  QMessageBox::critical(m_qnetTool, "Error", message);
3683  // Clear out everything relating to ground source
3684  clearGroundSource ();
3685  QApplication::restoreOverrideCursor();
3686  emit refreshNavList();
3687  return;
3688  }
3689  }
3690  }
3691 
3692  if (m_editPoint != NULL &&
3693  (m_editPoint->GetType() != ControlPoint::Free)) loadPoint();
3694  m_groundFileNameLabel->setText("Ground Source File: " + m_groundFile);
3695  m_radiusFileNameLabel->setText("Radius Source File: " + m_demFile);
3696 
3697  emit refreshNavList();
3698  QApplication::restoreOverrideCursor();
3699  }
3700 
3701 
3710 
3711  if (m_groundFile.isEmpty()) {
3712  QString message = "You must enter a ground source before opening a Dem.";
3713  QMessageBox::critical(m_qnetTool, "Error", message);
3714  return;
3715  }
3716 
3717  QString filter = "Isis cubes (*.cub *.cub.*);;";
3718  filter += "Detached labels (*.lbl);;";
3719  filter += "All (*)";
3720  QString dem = QFileDialog::getOpenFileName((QWidget*)parent(),
3721  "Open DEM",
3722  ".",
3723  filter);
3724  if (dem.isEmpty()) return;
3725 
3726  initDem(dem);
3727 
3728  }
3729 
3730 
3731  void QnetTool::initDem (QString demFile) {
3732 
3733  // If a DEM is already opened, check if new is same as old. If new,
3734  // close old, open new.
3735  QApplication::setOverrideCursor(Qt::WaitCursor);
3736  if (m_demOpen) {
3737  if (m_demFile == demFile) {
3738  QApplication::restoreOverrideCursor();
3739  return;
3740  }
3741 
3742  m_demCube.reset(NULL);
3743  m_demFile.clear();
3744  }
3745 
3746  try {
3747  QScopedPointer<Cube> newDemCube(new Cube(demFile, "r"));
3748 
3749  m_demFile = FileName(newDemCube->fileName()).name();
3750  m_demCube.reset(newDemCube.take());
3751  }
3752  catch (IException &e) {
3753  QMessageBox::critical(m_qnetTool, "Error", e.toString());
3754  QApplication::restoreOverrideCursor();
3755  return;
3756  }
3757  m_demOpen = true;
3758 
3759  // Make sure this is a dem
3760  if (!m_demCube->hasTable("ShapeModelStatistics")) {
3761  QString message = m_demFile + " is not a DEM.";
3762  QMessageBox::critical(m_qnetTool, "Error", message);
3763  m_demCube.reset(NULL);
3764  m_demOpen = false;
3765  m_demFile.clear();
3766  QApplication::restoreOverrideCursor();
3767  return;
3768  }
3769  m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3770  m_groundFileNameLabel->setText("Ground Source File: " + m_groundFile);
3771  m_radiusFileNameLabel->setText("Radius Source File: " + m_demFile);
3772  m_radiusSourceFile = demFile;
3773 
3774  QApplication::restoreOverrideCursor();
3775  }
3776 
3777 
3778 
3786 
3787  // Only continue to clearGroundSource if the viewport is not already closed
3788  // Otherwise, it could be called twice
3789  clearGroundSource();
3790  }
3791 
3792 
3793 
3794  void QnetTool::clearGroundSource () {
3795 
3796  m_leftCombo->removeItem(m_leftCombo->findText(m_groundFile));
3797  m_rightCombo->removeItem(m_rightCombo->findText(m_groundFile));
3798 
3799  // Close viewport containing ground source
3800  MdiCubeViewport *vp;
3801  for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3802  vp = (*(cubeViewportList()))[i];
3803  if (vp->cube() == m_groundCube.data()) {
3804  // disconnect signal to avoid recursive situartion. When a viewport is closed, a signal
3805  // is emitted which would then call groundViewportClosed, then this method again.
3806  disconnect(vp, SIGNAL(viewportClosed(CubeViewport *)),
3807  this, SLOT(groundViewportClosed(CubeViewport *)));
3808  vp->parentWidget()->parentWidget()->close();
3809  QApplication::processEvents();
3810  break;
3811  }
3812  }
3813  // If we could not find the ground source in the open viewports, user might
3814  // have closed the viewport , reset ground source variables and re-open.
3815  m_groundOpen = false;
3816  m_groundCube.take();
3817  m_groundFile.clear();
3818  m_groundGmap.reset(NULL);
3819 
3820  m_groundFileNameLabel->setText("Ground Source File: ");
3821  if (!m_demOpen) {
3822  m_radiusFileNameLabel->setText("Radius Source File: " + m_demFile);
3823  }
3824 
3825  // Remove from serial number list
3826  m_serialNumberList->Delete(m_groundSN);
3827 
3828  // If the loaded point is a fixed point, see if there is a temporary measure
3829  // holding the coordinate information for the currentground source. If so,
3830  // delete this measure and re-load point
3831  if (m_editPoint && m_editPoint->GetType() != ControlPoint::Free &&
3832  m_editPoint->HasSerialNumber(m_groundSN)) {
3833  m_editPoint->Delete(m_groundSN);
3834  m_groundSN = "";
3835  loadPoint();
3836  }
3837  else {
3838  m_groundSN = "";
3839  }
3840  }
3841 
3842 
3843 
3844 
3845 
3853  double QnetTool::demRadius(double latitude, double longitude) {
3854 
3855  if (!m_demOpen) return Null;
3856 
3857  UniversalGroundMap *demMap = new UniversalGroundMap(*m_demCube);
3858  if (!demMap->SetUniversalGround(latitude, longitude)) {
3859  delete demMap;
3860  demMap = NULL;
3861  return Null;
3862  }
3863 
3864  // Use bilinear interpolation to read radius from DEM
3865  // Use bilinear interpolation from dem
3866  Interpolator *interp = new Interpolator(Interpolator::BiLinearType);
3867 
3868  // Buffer used to read from the model
3869  Portal *portal = new Portal(interp->Samples(), interp->Lines(),
3870  m_demCube->pixelType(),
3871  interp->HotSample(), interp->HotLine());
3872  portal->SetPosition(demMap->Sample(), demMap->Line(), 1);
3873  m_demCube->read(*portal);
3874  double radius = interp->Interpolate(demMap->Sample(), demMap->Line(),
3875  portal->DoubleBuffer());
3876  delete demMap;
3877  demMap = NULL;
3878  delete interp;
3879  interp = NULL;
3880  delete portal;
3881  portal = NULL;
3882 
3883 // cout.width(15);
3884 // cout.precision(4);
3885 // cout<<"DEM Radius = "<<fixed<<radius<<endl;
3886  return radius;
3887  }
3888 
3889 
3890 
3897 
3898  QColor qc = Qt::red;
3899  QPalette p = m_savePoint->palette();
3900  p.setColor(QPalette::ButtonText,qc);
3901  m_savePoint->setPalette(p);
3902 
3903  }
3904 
3905 
3906 
3919  bool QnetTool::IsMeasureLocked (QString serialNumber) {
3920 
3921  if (m_editPoint == NULL) return false;
3922 
3923  // Reference implicitly editLocked
3924  if (m_editPoint->IsEditLocked() && m_editPoint->IsReferenceExplicit() &&
3925  (m_editPoint->GetReferenceSN() == serialNumber)) {
3926  return true;
3927  }
3928  // Return measures explicit editLocked value
3929  else {
3930  return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
3931  }
3932 
3933  }
3934 
3935 
3936 
3943  FileName config("$HOME/.Isis/qnet/QnetTool.config");
3944  QSettings settings(config.expanded(), QSettings::NativeFormat);
3945  QPoint pos = settings.value("pos", QPoint(300, 100)).toPoint();
3946  QSize size = settings.value("size", QSize(900, 500)).toSize();
3947  m_qnetTool->resize(size);
3948  m_qnetTool->move(pos);
3949  }
3950 
3951 
3959  /*We do not want to write the settings unless the window is
3960  visible at the time of closing the application*/
3961  if(!m_qnetTool->isVisible()) return;
3962  FileName config("$HOME/.Isis/qnet/QnetTool.config");
3963  QSettings settings(config.expanded(), QSettings::NativeFormat);
3964  settings.setValue("pos", m_qnetTool->pos());
3965  settings.setValue("size", m_qnetTool->size());
3966  }
3967 
3968 
3969 
3970  void QnetTool::enterWhatsThisMode() {
3971  QWhatsThis::enterWhatsThisMode();
3972  }
3973 
3974 
3975 }
3976