Isis 3 Programmer Reference
ControlPointEditWidget.cpp
1 #include "IsisDebug.h"
2 
3 #include "ControlPointEditWidget.h"
4 
5 #include <iomanip>
6 #include <sstream>
7 #include <vector>
8 
9 #include <QAction>
10 #include <QCheckBox>
11 #include <QComboBox>
12 #include <QFileDialog>
13 #include <QFileInfo>
14 #include <QFormLayout>
15 #include <QGroupBox>
16 #include <QHBoxLayout>
17 #include <QLabel>
18 #include <QMainWindow>
19 #include <QMessageBox>
20 #include <QObject>
21 #include <QPushButton>
22 #include <QScrollBar>
23 #include <QShortcut>
24 #include <QSplitter>
25 #include <QTableWidget>
26 #include <QTextEdit>
27 #include <QVBoxLayout>
28 
29 #include "Application.h"
30 #include "Camera.h"
31 #include "Control.h"
32 #include "ControlMeasureEditWidget.h"
33 #include "ControlMeasure.h"
34 #include "ControlMeasureLogData.h"
35 #include "ControlNet.h"
36 #include "ControlPoint.h"
37 #include "DeleteControlPointDialog.h"
38 #include "Directory.h"
39 #include "FileName.h"
40 #include "IException.h"
41 #include "Latitude.h"
42 #include "Longitude.h"
43 #include "MainWindow.h"
44 #include "MdiCubeViewport.h"
45 #include "NewControlPointDialog.h"
46 #include "NewGroundSourceLocationDialog.h"
47 #include "Project.h"
48 #include "Pvl.h"
49 #include "PvlEditDialog.h"
50 #include "SerialNumber.h"
51 #include "SerialNumberList.h"
52 #include "Shape.h"
53 #include "ShapeList.h"
54 #include "SpecialPixel.h"
55 #include "Table.h"
56 #include "TemplateList.h"
57 #include "ToolPad.h"
58 #include "UniversalGroundMap.h"
59 #include "ViewportMainWindow.h"
60 #include "Workspace.h"
61 
62 using namespace std;
63 
64 namespace Isis {
72  ControlPointEditWidget::ControlPointEditWidget (Directory *directory, QWidget *parent,
73  bool addMeasures) : QWidget(parent) {
74 
75  m_directory = directory;
76  m_addMeasuresButton = addMeasures;
77  m_cnetModified = false;
78  m_templateModified = false;
79  m_serialNumberList = NULL;
80  m_editPoint = NULL;
81 
84  m_demOpen = false;
85 
86  m_parent = parent;
87 
89 
90  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
91  m_measureEditor, SIGNAL(newControlNetwork(ControlNet *)));
92 
93  connect(m_directory->project(), SIGNAL(templatesAdded(TemplateList *)),
94  this, SLOT(addTemplates(TemplateList *)));
95  }
96 
97 
98  ControlPointEditWidget::~ControlPointEditWidget () {
99 
100  }
101 
102 
103  QString ControlPointEditWidget::editPointId() {
104 
105  QString result = "";
106  if (m_editPoint) {
107  result = m_editPoint->GetId();
108  }
109  return result;
110  }
111 
112 
113  ControlPoint *ControlPointEditWidget::editPoint() {
114 
115  ControlPoint *result = NULL;
116  if (m_editPoint) {
117  result = m_editPoint;
118  }
119  return result;
120  }
121 
122 
148  void ControlPointEditWidget::createPointEditor(QWidget *parent, bool addMeasures) {
149 
150  setWindowTitle("Control Point Editor");
151  setObjectName("ControlPointEditWidget");
152  connect(this, SIGNAL(destroyed(QObject *)), this, SLOT(clearEditPoint()));
153 
154  createActions();
155 
156  // create m_measureEditor first since we need to get its templateFileName
157  // later
158  m_measureEditor = new ControlMeasureEditWidget(parent, true, true);
159 
160  // TODO Does this need to be moved to ControlNetEditMainWindow???
161  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
162  m_measureEditor, SIGNAL(newControlNetwork(ControlNet *)));
163 
164 
165  connect(this, SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
166  m_measureEditor, SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)));
167  connect(m_measureEditor, SIGNAL(measureSaved()), this, SLOT(measureSaved()));
168  connect(this, SIGNAL(cnetModified()), this, SLOT(colorizeSaveNetButton()));
169 
170  QPushButton *addMeasure = NULL;
171  if (m_addMeasuresButton) {
172  addMeasure = new QPushButton("Add Measure(s) to Point");
173  addMeasure->setToolTip("Add a new measure to the edit control point.");
174  addMeasure->setWhatsThis("This allows a new control measure to be added "
175  "to the currently edited control point. A selection "
176  "box with all cubes from the input list will be "
177  "displayed with those that intersect with the "
178  "control point highlighted.");
179  //TODO addMeasure() slot is not implemented ???
180  connect(addMeasure, SIGNAL(clicked()), this, SLOT(addMeasure()));
181  }
182 
183  m_reloadPoint = new QPushButton("Reload Point");
184  m_reloadPoint->setToolTip("Reload the control point.");
185  m_reloadPoint->setWhatsThis("Reload the measures for the control point"
186  " in the Chip Viewports to its saved values. ");
187  connect(m_reloadPoint, SIGNAL(clicked()), this, SLOT(reloadPoint()));
188 
189  m_savePoint = new QPushButton ("Save Point");
190  m_savePoint->setShortcut(Qt::Key_P);
191  m_savePoint->setToolTip("Save the edit control point to the control network. "
192  "<strong>Shortcut: P</strong>");
193  m_savePoint->setWhatsThis("Save the edit control point to the control "
194  "network which is loaded into memory in its entirety. "
195  "When a control point is selected for editing, "
196  "a copy of the point is made so that the original control "
197  "point remains in the network.");
198  m_saveDefaultPalette = m_savePoint->palette();
199  connect (m_savePoint, SIGNAL(clicked()), this, SLOT(savePoint()));
200 
201  m_saveNet = new QPushButton ("Save Control Net");
202  m_saveNet->setShortcut(Qt::Key_S);
203  m_saveNet->setToolTip("Save current control network. "
204  "<strong>Shortcut: S</strong>");
205  m_savePoint->setWhatsThis("Save the control network.");
206 // m_saveDefaultPalette = m_savePoint->palette();
207 // This slot is needed because we cannot directly emit a signal with a ControlNet
208 // argument after the "Save Net" push button is selected since the parameter list must match.
209 // The saveNet slot will simply emit a signal with the ControlNet as the argument.
210  connect (m_saveNet, SIGNAL(clicked()), this, SLOT(saveNet()));
211 
212  QHBoxLayout * saveMeasureLayout = new QHBoxLayout;
213  if (m_addMeasuresButton) {
214  saveMeasureLayout->addWidget(addMeasure);
215  }
216 
217  saveMeasureLayout->addWidget(m_reloadPoint);
218  saveMeasureLayout->addWidget(m_savePoint);
219  saveMeasureLayout->addWidget(m_saveNet);
220  saveMeasureLayout->insertStretch(-1);
221 
222  m_cnetFileNameLabel = new QLabel("Control Network: " + m_cnetFileName);
223 
224  // Create a combobox to allow user to select either the default registration file or one of the
225  // imported registration files.
227  m_templateComboBox->setToolTip("Choose a template file");
228  m_templateComboBox->setWhatsThis("FileName of the sub-pixel "
229  "registration template. Refer to $ISISROOT/doc/documents/"
230  "PatternMatch/PatternMatch.html for a description of the "
231  "contents of this file.");
232  m_templateComboBox->addItem(m_measureEditor->templateFileName());
233  QList <TemplateList *> regTemplates = m_directory->project()->regTemplates();
234  foreach(TemplateList *templateList, regTemplates) {
235  foreach(Template *templateFile, *templateList){
236  m_templateComboBox->addItem(templateFile->importName()
237  + "/" + FileName(templateFile->fileName()).name());
238  }
239  }
240  QFormLayout *templateFileLayout = new QFormLayout();
241  templateFileLayout->addRow("Template File:", m_templateComboBox);
242 
243  // Set-up connections to give registration combobox functionality
244  connect(m_templateComboBox, SIGNAL(activated(QString)),
245  this, SLOT(setTemplateFile(QString)));
246  connect(m_measureEditor, SIGNAL(setTemplateFailed(QString)),
247  this, SLOT(resetTemplateComboBox(QString)));
248 
249  QVBoxLayout * centralLayout = new QVBoxLayout;
250 
251  centralLayout->addWidget(m_cnetFileNameLabel);
252  centralLayout->addLayout(templateFileLayout);
253  centralLayout->addWidget(createTopSplitter());
254  centralLayout->addStretch();
255  centralLayout->addWidget(m_measureEditor);
256  centralLayout->addLayout(saveMeasureLayout);
257 
258  QWidget *centralWidget = new QWidget;
259  centralWidget->setLayout(centralLayout);
260 
261  QScrollArea *scrollArea = new QScrollArea();
262  scrollArea->setObjectName("ControlPointEditWidgetScroll");
263  scrollArea->setWidget(centralWidget);
264  scrollArea->setWidgetResizable(true);
265  centralWidget->adjustSize();
266 
267  QHBoxLayout *mainLayout = new QHBoxLayout;
268  mainLayout->addWidget(scrollArea);
269  setLayout(mainLayout);
270 
271 // connect(this, SIGNAL(controlPointChanged()), this, SLOT(paintAllViewports()));
272 
273 // readSettings();
274  }
275 
276 
283 
284  QHBoxLayout * measureLayout = new QHBoxLayout;
285  measureLayout->addWidget(createLeftMeasureGroupBox());
286  measureLayout->addWidget(createRightMeasureGroupBox());
287 
288  QVBoxLayout * groupBoxesLayout = new QVBoxLayout;
289  groupBoxesLayout->addWidget(createControlPointGroupBox());
290  groupBoxesLayout->addStretch();
291  groupBoxesLayout->addLayout(measureLayout);
292 
293  QWidget * groupBoxesWidget = new QWidget;
294  groupBoxesWidget->setLayout(groupBoxesLayout);
295 
297 
298  QSplitter * topSplitter = new QSplitter;
299  topSplitter->addWidget(groupBoxesWidget);
300  topSplitter->addWidget(m_templateEditorWidget);
301 // topSplitter->setStretchFactor(0, 4);
302 // topSplitter->setStretchFactor(1, 3);
303 
304  m_templateEditorWidget->hide();
305 
306  return topSplitter;
307  }
308 
309 
316 
317  // create left vertical layout
318  m_ptIdValue = new QLabel;
319 
320  m_numMeasures = new QLabel;
321 
322  m_aprioriLatitude = new QLabel;
323  m_aprioriLongitude = new QLabel;
324  m_aprioriRadius = new QLabel;
325 
326  // create right vertical layout's top layout
327  m_lockPoint = new QCheckBox("Edit Lock Point");
328  connect(m_lockPoint, SIGNAL(clicked(bool)), this, SLOT(setLockPoint(bool)));
329  m_ignorePoint = new QCheckBox("Ignore Point");
330  connect(m_ignorePoint, SIGNAL(clicked(bool)),
331  this, SLOT(setIgnorePoint(bool)));
332  connect(this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
333 
335  for (int i=0; i<ControlPoint::PointTypeCount; i++) {
338  }
339  QFormLayout *pointTypeLayout = new QFormLayout;
340  pointTypeLayout->addRow("PointType:", m_pointTypeCombo);
341  connect(m_pointTypeCombo, SIGNAL(activated(int)),
342  this, SLOT(setPointType(int)));
343 
346  connect(m_groundSourceCombo, SIGNAL(currentIndexChanged(int)),
347  this, SLOT(groundSourceFileSelectionChanged(int)));
348  QFormLayout *groundSourceLayout = new QFormLayout;
349  groundSourceLayout->addRow("Ground Source:", m_groundSourceCombo);
350  QFormLayout *radiusSourceLayout = new QFormLayout;
351  radiusSourceLayout->addRow("Radius Source:", m_radiusSourceCombo);
352 
353  QVBoxLayout * mainLayout = new QVBoxLayout;
354  mainLayout->addWidget(m_ptIdValue);
355  mainLayout->addWidget(m_numMeasures);
356  mainLayout->addLayout(groundSourceLayout);
357  mainLayout->addLayout(radiusSourceLayout);
358  mainLayout->addWidget(m_aprioriLatitude);
359  mainLayout->addWidget(m_aprioriLongitude);
360  mainLayout->addWidget(m_aprioriRadius);
361  mainLayout->addWidget(m_lockPoint);
362  mainLayout->addWidget(m_ignorePoint);
363  mainLayout->addLayout(pointTypeLayout);
364 
365  // create the groupbox
366  QGroupBox * groupBox = new QGroupBox("Control Point");
367  groupBox->setLayout(mainLayout);
368 
369  return groupBox;
370  }
371 
372 
379 
380  m_leftCombo = new QComboBox;
381  m_leftCombo->view()->installEventFilter(this);
382  m_leftCombo->setToolTip("Choose left control measure");
383  m_leftCombo->setWhatsThis("Choose left control measure identified by "
384  "cube filename.");
385  connect(m_leftCombo, SIGNAL(activated(int)),
386  this, SLOT(selectLeftMeasure(int)));
387  m_lockLeftMeasure = new QCheckBox("Edit Lock Measure");
388  connect(m_lockLeftMeasure, SIGNAL(clicked(bool)),
389  this, SLOT(setLockLeftMeasure(bool)));
390  m_ignoreLeftMeasure = new QCheckBox("Ignore Measure");
391  connect(m_ignoreLeftMeasure, SIGNAL(clicked(bool)),
392  this, SLOT(setIgnoreLeftMeasure(bool)));
393  connect(this, SIGNAL(ignoreLeftChanged()),
394  m_ignoreLeftMeasure, SLOT(toggle()));
395  m_leftReference = new QLabel();
396  m_leftMeasureType = new QLabel();
397  QVBoxLayout * leftLayout = new QVBoxLayout;
398  leftLayout->addWidget(m_leftCombo);
399  leftLayout->addWidget(m_lockLeftMeasure);
400  leftLayout->addWidget(m_ignoreLeftMeasure);
401  leftLayout->addWidget(m_leftReference);
402  leftLayout->addWidget(m_leftMeasureType);
403 
404  QGroupBox * leftGroupBox = new QGroupBox("Left Measure");
405  leftGroupBox->setLayout(leftLayout);
406 
407  return leftGroupBox;
408  }
409 
410 
421 
422  // create widgets for the right groupbox
423  m_rightCombo = new QComboBox;
424  m_model = new QStandardItemModel();
425  m_rightCombo->setModel(m_model);
426  m_rightCombo->view()->installEventFilter(this);
427  m_rightCombo->setToolTip("Choose right control measure. "
428  "<strong>Shortcuts: PageUp/PageDown</strong>");
429  m_rightCombo->setWhatsThis("Choose right control measure identified by "
430  "cube filename. "
431  "Note: PageUp selects previous measure; "
432  "PageDown selects next meausure.");
433 
434  m_rightCombo->view()->setSelectionMode(QAbstractItemView::SingleSelection);
435  m_rightCombo->view()->setDragEnabled(true);
436  m_rightCombo->view()->setAcceptDrops(true);
437  m_rightCombo->view()->setDropIndicatorShown(true);
438  m_rightCombo->view()->setDragDropMode(QAbstractItemView::InternalMove);
439 
440  // Attach shortcuts to this widget for selecting right measures
441  // Note: Qt handles this memory for us since ControlPointEditWidget is the parent of these shortcuts
442  QShortcut *nextMeasure = new QShortcut(Qt::Key_PageDown, this);
443  connect(nextMeasure, SIGNAL(activated()), this, SLOT(nextRightMeasure()));
444  QShortcut *prevMeasure = new QShortcut(Qt::Key_PageUp, this);
445  connect(prevMeasure, SIGNAL(activated()), this, SLOT(previousRightMeasure()));
446 
447  connect(m_rightCombo, SIGNAL(activated(int)),
448  this, SLOT(selectRightMeasure(int)));
449  m_lockRightMeasure = new QCheckBox("Edit Lock Measure");
450  connect(m_lockRightMeasure, SIGNAL(clicked(bool)),
451  this, SLOT(setLockRightMeasure(bool)));
452  m_ignoreRightMeasure = new QCheckBox("Ignore Measure");
453  connect(m_ignoreRightMeasure, SIGNAL(clicked(bool)),
454  this, SLOT(setIgnoreRightMeasure(bool)));
455  connect(this, SIGNAL(ignoreRightChanged()),
456  m_ignoreRightMeasure, SLOT(toggle()));
457  m_rightReference = new QLabel();
458  m_rightMeasureType = new QLabel();
459 
460  // create right groupbox
461  QVBoxLayout * rightLayout = new QVBoxLayout;
462  rightLayout->addWidget(m_rightCombo);
463  rightLayout->addWidget(m_lockRightMeasure);
464  rightLayout->addWidget(m_ignoreRightMeasure);
465  rightLayout->addWidget(m_rightReference);
466  rightLayout->addWidget(m_rightMeasureType);
467 
468  QGroupBox * rightGroupBox = new QGroupBox("Right Measure");
469  rightGroupBox->setLayout(rightLayout);
470 
471  return rightGroupBox;
472  }
473 
474 
479 
480  QToolBar *toolBar = new QToolBar("Template Editor ToolBar");
481 
482  toolBar->addAction(m_openTemplateFile);
483  toolBar->addSeparator();
484  toolBar->addAction(m_saveTemplateFile);
485  toolBar->addAction(m_saveTemplateFileAs);
486 
487  m_templateEditor = new QTextEdit;
488  connect(m_templateEditor, SIGNAL(textChanged()), this,
489  SLOT(setTemplateModified()));
490 
491  QVBoxLayout *mainLayout = new QVBoxLayout;
492  mainLayout->addWidget(toolBar);
493  mainLayout->addWidget(m_templateEditor);
494 
496  m_templateEditorWidget->setLayout(mainLayout);
497  }
498 
499 
504 
505  m_closePointEditor = new QAction(QIcon(FileName("base/icons/fileclose.png").expanded()),
506  "&Close", this);
507  m_closePointEditor->setToolTip("Close this window");
508  m_closePointEditor->setStatusTip("Close this window");
509  m_closePointEditor->setShortcut(Qt::ALT + Qt::Key_F4);
510  QString whatsThis = "<b>Function:</b> Closes the Match Tool window for this point "
511  "<p><b>Shortcut:</b> Alt+F4 </p>";
512  m_closePointEditor->setWhatsThis(whatsThis);
513  connect(m_closePointEditor, SIGNAL(triggered()), this, SLOT(close()));
514 
515  m_showHideTemplateEditor = new QAction(QIcon(FileName("base/icons/view_text.png").expanded()),
516  "&View/edit registration template", this);
517  m_showHideTemplateEditor->setCheckable(true);
518  m_showHideTemplateEditor->setToolTip("View and/or edit the registration template");
519  m_showHideTemplateEditor->setStatusTip("View and/or edit the registration template");
520  whatsThis = "<b>Function:</b> Displays the curent registration template. "
521  "The user may edit and save changes under a chosen filename.";
522  m_showHideTemplateEditor->setWhatsThis(whatsThis);
523  connect(m_showHideTemplateEditor, SIGNAL(triggered()), this,
524  SLOT(showHideTemplateEditor()));
525 
526  m_saveChips = new QAction(QIcon(FileName("base/icons/window_new.png").expanded()),
527  "Save registration chips", this);
528  m_saveChips->setToolTip("Save registration chips");
529  m_saveChips->setStatusTip("Save registration chips");
530  whatsThis = "<b>Function:</b> Save registration chips to file. "
531  "Each chip: pattern, search, fit will be saved to a separate file.";
532  m_saveChips->setWhatsThis(whatsThis);
533  connect(m_saveChips, SIGNAL(triggered()), this, SLOT(saveChips()));
534 
535  m_openTemplateFile = new QAction(QIcon(FileName("base/icons/fileopen.png").expanded()),
536  "&Open registration template", this);
537  m_openTemplateFile->setToolTip("Set registration template");
538  m_openTemplateFile->setStatusTip("Set registration template");
539  whatsThis = "<b>Function:</b> Allows user to select a new file to set as "
540  "the registration template";
541  m_openTemplateFile->setWhatsThis(whatsThis);
542  connect(m_openTemplateFile, SIGNAL(triggered()), this, SLOT(openTemplateFile()));
543 
544  m_saveTemplateFile = new QAction(QIcon(FileName("base/icons/mActionFileSave.png").expanded()),
545  "&Save template file", this);
546  m_saveTemplateFile->setToolTip("Save the template file");
547  m_saveTemplateFile->setStatusTip("Save the template file");
548  m_saveTemplateFile->setWhatsThis("Save the registration template file");
549  connect(m_saveTemplateFile, SIGNAL(triggered()), this,
550  SLOT(saveTemplateFile()));
551 
552  m_saveTemplateFileAs = new QAction(QIcon(FileName("base/icons/mActionFileSaveAs.png").expanded()),
553  "&Save template as...", this);
554  m_saveTemplateFileAs->setToolTip("Save the template file as");
555  m_saveTemplateFileAs->setStatusTip("Save the template file as");
556  m_saveTemplateFileAs->setWhatsThis("Save the registration template file as");
557  connect(m_saveTemplateFileAs, SIGNAL(triggered()), this,
558  SLOT(saveTemplateFileAs()));
559  }
560 
561 
576  void ControlPointEditWidget::setShapesForPoint(double latitude, double longitude) {
577 
578  if (latitude == Null || longitude == Null) {
579  // Use current editPoint to get latitude, longitude.
580  // Use apriori surface point to find location on ground source. If
581  // apriori surface point does not exist use reference measure
582  if (m_editPoint->HasAprioriCoordinates()) {
583  SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
584  latitude = sPt.GetLatitude().degrees();
585  longitude = sPt.GetLongitude().degrees();
586  }
587  else {
588  ControlMeasure m = *(m_editPoint->GetRefMeasure());
590  Camera *cam;
591  cam = m_controlNet->Camera(camIndex);
592  cam->SetImage(m.GetSample(),m.GetLine());
593  latitude = cam->UniversalLatitude();
594  longitude = cam->UniversalLongitude();
595  }
596  }
597 
599  m_projectShapeNames.clear();
600  m_nameToShapeMap.clear();
601 
602  // Get all shapes from project, putting shapes that contain the current m_editPoint at the
603  // top of the list.
604  QStringList shapeNamesNoPoint;
605  // Create map between the Shape file name & Shape
606  QList<ShapeList *> shapeLists = m_directory->project()->shapes();
607  foreach (ShapeList *shapeList, shapeLists) {
608  foreach (Shape *shape, *shapeList) {
609  UniversalGroundMap *gmap = new UniversalGroundMap(*(shape->cube()));
610  if (gmap->SetUniversalGround(latitude, longitude)) {
611  m_projectShapeNames<<shape->fileName();
612  }
613  else {
614  shapeNamesNoPoint<<shape->fileName();
615  }
616  m_nameToShapeMap[shape->fileName()] = shape;
617  delete gmap;
618  }
619  }
621  // Add shapes that do not contain point
622  if (shapeNamesNoPoint.count() > 0) {
623  m_projectShapeNames<<shapeNamesNoPoint;
624  }
625  }
626 
627 
635  m_measureEditor->setLeftMeasure(m_leftMeasure, m_leftCube.data(), m_editPoint->GetId());
636  m_measureEditor->setRightMeasure(m_rightMeasure, m_rightCube.data(), m_editPoint->GetId());
637  }
638 
639 
646 
647  // TODO If network & snList already exists do some error checking
648  // Make copy; we add ground source files to the list, and we don't want to cause problems for
649  // other ipce entities that are using
650 // if (m_serialNumberList) {
651 // delete m_serialNumberList;
652 // m_serialNumberList = NULL;
653 // }
654 // m_serialNumberList = new SerialNumberList(snList);
655  m_serialNumberList = snList;
656  }
657 
658 
667  // TODO more error checking
668  m_control = control;
669  m_controlNet = control->controlNet();
670  m_cnetFileName = control->fileName();
671 
672  QStringList cnetDirs = m_cnetFileName.split('/');
673  QString strippedCnetFilename = cnetDirs.value(cnetDirs.length() -1);
674  m_cnetFileNameLabel->setText("Control Network: " + strippedCnetFilename);
675  m_cnetFileNameLabel->setToolTip(m_cnetFileName);
676  m_cnetFileNameLabel->setWhatsThis(m_cnetFileName);
677  setWindowTitle("Control Point Editor- Control Network File: " + m_cnetFileName);
678 
679  emit newControlNetwork(m_controlNet);
680  }
681 
682 
690 
691  if (m_directory->project()->activeControl()) {
692  m_control = m_directory->project()->activeControl();
693  m_controlNet = m_control->controlNet();
694  m_cnetFileName = m_control->fileName();
695 
696  m_cnetFileNameLabel->setText("Control Network: " + m_cnetFileName);
697  setWindowTitle("Control Point Editor- Control Network File: " + m_cnetFileName);
698 
699  emit newControlNetwork(m_controlNet);
700  }
701  }
702 
703 
716 
717  ControlMeasure *groundMeasure = createTemporaryGroundMeasure();
718  if (groundMeasure) {
719  m_editPoint->Add(groundMeasure);
720 
721  // Add to measure combo boxes
722  QString groundFile = m_serialNumberList->fileName(groundMeasure->GetCubeSerialNumber());
723  QString tempFileName = FileName(groundFile).name();
724 
725  m_pointFiles<<groundFile;
726  m_leftCombo->addItem(tempFileName);
727  m_rightCombo->addItem(tempFileName);
728  int rightIndex = m_rightCombo->findText(tempFileName);
729  m_rightCombo->setCurrentIndex(rightIndex);
730  selectRightMeasure(rightIndex);
732  }
733  }
734 
735 
749 
750  ControlMeasure *groundMeasure = NULL;
751 
752  // Try to set ground source file information. If unsuccessful, return null ground measure
753  if (!setGroundSourceInfo()) {
754  return groundMeasure;
755  }
756 
757  // Use apriori surface point to find location on ground source. If
758  // apriori surface point does not exist use reference measure
759  double lat = 0.;
760  double lon = 0.;
761  if (m_editPoint->HasAprioriCoordinates()) {
762  SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
763  lat = sPt.GetLatitude().degrees();
764  lon = sPt.GetLongitude().degrees();
765  }
766  else {
767  ControlMeasure m = *(m_editPoint->GetRefMeasure());
769  Camera *cam;
770  cam = m_controlNet->Camera(camIndex);
771  cam->SetImage(m.GetSample(),m.GetLine());
772  lat = cam->UniversalLatitude();
773  lon = cam->UniversalLongitude();
774  }
775 
776  // Try to locate point position on current ground source,
777  if (!m_groundGmap->SetUniversalGround(lat,lon)) {
778  QString message = "This point does not exist on the ground source.\n";
779  message += "Latitude = " + QString::number(lat);
780  message += " Longitude = " + QString::number(lon);
781  message += "\n A ground measure will not be created.";
782  QMessageBox::warning(this, "Warning", message);
783  }
784  else {
785  groundMeasure = new ControlMeasure;
786  groundMeasure->SetCubeSerialNumber(m_groundSN);
787  groundMeasure->SetType(ControlMeasure::Candidate);
788  groundMeasure->SetCoordinate(m_groundGmap->Sample(), m_groundGmap->Line());
789  groundMeasure->SetChooserName("GroundMeasureTemporary");
790  }
791 
792  return groundMeasure;
793  }
794 
795 
806 
807  FileName groundFile;
808  ControlPoint::SurfacePointSource::Source groundSourceType =
809  ControlPoint::SurfacePointSource::None;
810 
811  bool success = false;
812 
813  // No ground source chosen, clear out any old info
814  if (m_groundSourceCombo->currentText().contains("NONE")) {
815  success = false;
816  }
817  else {
818  // Chosen ground source is an imported shape in project
819  if (m_groundSourceCombo->currentText().contains(".ecub")) {
820  Shape *shape = m_nameToShapeMap[m_groundSourceCombo->currentText()];
821  groundFile = FileName(shape->fileName());
822  //groundSourceType = shape->surfacePointSource();
823  success = true;
824  }
825  // Not imported shape, must be from m_editPoints AprioriXYZSource in the cnet
826  else if (m_editPoint->HasAprioriSurfacePointSourceFile()) {
827  groundFile = FileName(m_groundSourceCombo->currentText());
828  // Apriori ground source does not exist and user chose not to give new location so simply
829  // return unsuccessful
830  if (!groundFile.fileExists()) {
831  success = false;
832  }
833  else {
834  groundSourceType = m_editPoint->GetAprioriSurfacePointSource();
835  success = true;
836  }
837  }
838  }
839 
840  // If a new ground file was found set ground source information for later use, first clearing
841  // out the old ground source information. If new ground same as old ground, we will not change
842  // anything, simply return successful.
843  if (success && (groundFile.expanded() != m_groundFilename)) {
845  m_groundFilename = groundFile.expanded();
846 
847  // Get cube, then universal groundmap
848  QScopedPointer<Cube> groundCube(new Cube(groundFile, "r"));
849  m_groundGmap.reset(NULL);
850  QScopedPointer<UniversalGroundMap> newGroundGmap(new UniversalGroundMap(*groundCube));
851  m_groundGmap.reset(newGroundGmap.take());
852 
853  // Create new serial number for ground source and add to serial number list
854  m_groundSN = SerialNumber::Compose(groundFile.expanded(), true);
856 
857  m_groundSourceType = groundSourceType;
858  }
859  // Could not successfully find a ground source file, clear out any old info and return
860  // unsuccessful
861  else if (!success) {
863  }
864 
865  return success;
866  }
867 
868 
880 
881  FileName newGroundFile;
882 
883  if (!groundFile.fileExists()) {
884 
885  // If user previously chose to change all ground source locations, but didn't update the net
886  // fix this ground source to new location
887  // If all groundLocations are to be changed...
889  QFileInfo oldFile(groundFile.expanded());
890  QFileInfo newFile(m_newGroundDir, oldFile.fileName());
891 
892  newGroundFile = FileName(newFile.absoluteFilePath());
893  }
894 
895  // If can't find ground, re-prompt user for new location. Maybe it's a new ground source.
896  if (!newGroundFile.fileExists()) {
897  // Give options for finding ground source file location. A new location
898  // for new location or new source, either a Shape in the project, or import a new shape,
899  // or simplay choose file?
900  QString message = "Ground Source file " + groundFile.expanded();
901  message += " doesn't exist. Has the file moved? Would you like to enter a new location for"
902  " this ground source?";
903  int ret = QMessageBox::question(this, "Ground Source not found", message);
904  if (ret == QMessageBox::Yes) {
905  QString dir = m_directory->project()->shapeDataRoot();
907  "New Ground Source Location", dir);
908  if (dialog->exec() == QDialog::Accepted) {
909  m_newGroundDir = dialog->selectedFiles().value(0);
912  // Change all ground source locations to reflect new directory
915  }
916  // Change location of apriori for current edit point so combo boxes updated properly
917  QFileInfo oldFile(groundFile.expanded());
918  QFileInfo newFile(m_newGroundDir, oldFile.fileName());
919  newGroundFile = newFile.absoluteFilePath();
920  m_editPoint->SetAprioriSurfacePointSourceFile(newGroundFile.toString());
921  }
922  else {
923  // Either user does not want to change location of ground source or the new location
924  // Dialog was cancelled. Load point without the ground source.
925  newGroundFile = NULL;
926  }
927  }
928  else {
929  // Either user does not want to change location of ground source or the new location
930  // Dialog was cancelled. Load point without the ground source.
931  newGroundFile = NULL;
932  }
933  }
934  }
935  return newGroundFile;
936  }
937 
938 
945 
946  for (int i = 0; i < m_controlNet->GetNumPoints(); i++ ) {
947  ControlPoint *cp = m_controlNet->GetPoint(i);
949  FileName groundFile(cp->GetAprioriSurfacePointSourceFile());
950  QFileInfo oldFile(groundFile.expanded());
951  QFileInfo newFile(m_newGroundDir, oldFile.fileName());
952  groundFile = newFile.absoluteFilePath();
953  cp->SetAprioriSurfacePointSourceFile(groundFile.expanded());
954  }
955  }
956  emit cnetModified();
957  }
958 
959 
967 
968  //Get the reference image's shape model
969  QString referenceSN = m_editPoint->GetReferenceSN();
970  QString referenceFileName = m_serialNumberList->fileName(referenceSN);
971  QScopedPointer<Cube> referenceCube(new Cube(referenceFileName, "r"));
972  PvlGroup kernels = referenceCube->group("Kernels");
973  QString shapeFile = kernels["ShapeModel"];
974 
975  // If the reference measure has a shape model cube then set that as the radius
976  // This will NOT WORK for shape model files (not the default of Null or Ellipsoid)
977  // that are not cubes
978  if (shapeFile.contains(".cub")) {
979  if (shapeFile.contains("dem")) {
980  m_radiusSourceType = ControlPoint::RadiusSource::DEM;
981  }
982  else {
983  m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
984  }
985 
986  m_radiusFilename = shapeFile;
987  initDem(shapeFile);
988  }
989  // If no shape model then use the ABC of the target body
990  else {
991  m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
992  Spice *refSpice = new Spice(*referenceCube);
993  Distance refRadii[3];
994  refSpice->radii(refRadii);
995  m_demFile = QString::number(refRadii[0].meters()) + ", " +
996  QString::number(refRadii[1].meters()) + ", " +
997  QString::number(refRadii[2].meters());
998 
999  m_radiusFilename = "";
1000  }
1001  }
1002 
1003 
1011  void ControlPointEditWidget::initDem (QString demFile) {
1012 
1013  // If a DEM is already opened, check if new is same as old. If new,
1014  // close old, open new.
1015  if (m_demOpen) {
1016  if (m_demFile == demFile) {
1017  return;
1018  }
1019 
1020  m_demCube.reset(NULL);
1021  m_demFile.clear();
1022  }
1023 
1024  QApplication::setOverrideCursor(Qt::WaitCursor);
1025  try {
1026  QScopedPointer<Cube> newDemCube(new Cube(demFile, "r"));
1027 
1028  m_demFile = FileName(newDemCube->fileName()).name();
1029  m_demCube.reset(newDemCube.take());
1030  }
1031  catch (IException &e) {
1032  QMessageBox::critical(this, "Error", e.toString());
1033  QApplication::restoreOverrideCursor();
1034  return;
1035  }
1036  m_demOpen = true;
1037 
1038  // Make sure this is a dem
1039  if (!m_demCube->hasTable("ShapeModelStatistics")) {
1040  QString message = m_demFile + " is not a DEM.";
1041  QMessageBox::critical(this, "Error", message);
1042  m_demCube.reset(NULL);
1043  m_demOpen = false;
1044  m_demFile.clear();
1045  QApplication::restoreOverrideCursor();
1046  return;
1047  }
1048  m_radiusSourceType = ControlPoint::RadiusSource::DEM;
1049  m_radiusFilename = demFile;
1050 
1051  QApplication::restoreOverrideCursor();
1052  }
1053 
1054 
1062  double ControlPointEditWidget::demRadius(double latitude, double longitude) {
1063 
1064  if (!m_demOpen) return Null;
1065 
1066  UniversalGroundMap *demMap = new UniversalGroundMap(*m_demCube);
1067  if (!demMap->SetUniversalGround(latitude, longitude)) {
1068  delete demMap;
1069  demMap = NULL;
1070  return Null;
1071  }
1072 
1073  // Use bilinear interpolation to read radius from DEM
1074  // Use bilinear interpolation from dem
1075  Interpolator *interp = new Interpolator(Interpolator::BiLinearType);
1076 
1077  // Buffer used to read from the model
1078  Portal *portal = new Portal(interp->Samples(), interp->Lines(),
1079  m_demCube->pixelType(),
1080  interp->HotSample(), interp->HotLine());
1081  portal->SetPosition(demMap->Sample(), demMap->Line(), 1);
1082  m_demCube->read(*portal);
1083  double radius = interp->Interpolate(demMap->Sample(), demMap->Line(),
1084  portal->DoubleBuffer());
1085  delete demMap;
1086  demMap = NULL;
1087  delete interp;
1088  interp = NULL;
1089  delete portal;
1090  portal = NULL;
1091 
1092  return radius;
1093  }
1094 
1095 
1103 
1104  QString newChosenGroundFile = m_groundSourceCombo->currentText();
1105  if (newChosenGroundFile == m_groundFilename) {
1106  return;
1107  }
1109  }
1110 
1111 
1117 
1118  if (m_groundSN.isEmpty()) {
1119  return;
1120  }
1121 
1122  // If the loaded point is a fixed point, see if there is a temporary measure
1123  // holding the coordinate information for the current ground source. If so,
1124  // delete this measure and remove from the Chip viewport and measure selection combo.
1125  if (m_editPoint && m_editPoint->GetType() != ControlPoint::Free &&
1126  m_editPoint->HasSerialNumber(m_groundSN)) {
1127  m_editPoint->Delete(m_groundSN);
1128 
1129  if (m_leftCombo->findText(QFileInfo(m_groundFilename).fileName()) >= 0) {
1130  m_leftCombo->removeItem(m_leftCombo->findText(QFileInfo(m_groundFilename).fileName()));
1131  if (m_leftMeasure->GetCubeSerialNumber() == m_groundSN) {
1132  selectLeftMeasure(0);
1133  }
1134  }
1135  if (m_rightCombo->findText(QFileInfo(m_groundFilename).fileName())) {
1136  m_rightCombo->removeItem(m_rightCombo->findText(QFileInfo(m_groundFilename).fileName()));
1137  if (m_rightMeasure->GetCubeSerialNumber() == m_groundSN) {
1138  selectRightMeasure(0);
1139  }
1140  }
1141  m_pointFiles.removeAll(m_groundFilename);
1142  }
1143  // Remove from serial number list
1145 
1146  // Reset ground source variables
1147  m_groundFilename.clear();
1148  m_groundSN.clear();
1149  m_groundGmap.reset(NULL);
1150  m_groundSourceType = ControlPoint::SurfacePointSource::None;
1151  }
1152 
1153 
1161  void ControlPointEditWidget::setEditPoint(ControlPoint *controlPoint, QString serialNumber) {
1162 
1163  // If m_editPoint was never saved to control net (parent=NULL), delete
1164  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1165  delete m_editPoint;
1166  m_editPoint = NULL;
1167  }
1168 
1169  // If incoming control point is new point (has not been saved to control net, simply assign
1170  // to m_editPoint, otherwise create copy. It will not be saved to net until "Save Point"
1171  // is selected
1172  if (controlPoint->Parent() == NULL) {
1173  m_editPoint = controlPoint;
1174 
1175  // New point in editor, so colorize all save buttons
1176  colorizeAllSaveButtons("red");
1177  }
1178  else {
1179  m_editPoint = new ControlPoint;
1180  *m_editPoint = *controlPoint;
1181 
1182  // New point loaded, make sure all save button's text is default black color
1183  colorizeAllSaveButtons("black");
1184  }
1185  loadPoint(serialNumber);
1186  loadTemplateFile(m_measureEditor->templateFileName());
1187  }
1188 
1189 
1190  void ControlPointEditWidget::colorizeAllSaveButtons(QString color) {
1191 
1192  if (color == "black") {
1193  // Don't need to colorize save measure button, when loading new measure, the measure editor
1194  // will set back to default palette.
1195  m_savePoint->setPalette(m_saveDefaultPalette);
1196  m_saveNet->setPalette(m_saveDefaultPalette);
1197  }
1198  else if (color == "red") {
1199  m_measureEditor->colorizeSaveButton();
1202  }
1203  }
1204 
1205 
1226  void ControlPointEditWidget::loadPoint(QString serialNumber) {
1227 
1228  // Write pointId
1229  QString CPId = m_editPoint->GetId();
1230 
1231  QString ptId("Point ID: ");
1232  ptId += (QString) CPId;
1233  m_ptIdValue->setText(ptId);
1234 
1235  // Set shapes for this point. Shapes are what has been imported into project.
1237 
1238  // Write number of measures
1239  QString ptsize = "Number of Measures: " +
1240  QString::number(m_editPoint->GetNumMeasures());
1241  m_numMeasures->setText(ptsize);
1242 
1243  // Set EditLock box correctly
1244  m_lockPoint->setChecked(m_editPoint->IsEditLocked());
1245 
1246  // Set ignore box correctly
1247  m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1248 
1249 
1250  // Refill combos since they are dependent on the current edit point
1251  // Turn off signals until filled since we don't want slot called.
1252  m_groundSourceCombo->blockSignals(true);
1253  m_radiusSourceCombo->blockSignals(true);
1254  m_groundSourceCombo->clear();
1255  m_radiusSourceCombo->clear();
1256  m_groundSourceCombo->addItem("NONE");
1257  m_groundSourceCombo->setCurrentText("NONE");
1258  m_radiusSourceCombo->addItem("NONE - Use reference measure's radius");
1259  m_radiusSourceCombo->setCurrentText("NONE - Use reference measure's radius");
1260 
1261  // Load any imported project shapes that contain m_editPoint into the ground and any Dem's into
1262  // radius source combo boxes. Only add Dems to radius combo.
1263  if (m_projectShapeNames.count() > 0) {
1264  for (int i=0; i<m_numberProjectShapesWithPoint; i++) {
1265  Shape *shape = m_nameToShapeMap[m_projectShapeNames.at(i)];
1266  if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1267  m_radiusSourceCombo->addItem(shape->fileName());
1268  }
1269  else {
1270  m_groundSourceCombo->addItem(shape->fileName());
1271  }
1272  }
1273  }
1274 
1275  // If available, add the CP AprioriSurfacePointSourceFile and AprioriRadiusSourceFile
1276  if (m_editPoint->HasAprioriSurfacePointSourceFile()) {
1277  FileName aprioriSurfacePointFile = FileName(m_editPoint->GetAprioriSurfacePointSourceFile());
1278  // If file doesn't exist, prompt user for changing location before adding to combo
1279  if (!aprioriSurfacePointFile.fileExists()) {
1280  aprioriSurfacePointFile = checkGroundFileLocation(aprioriSurfacePointFile);
1281  }
1282  if (!aprioriSurfacePointFile.toString().isEmpty()) {
1283  m_groundSourceCombo->addItem(aprioriSurfacePointFile.toString());
1284  m_groundSourceCombo->setCurrentText(aprioriSurfacePointFile.toString());
1285  m_groundSourceCombo->setItemData(m_groundSourceCombo->currentIndex(),
1286  QColor(Qt::darkGreen), Qt::ForegroundRole);
1287  m_groundSourceCombo->setItemData(m_groundSourceCombo->currentIndex(),
1288  QFont("DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1289  }
1290  }
1291 
1292  if (m_editPoint->HasAprioriRadiusSourceFile()) {
1293  //TODO check location of radius file
1294  m_radiusSourceCombo->addItem(m_editPoint->GetAprioriRadiusSourceFile());
1295  m_radiusSourceCombo->setCurrentText(m_editPoint->GetAprioriRadiusSourceFile());
1296  m_radiusSourceCombo->setItemData(m_radiusSourceCombo->currentIndex(),
1297  QColor(Qt::green), Qt::ForegroundRole);
1298  m_radiusSourceCombo->setItemData(m_groundSourceCombo->currentIndex(),
1299  QFont("DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1300  }
1301  if (m_editPoint->GetType() == ControlPoint::Free) {
1302  m_groundSourceCombo->setEnabled(false);
1303  m_radiusSourceCombo->setEnabled(false);
1304  }
1305  else {
1306  m_groundSourceCombo->setEnabled(true);
1307  m_radiusSourceCombo->setEnabled(true);
1308  }
1309  m_groundSourceCombo->blockSignals(false);
1310  m_radiusSourceCombo->blockSignals(false);
1311 
1312 
1313  // If constrained or fixed point, create a measure for
1314  // the ground source, load reference on left, ground source on right
1315  if (m_editPoint->GetType() != ControlPoint::Free) {
1316  // If m_editPoint already has a ground measure, delete
1317  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1318  ControlMeasure &m = *(*m_editPoint)[i];
1319  if (m.GetChooserName() == "GroundMeasureTemporary") {
1320  m_editPoint->Delete(&m);
1321  }
1322  }
1323  // Create a temporary measure to hold the ground point info for ground source
1324  // This measure will be deleted when the ControlPoint is saved to the
1325  // ControlNet.
1326  ControlMeasure *groundMeasure = createTemporaryGroundMeasure();
1327  if (groundMeasure) {
1328  m_editPoint->Add(groundMeasure);
1329  }
1330  }
1331 
1332 
1333 
1334  // Reset PointType combo box appropriately.
1335  m_pointTypeCombo->clear();
1336  for (int i=0; i<ControlPoint::PointTypeCount; i++) {
1339  }
1340  m_pointTypeCombo->setCurrentText(ControlPoint::PointTypeToString(m_editPoint->GetType()));
1341  m_pointTypeCombo->setToolTip("Change ControlPoint type");
1342 
1344 
1345 
1346 
1347  // Clear combo boxes
1348  m_leftCombo->clear();
1349  m_rightCombo->clear();
1350  m_pointFiles.clear();
1351 
1352 
1353  // Need all files for this point
1354  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1355  ControlMeasure &m = *(*m_editPoint)[i];
1356  QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
1357  m_pointFiles<<file;
1358  QString tempFileName = FileName(file).name();
1359 
1360  // This actually fills the right combo box for selecting measures. A model was used to enable
1361  // drag & drop for ordering measures which will also set the blink order.
1362  QStandardItem *item = new QStandardItem(tempFileName);
1363  item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
1364  m_model->appendRow(item);
1365 
1366  m_leftCombo->addItem(tempFileName);
1367 
1368  if (m_editPoint->IsReferenceExplicit() &&
1369  (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
1370  m_leftCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1371  m_rightCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1372  }
1373  }
1374 
1376 
1377  int leftIndex = -1;
1378  int rightIndex = -1;
1379 
1380  QString referenceSerialNumber;
1381  // Check for reference
1382  if (m_editPoint->IsReferenceExplicit()) {
1383  referenceSerialNumber = m_editPoint->GetReferenceSN();
1384  leftIndex = m_editPoint->IndexOfRefMeasure();
1385  }
1386 
1387  if (!serialNumber.isEmpty() && serialNumber != referenceSerialNumber) {
1388  QString file = m_serialNumberList->fileName(serialNumber);
1389  rightIndex = m_rightCombo->findText(FileName(file).name());
1390  if (leftIndex == -1) {
1391  if (rightIndex == 0) {
1392  leftIndex = 1;
1393  }
1394  else {
1395  leftIndex = 0;
1396  }
1397  }
1398  }
1399 
1400  if (leftIndex == -1) {
1401  if (rightIndex == 0) {
1402  leftIndex = 1;
1403  }
1404  else {
1405  leftIndex = 0;
1406  }
1407  }
1408 
1409  // If ground measure exists, load in right viewport
1410  if (m_editPoint->HasSerialNumber(m_groundSN)) {
1411  rightIndex = m_rightCombo->findText(m_groundSN);
1412  }
1413  if (rightIndex <= 0) {
1414  if (leftIndex == 0) {
1415  rightIndex = 1;
1416  }
1417  else {
1418  rightIndex = 0;
1419  }
1420  }
1421  // Handle pts with a single measure, for now simply put measure on left/right
1422  // Evenutally put on left with black on right??
1423  if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
1424 
1425  m_rightCombo->setCurrentIndex(rightIndex);
1426  m_leftCombo->setCurrentIndex(leftIndex);
1427 
1428  // Initialize pointEditor with measures
1429  selectLeftMeasure(leftIndex);
1430  selectRightMeasure(rightIndex);
1431 
1432  this->setVisible(true);
1433  this->raise();
1434  }
1435 
1436 
1447  void ControlPointEditWidget::createControlPoint(double latitude, double longitude, Cube *cube,
1448  bool isGroundSource) {
1449 
1450  // TODO: CHECK SUBPIXEL REGISTER RADIO BUTTON OPTION (CHECKBOX?)
1451 
1452  // Create list box of all files highlighting those that
1453  // contain the point.
1454  QStringList pointFiles;
1455 
1456  Camera *cam;
1457  for (int i = 0; i < m_serialNumberList->size(); i++) {
1458  if (m_serialNumberList->serialNumber(i) == m_groundSN) continue;
1459  cam = m_controlNet->Camera(i);
1460  if (cam->SetUniversalGround(latitude, longitude)) {
1461  // Make sure point is within image boundary
1462  double samp = cam->Sample();
1463  double line = cam->Line();
1464  if (samp >= 1 && samp <= cam->Samples() &&
1465  line >= 1 && line <= cam->Lines()) {
1466  pointFiles<<m_serialNumberList->fileName(i);
1467  }
1468  }
1469  }
1470 
1471  // Set shapes from project to fill dialog, indicating number of shapes that contain the CP.
1472  // The shapes which contain the CP will be at the front of the QStringList.
1473  setShapesForPoint(latitude, longitude);
1474 
1476  m_serialNumberList, m_lastUsedPointId, this, true, true, true);
1477  newPointDialog->setFiles(pointFiles);
1478  newPointDialog->setGroundSource(m_projectShapeNames, m_numberProjectShapesWithPoint);
1479 
1480  // Load imported project shapes that are Dems and contain point location into the radius combo.
1481  if (m_projectShapeNames.count() > 0) {
1482  QStringList radiusSourceFiles;
1483  for (int i=0; i<m_numberProjectShapesWithPoint; i++) {
1484  Shape *shape = m_nameToShapeMap[m_projectShapeNames.at(i)];
1485  if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1486  radiusSourceFiles<<shape->fileName();
1487  }
1488  }
1489  newPointDialog->setRadiusSource(radiusSourceFiles);
1490  }
1491 
1492 
1493 
1494  if (newPointDialog->exec() == QDialog::Accepted) {
1495  m_lastUsedPointId = newPointDialog->pointId();
1496  ControlPoint *newPoint =
1498 
1499  // If this ControlPointId already exists, message box pops up and user is
1500  // asked to enter a new value.
1501  if (m_controlNet->ContainsPoint(newPoint->GetId())) {
1502  QString message = "A ControlPoint with Point Id = [" + newPoint->GetId();
1503  message += "] already exists. Re-enter Point Id for this ControlPoint.";
1504  QMessageBox::warning(this, "New Point Id", message);
1505  pointFiles.clear();
1506  delete newPoint;
1507  newPoint = NULL;
1508  createControlPoint(latitude, longitude);
1509  return;
1510  }
1511 
1513 
1514  QStringList selectedFiles = newPointDialog->selectedFiles();
1515  foreach (QString selectedFile, selectedFiles) {
1516  // Create measure for any file selected
1517  ControlMeasure *m = new ControlMeasure;
1518  // Find serial number for this file
1519  QString sn = m_serialNumberList->serialNumber(selectedFile);
1520  m->SetCubeSerialNumber(sn);
1521  int camIndex = m_serialNumberList->fileNameIndex(selectedFile);
1522  cam = m_controlNet->Camera(camIndex);
1523  cam->SetUniversalGround(latitude, longitude);
1524  m->SetCoordinate(cam->Sample(),cam->Line());
1525  m->SetAprioriSample(cam->Sample());
1526  m->SetAprioriLine(cam->Line());
1529  m->SetCamera(cam);
1530  newPoint->Add(m);
1531  }
1532 
1533  // Get point type from dialog
1534  bool isGroundPoint = (newPointDialog->pointType() != ControlPoint::Free);
1535  newPoint->SetType((ControlPoint::PointType) newPointDialog->pointType());
1536 
1537  if (isGroundPoint) {
1538  Shape *shape = m_nameToShapeMap[newPointDialog->groundSource()];
1539  // Save ground source information in control point
1540  if (shape) {
1541  newPoint->SetAprioriSurfacePointSource(shape->surfacePointSource());
1542  }
1543  else {
1544  newPoint->SetAprioriSurfacePointSource(ControlPoint::SurfacePointSource::None);
1545  }
1547  }
1548 
1549  setEditPoint(newPoint);
1550  emit controlPointAdded(newPoint->GetId());
1551  }
1552  }
1553 
1554 
1561 
1562  // Make a copy and make sure editPoint is a copy (which means it does not
1563  // have a parent network.
1564  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1565  delete m_editPoint;
1566  m_editPoint = NULL;
1567  }
1568  m_editPoint = new ControlPoint;
1569  *m_editPoint = *controlPoint;
1570  loadPoint();
1571 
1572  DeleteControlPointDialog *deletePointDialog = new DeleteControlPointDialog;
1573  QString CPId = m_editPoint->GetId();
1574  deletePointDialog->pointIdValue->setText(CPId);
1575 
1576  // Need all files for this point
1577  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1578  ControlMeasure &m = *(*m_editPoint)[i];
1579  QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
1580  deletePointDialog->fileList->addItem(file);
1581  }
1582 
1583  if (deletePointDialog->exec()) {
1584 
1585  int numDeleted = deletePointDialog->fileList->selectedItems().count();
1586 
1587  // Delete entire control point, either through deleteAllCheckBox or all measures selected
1588  if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1589  numDeleted == m_editPoint->GetNumMeasures()) {
1590 
1591  // If all measures being deleted, let user know and give them the option to quit operation
1592  if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1593  QString message = "You have selected all measures in this point to be deleted. This "
1594  "control point will be deleted. Do you want to delete this control point?";
1595  int response = QMessageBox::question(this,
1596  "Delete control point", message,
1597  QMessageBox::Yes | QMessageBox::No,
1598  QMessageBox::Yes);
1599  // If No, do nothing
1600  if (response == QMessageBox::No) {
1601  return;
1602  }
1603  }
1604 
1605  //this->setVisible(false);
1606  // remove this point from the control network
1607  if (m_controlNet->DeletePoint(m_editPoint->GetId()) ==
1609  QMessageBox::information(this, "EditLocked Point",
1610  "This point is EditLocked and cannot be deleted.");
1611  return;
1612  }
1613  if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1614 // delete m_editPoint;
1615 // m_editPoint = NULL;
1616  }
1617  }
1618 
1619  // Delete specific measures from control point
1620  else {
1621  // Keep track of editLocked measures for reporting
1622  int lockedMeasures = 0;
1623  for (int i=0; i<deletePointDialog->fileList->count(); i++) {
1624  QListWidgetItem *item = deletePointDialog->fileList->item(i);
1625  if (!deletePointDialog->fileList->isItemSelected(item)) continue;
1626 
1627  // Do not delete reference without asking user
1628  if (m_editPoint->IsReferenceExplicit() &&
1629  (m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
1630  (*m_editPoint)[i]->GetCubeSerialNumber())) {
1631  QString message = "You are trying to delete the Reference measure."
1632  " Do you really want to delete the Reference measure?";
1633  switch (QMessageBox::question(this,
1634  "Delete Reference measure?", message,
1635  "&Yes", "&No", 0, 0)) {
1636  // Yes: skip to end of switch todelete the measure
1637  case 0:
1638  break;
1639  // No: continue to next measure in the loop
1640  case 1:
1641  // if only a single measure and it's reference and user chooses not to delete,
1642  // simply return. The point has not changed.
1643  if (numDeleted == 1) {
1644  return;
1645  }
1646  continue;
1647  }
1648  }
1649 
1650  if (m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
1651  lockedMeasures++;
1652  }
1653  }
1654 
1655  if (lockedMeasures > 0) {
1656  QMessageBox::information(this,"EditLocked Measures",
1657  QString::number(lockedMeasures) + " / "
1658  + QString::number(
1659  deletePointDialog->fileList->selectedItems().size()) +
1660  " measures are EditLocked and were not deleted.");
1661  }
1662 
1663  loadPoint();
1664 
1665 // loadTemplateFile(m_pointEditor->templateFileName());
1666  }
1667 
1668  // emit a signal to alert user to save when exiting
1669  m_control->setModified(true);
1670  emit cnetModified();
1671 
1672  if (m_editPoint != NULL) {
1673  // Change Save Point button text to red
1675  }
1676  }
1677  }
1678 
1679 
1743 
1744  // Read original measures from the network for comparison with measures
1745  // that have been edited
1746  ControlMeasure *origLeftMeasure =
1747  m_editPoint->GetMeasure(m_leftMeasure->GetCubeSerialNumber());
1748  ControlMeasure *origRightMeasure =
1749  m_editPoint->GetMeasure(m_rightMeasure->GetCubeSerialNumber());
1750  // Neither measure has changed, return
1751  if (*origLeftMeasure == *m_leftMeasure && *origRightMeasure == *m_rightMeasure) {
1752  return;
1753  }
1754 
1755  if (m_editPoint->IsIgnored()) {
1756  QString message = "You are saving changes to a measure on an ignored ";
1757  message += "point. Do you want to set Ignore = False on the point and ";
1758  message += "both measures?";
1759  switch (QMessageBox::question(this, "Save Measure", message, "&Yes", "&No", 0, 0)) {
1760  // Yes: set Ignore=false for the point and measures and save point
1761  case 0:
1762  m_editPoint->SetIgnored(false);
1763  emit ignorePointChanged();
1764  if (m_leftMeasure->IsIgnored()) {
1765  m_leftMeasure->SetIgnored(false);
1766  emit ignoreLeftChanged();
1767  }
1768  if (m_rightMeasure->IsIgnored()) {
1769  m_rightMeasure->SetIgnored(false);
1770  emit ignoreRightChanged();
1771  }
1772  // No: keep Ignore=true and save measure
1773  case 1:
1774  break;
1775  }
1776  }
1777 
1778  bool savedAMeasure = false;
1779  // Error check both measures for edit lock, ignore status and reference
1780  bool leftChangeOk = validateMeasureChange(m_leftMeasure);
1781  if (leftChangeOk) {
1782  m_leftMeasure->SetChooserName(Application::UserName());
1783  *origLeftMeasure = *m_leftMeasure;
1784  savedAMeasure = true;
1785  }
1786  bool rightChangeOk = validateMeasureChange(m_rightMeasure);
1787  if (rightChangeOk) {
1788  m_rightMeasure->SetChooserName(Application::UserName());
1789  *origRightMeasure = *m_rightMeasure;
1790  savedAMeasure = true;
1791  }
1792 
1793  // If this is a fixed or constrained point, and either the left or right measure is the ground
1794  // source, update the lat,lon,radius.
1795  //
1796  if (m_editPoint->GetType() != ControlPoint::Free &&
1797  (m_leftMeasure->GetCubeSerialNumber() == m_groundSN ||
1798  m_rightMeasure->GetCubeSerialNumber() == m_groundSN)) {
1799  // If point is locked and it is not a new point, print error
1800  if (m_editPoint->IsEditLocked() && m_controlNet->ContainsPoint(m_editPoint->GetId())) {
1801  QString message = "This control point is edit locked. The Apriori latitude, longitude and ";
1802  message += "radius cannot be updated. You must first unlock the point by clicking the ";
1803  message += "check box above labeled \"Edit Lock Point\".";
1804  QMessageBox::warning(this, "Point Locked", message);
1805  return;
1806  }
1807  if (m_leftMeasure->IsIgnored()) {
1808  QString message = "This is a Constrained or Fixed point and the reference measure is ";
1809  message += "Ignored. Unset the Ignore flag on the reference measure before saving.";
1810  QMessageBox::warning(this, "Point Locked", message);
1811  return;
1812  }
1813  updateGroundPosition();
1814  }
1815 
1816  // If left measure == right measure, update left
1817  if (m_leftMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
1819  // Update left measure of measureEditor
1820  m_measureEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
1821  m_editPoint->GetId());
1822  }
1823 
1824  // Change Save Point button text to red
1825  if (savedAMeasure) {
1827  }
1828 
1829  // Update measure info
1832  }
1833 
1834 
1843 
1844  // Read original measures from the network for comparison with measures
1845  // that have been edited
1846  ControlMeasure *origMeasure =
1847  m_editPoint->GetMeasure(m->GetCubeSerialNumber());
1848 
1849  // If measure hasn't changed, return false, to keep original
1850  if (*m == *origMeasure) return false;
1851 
1852  // Is measure on Left or Right? This is needed to print correct information
1853  // to users in identifying the measure and for updating information widgets.
1854  QString side = "right";
1855  if (m->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1856  side = "left";
1857  }
1858 
1859  // Only print error if both original measure in network and the current
1860  // edit measure are both editLocked and measure has changed. If only the edit measure is
1861  // locked, then user just locked and it needs to be saved.
1862  // Do not use this classes IsMeasureLocked since we actually want to
1863  // check the original againsted the edit measure and we don't care
1864  // if this is a reference measure. The check for moving a reference is
1865  // done below.
1866  if (origMeasure->IsEditLocked() && m->IsEditLocked()) {
1867  QString message = "The " + side + " measure is editLocked ";
1868  message += "for editing. Do you want to set EditLock = False for this ";
1869  message += "measure?";
1870  int response = QMessageBox::question(this, "Save Measure",
1871  message, QMessageBox::Yes | QMessageBox::No);
1872  // Yes: set EditLock=false for the right measure
1873  if (response == QMessageBox::Yes) {
1874  m->SetEditLock(false);
1875  if (side == "left") {
1876  m_lockLeftMeasure->setChecked(false);
1877  }
1878  else {
1879  m_lockRightMeasure->setChecked(false);
1880  }
1881  }
1882  // No: keep EditLock=true and do NOT save measure
1883  else {
1884  return false;
1885  }
1886  }
1887 
1888  if (origMeasure->IsIgnored() && m->IsIgnored()) {
1889  QString message = "The " + side + "measure is ignored. ";
1890  message += "Do you want to set Ignore = False on the measure?";
1891  switch (QMessageBox::question(this, "Save Measure", message, "&Yes", "&No", 0, 0)) {
1892  // Yes: set Ignore=false for the right measure and save point
1893  case 0:
1894  m->SetIgnored(false);
1895  if (side == "left") {
1896  emit ignoreLeftChanged();
1897  }
1898  else {
1899  emit ignoreRightChanged();
1900  }
1901  // No: keep Ignore=true and save point
1902  case 1:
1903  break;;
1904  }
1905  }
1906 
1907  // If measure is explicit reference and it has moved,warn user
1908  ControlMeasure *refMeasure = m_editPoint->GetRefMeasure();
1909  if (m_editPoint->IsReferenceExplicit()) {
1910  if (refMeasure->GetCubeSerialNumber() == m->GetCubeSerialNumber()) {
1911  if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
1912  QString message = "You are making a change to the reference measure. You ";
1913  message += "may need to move all of the other measures to match the new ";
1914  message += " coordinate of the reference measure. Do you really want to ";
1915  message += " change the reference measure's location? ";
1916  switch(QMessageBox::question(this, "Save Measure",
1917  message, "&Yes", "&No", 0, 0)){
1918  // Yes: Save measure
1919  case 0:
1920  break;
1921  // No: keep original reference, return without saving
1922  case 1:
1923  ControlMeasure *origLeftMeasure =
1924  m_editPoint->GetMeasure(m_leftMeasure->GetCubeSerialNumber());
1925  m_measureEditor->setLeftPosition(origLeftMeasure->GetSample(),
1926  origLeftMeasure->GetLine());
1927  return false;
1928  }
1929  }
1930  }
1931  // New reference measure
1932  else if (side == "left" && (refMeasure->GetCubeSerialNumber() != m->GetCubeSerialNumber())) {
1933  QString message = "This point already contains a reference measure. ";
1934  message += "Would you like to replace it with the measure on the left?";
1935  int response = QMessageBox::question(this,
1936  "Save Measure", message,
1937  QMessageBox::Yes | QMessageBox::No,
1938  QMessageBox::Yes);
1939  // Replace reference measure
1940  if (response == QMessageBox::Yes) {
1941  // Update measure file combo boxes: old reference normal font,
1942  // new reference bold font
1943  QString file = m_serialNumberList->fileName(m_leftMeasure->GetCubeSerialNumber());
1944  QString fname = FileName(file).name();
1945  int iref = m_leftCombo->findText(fname);
1946 
1947  // Save normal font from new reference measure
1948  QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
1949  m_leftCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1950  iref = m_rightCombo->findText(fname);
1951  m_rightCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1952 
1953  file = m_serialNumberList->fileName(refMeasure->GetCubeSerialNumber());
1954  fname = FileName(file).name();
1955  iref = m_leftCombo->findText(fname);
1956  m_leftCombo->setItemData(iref,font,Qt::FontRole);
1957  iref = m_rightCombo->findText(fname);
1958  m_rightCombo->setItemData(iref,font,Qt::FontRole);
1959 
1960  m_editPoint->SetRefMeasure(m->GetCubeSerialNumber());
1961  }
1962  }
1963  }
1964  else {
1965  // No explicit reference, If left, set explicit reference
1966  if (side == "left") {
1967  m_editPoint->SetRefMeasure(m->GetCubeSerialNumber());
1968  }
1969  }
1970 
1971  // All test pass, return true (ok to change measure)
1972  return true;
1973 
1974 
1975  }
1976 
1977 
1988 
1989  // Check if ControlPoint has reference measure, if reference Measure is
1990  // not the same measure that is on the left chip viewport, set left
1991  // measure as reference.
1992  ControlMeasure *refMeasure = m_editPoint->GetRefMeasure();
1993  if (refMeasure->GetCubeSerialNumber() != m_leftMeasure->GetCubeSerialNumber()) {
1994  QString message = "This point already contains a reference measure. ";
1995  message += "Would you like to replace it with the measure on the left?";
1996  int response = QMessageBox::question(this,
1997  "Match Tool Save Measure", message,
1998  QMessageBox::Yes | QMessageBox::No,
1999  QMessageBox::Yes);
2000  // Replace reference measure
2001  if (response == QMessageBox::Yes) {
2002  // Update measure file combo boxes: old reference normal font,
2003  // new reference bold font
2004  QString file = m_serialNumberList->fileName(m_leftMeasure->GetCubeSerialNumber());
2005  QString fname = FileName(file).name();
2006  int iref = m_leftCombo->findText(fname);
2007 
2008  // Save normal font from new reference measure
2009  QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
2010  m_leftCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2011  iref = m_rightCombo->findText(fname);
2012  m_rightCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2013 
2014  file = m_serialNumberList->fileName(refMeasure->GetCubeSerialNumber());
2015  fname = FileName(file).name();
2016  iref = m_leftCombo->findText(fname);
2017  m_leftCombo->setItemData(iref,font,Qt::FontRole);
2018  iref = m_rightCombo->findText(fname);
2019  m_rightCombo->setItemData(iref,font,Qt::FontRole);
2020 
2021  m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
2022  }
2023 
2024  // ??? Need to set rest of measures to Candiate and add more warning. ???//
2025  }
2026  }
2027 
2028 
2029  /*
2030  * Update the position of ground point
2031  *
2032  * @author 2012-04-26 Tracie Sucharski - moved functionality from measureSaved
2033  *
2034  * @internal
2035  *
2036  */
2037  void ControlPointEditWidget::updateGroundPosition() {
2038 
2039  // Determine if the left or right measure is the ground. Use ground measure to update
2040  // apriori surface point.
2041  ControlMeasure *groundMeasure;
2042  if (m_leftMeasure->GetCubeSerialNumber() == m_groundSN) {
2043  groundMeasure = m_leftMeasure;
2044  }
2045  else {
2046  groundMeasure = m_rightMeasure;
2047  }
2048  m_groundGmap->SetImage(groundMeasure->GetSample(), groundMeasure->GetLine());
2049 
2050  double lat = m_groundGmap->UniversalLatitude();
2051  double lon = m_groundGmap->UniversalLongitude();
2052 
2053  // Find radius source file
2054  // If nothing has been selected from the Radius source combo, use the Reference measure
2055  if (m_radiusSourceCombo->currentText().contains("NONE")) {
2056  m_radiusFilename.clear();
2057  m_demOpen = false;
2058  m_demFile.clear();
2059  m_demCube.reset(NULL);
2061  }
2062  else {
2063  Shape *shape = m_nameToShapeMap[m_radiusSourceCombo->currentText()];
2064  if (shape) {
2065  m_radiusFilename = shape->cube()->externalCubeFileName().toString();
2066  //m_radiusSourceType = shape->radiusSource();
2067  }
2068  // Radius source comes from what is already saved in the cnet as AprioriRadiusSourceFile
2069  // This will contain the path
2070  else {
2071  m_radiusFilename = m_radiusSourceCombo->currentText();
2072  m_radiusSourceType = m_editPoint->GetAprioriRadiusSource();
2073  }
2074  initDem(m_radiusFilename);
2075  }
2076 
2077 
2078  double radius;
2079  // Update radius, order of precedence
2080  // 1. If a dem has been opened, read radius from dem.
2081  // 2. Get radius from reference measure
2082  // If image has shape model, radius will come from shape model
2083  //
2084  if (m_demOpen) {
2085  radius = demRadius(lat,lon);
2086  if (radius == Null) {
2087  QString msg = "Could not read radius from DEM, will default to "
2088  "local radius of reference measure.";
2089  QMessageBox::warning(this, "Warning", msg);
2090  if (m_editPoint->GetRefMeasure()->Camera()->SetGround(Latitude(lat, Angle::Degrees),
2091  Longitude(lon, Angle::Degrees))) {
2092  radius = m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2093  // TODO Should this be set here, this is probably not working as intended since it is
2094  // overwritten below outside of if (radius == Null)
2095  m_editPoint->SetAprioriRadiusSource(ControlPoint::RadiusSource::None);
2096  }
2097  else {
2098  QString message = "Error trying to get radius at this pt. "
2099  "Lat/Lon does not fall on the reference measure. "
2100  "Cannot save this measure.";
2101  QMessageBox::critical(this,"Error",message);
2102  return;
2103  }
2104  }
2105  m_editPoint->SetAprioriRadiusSource(m_radiusSourceType);
2106  m_editPoint->SetAprioriRadiusSourceFile(m_radiusFilename);
2107  }
2108  else {
2109  // Get radius from reference image
2110  if (m_editPoint->GetRefMeasure()->Camera()->SetGround(Latitude(lat, Angle::Degrees),
2111  Longitude(lon, Angle::Degrees))) {
2112  radius = m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2113  }
2114  else {
2115  QString message = "Error trying to get radius at this pt. "
2116  "Lat/Lon does not fall on the reference measure. "
2117  "Cannot save this measure.";
2118  QMessageBox::critical(this,"Error",message);
2119  return;
2120  }
2121  }
2122 
2123  try {
2124  // Read apriori surface point if it exists so that point is
2125  // replaced, but sigmas are retained. Save sigmas because the
2126  // SurfacePoint class will change them if the coordinates change.
2127  if (m_editPoint->HasAprioriCoordinates()) {
2128  SurfacePoint aprioriPt = m_editPoint->GetAprioriSurfacePoint();
2129  Distance latSigma = aprioriPt.GetLatSigmaDistance();
2130  Distance lonSigma = aprioriPt.GetLonSigmaDistance();
2131  Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
2132  aprioriPt.SetSphericalCoordinates(Latitude(lat, Angle::Degrees),
2133  Longitude(lon, Angle::Degrees),
2134  Distance(radius, Distance::Meters));
2135  aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
2136  m_editPoint->SetAprioriSurfacePoint(aprioriPt);
2137  }
2138  else {
2139  m_editPoint->SetAprioriSurfacePoint(SurfacePoint(
2140  Latitude(lat, Angle::Degrees),
2141  Longitude(lon, Angle::Degrees),
2142  Distance(radius, Distance::Meters)));
2143  }
2144  }
2145  catch (IException &e) {
2146  QString message = "Unable to set Apriori Surface Point.\n";
2147  message += "Latitude = " + QString::number(lat);
2148  message += " Longitude = " + QString::number(lon);
2149  message += " Radius = " + QString::number(radius) + "\n";
2150  message += e.toString();
2151  QMessageBox::critical(this,"Error",message);
2152  return;
2153  }
2154 
2155  m_editPoint->SetAprioriSurfacePointSource(m_groundSourceType);
2156  QString fullGroundFilename;
2157  if (m_groundFilename.contains(".ecub")) {
2158  // Find shape to get external cube filename
2159  fullGroundFilename = m_nameToShapeMap[m_groundFilename]->cube()->externalCubeFileName().expanded();
2160  }
2161  else {
2162  fullGroundFilename = m_groundFilename;
2163  }
2164  m_editPoint->SetAprioriSurfacePointSourceFile(fullGroundFilename);
2165 
2167  }
2168 
2169 
2185 
2186  // Make a copy of edit point for updating the control net since the edit
2187  // point is still loaded in the point editor.
2188  ControlPoint *updatePoint = new ControlPoint;
2189  *updatePoint = *m_editPoint;
2190 
2191  // If this is a fixed or constrained point, see if there is a temporary
2192  // measure holding the coordinate information from the ground source.
2193  // If so, delete this measure before saving point. Clear out the
2194  // fixed Measure variable (memory deleted in ControlPoint::Delete).
2195  if (updatePoint->GetType() != ControlPoint::Free && updatePoint->HasSerialNumber(m_groundSN)) {
2196  // Delete measure with m_groundSN
2197  updatePoint->Delete(m_groundSN);
2198  }
2199 
2200  // If edit point exists in the network, save the updated point. If it
2201  // does not exist, add it.
2202  if (m_controlNet->ContainsPoint(updatePoint->GetId())) {
2203  ControlPoint *p;
2204  p = m_controlNet->GetPoint(QString(updatePoint->GetId()));
2205  *p = *updatePoint;
2206  delete updatePoint;
2207  updatePoint = NULL;
2208  emit controlPointChanged(m_editPoint->GetId());
2209  }
2210  else {
2211  m_controlNet->AddPoint(updatePoint);
2212  emit controlPointAdded(m_editPoint->GetId());
2213  }
2214 
2215  // Change Save Measure button text back to default
2216  m_savePoint->setPalette(m_saveDefaultPalette);
2217 
2218  // At exit, or when opening new net, use for prompting user for a save
2219  m_cnetModified = true;
2220  m_control->setModified(true);
2221  emit cnetModified();
2222  // Refresh chipViewports to show new positions of controlPoints
2223  m_measureEditor->refreshChips();
2224  }
2225 
2226 
2243 
2244  if (m_editPoint == NULL) return;
2245 
2246  // If pointType is equal to current type, nothing to do
2247  if (m_editPoint->GetType() == pointType) return;
2248  int oldType = m_editPoint->GetType();
2249 
2250  // Error check ignored and locked status
2251  if (pointType != ControlPoint::Free && m_leftMeasure->IsIgnored()) {
2252  m_pointTypeCombo->setCurrentIndex((int) m_editPoint->GetType());
2253  QString message = "The reference measure is Ignored. Unset the Ignore flag on the ";
2254  message += "reference measure before setting the point type to Constrained or Fixed.";
2255  QMessageBox::warning(m_parent, "Ignored Reference Measure", message);
2256  return;
2257  }
2258  ControlPoint::Status status = m_editPoint->SetType((ControlPoint::PointType) pointType);
2259  if (status == ControlPoint::PointLocked) {
2260  m_pointTypeCombo->setCurrentIndex((int) m_editPoint->GetType());
2261  QString message = "This control point is edit locked. The point type cannot be changed. You ";
2262  message += "must first unlock the point by clicking the check box above labeled ";
2263  message += "\"Edit Lock Point\".";
2264  QMessageBox::warning(m_parent, "Point Locked", message);
2265  return;
2266  }
2267 
2268  // Changing type between Contrained and Fixed, simply colorize Save CP button and return. Do
2269  // not re-load CP or re-create ground CM.
2270  if (oldType != ControlPoint::Free && m_editPoint->GetType() != ControlPoint::Free) {
2272  }
2273  // If changing from Constrained or Fixed to Free, remove ground CM, disable ground/radius source
2274  // combos, re-load CP, colorize Save CP.
2275  else if (oldType != ControlPoint::Free && m_editPoint->GetType() == ControlPoint::Free) {
2276  // Find temporary measure holding the coordinate information from the ground source and
2277  // delete from CP. This CM has a chooser name = GroundMeasureTemporary.
2278  // Clear out the fixed Measure variable (memory deleted in ControlPoint::Delete).
2279  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
2280  ControlMeasure &m = *(*m_editPoint)[i];
2281  if (m.GetChooserName() == "GroundMeasureTemporary") {
2282  m_editPoint->Delete(&m);
2283  }
2284  }
2285  loadPoint();
2286  m_groundSourceCombo->setEnabled(false);
2287  m_radiusSourceCombo->setEnabled(false);
2289  }
2290  // Changing from Free to Constrained or Fixed, loadGroundMeasure,which will create temporary
2291  // gound measure, load into the measure combo boxes and colorize Save CP button.
2292  else if (oldType == ControlPoint::Free && m_editPoint->GetType() != ControlPoint::Free) {
2294  m_groundSourceCombo->setEnabled(true);
2295  m_radiusSourceCombo->setEnabled(true);
2297  }
2298  }
2299 
2300 
2311 
2312  if (m_editPoint == NULL) return;
2313 
2314  m_editPoint->SetEditLock(lock);
2316  }
2317 
2318 
2330 
2331  if (m_editPoint == NULL) return;
2332 
2333  ControlPoint::Status status = m_editPoint->SetIgnored(ignore);
2334  if (status == ControlPoint::PointLocked) {
2335  m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2336  QString message = "Unable to change Ignored on point. Set EditLock ";
2337  message += " to False.";
2338  QMessageBox::critical(this, "Error", message);
2339  return;
2340  }
2342  }
2343 
2344 
2360 
2361  if (m_editPoint->IsEditLocked()) {
2362  m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
2363  QMessageBox::warning(this, "Point Locked","Point is Edit Locked. You must un-lock point"
2364  " before changing a measure.");
2365  m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
2366  return;
2367  }
2368 
2369  if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
2370 
2371  // If the right chip is the same as the left chip , update the right editLock
2372  // box.
2373  if (m_rightMeasure != NULL) {
2374  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
2375  m_rightMeasure->SetEditLock(lock);
2376  m_lockRightMeasure->setChecked(lock);
2377  }
2378  }
2379  emit measureChanged();
2380  }
2381 
2382 
2400 
2401  if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
2402 
2403  // If the right chip is the same as the left chip , update the right
2404  // ignore box.
2405  if (m_rightMeasure != NULL) {
2406  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
2407  m_rightMeasure->SetIgnored(ignore);
2408  m_ignoreRightMeasure->setChecked(ignore);
2409  }
2410  }
2411  emit measureChanged();
2412  }
2413 
2414 
2430 
2431  if (m_editPoint->IsEditLocked()) {
2432  m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
2433  QMessageBox::warning(this, "Point Locked","Point is Edit Locked. You must un-lock point"
2434  " before changing a measure.");
2435  m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
2436  return;
2437  }
2438 
2439  if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
2440 
2441  // If the left chip is the same as the right chip , update the left editLock box.
2442  if (m_leftMeasure != NULL) {
2443  if (m_leftMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
2444  m_leftMeasure->SetEditLock(lock);
2445  m_lockLeftMeasure->setChecked(lock);
2446  }
2447  }
2448  emit measureChanged();
2449  }
2450 
2451 
2470 
2471  if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
2472 
2473  // If the right chip is the same as the left chip , update the right
2474  // ignore blox.
2475  if (m_leftMeasure != NULL) {
2476  if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
2477  m_leftMeasure->SetIgnored(ignore);
2478  m_ignoreLeftMeasure->setChecked(ignore);
2479  }
2480  }
2481  emit measureChanged();
2482  }
2483 
2484 
2495 
2496  int curIndex = m_rightCombo->currentIndex();
2497  if (curIndex < m_rightCombo->count() - 1) {
2498  // update the right measure list index and select that measure
2499  m_rightCombo->setCurrentIndex(curIndex + 1);
2500  selectRightMeasure(curIndex+1);
2501  }
2502  }
2503 
2504 
2515 
2516  int curIndex = m_rightCombo->currentIndex();
2517  if (curIndex > 0) {
2518  // update the right measure list index and select that measure
2519  m_rightCombo->setCurrentIndex(curIndex - 1);
2520  selectRightMeasure(curIndex-1);
2521  }
2522  }
2523 
2524 
2525 
2539 
2540  QString file = m_pointFiles[index];
2541  QString serial;
2542  try {
2543  serial = m_serialNumberList->serialNumber(file);
2544  }
2545  catch (IException &e) {
2546  QString message = "Make sure the correct cube is opened.\n\n";
2547  message += e.toString();
2548  QMessageBox::critical(this, "Error", message);
2549 
2550  // Set index of combo back to what it was before user selected new. Find the index
2551  // of current left measure.
2552  QString file = m_serialNumberList->fileName(m_leftMeasure->GetCubeSerialNumber());
2553  int i = m_leftCombo->findText(FileName(file).name());
2554  if (i < 0) i = 0;
2555  m_leftCombo->setCurrentIndex(i);
2556  return;
2557  }
2558 
2559  if (m_leftMeasure != NULL) {
2560  delete m_leftMeasure;
2561  m_leftMeasure = NULL;
2562  }
2563 
2565  *m_leftMeasure = *((*m_editPoint)[serial]);
2566 
2567  // If m_leftCube is not null, delete before creating new one
2568  m_leftCube.reset(new Cube(file, "r"));
2569 
2570  // Update left measure of pointEditor
2571  m_measureEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(), m_editPoint->GetId());
2573  }
2574 
2575 
2587 
2588  QString file = m_pointFiles[index];
2589 
2590  QString serial;
2591  try {
2592  serial = m_serialNumberList->serialNumber(file);
2593  }
2594  catch (IException &e) {
2595  QString message = "Make sure the correct cube is opened.\n\n";
2596  message += e.toString();
2597  QMessageBox::critical(this, "Error", message);
2598 
2599  // Set index of combo back to what it was before user selected new. Find the index
2600  // of current left measure.
2601  QString file = m_serialNumberList->fileName(m_rightMeasure->GetCubeSerialNumber());
2602  int i = m_rightCombo->findText(FileName(file).name());
2603  if (i < 0) i = 0;
2604  m_rightCombo->setCurrentIndex(i);
2605  return;
2606  }
2607 
2608  if (m_rightMeasure != NULL) {
2609  delete m_rightMeasure;
2610  m_rightMeasure = NULL;
2611  }
2612 
2614  *m_rightMeasure = *((*m_editPoint)[serial]);
2615 
2616  // If m_rightCube is not null, delete before creating new one
2617  m_rightCube.reset(new Cube(file, "r"));
2618 
2619  // Update left measure of pointEditor
2620  m_measureEditor->setRightMeasure (m_rightMeasure, m_rightCube.data(), m_editPoint->GetId());
2622  }
2623 
2624 
2643 
2644  // Set editLock measure box correctly
2645  m_lockLeftMeasure->setChecked(IsMeasureLocked(
2646  m_leftMeasure->GetCubeSerialNumber()));
2647  // Set ignore measure box correctly
2648  m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2649 
2650  QString s = "Reference: ";
2651  if (m_editPoint->IsReferenceExplicit() &&
2652  (QString(m_leftMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2653  s += "True";
2654  }
2655  else {
2656  s += "False";
2657  }
2658  m_leftReference->setText(s);
2659 
2660  s = "Measure Type: ";
2661  if (m_leftMeasure->GetType() == ControlMeasure::Candidate) s += "Candidate";
2662  if (m_leftMeasure->GetType() == ControlMeasure::Manual) s += "Manual";
2663  if (m_leftMeasure->GetType() == ControlMeasure::RegisteredPixel) s += "RegisteredPixel";
2664  if (m_leftMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s += "RegisteredSubPixel";
2665  m_leftMeasureType->setText(s);
2666  }
2667 
2668 
2689 
2690  // Set editLock measure box correctly
2691  m_lockRightMeasure->setChecked(IsMeasureLocked(
2692  m_rightMeasure->GetCubeSerialNumber()));
2693  // Set ignore measure box correctly
2694  m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2695 
2696  QString s = "Reference: ";
2697  if (m_editPoint->IsReferenceExplicit() &&
2698  (QString(m_rightMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2699  s += "True";
2700  }
2701  else {
2702  s += "False";
2703  }
2704 
2705  m_rightReference->setText(s);
2706 
2707  s = "Measure Type: ";
2708  if (m_rightMeasure->GetType() == ControlMeasure::Candidate) s+= "Candidate";
2709  if (m_rightMeasure->GetType() == ControlMeasure::Manual) s+= "Manual";
2710  if (m_rightMeasure->GetType() == ControlMeasure::RegisteredPixel) s+= "RegisteredPixel";
2711  if (m_rightMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s+= "RegisteredSubPixel";
2712  m_rightMeasureType->setText(s);
2713  }
2714 
2715 
2716 
2728 
2729  if(e->type() != QEvent::Leave) return false;
2730  if(o == m_leftCombo->view()) {
2732  m_leftCombo->hidePopup();
2733  }
2734  if (o == m_rightCombo->view()) {
2736  m_rightCombo->hidePopup();
2737  }
2738  return true;
2739  }
2740 
2741 
2749 
2750  if (m_templateModified) {
2751  int r = QMessageBox::warning(this, tr("OK to continue?"),
2752  tr("The currently opened registration template has been modified.\n"
2753  "Save changes?"),
2754  QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2755  QMessageBox::Yes);
2756 
2757  if (r == QMessageBox::Yes)
2759  else if (r == QMessageBox::Cancel)
2760  return false;
2761  }
2762 
2763  return true;
2764  }
2765 
2766 
2773 
2774  if (!okToContinue())
2775  return;
2776 
2777  QString filename = QFileDialog::getOpenFileName(this,
2778  "Select a registration template", ".",
2779  "Registration template files (*.def *.pvl);;All files (*)");
2780 
2781  if (filename.isEmpty())
2782  return;
2783 
2784  if (m_measureEditor->setTemplateFile(filename)) {
2785  loadTemplateFile(filename);
2786  }
2787  }
2788 
2789 
2796 
2797  QFile file(FileName((QString) fn).expanded());
2798  if (!file.open(QIODevice::ReadOnly)) {
2799  QString msg = "Failed to open template file \"" + fn + "\"";
2800  QMessageBox::warning(this, "IO Error", msg);
2801  return;
2802  }
2803 
2804  QTextStream stream(&file);
2805  m_templateEditor->setText(stream.readAll());
2806  file.close();
2807 
2808  QScrollBar * sb = m_templateEditor->verticalScrollBar();
2809  sb->setValue(sb->minimum());
2810 
2811  m_templateModified = false;
2812  m_saveTemplateFile->setEnabled(false);
2813  }
2814 
2815 
2820 
2821  m_templateModified = true;
2822  m_saveTemplateFile->setEnabled(true);
2823  }
2824 
2825 
2830 
2831  if (!m_templateModified)
2832  return;
2833 
2834  QString filename =
2835  m_measureEditor->templateFileName();
2836 
2837  writeTemplateFile(filename);
2838  }
2839 
2840 
2845 
2846  QString filename = QFileDialog::getSaveFileName(this,
2847  "Save registration template", ".",
2848  "Registration template files (*.def *.pvl);;All files (*)");
2849 
2850  if (filename.isEmpty())
2851  return;
2852 
2853  writeTemplateFile(filename);
2854  }
2855 
2856 
2863 
2864  QString contents = m_templateEditor->toPlainText();
2865 
2866  // catch errors in Pvl format when populating pvl object
2867  stringstream ss;
2868  ss << contents;
2869  try {
2870  Pvl pvl;
2871  ss >> pvl;
2872  }
2873  catch(IException &e) {
2874  QString message = e.toString();
2875  QMessageBox::warning(this, "Error", message);
2876  return;
2877  }
2878 
2879  QString expandedFileName(FileName((QString) fn).expanded());
2880 
2881  QFile file(expandedFileName);
2882 
2883  if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2884  QString msg = "Failed to save template file to \"" + fn + "\"\nDo you "
2885  "have permission?";
2886  QMessageBox::warning(this, "IO Error", msg);
2887  return;
2888  }
2889 
2890  // now save contents
2891  QTextStream stream(&file);
2892  stream << contents;
2893  file.close();
2894 
2895  if (m_measureEditor->setTemplateFile(fn)) {
2896  m_templateModified = false;
2897  m_saveTemplateFile->setEnabled(false);
2898  }
2899  }
2900 
2901 
2915 
2916  try{
2917  // Get the template file from the ControlPointEditWidget object
2918  Pvl templatePvl(m_measureEditor->templateFileName());
2919  // Create registration dialog window using PvlEditDialog class
2920  // to view and/or edit the template
2921  PvlEditDialog registrationDialog(templatePvl);
2922  registrationDialog.setWindowTitle("View or Edit Template File: "
2923  + templatePvl.fileName());
2924  registrationDialog.resize(550,360);
2925  registrationDialog.exec();
2926  }
2927  catch (IException &e) {
2928  QString message = e.toString();
2929  QMessageBox::information(this, "Error", message);
2930  }
2931  }
2932 
2933 
2941 
2942  m_measureEditor->saveChips();
2943  }
2944 
2945 
2950 
2952  return;
2953 
2954  m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
2955  }
2956 
2957 
2964  if(templateList->type() == "registrations") {
2965  for(int i = 0; i < templateList->size(); i++) {
2966  m_templateComboBox->addItem(templateList->at(i)->importName()
2967  + "/" + FileName(templateList->at(i)->fileName()).name());
2968  }
2969  }
2970  }
2971 
2972 
2981  QString expandedFileName = filename;
2982  if(!filename.startsWith("$base")){
2983  expandedFileName = m_directory->project()->templateRoot()
2984  + "/registrations/" + filename;
2985  }
2986  if (m_measureEditor->setTemplateFile(expandedFileName)) {
2987  loadTemplateFile(expandedFileName);
2988  }
2989  }
2990 
2991 
2999  if(fileName.startsWith("$base")) {
3000  m_templateComboBox->setCurrentIndex(0);
3001  }
3002  QList<QString> components = fileName.split("/");
3003  int size = components.size();
3004  int index = m_templateComboBox->findText(components[size - 2] + "/" + components[size - 1]);
3005  if (index != -1) {
3006  m_templateComboBox->setCurrentIndex(index);
3007  }
3008  }
3009 
3010 
3023 
3024  QString s;
3025 
3026  SurfacePoint aprioriPoint = m_editPoint->GetAprioriSurfacePoint();
3027  if (aprioriPoint.GetLatitude().degrees() == Null) {
3028  s = "Apriori Latitude: Null";
3029  }
3030  else {
3031  s = "Apriori Latitude: " +
3032  QString::number(aprioriPoint.GetLatitude().degrees());
3033  }
3034  m_aprioriLatitude->setText(s);
3035  if (aprioriPoint.GetLongitude().degrees() == Null) {
3036  s = "Apriori Longitude: Null";
3037  }
3038  else {
3039  s = "Apriori Longitude: " +
3040  QString::number(aprioriPoint.GetLongitude().degrees());
3041  }
3042  m_aprioriLongitude->setText(s);
3043  if (aprioriPoint.GetLocalRadius().meters() == Null) {
3044  s = "Apriori Radius: Null";
3045  }
3046  else {
3047  s = "Apriori Radius: " +
3048  QString::number(aprioriPoint.GetLocalRadius().meters(),'f',2) +
3049  " <meters>";
3050  }
3051  m_aprioriRadius->setText(s);
3052  }
3053 
3054 
3070 // TODO Is this needed?
3071 //
3072 // void ControlPointEditWidget::refresh() {
3073 //
3074 // // Check point being edited, make sure it still exists, if not ???
3075 // // Update ignored checkbox??
3076 // if (m_editPoint != NULL) {
3077 // try {
3078 // QString id = m_ptIdValue->text().remove("Point ID: ");
3079 // m_controlNet->GetPoint(id);
3080 // }
3081 // catch (IException &) {
3082 // delete m_editPoint;
3083 // m_editPoint = NULL;
3084 // emit controlPointChanged();
3087 // }
3088 // }
3089 // }
3090 
3091 
3098 
3099  QColor qc = Qt::red;
3100  QPalette p = m_savePoint->palette();
3101  p.setColor(QPalette::ButtonText,qc);
3102  m_savePoint->setPalette(p);
3103  }
3104 
3105 
3115 
3116  if (reset) {
3117  // Change Save Net button text back to default black
3118  m_saveNet->setPalette(m_saveDefaultPalette);
3119  }
3120  else {
3121  QColor qc = Qt::red;
3122  QPalette p = m_savePoint->palette();
3123  p.setColor(QPalette::ButtonText,qc);
3124  m_saveNet->setPalette(p);
3125  }
3126 
3127  }
3128 
3129 
3141  bool ControlPointEditWidget::IsMeasureLocked (QString serialNumber) {
3142 
3143  if (m_editPoint == NULL) return false;
3144 
3145  // Reference implicitly editLocked
3146  if (m_editPoint->IsEditLocked() && m_editPoint->IsReferenceExplicit() &&
3147  (m_editPoint->GetReferenceSN() == serialNumber)) {
3148  return true;
3149  }
3150  // Return measures explicit editLocked value
3151  else {
3152  return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
3153  }
3154 
3155  }
3156 
3157 
3166 
3167  m_control->write();
3168 
3169  // Change Save Measure button text back to default
3170  m_saveNet->setPalette(m_saveDefaultPalette);
3171  }
3172 
3173 
3178  delete m_editPoint;
3179  m_editPoint = NULL;
3180  }
3181 
3182 
3183  // 2014-07-21 TLS Ipce This needs to be changed to return the help information or
3184  // widget?? to the calling program, so that it can be added to a menu or toolbar.
3185 #if 0
3186  void ControlPointEditWidget::showHelp() {
3187 
3188  QDialog *helpDialog = new QDialog(this);
3189  helpDialog->setWindowTitle("Match Tool Help");
3190 
3191  QVBoxLayout *mainLayout = new QVBoxLayout;
3192  helpDialog->setLayout(mainLayout);
3193 
3194  QLabel *matchTitle = new QLabel("<h2>Match Tool</h2>");
3195  mainLayout->addWidget(matchTitle);
3196 
3197  QLabel *matchSubtitle = new QLabel("A tool for interactively measuring and editing sample/line "
3198  "registration points between cubes. These "
3199  "points contain sample, line postions only, no latitude or "
3200  "longitude values are used or recorded.");
3201  matchSubtitle->setWordWrap(true);
3202  mainLayout->addWidget(matchSubtitle);
3203 
3204  QTabWidget *tabArea = new QTabWidget;
3205  tabArea->setDocumentMode(true);
3206  mainLayout->addWidget(tabArea);
3207 
3208  // TAB 1 - Overview
3209  QScrollArea *overviewTab = new QScrollArea;
3210  overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3211  overviewTab->setWidgetResizable(true);
3212  QWidget *overviewContainer = new QWidget;
3213  QVBoxLayout *overviewLayout = new QVBoxLayout;
3214  overviewContainer->setLayout(overviewLayout);
3215 
3216  QLabel *purposeTitle = new QLabel("<h2>Purpose</h2>");
3217  overviewLayout->addWidget(purposeTitle);
3218 
3219  QLabel *purposeText = new QLabel("<p>This tool is for recording and editing registration "
3220  "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3221  "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3222  "tool can be used on any images including ones that do not contain a camera model "
3223  "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3224  "This also means that the tool differs from the <i>qnet</i> control point network "
3225  "application in that no latitude or longitude values are ever used or recorded "
3226  "(regardless if the image has a camera model in Isis).</p>"
3227  "<p>The output control point network that this tool generates is primarily used 1) as "
3228  "input for an image-wide sample/line translation to register one image to another by "
3229  "'moving' pixel locations - refer to the documentation for applications such as "
3230  "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3231  "measurements in other spreadsheet or plotting packages to visualize magnitude "
3232  "and direction of varying translations of the images relative to one another.</p> "
3233  "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3234  "can be used to visually evaluate and edit the control point network created by "
3235  "<i>coreg</i>.</p> "
3236  "<p>The format of the output point network file is binary. This tool uses the Isis control "
3237  " network framework to create, co-register and save all control points and pixel "
3238  "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3239  "a readable PVL format."
3240  "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3241  "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3242  "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3243  "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3244  purposeText->setWordWrap(true);
3245  overviewLayout->addWidget(purposeText);
3246 
3247  overviewTab->setWidget(overviewContainer);
3248 
3249  // TAB 2 - Quick Start
3250  QScrollArea *quickTab = new QScrollArea;
3251  quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3252  quickTab->setWidgetResizable(true);
3253  QWidget *quickContainer = new QWidget;
3254  QVBoxLayout *quickLayout = new QVBoxLayout;
3255  quickContainer->setLayout(quickLayout);
3256 
3257  QLabel *quickTitle = new QLabel("<h2>Quick Start</h2>");
3258  quickLayout->addWidget(quickTitle);
3259 
3260  QLabel *quickSubTitle = new QLabel("<h3>Preparation:</h3>");
3261  quickLayout->addWidget(quickSubTitle);
3262 
3263  QString toolIconDir = FileName("$base/icons").expanded();
3264 
3265  QLabel *quickPrep = new QLabel("<p><ul>"
3266  "<li>Open the cubes with overlapping areas for choosing control points</li>"
3267  "<li>Choose the match tool <img src=\"" + toolIconDir +
3268  "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3269  "from the toolpad on the right side of the <i>qview</i> main window</li>");
3270  quickPrep->setWordWrap(true);
3271  quickLayout->addWidget(quickPrep);
3272 
3273  QLabel *morePrep = new QLabel("<p>Once the Match tool is activated the tool bar at the top "
3274  "of the main window contains file action buttons and a help button:");
3275  morePrep->setWordWrap(true);
3276  quickLayout->addWidget(morePrep);
3277 
3278  QLabel *fileButtons = new QLabel("<p><ul>"
3279  "<li><img src=\"" + toolIconDir + "/fileopen.png\" width=22 height=22> Open an existing "
3280  "control network <b>Note:</b> If you do not open an existing network, a new one will "
3281  "be created</li>"
3282  "<li><img src=\"" + toolIconDir + "/mActionFileSaveAs.png\" width=22 height=22> Save "
3283  "control network as ...</li>"
3284  "<li><img src=\"" + toolIconDir + "/mActionFileSave.png\" width=22 height=22> Save "
3285  "control network to current file</li>"
3286  "<li><img src=\"" + toolIconDir + "/help-contents.png\" width=22 height=22> Show Help "
3287  "</li></ul></p>");
3288  fileButtons->setWordWrap(true);
3289  quickLayout->addWidget(fileButtons);
3290 
3291  QLabel *quickFunctionTitle = new QLabel("<h3>Cube Viewport Functions:</h3>");
3292  quickLayout->addWidget(quickFunctionTitle);
3293 
3294  QLabel *quickFunction = new QLabel(
3295  "The match tool window will be shown once "
3296  "you click in a cube viewport window using one of the following "
3297  "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3298  quickFunction->setWordWrap(true);
3299  quickLayout->addWidget(quickFunction);
3300 
3301  QLabel *quickDesc = new QLabel("<p><ul>"
3302  "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3303  "All cubes in the control point must be displayed before loading the point</li>"
3304  "<li>Middle Click - Delete the control point closest to the click</li>"
3305  "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3306  quickDesc->setWordWrap(true);
3307  quickDesc->setOpenExternalLinks(true);
3308  quickLayout->addWidget(quickDesc);
3309 
3310  quickTab->setWidget(quickContainer);
3311 
3312  // TAB 3 - Control Point Editing
3313  QScrollArea *controlPointTab = new QScrollArea;
3314  controlPointTab->setWidgetResizable(true);
3315  controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3316  QWidget *controlPointContainer = new QWidget;
3317  QVBoxLayout *controlPointLayout = new QVBoxLayout;
3318  controlPointContainer->setLayout(controlPointLayout);
3319 
3320  QLabel *controlPointTitle = new QLabel("<h2>Control Point Editing</h2>");
3321  controlPointLayout->addWidget(controlPointTitle);
3322 
3323  QLabel *mouseLabel = new QLabel("<p><h3>When the \"Match\" tool "
3324  "is activated, the mouse buttons have the following function in the "
3325  "cube viewports of the main qview window:</h3>");
3326  mouseLabel->setWordWrap(true);
3327  mouseLabel->setScaledContents(true);
3328  controlPointLayout->addWidget(mouseLabel);
3329 
3330  QLabel *controlPointDesc = new QLabel("<ul>"
3331  "<li>Left click - Edit the closest control point <b>Note:</b> "
3332  "All cubes in the control point must be displayed before loading the point</li>"
3333  "<li>Middle click - Delete the closest control point</li>"
3334  "<li>Right click - Create new control point at cursor location. This will bring up a new "
3335  "point dialog which allows you to enter a point id and will list all cube viewports, "
3336  "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3337  "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3338  "control point into the control point editor window which will allow the control measure "
3339  "positions to be refined.</li>");
3340  controlPointDesc->setWordWrap(true);
3341  controlPointLayout->addWidget(controlPointDesc);
3342 
3343  QLabel *controlPointEditing = new QLabel(
3344  "<h4>Changing Control Measure Locations</h4>"
3345  "<p>Both the left and right control measure positions can be adjusted by:"
3346  "<ul>"
3347  "<li>Move the cursor location under the crosshair by clicking the left mouse "
3348  "button</li>"
3349  "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3350  "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3351  "</ul></p>"
3352  "<h4>Other Point Editor Functions</h4>"
3353  "<p>Along the right border of the window:</p>"
3354  "<ul>"
3355  "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3356  "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3357  "match the left view's zoom factor. "
3358  "<b>Note:</b> Zooming is controlled from the left view.</li>"
3359  "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3360  "its original orientation</li>"
3361  "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3362  "or entering degrees </li>"
3363  "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3364  "point locations visible within the view</li>"
3365  "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3366  "view</li>"
3367  "<li><strong>Circle:</strong> Draw circle which may help center measure "
3368  "on a crater</li></ul"
3369  "<p>Below the left view:</p>"
3370  "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3371  "left view window using the \"Blink Start\" button <img src=\"" + toolIconDir +
3372  "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3373  toolIconDir + "/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3374  "and right views and the keyboard arrow keys may be used to move the both views while "
3375  "blinking.</li>"
3376  "<li><strong>Register:</strong> Sub-pixel register the right view to "
3377  "the left view. A default registration template is used for setting parameters "
3378  "passed to the sub-pixel registration tool. The user may load in a predefined "
3379  "template or edit the current loaded template to influence successful "
3380  "co-registration results. For more information regarding the pattern matching "
3381  "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3382  "document and the <i>autoregtemplate</i> application.</li>"
3383  "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3384  "line positions under the crosshairs.</li>"
3385  "<li><strong>Save Point:</strong> Save the control point to the control network.</li>"
3386  "</ul>");
3387  controlPointEditing->setWordWrap(true);
3388  controlPointLayout->addWidget(controlPointEditing);
3389 
3390  controlPointTab->setWidget(controlPointContainer);
3391 
3392  tabArea->addTab(overviewTab, "&Overview");
3393  tabArea->addTab(quickTab, "&Quick Start");
3394  tabArea->addTab(controlPointTab, "&Control Point Editing");
3395 
3396  QHBoxLayout *buttonsLayout = new QHBoxLayout;
3397  // Flush the buttons to the right
3398  buttonsLayout->addStretch();
3399 
3400  QPushButton *closeButton = new QPushButton("&Close");
3401  closeButton->setIcon(QIcon(FileName("$base/icons/guiStop.png").expanded()));
3402  closeButton->setDefault(true);
3403  connect(closeButton, SIGNAL(clicked()),
3404  helpDialog, SLOT(close()));
3405  buttonsLayout->addWidget(closeButton);
3406 
3407  mainLayout->addLayout(buttonsLayout);
3408 
3409  helpDialog->show();
3410  }
3411 #endif
3412 }
static QString templateRoot(QString projectRoot)
Appends the root directory name &#39;templates&#39; to the project .
Definition: Project.cpp:2125
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:148
This represents an ISIS control net in a project-based GUI interface.
Definition: Control.h:79
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Internalizes a list of shapes and allows for operations on the entire list.
Definition: ShapeList.h:33
Status SetAprioriSurfacePointSource(SurfacePointSource::Source source)
This updates the source of the surface point.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
void createActions()
Creates the actions for the widget.
double HotSample()
Returns the sample coordinate of the center pixel in the buffer for the interpolator.
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
void clearEditPoint()
Cleans up the edit point memory.
void updateLeftMeasureInfo()
Update the left measure information.
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition: Buffer.h:154
bool m_addMeasuresButton
Indicates whether or not to add "Add Measures(s) to Point".
bool changeAllGroundSourceLocation()
Indicates whether all subsequent ground source files should be found in new source directory...
double Line() const
Returns the current line value of the camera model or projection.
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
void setLockRightMeasure(bool ignore)
Set the "EditLock" keyword of the measure shown in the right viewport to the value of the input param...
void writeTemplateFile(QString)
Write the contents of the template editor to the file provided.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
void setTemplateFile(QString)
Appends the filename to the registrations path (unless this is the default template) and calls setTem...
QPointer< QCheckBox > m_ignorePoint
Checkbox to ignore the current point.
QPointer< QLabel > m_leftMeasureType
Label for the left measure&#39;s adjustment type.
QPointer< QComboBox > m_pointTypeCombo
Combobox to change the type of the current point.
double Interpolate(const double isamp, const double iline, const double buf[])
Performs an interpolation on the data according to the parameters set in the constructor.
File name manipulation and expansion.
Definition: FileName.h:116
Universal Ground Map.
QString m_cnetFileName
Filename of the control network that is being modified.
bool validateMeasureChange(ControlMeasure *m)
Validates a change to a control measure.
void checkReference()
Change which measure is the reference.
bool eventFilter(QObject *o, QEvent *e)
Event filter for ControlPointEditWidget.
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:225
void openReferenceRadius()
Open a radius source using the shape model of the reference measure of m_editPoint.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
Buffer for containing a two dimensional section of an image.
Definition: Portal.h:52
FileName checkGroundFileLocation(FileName groundFile)
Ground source file from control net cannot be found, give user option to give new location...
void clearGroundSource()
Clear out the ground source used for Constrained or Fixed control points.
bool setGroundSourceInfo()
Find the ground source location: First look at current edit point for parameter, AprioriXYZSourceFile...
void setIgnorePoint(bool ignore)
Set point&#39;s "Ignore" keyword to the value of the input parameter.
QPointer< QPushButton > m_savePoint
Button to save current point being edited.
void selectLeftMeasure(int index)
Select left measure.
QPointer< QCheckBox > m_ignoreRightMeasure
Checkbox to ignore the right measure.
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name &#39;shapes&#39; to the project .
Definition: Project.cpp:2087
QString fileName() const
Get the file name that this Template represents.
Definition: Template.cpp:50
QString serialNumber(const QString &filename)
Return a serial number given a filename.
QPalette m_saveDefaultPalette
Default color pallet of the "Save Point" button.
QString m_groundSN
Serial number of ground source file.
void updateSurfacePointInfo()
Update the Surface Point Information in the ControlPointEditWidget.
PointType
These are the valid &#39;types&#39; of point.
Definition: ControlPoint.h:379
QPointer< ControlPoint > m_editPoint
The control point being edited.
bool HasAprioriSurfacePointSourceFile() const
Checks to see if the surface point source file has been set.
Namespace for the standard library.
QString m_newGroundDir
Contains the ground source location.
QPointer< ControlMeasure > m_leftMeasure
Left control measure.
void setShapesForPoint(double latitude=Null, double longitude=Null)
Fill m_projectShapeNames with ALL shapes currently in project.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
void viewTemplateFile()
Allows the user to view the template file that is currently set.
QList< TemplateList * > regTemplates()
Return registration template FileNames.
Definition: Project.cpp:2166
void loadTemplateFile(QString)
Updates the current template file being used.
void saveChips()
Slot which calls ControlPointEditWidget slot to save chips.
int fileNameIndex(const QString &filename)
Return a list index given a filename.
ControlMeasure * createTemporaryGroundMeasure()
Create a temporary measure to hold the ground point info for ground source.
Status SetChooserName(QString name)
Set the point&#39;s chooser name.
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
QPointer< QCheckBox > m_lockLeftMeasure
Checkbox to edit lock/unlock the left measure.
Registered to whole pixel (e.g.,pointreg)
void nextRightMeasure()
Selects the next right measure when activated by key shortcut.
Registered to sub-pixel (e.g., pointreg)
QPointer< QComboBox > m_rightCombo
Combobox to load right measure into right chip viewport.
Control * activeControl()
Return the Active Control (control network)
Definition: Project.cpp:1903
void resetTemplateComboBox(QString fileName)
Reset the selected template in the template combobox if the template selected by the user does not sa...
Distance measurement, usually in meters.
Definition: Distance.h:47
QString importName() const
Get the name of the TemplateList this file was imported under.
Definition: Template.cpp:68
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:249
QPointer< QCheckBox > m_ignoreLeftMeasure
Checkbox to ignore the left measure.
void reloadPoint()
Set both chip viewports to their original measures for the control point.
A Free point is a Control Point that identifies common measurements between two or more cubes...
Definition: ControlPoint.h:399
void deletePoint(ControlPoint *controlPoint)
Gives user options for deleting a control point from the control network.
void changeGroundLocationsInNet()
Change the location of all ground source locations in the ControlNet.
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
void createPointEditor(QWidget *parent, bool addMeasures)
Create the widget for editing control points.
void showHideTemplateEditor()
Toggles the visibility of the template editor widget.
QString fileName(const QString &sn)
Return a filename given a serial number.
QPointer< QAction > m_closePointEditor
Action to close the point editor.
bool okToContinue()
Checks the state of the template registration file and determines if it is safe to continue opening a...
bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:396
QPointer< QWidget > m_templateEditorWidget
Template editor widget.
void saveTemplateFileAs()
Save the contents of template editor to a file chosen by the user.
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:170
Status SetAprioriSurfacePointSourceFile(QString sourceFile)
This updates the filename of where the apriori surface point came from.
void createControlPoint(double latitude, double longitude, Cube *cube=0, bool isGroundSource=false)
Create a new control point at the given latitude, longitude.
QPointer< Control > m_control
Current Control.
bool changeControlNet()
Indicates whether the control network should be changed to reflect new ground source location...
QPointer< ControlNet > m_controlNet
Current control net.
double HotLine()
Returns the line coordinate of the center pixel in the buffer for the interpolator.
void groundSourceFileSelectionChanged(int index)
Slot called when user changes selection in m_groundSourceCombo.
void colorizeSaveNetButton(bool reset=false)
Turn "Save Net" button text to red.
void saveTemplateFile()
Save the file opened in the template editor.
void updateRightMeasureInfo()
Update the right measure information.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:73
QPointer< QPushButton > m_reloadPoint
Button to reload current point to saved measures.
a control network
Definition: ControlNet.h:271
Hand Measured (e.g., qnet)
void loadGroundMeasure()
Load ground measure into right side and add to file combo boxes.
QString GetId() const
Return the Id of the control point.
void setLockLeftMeasure(bool ignore)
Set the "EditLock" keyword of the measure shown in the left viewport to the value of the input parame...
Status SetCamera(Isis::Camera *camera)
Set pointer to camera associated with a measure.
int Samples()
Returns the number of samples needed by the interpolator.
QPointer< QAction > m_openTemplateFile
Action to open a registration template file to disk.
bool m_templateModified
Indicates if the registration template was edited.
void previousRightMeasure()
Selects the previous right measure when activated by key shortcut.
Cube * cube()
Get the Cube * associated with this display property.
Definition: Shape.cpp:325
Pixel value mapper.
Definition: Stretch.h:72
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
QMap< QString, Shape * > m_nameToShapeMap
Map between Shape display name and object.
QSplitter * createTopSplitter()
Creates everything above the ControlPointEdit.
QPointer< QTextEdit > m_templateEditor
Text editor for editing the registration template.
double Sample()
Returns the current sample number.
Definition: Camera.cpp:2702
ControlPoint::SurfacePointSource::Source m_groundSourceType
SurfacePoint type of ground source.
QPointer< QAction > m_saveTemplateFileAs
Action to save a new registration template.
bool IsMeasureLocked(QString serialNumber)
Check for implicitly locked measure in m_editPoint.
void selectRightMeasure(int index)
Select right measure.
QStringList m_projectShapeNames
List of Shapes imported into project, at time of loaded CP.
void setControl(Control *control)
New control network being edited.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
bool m_demOpen
Has a radius source been opened?
A single control point.
Definition: ControlPoint.h:369
QGroupBox * createControlPointGroupBox()
Creates the "Control Point" groupbox.
void initDem(QString demFile)
Initialize the given Dem and appropriate member variables for later use editing Fixed or Constrained ...
QPointer< QPushButton > m_saveNet
Button to save the current control network.
void loadPoint(QString serialNumber="")
Load point into ControlPointEditWidget.
void setTemplateModified()
Called when the template file is modified by the template editor.
bool m_changeGroundLocationInNet
Change the ground source location.
QString fileName() const
Get the file name of the cube that this shape represents.
Definition: Shape.cpp:377
void remove(const QString &sn)
Remove the specified serial number from the list.
Container for cube-like labels.
Definition: Pvl.h:135
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Definition: Control.cpp:142
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:248
QString m_lastUsedPointId
Point id of the last used control point.
void setSerialNumberList(SerialNumberList *snList)
Set the serial number list.
QString GetChooserName() const
Return the chooser name.
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Definition: Portal.h:109
bool m_cnetModified
Indicates if the control network has been modified.
int size() const
How many serial number / filename combos are in the list.
Status SetType(PointType newType)
Updates the control point&#39;s type.
QPointer< QLabel > m_cnetFileNameLabel
Label with name of the control network file.
QPointer< QAction > m_saveTemplateFile
Action to save a registration template file to disk.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Status
This is a return status for many of the mutating (setter) method calls.
Definition: ControlPoint.h:408
QScopedPointer< Cube > m_rightCube
Right cube.
QPointer< QComboBox > m_radiusSourceCombo
ComboBox for selecting ground source.
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:531
void savePoint()
Save edit point to the Control Network.
QPointer< QWidget > m_parent
Parent widget.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
int Lines()
Returns the number of lines needed by the interpolator.
Pixel interpolator.
Definition: Interpolator.h:51
This represents a shape in a project-based GUI interface.
Definition: Shape.h:78
double Line()
Returns the current line number.
Definition: Camera.cpp:2722
double demRadius(double latitude, double longitude)
Return a radius values from the dem using bilinear interpolation.
QPointer< QLabel > m_rightMeasureType
Label for the right measure&#39;s adjustment type.
QString type() const
Get the type of template in this TemplateList.
int m_numberProjectShapesWithPoint
Number of shapes containing control point.
static QString UserName()
Returns the user name.
Isis exception class.
Definition: IException.h:107
QPointer< QComboBox > m_templateComboBox
ComboBox of imported registration templates.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
QPointer< QLabel > m_ptIdValue
Label for the point id of the current point.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Project * project() const
Gets the Project for this directory.
Definition: Directory.cpp:1325
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
a control measurement
QGroupBox * createRightMeasureGroupBox()
Create the "Right Measure" groupbox.
void addTemplates(TemplateList *templateList)
Add registration TemplateList to combobox when imported to project.
QStringList m_pointFiles
Associated files for current control point.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
Definition: PvlEditDialog.h:39
void setFiles(QStringList pointFiles)
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
QGroupBox * createLeftMeasureGroupBox()
Creates the "Left Measure" groupbox.
Obtain SPICE information for a spacecraft.
Definition: Spice.h:294
The distance is being specified in meters.
Definition: Distance.h:56
void setIgnoreLeftMeasure(bool ignore)
Set the "Ignore" keyword of the measure shown in the left viewport to the value of the input paramete...
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
void setPointType(int pointType)
Set the point type.
double Sample() const
Returns the current line value of the camera model or projection.
QPointer< QCheckBox > m_lockRightMeasure
Checkbox to edit lock/unlock the right measure.
void setControlFromActive()
New active control was set from ipce.
PointType GetType() const
QPointer< QLabel > m_leftReference
Label indicating if left measure is the reference.
Serial Number list generator.
Distance GetLocalRadius() const
Return the radius of the surface point.
void measureSaved()
This method is connected with the measureSaved() signal from ControlMeasureEditWidget.
void radii(Distance r[3]) const
Returns the radii of the body in km.
Definition: Spice.cpp:855
void createTemplateEditorWidget()
Creates the Widget which contains the template editor and its toolbar.
void setIgnoreRightMeasure(bool ignore)
Set the "Ignore" keyword of the measure shown in the right viewport to the value of the input paramet...
QPointer< QLabel > m_rightReference
Label indicating if right measure is the reference.
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
void setLockPoint(bool ignore)
Set point&#39;s "EditLock" keyword to the value of the input parameter.
void colorizeSavePointButton()
Refresh all necessary widgets in ControlPointEditWidget including the PointEditor and CubeViewports...
QPointer< ControlMeasureEditWidget > m_measureEditor
Pointer to control measure editor widget.
QString fileName() const
Access the name of the control network file associated with this Control.
Definition: Control.cpp:264
void openTemplateFile()
Prompt user for a registration template file to open.
void setEditPoint(ControlPoint *controlPoint, QString serialNumber="")
Slot called by Directory to set the control point for editing.
void saveNet()
This slot is needed because we cannot directly emit a signal with a ControlNet argument after the "Sa...
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465
SerialNumberList * m_serialNumberList
Serial number list for the loaded cubes.
FileName externalCubeFileName() const
If this is an external cube label file, this will give you the cube dn file that this label reference...
Definition: Cube.cpp:1180
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
QString m_groundFilename
File name of ground source.
QPointer< QComboBox > m_groundSourceCombo
ComboBox for selecting ground source.
bool m_changeAllGroundLocation
Change the ground source location of all fixed, constrained points in the network.
Dialog used by ControlPointEditWidget to select a new location for ground source files.
QPointer< ControlMeasure > m_rightMeasure
Right control measure.
QScopedPointer< Cube > m_leftCube
Left cube.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
QPointer< QCheckBox > m_lockPoint
Checkbox that locks/unlocks the current point.
QPointer< QAction > m_saveChips
Action to save the registration chips Action to toggle visibility of the registration template editor...
This is returned when the operation requires Edit Lock to be false but it is currently true...
Definition: ControlPoint.h:423
IO Handler for Isis Cubes.
Definition: Cube.h:170
QPointer< QComboBox > m_leftCombo
Combobox to load left measure into left chip viewport.