Isis 3 Programmer Reference
QnetTool.cpp
1#include "QnetTool.h"
2
3#include <sstream>
4#include <vector>
5#include <iomanip>
6
7#include <QComboBox>
8#include <QFileDialog>
9#include <QMenuBar>
10#include <QMessageBox>
11#include <QScrollBar>
12#include <QShortcut>
13#include <QSplitter>
14#include <QStackedWidget>
15#include <QtWidgets>
16#include <QTableWidget>
17#include <QWhatsThis>
18
19#include "QnetDeletePointDialog.h"
20#include "QnetNewMeasureDialog.h"
21#include "NewControlPointDialog.h"
22#include "QnetFixedPointDialog.h"
23#include "Workspace.h"
24
25#include "Application.h"
26#include "Brick.h"
27#include "Camera.h"
28#include "CameraFactory.h"
29#include "ControlMeasure.h"
30#include "ControlMeasureLogData.h"
31#include "ControlNet.h"
32#include "ControlPoint.h"
33#include "ControlPointEdit.h"
34#include "Distance.h"
35#include "FileName.h"
36#include "IException.h"
37#include "Latitude.h"
38#include "Longitude.h"
39#include "MainWindow.h"
40#include "MdiCubeViewport.h"
41#include "Projection.h"
42#include "ProjectionFactory.h"
43#include "Pvl.h"
44#include "PvlEditDialog.h"
45#include "SerialNumber.h"
46#include "SpecialPixel.h"
47#include "Spice.h"
48#include "SurfacePoint.h"
49#include "Target.h"
50#include "ToolPad.h"
51#include "UniversalGroundMap.h"
52#include "ViewportMainWindow.h"
53
54using namespace std;
55
56namespace Isis {
57
67 QnetTool::QnetTool (QWidget *parent) : Tool(parent) {
68 m_controlNet = NULL;
69 m_demOpen = false;
70 m_groundOpen = false;
71 m_serialNumberList = NULL;
72 m_templateModified = false;
73
74 m_controlNet = new ControlNet;
75 m_serialNumberList = new SerialNumberList;
76
77 if (qobject_cast<Workspace *>(parent)) {
78 m_workspace = qobject_cast<Workspace *>(parent);
79 }
80 else if (qobject_cast<ViewportMainWindow *>(parent)) {
81 m_workspace = qobject_cast<ViewportMainWindow *>(parent)->workspace();
82 }
83 else {
85 tr("Could not find the workspace with the given parent, expected a Workspace or "
86 "ViewportMainWindow."),
87 _FILEINFO_);
88 }
89
90 createQnetTool(parent);
91 }
92
93
94 QnetTool::~QnetTool () {
96
97 delete m_editPoint;
98 delete m_leftMeasure;
99 delete m_rightMeasure;
100 delete m_measureTable;
101 delete m_measureWindow;
102 }
103
104
105
132
133 m_qnetTool = new MainWindow("Qnet Tool", parent);
134 m_qnetTool->setObjectName("QnetTool");
135
137 createMenus();
138 createToolBars();
139
140 // create m_pointEditor first since we need to get its templateFileName
141 // later
142 m_pointEditor = new ControlPointEdit(m_controlNet, parent);
143 connect(this, SIGNAL(newControlNetwork(ControlNet *)),
144 m_pointEditor, SIGNAL(newControlNetwork(ControlNet *)));
145 connect(this,
146 SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
147 m_pointEditor,
148 SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)));
149 connect(m_pointEditor, SIGNAL(measureSaved()), this, SLOT(measureSaved()));
150 connect(this, SIGNAL(measureChanged()),
151 m_pointEditor, SLOT(colorizeSaveButton()));
152
153 QPushButton *addMeasure = new QPushButton("Add Measure(s) to Point");
154 addMeasure->setShortcut(Qt::Key_A);
155 addMeasure->setToolTip("Add a new measure to the edit control point. "
156 "<strong>Shortcut: A</strong>");
157 addMeasure->setWhatsThis("This allows a new control measure to be added "
158 "to the currently edited control point. A selection "
159 "box with all cubes from the input list will be "
160 "displayed with those that intersect with the "
161 "control point highlighted.");
162 connect(addMeasure, SIGNAL(clicked()), this, SLOT(addMeasure()));
163
164 m_savePoint = new QPushButton ("Save Point");
165 m_savePoint->setShortcut(Qt::Key_P);
166 m_savePoint->setToolTip("Save the edit control point to the control network. "
167 "<strong>Shortcut: P</strong>");
168 m_savePoint->setWhatsThis("Save the edit control point to the control "
169 "network which is loaded into memory in its entirety. "
170 "When a control point is selected for editing, "
171 "a copy of the point is made so that the original control "
172 "point remains in the network.");
173 m_saveDefaultPalette = m_savePoint->palette();
174 connect (m_savePoint,SIGNAL(clicked()),this,SLOT(savePoint()));
175
176 QHBoxLayout * addMeasureLayout = new QHBoxLayout;
177 addMeasureLayout->addWidget(addMeasure);
178 addMeasureLayout->addWidget(m_savePoint);
179// addMeasureLayout->addStretch();
180
181 m_templateFileNameLabel = new QLabel("Template File: " +
182 m_pointEditor->templateFileName());
183 m_templateFileNameLabel->setToolTip("Sub-pixel registration template File.");
184// QString patternMatchDoc =
185// FileName("$ISISROOT/doc/documents/PatternMatch/PatternMatch.html").fileName();
186// m_templateFileNameLabel->setOpenExternalLinks(true);
187 m_templateFileNameLabel->setWhatsThis("FileName of the sub-pixel "
188 "registration template. Refer to $ISISROOT/doc/documents/"
189 "PatternMatch/PatternMatch.html for a description of the "
190 "contents of this file.");
191
192 m_groundFileNameLabel = new QLabel("Ground Source File: ");
193 m_groundFileNameLabel->setToolTip("Cube used to create ground control "
194 "points, either Fixed or Constrained.");
195 m_groundFileNameLabel->setWhatsThis("This cube is used to create ground "
196 "control points, Fixed or Constrained. This may "
197 "be a Dem, a shaded relief version of a Dem, "
198 "a projected basemap or an unprojected cube with "
199 "corrected camera pointing. This will be used "
200 "to set the apriori latitude, longitude.");
201 m_radiusFileNameLabel = new QLabel("Radius Source: ");
202 m_radiusFileNameLabel->setToolTip("Dem used to set the radius of ground "
203 "control points, Fixed or Constrained. This must "
204 "be a Dem and is strictly used to set the apriori "
205 "radius for ground control points.");
206
207 QVBoxLayout * centralLayout = new QVBoxLayout;
208
209 centralLayout->addWidget(m_templateFileNameLabel);
210 centralLayout->addWidget(m_groundFileNameLabel);
211 centralLayout->addWidget(m_radiusFileNameLabel);
212 centralLayout->addWidget(createTopSplitter());
213 centralLayout->addStretch();
214 centralLayout->addWidget(m_pointEditor);
215 centralLayout->addLayout(addMeasureLayout);
216 QWidget * centralWidget = new QWidget;
217 centralWidget->setLayout(centralLayout);
218
219 QScrollArea *scrollArea = new QScrollArea();
220 scrollArea->setObjectName("QnetToolScroll");
221 scrollArea->setWidget(centralWidget);
222 scrollArea->setWidgetResizable(true);
223 centralWidget->adjustSize();
224 m_qnetTool->setCentralWidget(scrollArea);
225// m_qnetTool->setCentralWidget(centralWidget);
226
227
228 connect(this, SIGNAL(editPointChanged(QString)),
229 this, SLOT(paintAllViewports(QString)));
230
231 readSettings();
232 }
233
234
237
238 QHBoxLayout * measureLayout = new QHBoxLayout;
239 measureLayout->addWidget(createLeftMeasureGroupBox());
240 measureLayout->addWidget(createRightMeasureGroupBox());
241
242 QVBoxLayout * groupBoxesLayout = new QVBoxLayout;
243 groupBoxesLayout->addWidget(createControlPointGroupBox());
244 groupBoxesLayout->addStretch();
245 groupBoxesLayout->addLayout(measureLayout);
246
247 QWidget * groupBoxesWidget = new QWidget;
248 groupBoxesWidget->setLayout(groupBoxesLayout);
249
251
252 QSplitter * topSplitter = new QSplitter;
253 topSplitter->addWidget(groupBoxesWidget);
254 topSplitter->addWidget(m_templateEditorWidget);
255 topSplitter->setStretchFactor(0, 4);
256 topSplitter->setStretchFactor(1, 3);
257
258 m_templateEditorWidget->hide();
259
260 return topSplitter;
261 }
262
263
266
267 // create left vertical layout
268 m_ptIdValue = new QLabel;
269 m_pointType = new QComboBox;
270 for (int i=0; i<ControlPoint::PointTypeCount; i++) {
271 m_pointType->insertItem(i, ControlPoint::PointTypeToString(
273 }
274 QHBoxLayout *pointTypeLayout = new QHBoxLayout;
275 QLabel *pointTypeLabel = new QLabel("PointType:");
276 pointTypeLayout->addWidget(pointTypeLabel);
277 pointTypeLayout->addWidget(m_pointType);
278 connect(m_pointType, SIGNAL(activated(int)),
279 this, SLOT(setPointType(int)));
280 m_numMeasures = new QLabel;
281 m_pointAprioriLatitude = new QLabel;
282 m_pointAprioriLongitude = new QLabel;
283 m_pointAprioriRadius = new QLabel;
284 m_pointAprioriLatitudeSigma = new QLabel;
285 m_pointAprioriLongitudeSigma = new QLabel;
286 m_pointAprioriRadiusSigma = new QLabel;
287 QVBoxLayout * leftLayout = new QVBoxLayout;
288 leftLayout->addWidget(m_ptIdValue);
289 leftLayout->addLayout(pointTypeLayout);
290 leftLayout->addWidget(m_pointAprioriLatitude);
291 leftLayout->addWidget(m_pointAprioriLongitude);
292 leftLayout->addWidget(m_pointAprioriRadius);
293 leftLayout->addWidget(m_pointAprioriLatitudeSigma);
294 leftLayout->addWidget(m_pointAprioriLongitudeSigma);
295 leftLayout->addWidget(m_pointAprioriRadiusSigma);
296
297 // create right vertical layout's top layout
298 m_lockPoint = new QCheckBox("Edit Lock Point");
299 connect(m_lockPoint, SIGNAL(clicked(bool)), this, SLOT(setLockPoint(bool)));
300 m_ignorePoint = new QCheckBox("Ignore Point");
301 connect(m_ignorePoint, SIGNAL(clicked(bool)),
302 this, SLOT(setIgnorePoint(bool)));
303 connect(this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
304 m_pointLatitude = new QLabel;
305 m_pointLongitude = new QLabel;
306 m_pointRadius = new QLabel;
307
308 QVBoxLayout * rightLayout = new QVBoxLayout;
309 rightLayout->addWidget(m_numMeasures);
310 rightLayout->addWidget(m_lockPoint);
311 rightLayout->addWidget(m_ignorePoint);
312 rightLayout->addWidget(m_pointLatitude);
313 rightLayout->addWidget(m_pointLongitude);
314 rightLayout->addWidget(m_pointRadius);
315
316
317 QHBoxLayout * mainLayout = new QHBoxLayout;
318 mainLayout->addLayout(leftLayout);
319 mainLayout->addStretch();
320 mainLayout->addLayout(rightLayout);
321
322 // create the groupbox
323 QGroupBox * groupBox = new QGroupBox("Control Point");
324 groupBox->setLayout(mainLayout);
325
326 return groupBox;
327 }
328
329
332
333 m_leftCombo = new QComboBox;
334 m_leftCombo->setEditable(true);
335 m_leftCombo->setInsertPolicy(QComboBox::NoInsert);
336 m_leftCombo->setToolTip("Choose left control measure");
337 m_leftCombo->setWhatsThis("Choose left control measure identified by "
338 "cube filename.");
339 connect(m_leftCombo, SIGNAL(activated(int)),
340 this, SLOT(selectLeftMeasure(int)));
341 m_lockLeftMeasure = new QCheckBox("Edit Lock Measure");
342 connect(m_lockLeftMeasure, SIGNAL(clicked(bool)),
343 this, SLOT(setLockLeftMeasure(bool)));
344 m_ignoreLeftMeasure = new QCheckBox("Ignore Measure");
345 connect(m_ignoreLeftMeasure, SIGNAL(clicked(bool)),
346 this, SLOT(setIgnoreLeftMeasure(bool)));
347 connect(this, SIGNAL(ignoreLeftChanged()),
348 m_ignoreLeftMeasure, SLOT(toggle()));
349 m_leftReference = new QLabel();
350 m_leftMeasureType = new QLabel();
351 m_leftSampError = new QLabel();
352 m_leftSampError->setToolTip("<strong>Jigsaw</strong> sample residual.");
353 m_leftSampError->setWhatsThis("This is the sample residual for the left "
354 "measure calculated by the application, "
355 "<strong>jigsaw</strong>.");
356 m_leftLineError = new QLabel();
357 m_leftLineError->setToolTip("<strong>Jigsaw</strong> line residual.");
358 m_leftLineError->setWhatsThis("This is the line residual for the left "
359 "measure calculated by the application, "
360 "<strong>jigsaw</strong>.");
361 m_leftSampShift = new QLabel();
362 m_leftSampShift->setToolTip("Sample shift between apriori and current");
363 m_leftSampShift->setWhatsThis("The shift between the apriori sample and "
364 "the current sample. The apriori sample is set "
365 "when creating a new measure.");
366 m_leftLineShift = new QLabel();
367 m_leftLineShift->setToolTip("Line shift between apriori and current");
368 m_leftLineShift->setWhatsThis("The shift between the apriori line and "
369 "the current line. The apriori line is set "
370 "when creating a new measure.");
371 m_leftGoodness = new QLabel();
372 m_leftGoodness->setToolTip("Goodness of Fit result from sub-pixel "
373 "registration.");
374 m_leftGoodness->setWhatsThis("Resulting Goodness of Fit from sub-pixel "
375 "registration.");
376 QVBoxLayout * leftLayout = new QVBoxLayout;
377 leftLayout->addWidget(m_leftCombo);
378 leftLayout->addWidget(m_lockLeftMeasure);
379 leftLayout->addWidget(m_ignoreLeftMeasure);
380 leftLayout->addWidget(m_leftReference);
381 leftLayout->addWidget(m_leftMeasureType);
382 leftLayout->addWidget(m_leftSampError);
383 leftLayout->addWidget(m_leftLineError);
384 leftLayout->addWidget(m_leftSampShift);
385 leftLayout->addWidget(m_leftLineShift);
386 leftLayout->addWidget(m_leftGoodness);
387
388 QGroupBox * leftGroupBox = new QGroupBox("Left Measure");
389 leftGroupBox->setLayout(leftLayout);
390
391 return leftGroupBox;
392 }
393
394
405
406 // create widgets for the right groupbox
407 m_rightCombo = new QComboBox;
408 m_rightCombo->setEditable(true);
409 m_rightCombo->setInsertPolicy(QComboBox::NoInsert);
410
411 // Attach shortcuts to Qnet Tool's window for selecting right measures
412 // Note: Qt handles this memory for us since m_qnetTool is the parent of these shortcuts
413 QShortcut *nextMeasure = new QShortcut(Qt::Key_PageDown, m_qnetTool);
414 connect(nextMeasure, SIGNAL(activated()), this, SLOT(nextRightMeasure()));
415 QShortcut *prevMeasure = new QShortcut(Qt::Key_PageUp, m_qnetTool);
416 connect(prevMeasure, SIGNAL(activated()), this, SLOT(previousRightMeasure()));
417
418 m_rightCombo->setToolTip("Choose right control measure. "
419 "<strong>Shortcuts: PageUp/PageDown</strong>");
420 m_rightCombo->setWhatsThis("Choose right control measure identified by "
421 "cube filename. "
422 "Note: PageUp selects previous measure; "
423 "PageDown selects next meausure.");
424 connect(m_rightCombo, SIGNAL(activated(int)),
425 this, SLOT(selectRightMeasure(int)));
426 m_lockRightMeasure = new QCheckBox("Edit Lock Measure");
427 connect(m_lockRightMeasure, SIGNAL(clicked(bool)),
428 this, SLOT(setLockRightMeasure(bool)));
429 m_ignoreRightMeasure = new QCheckBox("Ignore Measure");
430 connect(m_ignoreRightMeasure, SIGNAL(clicked(bool)),
431 this, SLOT(setIgnoreRightMeasure(bool)));
432 connect(this, SIGNAL(ignoreRightChanged()),
433 m_ignoreRightMeasure, SLOT(toggle()));
434 m_rightReference = new QLabel();
435 m_rightMeasureType = new QLabel();
436 m_rightSampError = new QLabel();
437 m_rightSampError->setToolTip("<strong>Jigsaw</strong> sample residual.");
438 m_rightSampError->setWhatsThis("This is the sample residual for the right "
439 "measure which was calculated by the application, "
440 "<strong>jigsaw</strong>.");
441 m_rightLineError = new QLabel();
442 m_rightLineError->setToolTip("<strong>Jigsaw</strong> line residual.");
443 m_rightLineError->setWhatsThis("This is the line residual for the right "
444 "measure which was calculated by the application, "
445 "<strong>jigsaw</strong>.");
446 m_rightSampShift = new QLabel();
447 m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
448 m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
449 m_rightLineShift = new QLabel();
450 m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
451 m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
452 m_rightGoodness = new QLabel();
453 m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
454 m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
455
456 // create right groupbox
457 QVBoxLayout * rightLayout = new QVBoxLayout;
458 rightLayout->addWidget(m_rightCombo);
459 rightLayout->addWidget(m_lockRightMeasure);
460 rightLayout->addWidget(m_ignoreRightMeasure);
461 rightLayout->addWidget(m_rightReference);
462 rightLayout->addWidget(m_rightMeasureType);
463 rightLayout->addWidget(m_rightSampError);
464 rightLayout->addWidget(m_rightLineError);
465 rightLayout->addWidget(m_rightSampShift);
466 rightLayout->addWidget(m_rightLineShift);
467 rightLayout->addWidget(m_rightGoodness);
468
469 QGroupBox * rightGroupBox = new QGroupBox("Right Measure");
470 rightGroupBox->setLayout(rightLayout);
471
472 return rightGroupBox;
473 }
474
475
478
479 QToolBar *toolBar = new QToolBar("Template Editor ToolBar");
480
481 toolBar->addAction(m_openTemplateFile);
482 toolBar->addSeparator();
483 toolBar->addAction(m_saveTemplateFile);
484 toolBar->addAction(m_saveTemplateFileAs);
485
486 m_templateEditor = new QTextEdit;
487 connect(m_templateEditor, SIGNAL(textChanged()), this,
488 SLOT(setTemplateModified()));
489
490 QVBoxLayout *mainLayout = new QVBoxLayout;
491 mainLayout->addWidget(toolBar);
492 mainLayout->addWidget(m_templateEditor);
493
494 m_templateEditorWidget = new QWidget;
495 m_templateEditorWidget->setLayout(mainLayout);
496 }
497
498
499
508 m_openGround = new QAction(m_qnetTool);
509 m_openGround->setText("Open &Ground Source");
510 m_openGround->setToolTip("Open a ground source for choosing ground control "
511 "points");
512 m_openGround->setStatusTip("Open a ground source for choosing ground "
513 "control points");
514 QString whatsThis =
515 "<b>Function:</b> Open and display a ground source for choosing "
516 "ground control points, both Fixed and Constrained."
517 "This cube can be a level1, level2 or dem cube.";
518 m_openGround->setWhatsThis(whatsThis);
519 connect (m_openGround,SIGNAL(triggered()),this,SLOT(openGround()));
520
521 m_openDem = new QAction(m_qnetTool);
522 m_openDem->setText("Open &Radius Source");
523 m_openDem->setToolTip("Open radius source file for ground control points");
524 m_openDem->setStatusTip("Open radius source file for ground control points");
525 whatsThis =
526 "<b>Function:</b> Open a DEM for determining the radius when "
527 "choosing ground control points. This is not the file that will be "
528 "displayed for visually picking points. This is strictly used to "
529 "determine the radius value for ground control points.";
530 m_openDem->setWhatsThis(whatsThis);
531 connect (m_openDem,SIGNAL(triggered()),this,SLOT(openDem()));
532
533 m_saveNet = new QAction(QIcon(toolIconDir() + "/filesave.png"), "Save Control Network ...",
534 m_qnetTool);
535 m_saveNet->setShortcut(Qt::CTRL + Qt::Key_S);
536 m_saveNet->setToolTip("Save current control network");
537 m_saveNet->setStatusTip("Save current control network");
538 whatsThis = "<b>Function:</b> Saves the current <i>"
539 "control network</i>";
540 m_saveNet->setWhatsThis(whatsThis);
541 connect(m_saveNet, SIGNAL(triggered()), this, SLOT(saveNet()));
542
543 m_saveAsNet = new QAction(QIcon(toolIconDir() + "/filesaveas.png"), "Save Control Network &As...",
544 m_qnetTool);
545 m_saveAsNet->setToolTip("Save current control network to chosen file");
546 m_saveAsNet->setStatusTip("Save current control network to chosen file");
547 whatsThis = "<b>Function:</b> Saves the current <i>"
548 "control network</i> under chosen filename";
549 m_saveAsNet->setWhatsThis(whatsThis);
550 connect(m_saveAsNet, SIGNAL(triggered()), this, SLOT(saveAsNet()));
551
552 m_closeQnetTool = new QAction(QIcon(toolIconDir() + "/fileclose.png"), "&Close", m_qnetTool);
553 m_closeQnetTool->setToolTip("Close this window");
554 m_closeQnetTool->setStatusTip("Close this window");
555 m_closeQnetTool->setShortcut(Qt::ALT + Qt::Key_F4);
556 whatsThis = "<b>Function:</b> Closes the Qnet Tool window for this point "
557 "<p><b>Shortcut:</b> Alt+F4 </p>";
558 m_closeQnetTool->setWhatsThis(whatsThis);
559 connect(m_closeQnetTool, SIGNAL(triggered()), m_qnetTool, SLOT(close()));
560
561 m_showHideTemplateEditor = new QAction(QIcon(toolIconDir() + "/view_text.png"),
562 "&View/edit registration template", m_qnetTool);
563 m_showHideTemplateEditor->setCheckable(true);
564 m_showHideTemplateEditor->setToolTip("View and/or edit the registration "
565 "template");
566 m_showHideTemplateEditor->setStatusTip("View and/or edit the registration "
567 "template");
568 whatsThis = "<b>Function:</b> Displays the curent registration template. "
569 "The user may edit and save changes under a chosen filename.";
570 m_showHideTemplateEditor->setWhatsThis(whatsThis);
571 connect(m_showHideTemplateEditor, SIGNAL(triggered()), this,
572 SLOT(showHideTemplateEditor()));
573
574 m_saveChips = new QAction(QIcon(toolIconDir() + "/savechips.png"), "Save registration chips",
575 m_qnetTool);
576 m_saveChips->setToolTip("Save registration chips");
577 m_saveChips->setStatusTip("Save registration chips");
578 whatsThis = "<b>Function:</b> Save registration chips to file. "
579 "Each chip: pattern, search, fit will be saved to a separate file.";
580 m_saveChips->setWhatsThis(whatsThis);
581 connect(m_saveChips, SIGNAL(triggered()), this, SLOT(saveChips()));
582
583 m_openTemplateFile = new QAction(QIcon(toolIconDir() + "/fileopen.png"), "&Open registration "
584 "template", m_qnetTool);
585 m_openTemplateFile->setToolTip("Set registration template");
586 m_openTemplateFile->setStatusTip("Set registration template");
587 whatsThis = "<b>Function:</b> Allows user to select a new file to set as "
588 "the registration template";
589 m_openTemplateFile->setWhatsThis(whatsThis);
590 connect(m_openTemplateFile, SIGNAL(triggered()), this, SLOT(openTemplateFile()));
591
592 m_saveTemplateFile = new QAction(QIcon(toolIconDir() + "/filesave.png"), "&Save template file",
593 m_qnetTool);
594 m_saveTemplateFile->setToolTip("Save the template file");
595 m_saveTemplateFile->setStatusTip("Save the template file");
596 m_saveTemplateFile->setWhatsThis("Save the registration template file");
597 connect(m_saveTemplateFile, SIGNAL(triggered()), this,
598 SLOT(saveTemplateFile()));
599
600 m_saveTemplateFileAs = new QAction(QIcon(toolIconDir() + "/filesaveas.png"), "&Save template as...",
601 m_qnetTool);
602 m_saveTemplateFileAs->setToolTip("Save the template file as");
603 m_saveTemplateFileAs->setStatusTip("Save the template file as");
604 m_saveTemplateFileAs->setWhatsThis("Save the registration template file as");
605 connect(m_saveTemplateFileAs, SIGNAL(triggered()), this,
606 SLOT(saveTemplateFileAs()));
607
608 m_whatsThis = new QAction(QIcon(FileName(
609 "$ISISROOT/appdata/images/icons/contexthelp.png").expanded()),"&Whats's This", m_qnetTool);
610 m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
611 m_whatsThis->setToolTip("Activate What's This and click on items on "
612 "user interface to see more information.");
613 connect(m_whatsThis, SIGNAL(triggered()), this, SLOT(enterWhatsThisMode()));
614
615 }
616
617
618
629
630 QMenu *fileMenu = m_qnetTool->menuBar()->addMenu("&File");
631 fileMenu->addAction(m_openGround);
632 fileMenu->addAction(m_openDem);
633 fileMenu->addAction(m_saveNet);
634 fileMenu->addAction(m_saveAsNet);
635 fileMenu->addAction(m_closeQnetTool);
636
637 QMenu * regMenu = m_qnetTool->menuBar()->addMenu("&Registration");
638 regMenu->addAction(m_openTemplateFile);
639 regMenu->addAction(m_showHideTemplateEditor);
640 regMenu->addAction(m_saveChips);
641
642 QMenu *helpMenu = m_qnetTool->menuBar()->addMenu("&Help");
643 helpMenu->addAction(m_whatsThis);
644 }
645
646
647 void QnetTool::createToolBars() {
648
649 toolBar = new QToolBar;
650 toolBar->setObjectName("TemplateEditorToolBar");
651 toolBar->setFloatable(false);
652 toolBar->addAction(m_saveNet);
653 toolBar->addSeparator();
654 toolBar->addAction(m_showHideTemplateEditor);
655 toolBar->addAction(m_saveChips);
656 toolBar->addAction(m_whatsThis);
657
658 m_qnetTool->addToolBar(Qt::TopToolBarArea, toolBar);
659 }
660
661
662
727 // Read original measures from the network for comparison with measures
728 // that have been edited
729 ControlMeasure *origLeftMeasure =
730 m_editPoint->GetMeasure(m_leftMeasure->GetCubeSerialNumber());
731 ControlMeasure *origRightMeasure =
732 m_editPoint->GetMeasure(m_rightMeasure->GetCubeSerialNumber());
733
734 if (m_editPoint->IsIgnored()) {
735 QString message = "You are saving changes to a measure on an ignored ";
736 message += "point. Do you want to set Ignore = False on the point and ";
737 message += "both measures?";
738 switch (QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
739 message, "&Yes", "&No", 0, 0)) {
740 // Yes: set Ignore=false for the point and measures and save point
741 case 0:
742 m_editPoint->SetIgnored(false);
743 emit ignorePointChanged();
744 if (m_leftMeasure->IsIgnored()) {
745 m_leftMeasure->SetIgnored(false);
746 emit ignoreLeftChanged();
747 }
748 if (m_rightMeasure->IsIgnored()) {
749 m_rightMeasure->SetIgnored(false);
750 emit ignoreRightChanged();
751 }
752 // No: keep Ignore=true and save measure
753 case 1:
754 break;
755
756 }
757 }
758 if (origRightMeasure->IsIgnored() && m_rightMeasure->IsIgnored()) {
759 QString message = "You are saving changes to an ignored measure. ";
760 message += "Do you want to set Ignore = False on the right measure?";
761 switch(QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
762 message, "&Yes", "&No", 0, 0)){
763 // Yes: set Ignore=false for the right measure and save point
764 case 0:
765 m_rightMeasure->SetIgnored(false);
766 emit ignoreRightChanged();
767 // No: keep Ignore=true and save point
768 case 1:
769 break;
770 }
771 }
772
773 // Only check reference if point contains explicit reference. Otherwise,
774 // there has not been a reference set, set the measure on the left as the reference.
775 if (m_editPoint->IsReferenceExplicit()) {
776 if (m_editPoint->IsEditLocked()) {
777 QString message = "This control point is edit locked. The Apriori latitude, longitude and ";
778 message += "radius cannot be updated. You must first unlock the point by clicking the ";
779 message += "check box above labeled \"Edit Lock Point\".";
780 QMessageBox::warning(m_qnetTool, "Point Locked", message);
781 return;
782 }
783 // If user does not want to change the reference then don't update the measure
784 if (!checkReference()) {
785 return;
786 }
787 }
788 else if (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) {
789 m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
790 }
791
792 // If this is a fixed or constrained point, and the right measure is the ground source,
793 // update the lat,lon,radius. Only the right measure can be moved, so only need to update
794 // position if the ground measure is loaded on the right.
795 //
796 // If point is locked and it is not a new point, print error
797 // TODO:: Only update if the measure moved
798 if (m_editPoint->GetType() != ControlPoint::Free && (m_groundOpen &&
799 m_rightMeasure->GetCubeSerialNumber() == m_groundSN)) {
800 if (m_editPoint->IsEditLocked() && m_controlNet->ContainsPoint(m_editPoint->GetId())) {
801 QString message = "This control point is edit locked. The Apriori latitude, longitude and ";
802 message += "radius cannot be updated. You must first unlock the point by clicking the ";
803 message += "check box above labeled \"Edit Lock Point\".";
804 QMessageBox::warning(m_qnetTool, "Point Locked", message);
805 return;
806 }
807 if (m_leftMeasure->IsIgnored()) {
808 QString message = "This is a Constrained or Fixed point and the reference measure is ";
809 message += "Ignored. Unset the Ignore flag on the reference measure before saving.";
810 QMessageBox::warning(m_qnetTool, "Point Locked", message);
811 return;
812 }
813 updateGroundPosition();
814 }
815
816 // Save the right measure and left (if ignore or edit lock flag changed) to
817 // the editPoint The Ignore flag is the only thing that can change on the left
818 // measure.
819 m_rightMeasure->SetChooserName(Application::UserName());
820 *origRightMeasure = *m_rightMeasure;
821
822 // Only save the left measure if the ignore flag or editLock has changed
823 if (m_leftMeasure->IsIgnored() != origLeftMeasure->IsIgnored() ||
824 m_leftMeasure->IsEditLocked() != origLeftMeasure->IsEditLocked()) {
825 m_leftMeasure->SetChooserName(Application::UserName());
826 *origLeftMeasure = *m_leftMeasure;
827 }
828
829 // If left measure == right measure, update left
830 if (m_leftMeasure->GetCubeSerialNumber() ==
831 m_rightMeasure->GetCubeSerialNumber()) {
832 *m_leftMeasure = *m_rightMeasure;
833 // Update left measure of pointEditor
834 m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
835 m_editPoint->GetId());
836 }
837
838 // Change Save Point button text to red
840
841 editPointChanged(m_editPoint->GetId());
842
843 // Update measure info
847 }
848
849
850
867
868 // Check if ControlPoint has reference measure, if reference Measure is
869 // not the same measure that is on the left chip viewport, set left
870 // measure as reference.
871 ControlMeasure *refMeasure = m_editPoint->GetRefMeasure();
872 if ( (m_leftMeasure->GetCubeSerialNumber() != m_groundSN) &&
873 (refMeasure->GetCubeSerialNumber() != m_leftMeasure->GetCubeSerialNumber()) ) {
874 QString message = "This point already contains a reference measure. ";
875 message += "Would you like to replace it with the measure on the left?";
876 int response = QMessageBox::question(m_qnetTool,
877 "Qnet Tool Save Measure", message,
878 QMessageBox::Yes | QMessageBox::No,
879 QMessageBox::Yes);
880 // Replace reference measure
881 if (response == QMessageBox::Yes) {
882 // Update measure file combo boxes: old reference normal font,
883 // new reference bold font
884 QString file = m_serialNumberList->fileName(m_leftMeasure->GetCubeSerialNumber());
885 QString fname = FileName(file).name();
886 int iref = m_leftCombo->findText(fname);
887
888 // Save normal font from new reference measure
889 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
890 m_leftCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
891 iref = m_rightCombo->findText(fname);
892 m_rightCombo->setItemData(iref,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
893
894 file = m_serialNumberList->fileName(refMeasure->GetCubeSerialNumber());
895 fname = FileName(file).name();
896 iref = m_leftCombo->findText(fname);
897 m_leftCombo->setItemData(iref,font,Qt::FontRole);
898 iref = m_rightCombo->findText(fname);
899 m_rightCombo->setItemData(iref,font,Qt::FontRole);
900
901 m_editPoint->SetRefMeasure(m_leftMeasure->GetCubeSerialNumber());
902 // Update reference measure to new reference measure
903 refMeasure = m_editPoint->GetRefMeasure();
904 }
905 // ??? Need to set rest of measures to Candidate and add more warning. ???//
906 }
907
908 // If the right measure is the reference, make sure they really want
909 // to move the reference.
910 if (refMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
911 QString message = "You are making a change to the reference measure. You ";
912 message += "may need to move all of the other measures to match the new ";
913 message += " coordinate of the reference measure. Do you really want to ";
914 message += " change the reference measure? ";
915 switch(QMessageBox::question(m_qnetTool, "Qnet Tool Save Measure",
916 message, "&Yes", "&No", 0, 0)){
917 // Yes: Save measure
918 case 0:
919 return true;
920 // No: keep original reference, return ChipViewports to previous states
921 case 1:
922 selectRightMeasure(m_rightCombo->currentIndex());
923 selectLeftMeasure(m_leftCombo->currentIndex());
924 return false;
925 }
926 }
927 return true;
928 }
929
930
931
932 /*
933 * Update the position of ground point
934 *
935 * @author 2012-04-26 Tracie Sucharski - moved functionality from measureSaved
936 *
937 * @internal
938 *
939 */
940 void QnetTool::updateGroundPosition() {
941
942 // TODO: If groundSource file opened does not match the SurfacePoint Source
943 // file, print warning.
944
945 // This method only called if ground measure is on the right. Use ground measure to update
946 // apriori surface point.
947 ControlMeasure *groundMeasure = m_rightMeasure;
948 if (!m_groundGmap->SetImage(groundMeasure->GetSample(),
949 groundMeasure->GetLine())) {
950 // TODO : should never happen, either add error check or
951 // get rid of
952 }
953
954 double lat = m_groundGmap->UniversalLatitude();
955 double lon = m_groundGmap->UniversalLongitude();
956// cout<<"lat = "<<setprecision(15)<<lat<<endl;
957// cout<<"lon = "<<lon<<endl;
958 double radius;
959 // Update radius, order of precedence
960 // 1. If a dem has been opened, read radius from dem.
961 // 2. Get radius from reference measure
962 // If image has shape model, radius will come from shape model
963 //
964 if (m_demOpen) {
965 radius = demRadius(lat,lon);
966 if (radius == Null) {
967 QString msg = "Could not read radius from DEM, will default to "
968 "local radius of reference measure.";
969 QMessageBox::warning(m_qnetTool, "Warning", msg);
970 if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
971 Latitude(lat, Angle::Degrees), Longitude(lon, Angle::Degrees))) {
972 radius =
973 m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
974 m_editPoint->SetAprioriRadiusSource(
975 ControlPoint::RadiusSource::None);
976 //m_editPoint->SetAprioriRadiusSourceFile(m_radiusSourceFile);
977 }
978 else {
979 QString message = "Error trying to get radius at this pt. "
980 "Lat/Lon does not fall on the reference measure. "
981 "Cannot save this measure.";
982 QMessageBox::critical(m_qnetTool,"Error",message);
983 return;
984 }
985 }
986 m_editPoint->SetAprioriRadiusSource(m_groundRadiusSource);
987 m_editPoint->SetAprioriRadiusSourceFile(m_radiusSourceFile);
988 }
989 else {
990 // Get radius from reference image
991 if (m_editPoint->GetRefMeasure()->Camera()->SetGround(
992 Latitude(lat, Angle::Degrees), Longitude(lon, Angle::Degrees))) {
993 radius =
994 m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
995// cout.width(15);
996// cout.precision(4);
997// cout<<"Camera Radius = "<<fixed<<radius<<endl;
998 //radius = m_groundGmap->Projection()->LocalRadius();
999 }
1000 else {
1001 QString message = "Error trying to get radius at this pt. "
1002 "Lat/Lon does not fall on the reference measure. "
1003 "Cannot save this measure.";
1004 QMessageBox::critical(m_qnetTool,"Error",message);
1005 return;
1006 }
1007 }
1008
1009 try {
1010 // Read apriori surface point if it exists so that point is
1011 // replaced, but sigmas are retained. Save sigmas because the
1012 // SurfacePoint class will change them if the coordinates change.
1013 if (m_editPoint->HasAprioriCoordinates()) {
1014 SurfacePoint aprioriPt = m_editPoint->GetAprioriSurfacePoint();
1015 Distance latSigma = aprioriPt.GetLatSigmaDistance();
1016 Distance lonSigma = aprioriPt.GetLonSigmaDistance();
1017 Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
1018 aprioriPt.SetSphericalCoordinates(Latitude(lat, Angle::Degrees),
1019 Longitude(lon, Angle::Degrees),
1020 Distance(radius, Distance::Meters));
1021 aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
1022 m_editPoint->SetAprioriSurfacePoint(aprioriPt);
1023 }
1024 else {
1025 m_editPoint->SetAprioriSurfacePoint(SurfacePoint(
1026 Latitude(lat, Angle::Degrees),
1027 Longitude(lon, Angle::Degrees),
1028 Distance(radius, Distance::Meters)));
1029 }
1030 }
1031 catch (IException &e) {
1032 QString message = "Unable to set Apriori Surface Point.\n";
1033 message += "Latitude = " + QString::number(lat);
1034 message += " Longitude = " + QString::number(lon);
1035 message += " Radius = " + QString::number(radius) + "\n";
1036 message += e.toString();
1037 QMessageBox::critical(m_qnetTool,"Error",message);
1038 }
1039 m_editPoint->SetAprioriSurfacePointSource(m_groundSurfacePointSource);
1040 m_editPoint->SetAprioriSurfacePointSourceFile(m_groundSourceFile);
1041
1043
1044 }
1045
1046
1047
1063
1064 // Make a copy of edit point for updating the control net since the edit
1065 // point is still loaded in the point editor.
1066 ControlPoint *updatePoint = new ControlPoint;
1067 *updatePoint = *m_editPoint;
1068
1069 // If this is a fixed or constrained point, see if there is a temporary
1070 // measure holding the coordinate information from the ground source.
1071 // If so, delete this measure before saving point. Clear out the
1072 // fixed Measure variable (memory deleted in ControlPoint::Delete).
1073 if (updatePoint->GetType() != ControlPoint::Free &&
1074 updatePoint->HasSerialNumber(m_groundSN)) {
1075 updatePoint->Delete(m_groundSN);
1076 }
1077
1078 // If edit point exists in the network, save the updated point. If it
1079 // does not exist, add it.
1080 if (m_controlNet->ContainsPoint(updatePoint->GetId())) {
1081 ControlPoint *p;
1082 p = m_controlNet->GetPoint(QString(updatePoint->GetId()));
1083 *p = *updatePoint;
1084 delete updatePoint;
1085 updatePoint = NULL;
1086 }
1087 else {
1088 m_controlNet->AddPoint(updatePoint);
1089 }
1090
1091 // Change Save Measure button text back to default
1092 m_savePoint->setPalette(m_saveDefaultPalette);
1093
1094 // ???? Why was this here??? loadPoint();
1095 // emit signal so the nav tool refreshes the list
1096 emit refreshNavList();
1097 // emit signal so the nav tool can update edit point
1098 emit editPointChanged(m_editPoint->GetId());
1099 // emit a signal to alert user to save when exiting
1100 emit netChanged();
1101 // Refresh chipViewports to show new positions of controlPoints
1102 m_pointEditor->refreshChips();
1103 }
1104
1105
1106
1121 void QnetTool::setPointType (int pointType) {
1122 if (m_editPoint == NULL) return;
1123
1124 // If pointType is equal to current type, nothing to do
1125 if (m_editPoint->GetType() == pointType) return;
1126
1127 if (pointType != ControlPoint::Free && m_leftMeasure->IsIgnored()) {
1128 m_pointType->setCurrentIndex((int) m_editPoint->GetType());
1129 QString message = "The reference measure is Ignored. Unset the Ignore flag on the ";
1130 message += "reference measure before setting the point type to Constrained or Fixed.";
1131 QMessageBox::warning(m_qnetTool, "Ignored Reference Measure", message);
1132 return;
1133 }
1134
1135 bool unloadGround = false;
1136 if (m_editPoint->GetType() != ControlPoint::Free && pointType == ControlPoint::Free)
1137 unloadGround = true;
1138
1139 // save the old point's type
1140 int temp = m_editPoint->GetType();
1141
1142 ControlPoint::Status status = m_editPoint->SetType((ControlPoint::PointType) pointType);
1143 if (status == ControlPoint::PointLocked) {
1144 m_pointType->setCurrentIndex((int) m_editPoint->GetType());
1145 QString message = "This control point is edit locked. The point type cannot be changed. You ";
1146 message += "must first unlock the point by clicking the check box above labeled ";
1147 message += "\"Edit Lock Point\".";
1148 QMessageBox::warning(m_qnetTool, "Point Locked", message);
1149 return;
1150 }
1151
1152 // If ground loaded and changing from Free to ground point,
1153 // read temporary ground measure to the point
1154 // Note: changing between Fixed and Constrained will not reload the ground measure
1155 if (pointType != ControlPoint::Free && temp == ControlPoint::Free && m_groundOpen) {
1157 m_pointEditor->colorizeSaveButton();
1158 }
1159 // If going from constrained or fixed to free, unload the ground measure.
1160 else if (unloadGround) {
1161 // Find in point and delete, it will be re-created with current
1162 // ground source if this is a fixed point
1163 if (m_editPoint->HasSerialNumber(m_groundSN)) {
1164 m_editPoint->Delete(m_groundSN);
1165 }
1166
1167 loadPoint();
1168 m_pointEditor->colorizeSaveButton();
1169 }
1170
1172 }
1173
1174
1175
1188
1189 if (!m_groundOpen) return;
1190
1191 if (findPointLocation()) {
1193
1194 // Add to measure combo boxes
1195 QString file = m_serialNumberList->fileName(groundMeasure->GetCubeSerialNumber());
1196 m_pointFiles<<file;
1197 QString tempFileName = FileName(file).name();
1198
1199 m_leftCombo->addItem(tempFileName);
1200 m_rightCombo->addItem(tempFileName);
1201 int rightIndex = m_rightCombo->findText((QString)m_groundFile);
1202 m_rightCombo->setCurrentIndex(rightIndex);
1203 selectRightMeasure(rightIndex);
1204
1206
1208 }
1209 }
1210
1211
1212
1222 void QnetTool::setLockPoint (bool lock) {
1223 if (m_editPoint == NULL) return;
1224
1225 m_editPoint->SetEditLock(lock);
1227 }
1228
1229
1230
1241 void QnetTool::setIgnorePoint (bool ignore) {
1242 if (m_editPoint == NULL) return;
1243
1244 ControlPoint::Status status = m_editPoint->SetIgnored(ignore);
1245 if (status == ControlPoint::PointLocked) {
1246 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1247 QString message = "This control point is edit locked. The Ignored status cannot be ";
1248 message += "changed. You must first unlock the point by clicking the check box above ";
1249 message += "labeled \"Edit Lock Point\".";
1250 QMessageBox::warning(m_qnetTool, "Point Locked", message);
1251 return;
1252 }
1254 }
1255
1256
1257
1258
1275
1276 if (m_editPoint->IsEditLocked()) {
1277 m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
1278 QMessageBox::warning(m_qnetTool, "Point Locked","Point is Edit Locked. You must un-lock point"
1279 " before changing a measure.");
1280 m_lockLeftMeasure->setChecked(m_leftMeasure->IsEditLocked());
1281 return;
1282 }
1283
1284 if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
1285
1286 // If the right chip is the same as the left chip , update the right editLock
1287 // box.
1288 if (m_rightMeasure != NULL) {
1289 if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1290 m_rightMeasure->SetEditLock(lock);
1291 m_lockRightMeasure->setChecked(lock);
1292 }
1293 }
1294 emit measureChanged();
1295 }
1296
1297
1316 if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
1317
1318 // If the right chip is the same as the left chip , update the right
1319 // ignore box.
1320 if (m_rightMeasure != NULL) {
1321 if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1322 m_rightMeasure->SetIgnored(ignore);
1323 m_ignoreRightMeasure->setChecked(ignore);
1324 }
1325 }
1326 emit measureChanged();
1327 }
1328
1329
1346
1347 if (m_editPoint->IsEditLocked()) {
1348 m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
1349 QMessageBox::warning(m_qnetTool, "Point Locked","Point is Edit Locked. You must un-lock point"
1350 " before changing a measure.");
1351 m_lockRightMeasure->setChecked(m_rightMeasure->IsEditLocked());
1352 return;
1353 }
1354
1355 if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
1356
1357 // If the left chip is the same as the right chip , update the left editLock box.
1358 if (m_leftMeasure != NULL) {
1359 if (m_leftMeasure->GetCubeSerialNumber() == m_rightMeasure->GetCubeSerialNumber()) {
1360 m_leftMeasure->SetEditLock(lock);
1361 m_lockLeftMeasure->setChecked(lock);
1362 }
1363 }
1364 emit measureChanged();
1365 }
1366
1367
1386 if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
1387
1388 // If the right chip is the same as the left chip , update the right
1389 // ignore blox.
1390 if (m_leftMeasure != NULL) {
1391 if (m_rightMeasure->GetCubeSerialNumber() == m_leftMeasure->GetCubeSerialNumber()) {
1392 m_leftMeasure->SetIgnored(ignore);
1393 m_ignoreLeftMeasure->setChecked(ignore);
1394 }
1395 }
1396 emit measureChanged();
1397 }
1398
1399
1400
1407 if (m_cnetFileName.isEmpty()) {
1408 QString message = "This is a new network, you must select "
1409 "\"Save As\" under the File Menu.";
1410 QMessageBox::critical(m_qnetTool, "Error", message);
1411 return;
1412 }
1413 emit qnetToolSave();
1414 //m_controlNet->Write(m_cnetFileName);
1415 }
1416
1417
1418
1423 emit qnetToolSaveAs();
1424 }
1425
1426
1427
1428
1432 void QnetTool::updateList() {
1433
1434 //m_pointEditor->setSerialList (*m_serialNumberList);
1435
1436 }
1437
1438
1455 void QnetTool::updateNet(QString cNetFileName) {
1456 m_cnetFileName = cNetFileName;
1457 m_qnetTool->setWindowTitle("Qnet Tool - Control Network File: " +
1458 cNetFileName);
1459 //m_pointEditor->setControlNet(*m_controlNet);
1460
1461 }
1462
1463
1464
1477 QAction *action = new QAction(pad);
1478 action->setIcon(QPixmap(toolIconDir()+"/stock_draw-connector-with-arrows.png"));
1479 action->setToolTip("Control Point Editor (T)");
1480 action->setShortcut(Qt::Key_T);
1481 QObject::connect(action,SIGNAL(triggered(bool)),this,SLOT(showNavWindow(bool)));
1482 return action;
1483 }
1484
1485
1486
1521 void QnetTool::mouseButtonRelease(QPoint p, Qt::MouseButton s) {
1523 if (cvp == NULL) return;
1524
1525 QString file = cvp->cube()->fileName();
1526 QString sn;
1527 try {
1528 sn = m_serialNumberList->serialNumber(file);
1529 }
1530 catch (IException &e) {
1531 QString message = "Cannot get serial number for " + file + ". Is file contained in the ";
1532 message += "cube list?\n";
1533 message += e.toString();
1534 QMessageBox::critical(m_qnetTool, "Error", message);
1535 return;
1536 }
1537
1538 double samp,line;
1539 cvp->viewportToCube(p.x(),p.y(),samp,line);
1540
1541 m_leftFile.clear();
1542
1543 if (s == Qt::LeftButton) {
1544 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1545 QString message = "No points exist for editing. Create points ";
1546 message += "using the right mouse button.";
1547 QMessageBox::warning(m_qnetTool, "Warning", message);
1548 return;
1549 }
1550
1551 if (sn == m_groundSN) {
1552 QString message = "Cannot select point for editing on ground source. Select ";
1553 message += "point using un-projected images or the Navigator Window.";
1554 QMessageBox::critical(m_qnetTool, "Error", message);
1555 return;
1556 }
1557
1558 // Find closest control point in network
1559 QString sn = m_serialNumberList->serialNumber(file);
1560
1561 // since we are in a connected slot, we need to handle exceptions thrown by FindClosest
1562 try {
1563 ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1564 modifyPoint(point);
1565 }
1566 catch (IException &ie) {
1567 QString message = "No points exist for editing. Create points using the right mouse";
1568 message += " button.";
1569 QMessageBox::warning(m_qnetTool, "Warning", message);
1570 return;
1571 }
1572 }
1573
1574 else if (s == Qt::MidButton) {
1575 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1576 QString message = "No points exist for deleting. Create points ";
1577 message += "using the right mouse button.";
1578 QMessageBox::warning(m_qnetTool, "Warning", message);
1579 return;
1580 }
1581
1582 if (m_groundOpen && file == m_groundCube->fileName()) {
1583 QString message = "Cannot select point for deleting on ground source. Select ";
1584 message += "point using un-projected images or the Navigator Window.";
1585 QMessageBox::critical(m_qnetTool, "Error", message);
1586 return;
1587 }
1588 // Find closest control point in network
1589 ControlPoint *point = NULL;
1590 try {
1591 point = m_controlNet->FindClosest(sn, samp, line);
1592
1593 if (point == NULL) {
1594 QString message = "No points exist for deleting. Create points ";
1595 message += "using the right mouse button.";
1596 QMessageBox::warning(m_qnetTool, "Warning", message);
1597 return;
1598 }
1599 }
1600 catch (IException &e) {
1601 QString message = "Cannot find point on this image for deleting.";
1602 QMessageBox::critical(m_qnetTool, "Error", message);
1603 return;
1604 }
1605
1606 deletePoint(point);
1607 }
1608 else if (s == Qt::RightButton) {
1609 m_leftFile = file;
1610 UniversalGroundMap *gmap = cvp->universalGroundMap();
1611 if (!gmap->SetImage(samp,line)) {
1612 QString message = "Invalid latitude or longitude at this point. ";
1613 QMessageBox::critical(m_qnetTool,"Error", message);
1614 return;
1615 }
1616 double lat = gmap->UniversalLatitude();
1617 double lon = gmap->UniversalLongitude();
1618 if (m_groundOpen && file == m_groundCube->fileName()) {
1619 createFixedPoint (lat,lon);
1620 }
1621 else {
1622 createPoint(lat,lon);
1623 }
1624 }
1625 }
1626
1627
1628
1673 void QnetTool::createPoint(double lat,double lon) {
1674
1675 // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1676
1677 // Create list box of all files highlighting those that
1678 // contain the point.
1679 QStringList pointFiles;
1680
1681 Camera *cam;
1682 for(int i = 0; i < m_serialNumberList->size(); i++) {
1683 if (m_serialNumberList->serialNumber(i) == m_groundSN) continue;
1684 cam = m_controlNet->Camera(i);
1685 if(cam->SetUniversalGround(lat, lon)) {
1686 // Make sure point is within image boundary
1687 double samp = cam->Sample();
1688 double line = cam->Line();
1689 if (samp >= 1 && samp <= cam->Samples() &&
1690 line >= 1 && line <= cam->Lines()) {
1691 pointFiles<<m_serialNumberList->fileName(i);
1692 }
1693 }
1694 }
1695
1696 NewControlPointDialog *newPointDialog =
1697 new NewControlPointDialog(m_controlNet, m_serialNumberList, m_lastUsedPointId);
1698 newPointDialog->setFiles(pointFiles);
1699 if (newPointDialog->exec()) {
1700 m_lastUsedPointId = newPointDialog->pointId();
1701 ControlPoint *newPoint =
1702 new ControlPoint(m_lastUsedPointId);
1703
1704 // If this ControlPointId already exists, message box pops up and user is
1705 // asked to enter a new value.
1706 if (m_controlNet->ContainsPoint(newPoint->GetId())) {
1707 QString message = "A ControlPoint with Point Id = [" + newPoint->GetId();
1708 message += "] already exists. Re-enter Point Id for this ControlPoint.";
1709 QMessageBox::warning(m_qnetTool, "New Point Id", message);
1710 pointFiles.clear();
1711 delete newPoint;
1712 newPoint = NULL;
1713 createPoint(lat, lon);
1714 return;
1715 }
1716
1718
1719 QStringList selectedFiles = newPointDialog->selectedFiles();
1720 foreach (QString selectedFile, selectedFiles) {
1721 // Create measure for any file selected
1723 // Find serial number for this file
1724 QString sn =
1725 m_serialNumberList->serialNumber(selectedFile);
1726 m->SetCubeSerialNumber(sn);
1727 int camIndex =
1728 m_serialNumberList->fileNameIndex(selectedFile);
1729 cam = m_controlNet->Camera(camIndex);
1730 cam->SetUniversalGround(lat,lon);
1731 m->SetCoordinate(cam->Sample(),cam->Line());
1732 m->SetAprioriSample(cam->Sample());
1733 m->SetAprioriLine(cam->Line());
1734 m->SetType(ControlMeasure::Manual);
1735 m->SetChooserName(Application::UserName());
1736 m->SetCamera(cam);
1737 newPoint->Add(m);
1738 }
1739 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1740 delete m_editPoint;
1741 m_editPoint = NULL;
1742 }
1743 m_editPoint = newPoint;
1744
1745 // If the image that the user clicked on to select the point is not
1746 // included, clear out the leftFile value.
1747 if (!m_leftFile.isEmpty()) {
1748 if (selectedFiles.indexOf(m_leftFile) == -1) {
1749 m_leftFile.clear();
1750 }
1751 }
1752
1753 // Load new point in QnetTool
1754 loadPoint();
1755 m_qnetTool->setVisible(true);
1756 m_qnetTool->raise();
1757
1759 m_pointEditor->templateFileName());
1760
1761
1762 // emit signal so the nave tool refreshes the list
1763 emit refreshNavList();
1764 // emit signal so the nav tool can update edit point
1765 emit editPointChanged(m_editPoint->GetId());
1767 delete newPointDialog;
1768
1769 }
1770 }
1771
1772
1773
1774
1775
1776
1788 void QnetTool::createFixedPoint(double lat,double lon) {
1789
1790 // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1791
1792 // Create list of list box of all files highlighting those that
1793 // contain the point.
1794 QStringList pointFiles;
1795
1796 Camera *cam;
1797 for (int i=0; i<m_serialNumberList->size(); i++) {
1798 if (m_serialNumberList->serialNumber(i) == m_groundSN) continue;
1799 cam = m_controlNet->Camera(i);
1800 if (cam->SetUniversalGround(lat,lon)) {
1801 // Make sure point is within image boundary
1802 double samp = cam->Sample();
1803 double line = cam->Line();
1804 if (samp >= 1 && samp <= cam->Samples() &&
1805 line >= 1 && line <= cam->Lines()) {
1806 pointFiles<<m_serialNumberList->fileName(i);
1807 }
1808 }
1809 }
1810
1811 if (pointFiles.count() == 0) {
1812 QString message = "Point does not intersect any images.";
1813 QMessageBox::critical(m_qnetTool, "No intersection", message);
1814 return;
1815 }
1816
1817 QnetFixedPointDialog *fixedPointDialog = new QnetFixedPointDialog(this, m_lastUsedPointId);
1818 fixedPointDialog->setFiles(pointFiles);
1819 if (fixedPointDialog->exec()) {
1820 ControlPoint *fixedPoint =
1821 new ControlPoint(fixedPointDialog->pointId());
1822
1823 if (fixedPointDialog->isFixed()) {
1824 fixedPoint->SetType(ControlPoint::Fixed);
1825 }
1826 else {
1827 fixedPoint->SetType(ControlPoint::Constrained);
1828 }
1829
1830 // If this ControlPointId already exists, message box pops up and user is
1831 // asked to enter a new value.
1832 if (m_controlNet->ContainsPoint(fixedPoint->GetId())) {
1833 QString message = "A ControlPoint with Point Id = [" + fixedPoint->GetId();
1834 message += "] already exists. Re-enter Point Id for this ControlPoint.";
1835 QMessageBox::warning(m_qnetTool, "New Point Id", message);
1836 pointFiles.clear();
1837 delete fixedPoint;
1838 fixedPoint = NULL;
1839 createFixedPoint(lat,lon);
1840 return;
1841 }
1842
1843 fixedPoint->SetChooserName(Application::UserName());
1844
1845 QStringList selectedFiles = fixedPointDialog->selectedFiles();
1846 foreach (QString selectedFile, selectedFiles) {
1847 // Create measure for any file selected
1849 // Find serial number for this file
1850 QString sn =
1851 m_serialNumberList->serialNumber(selectedFile);
1852
1853 // If ground, do not add measure, it will be added in loadPoint
1854 if (sn == m_groundSN) continue;
1855
1856 m->SetCubeSerialNumber(sn);
1857 int camIndex =
1858 m_serialNumberList->fileNameIndex(selectedFile);
1859 cam = m_controlNet->Camera(camIndex);
1860 cam->SetUniversalGround(lat,lon);
1861 m->SetCoordinate(cam->Sample(),cam->Line());
1862 m->SetType(ControlMeasure::Manual);
1863 m->SetChooserName(Application::UserName());
1864 m->SetCamera(cam);
1865 fixedPoint->Add(m);
1866 }
1867
1868 // ?????? What radius , check for dem or shape model
1869 double radius = 0;
1870 if (m_demOpen) {
1871 radius = demRadius(lat,lon);
1872 if (radius == Null) {
1873 QString msg = "Could not read radius from DEM, will default to the "
1874 "local radius of the first measure in the control point. This "
1875 "will be updated to the local radius of the chosen reference "
1876 "measure.";
1877 QMessageBox::warning(m_qnetTool, "Warning", msg);
1878 if ((*fixedPoint)[0]->Camera()->SetGround(
1880 radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
1881 }
1882 else {
1883 QString msg = "Error trying to get radius at this pt. "
1884 "Lat/Lon does not fall on the reference measure. "
1885 "Cannot create this point.";
1886 QMessageBox::critical(m_qnetTool, "Error", msg);
1887 delete fixedPoint;
1888 fixedPoint = NULL;
1889 delete fixedPointDialog;
1890 fixedPointDialog = NULL;
1891 return;
1892 }
1893 }
1894 }
1895 else {
1896 if ((*fixedPoint)[0]->Camera()->SetGround(
1898 radius = (*fixedPoint)[0]->Camera()->LocalRadius().meters();
1899 }
1900 else {
1901 QString msg = "Error trying to get radius at this pt. "
1902 "Lat/Lon does not fall on the reference measure. "
1903 "Cannot create this point.";
1904 QMessageBox::critical(m_qnetTool, "Error", msg);
1905 delete fixedPoint;
1906 fixedPoint = NULL;
1907 delete fixedPointDialog;
1908 fixedPointDialog = NULL;
1909 return;
1910 }
1911 }
1912
1913 fixedPoint->SetAprioriSurfacePoint(SurfacePoint(
1916 Distance(radius, Distance::Meters)));
1917
1918 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1919 delete m_editPoint;
1920 m_editPoint = NULL;
1921 }
1922 m_editPoint = fixedPoint;
1923
1924 // Load new point in QnetTool
1925 loadPoint();
1926 m_qnetTool->setVisible(true);
1927 m_qnetTool->raise();
1928
1929 delete fixedPointDialog;
1930 fixedPointDialog = NULL;
1931
1932 // emit signal so the nave tool refreshes the list
1933 emit refreshNavList();
1934 // emit signal so the nav tool can update edit point
1935 emit editPointChanged(m_editPoint->GetId());
1937 }
1938 }
1939
1940
1941
1963
1964 // Make a copy and make sure editPoint is a copy (which means it does not
1965 // have a parent network.
1966 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1967 delete m_editPoint;
1968 m_editPoint = NULL;
1969 }
1970 m_editPoint = new ControlPoint;
1971 *m_editPoint = *point;
1972 loadPoint();
1973
1974 // Change point in viewport to red so user can see what point they are
1975 // about to delete.
1976 // the nav tool will update edit point
1977 emit editPointChanged(m_editPoint->GetId());
1978
1979 QnetDeletePointDialog *deletePointDialog = new QnetDeletePointDialog;
1980 QString CPId = m_editPoint->GetId();
1981 deletePointDialog->pointIdValue->setText(CPId);
1982
1983 // Need all files for this point
1984 for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1985 ControlMeasure &m = *(*m_editPoint)[i];
1986 QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
1987 deletePointDialog->fileList->addItem(file);
1988 }
1989
1990 if (deletePointDialog->exec()) {
1991
1992 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1993
1994 // Delete entire control point, either through deleteAllCheckBox or all measures selected
1995 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1996 numDeleted == m_editPoint->GetNumMeasures()) {
1997
1998 // If all measures being deleted, let user know and give them the option to quit operation
1999 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
2000 QString message = "You have selected all measures in this point to be deleted. This "
2001 "control point will be deleted. Do you want to delete this control point?";
2002 int response = QMessageBox::question(m_qnetTool,
2003 "Delete control point", message,
2004 QMessageBox::Yes | QMessageBox::No,
2005 QMessageBox::Yes);
2006 // If No, do nothing
2007 if (response == QMessageBox::No) {
2008 return;
2009 }
2010 }
2011
2012 // First get rid of deleted point from m_filteredPoints list
2013 // need index in control net for pt
2014 //int i = m_controlNet->
2015 //m_filteredPoints.
2016 m_qnetTool->setVisible(false);
2017 // remove this point from the control network
2018 if (m_controlNet->DeletePoint(m_editPoint->GetId()) ==
2020 QMessageBox::information(m_qnetTool, "EditLocked Point",
2021 "This point is EditLocked and cannot be deleted.");
2022 return;
2023 }
2024 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
2025 delete m_editPoint;
2026 m_editPoint = NULL;
2027 }
2028 // emit signal so the nav tool refreshes the list
2029 emit refreshNavList();
2030 }
2031
2032 // Delete specific measures from control point
2033 else {
2034 // Keep track of editLocked measures for reporting
2035 int lockedMeasures = 0;
2036 for (int i=0; i<deletePointDialog->fileList->count(); i++) {
2037 QListWidgetItem *item = deletePointDialog->fileList->item(i);
2038 if (!deletePointDialog->fileList->isItemSelected(item)) continue;
2039
2040 // Do not delete reference without asking user
2041 if (m_editPoint->IsReferenceExplicit() &&
2042 (m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
2043 (*m_editPoint)[i]->GetCubeSerialNumber())) {
2044 QString message = "You are trying to delete the Reference measure."
2045 " Do you really want to delete the Reference measure?";
2046 switch (QMessageBox::question(m_qnetTool,
2047 "Delete Reference measure?", message,
2048 "&Yes", "&No", 0, 0)) {
2049 // Yes: skip to end of switch todelete the measure
2050 case 0:
2051 break;
2052 // No: continue to next measure in the loop
2053 case 1:
2054 // if only a single measure and it's reference and user chooses not to delete,
2055 // simply return. The point has not changed.
2056 if (numDeleted == 1) {
2057 return;
2058 }
2059 continue;
2060 }
2061 }
2062
2063 if (m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
2064 lockedMeasures++;
2065 }
2066 }
2067
2068 if (lockedMeasures > 0) {
2069 QMessageBox::information(m_qnetTool,"EditLocked Measures",
2070 QString::number(lockedMeasures) + " / "
2071 + QString::number(
2072 deletePointDialog->fileList->selectedItems().size()) +
2073 " measures are EditLocked and were not deleted.");
2074 }
2075
2076 loadPoint();
2077 m_qnetTool->setVisible(true);
2078 m_qnetTool->raise();
2079
2080 loadTemplateFile(m_pointEditor->templateFileName());
2081 }
2082
2083 // emit a signal to alert user to save when exiting
2084 emit netChanged();
2085
2086 // emit signal so the nav tool can update edit point
2087 if (m_editPoint != NULL) {
2088 emit editPointChanged(m_editPoint->GetId());
2089 // Change Save Point button text to red
2091 }
2092 else {
2093 // if the entire point is deleted, update with point Id = ""
2094 // this signal is connected to QnetTool::paintAllViewports
2095 // and QnetNavTool::updateEditPoint
2096 emit editPointChanged("");
2097 }
2098 }
2099 }
2100
2101
2102
2112
2113 // If no measures, print info and return
2114 if (point->GetNumMeasures() == 0) {
2115 QString message = "This point has no measures.";
2116 QMessageBox::warning(m_qnetTool, "Warning", message);
2117 // update nav list to re-highlight old point
2118 if (m_editPoint != NULL) {
2119 // emit signal so the nav tool can update edit point
2120 emit editPointChanged(m_editPoint->GetId());
2121 }
2122 else {
2123 // this signal is connected to QnetTool::paintAllViewports
2124 // and QnetNavTool::updateEditPoint
2125 emit editPointChanged("");
2126 }
2127 return;
2128 }
2129 // Make a copy of point for editing, first make sure memory not already
2130 // allocated
2131 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
2132 delete m_editPoint;
2133 m_editPoint = NULL;
2134 }
2135 m_editPoint = new ControlPoint;
2136 *m_editPoint = *point;
2137
2138 // If navTool modfify button pressed, m_leftFile needs to be reset
2139 // TODO: better way - have 2 slots
2140 if (sender() != this) m_leftFile.clear();
2141 loadPoint();
2142 m_qnetTool->setVisible(true);
2143 m_qnetTool->raise();
2144 loadTemplateFile(m_pointEditor->templateFileName());
2145
2146 // emit signal so the nav tool can update edit point
2147 emit editPointChanged(m_editPoint->GetId());
2148
2149 // New point loaded, make sure Save Measure Button text is default
2150 m_savePoint->setPalette(m_saveDefaultPalette);
2151 }
2152
2153
2164 bool located = true;
2165
2166 // Use apriori surface point to find location on ground source. If
2167 // apriori surface point does not exist use reference measure
2168 double lat = 0.;
2169 double lon = 0.;
2170 if (m_editPoint->HasAprioriCoordinates()) {
2171 SurfacePoint sPt = m_editPoint->GetAprioriSurfacePoint();
2172 lat = sPt.GetLatitude().degrees();
2173 lon = sPt.GetLongitude().degrees();
2174 }
2175 else {
2176 ControlMeasure m = *(m_editPoint->GetRefMeasure());
2177 int camIndex = m_serialNumberList->serialNumberIndex(m.GetCubeSerialNumber());
2178 Camera *cam;
2179 cam = m_controlNet->Camera(camIndex);
2180 cam->SetImage(m.GetSample(),m.GetLine());
2181 lat = cam->UniversalLatitude();
2182 lon = cam->UniversalLongitude();
2183 }
2184
2185 // Try to locate point position on current ground source,
2186 // TODO ???if doesn't exist,???
2187 if (!m_groundGmap->SetUniversalGround(lat,lon)) {
2188 located = false;
2189 QString message = "This point does not exist on the ground source.\n";
2190 message += "Latitude = " + QString::number(lat);
2191 message += " Longitude = " + QString::number(lon);
2192 message += "\n A ground measure will not be created.";
2193 QMessageBox::warning(m_qnetTool, "Warning", message);
2194 }
2195
2196 return located;
2197 }
2198
2199
2210
2211 // This measure will be deleted when the ControlPoint is saved to the
2212 // ControlNet.
2213 ControlMeasure *groundMeasure = new ControlMeasure;
2214 groundMeasure->SetCubeSerialNumber(m_groundSN);
2215 groundMeasure->SetType(ControlMeasure::Candidate);
2216 groundMeasure->SetCoordinate(m_groundGmap->Sample(),m_groundGmap->Line());
2217 m_editPoint->Add(groundMeasure);
2218
2219 return groundMeasure;
2220 }
2221
2222
2247
2248 // Write pointId
2249 QString CPId = m_editPoint->GetId();
2250 QString ptId("Point ID: ");
2251 ptId += (QString) CPId;
2252 m_ptIdValue->setText(ptId);
2253
2254 // Write point type
2255// QString ptType("Point Type: ");
2256// ptType += (QString) m_editPoint->GetPointTypeString();
2257// m_pointType->setText(ptType);
2258 m_pointType->setCurrentIndex((int) m_editPoint->GetType());
2259
2260 // Write number of measures
2261 QString ptsize = "Number of Measures: " +
2262 QString::number(m_editPoint->GetNumMeasures());
2263 m_numMeasures->setText(ptsize);
2264
2265 // Set EditLock box correctly
2266 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2267
2268 // Set ignore box correctly
2269 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2270
2271 // Clear combo boxes
2272 m_leftCombo->clear();
2273 m_rightCombo->clear();
2274 m_pointFiles.clear();
2275
2276 // Find in point and delete, it will be re-created with current
2277 // ground source if this is a fixed point
2278 if (m_editPoint->HasSerialNumber(m_groundSN)) {
2279 m_editPoint->Delete(m_groundSN);
2280 }
2281
2282 // If fixed, add ground source file to combos, create a measure for
2283 // the ground source, load reference on left, ground source on right
2284 if (m_groundOpen && (m_editPoint->GetType() != ControlPoint::Free)) {
2285
2286 if (findPointLocation()) {
2287 // Create a temporary measure to hold the ground point info for ground source
2288 // This measure will be deleted when the ControlPoint is saved to the
2289 // ControlNet.
2290 // TODO: Does open ground source match point ground source
2292 }
2293 }
2294
2295 // Load a radius source if there isn't a radius source already open, and there is a ground source
2296 if (m_groundOpen && !m_demOpen) {
2298 }
2299
2300
2301 // Need all files for this point
2302 for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
2303 ControlMeasure &m = *(*m_editPoint)[i];
2304 QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
2305 m_pointFiles<<file;
2306 QString tempFileName = FileName(file).name();
2307 m_leftCombo->addItem(tempFileName);
2308 m_rightCombo->addItem(tempFileName);
2309 if (m_editPoint->IsReferenceExplicit() &&
2310 (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
2311 m_leftCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2312 m_rightCombo->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2313 }
2314 }
2315
2316
2317 // TODO: WHAT HAPPENS IF THERE IS ONLY ONE MEASURE IN THIS CONTROLPOINT??
2318 // Assuming combo loaded in same order as measures in the control point-is
2319 // this a safe assumption???
2320 //
2321 // Find the file from the cubeViewport that was originally used to select
2322 // the point, this will be displayed on the left ChipViewport, unless the
2323 // point was selected on the ground source image. In this case, simply
2324 // load the first measure on the left.
2325 int leftIndex = 0;
2326 int rightIndex = 0;
2327 // Check for reference
2328 if (m_editPoint->IsReferenceExplicit()) {
2329 leftIndex = m_editPoint->IndexOfRefMeasure();
2330 }
2331 else {
2332 if ((m_editPoint->GetType() == ControlPoint::Free) && !m_leftFile.isEmpty()) {
2333 QString baseFileName = FileName(m_leftFile).name();
2334 leftIndex = m_leftCombo->findText(baseFileName);
2335 // Sanity check
2336 if (leftIndex < 0 ) leftIndex = 0;
2337 }
2338 }
2339
2340 // Determine index for right measure.
2341 // First, try to find correct ground. If no correct ground, set right index to either 0 or 1,
2342 // depending on value of the left index.
2343 if (m_groundOpen && (m_editPoint->GetType() != ControlPoint::Free)) {
2344 rightIndex = m_rightCombo->findText((QString)m_groundFile);
2345 }
2346 if (rightIndex <= 0) {
2347 if (leftIndex == 0) {
2348 rightIndex = 1;
2349 }
2350 else {
2351 rightIndex = 0;
2352 }
2353 }
2354
2355 // Handle pts with a single measure, for now simply put measure on left/right
2356 // Evenutally put on left with black on right??
2357 if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
2358 m_rightCombo->setCurrentIndex(rightIndex);
2359 m_leftCombo->setCurrentIndex(leftIndex);
2360 // Initialize pointEditor with measures
2361 selectLeftMeasure(leftIndex);
2362 selectRightMeasure(rightIndex);
2363
2365
2367 }
2368
2369
2370
2371
2372
2381 if (m_measureWindow == NULL) {
2382 m_measureWindow = new QMainWindow();
2383 m_measureTable = new QTableWidget();
2384 m_measureTable->setMinimumWidth(1600);
2385 m_measureTable->setAlternatingRowColors(true);
2386 m_measureWindow->setCentralWidget(m_measureTable);
2387 }
2388 else {
2389 m_measureTable->clear();
2390 m_measureTable->setSortingEnabled(false);
2391 }
2392 m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
2393 m_measureTable->setColumnCount(NUMCOLUMNS);
2394
2395 QStringList labels;
2396 for (int i=0; i<NUMCOLUMNS; i++) {
2397 labels<<measureColumnToString((MeasureColumns)i);
2398 }
2399 m_measureTable->setHorizontalHeaderLabels(labels);
2400
2401 // Fill in values
2402 for (int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2403 int column = 0;
2404 ControlMeasure &m = *(*m_editPoint)[row];
2405
2406 QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
2407 QTableWidgetItem *tableItem = new QTableWidgetItem(QString(file));
2408 m_measureTable->setItem(row,column++,tableItem);
2409
2410 tableItem = new QTableWidgetItem(QString(m.GetCubeSerialNumber()));
2411 m_measureTable->setItem(row,column++,tableItem);
2412
2413 tableItem = new QTableWidgetItem();
2414 tableItem->setData(0,m.GetSample());
2415 m_measureTable->setItem(row,column++,tableItem);
2416
2417 tableItem = new QTableWidgetItem();
2418 tableItem->setData(0,m.GetLine());
2419 m_measureTable->setItem(row,column++,tableItem);
2420
2421 if (m.GetAprioriSample() == Null) {
2422 tableItem = new QTableWidgetItem("Null");
2423 }
2424 else {
2425 tableItem = new QTableWidgetItem();
2426 tableItem->setData(0,m.GetAprioriSample());
2427 }
2428 m_measureTable->setItem(row,column++,tableItem);
2429
2430 if (m.GetAprioriLine() == Null) {
2431 tableItem = new QTableWidgetItem("Null");
2432 }
2433 else {
2434 tableItem = new QTableWidgetItem();
2435 tableItem->setData(0,m.GetAprioriLine());
2436 }
2437 m_measureTable->setItem(row,column++,tableItem);
2438
2439 if (m.GetSampleResidual() == Null) {
2440 tableItem = new QTableWidgetItem(QString("Null"));
2441 }
2442 else {
2443 tableItem = new QTableWidgetItem();
2444 tableItem->setData(0,m.GetSampleResidual());
2445 }
2446 m_measureTable->setItem(row,column++,tableItem);
2447
2448 if (m.GetLineResidual() == Null) {
2449 tableItem = new QTableWidgetItem(QString("Null"));
2450 }
2451 else {
2452 tableItem = new QTableWidgetItem();
2453 tableItem->setData(0,m.GetLineResidual());
2454 }
2455 m_measureTable->setItem(row,column++,tableItem);
2456
2457 if (m.GetResidualMagnitude() == Null) {
2458 tableItem = new QTableWidgetItem(QString("Null"));
2459 }
2460 else {
2461 tableItem = new QTableWidgetItem();
2462 tableItem->setData(0,m.GetResidualMagnitude());
2463 }
2464 m_measureTable->setItem(row,column++,tableItem);
2465
2466 double sampleShift = m.GetSampleShift();
2467 if (sampleShift == Null) {
2468 tableItem = new QTableWidgetItem(QString("Null"));
2469 }
2470 else {
2471 tableItem = new QTableWidgetItem();
2472 tableItem->setData(0,sampleShift);
2473 }
2474 m_measureTable->setItem(row,column++,tableItem);
2475
2476 double lineShift = m.GetLineShift();
2477 if (lineShift == Null) {
2478 tableItem = new QTableWidgetItem(QString("Null"));
2479 }
2480 else {
2481 tableItem = new QTableWidgetItem();
2482 tableItem->setData(0,lineShift);
2483 }
2484 m_measureTable->setItem(row,column++,tableItem);
2485
2486 double pixelShift = m.GetPixelShift();
2487 if (pixelShift == Null) {
2488 tableItem = new QTableWidgetItem(QString("Null"));
2489 }
2490 else {
2491 tableItem = new QTableWidgetItem();
2492 tableItem->setData(0,pixelShift);
2493 }
2494 m_measureTable->setItem(row,column++,tableItem);
2495
2496 double goodnessOfFit = m.GetLogData(
2497 ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
2498 if (goodnessOfFit == Null) {
2499 tableItem = new QTableWidgetItem(QString("Null"));
2500 }
2501 else {
2502 tableItem = new QTableWidgetItem();
2503 tableItem->setData(0,goodnessOfFit);
2504 }
2505 m_measureTable->setItem(row,column++,tableItem);
2506
2507 if (m.IsIgnored()) tableItem = new QTableWidgetItem("True");
2508 if (!m.IsIgnored()) tableItem = new QTableWidgetItem("False");
2509 m_measureTable->setItem(row,column++,tableItem);
2510
2511 if (IsMeasureLocked(m.GetCubeSerialNumber()))
2512 tableItem = new QTableWidgetItem("True");
2513 if (!IsMeasureLocked(m.GetCubeSerialNumber()))
2514 tableItem = new QTableWidgetItem("False");
2515 m_measureTable->setItem(row,column++,tableItem);
2516
2517 tableItem = new QTableWidgetItem(
2519 m_measureTable->setItem(row,column,tableItem);
2520
2521 // If reference measure set font on this row to bold
2522 if (m_editPoint->IsReferenceExplicit() &&
2523 (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
2524 QFont font;
2525 font.setBold(true);
2526
2527 for (int col=0; col<m_measureTable->columnCount(); col++)
2528 m_measureTable->item(row, col)->setFont(font);
2529 }
2530
2531 }
2532
2533 m_measureTable->resizeColumnsToContents();
2534 m_measureTable->resizeRowsToContents();
2535 m_measureTable->setSortingEnabled(true);
2536 m_measureWindow->show();
2537 }
2538
2539
2540
2541 QString QnetTool::measureColumnToString(QnetTool::MeasureColumns column) {
2542 switch (column) {
2543 case FILENAME:
2544 return "FileName";
2545 case CUBESN:
2546 return "Serial #";
2547 case SAMPLE:
2548 return "Sample";
2549 case LINE:
2550 return "Line";
2551 case SAMPLERESIDUAL:
2552 return "Sample Residual";
2553 case LINERESIDUAL:
2554 return "Line Residual";
2555 case RESIDUALMAGNITUDE:
2556 return "Residual Magnitude";
2557 case SAMPLESHIFT:
2558 return "Sample Shift";
2559 case LINESHIFT:
2560 return "Line Shift";
2561 case PIXELSHIFT:
2562 return "Pixel Shift";
2563 case GOODNESSOFFIT:
2564 return "Goodness of Fit";
2565 case IGNORED:
2566 return "Ignored";
2567 case EDITLOCK:
2568 return "Edit Lock";
2569 case TYPE:
2570 return "Measure Type";
2571 case APRIORISAMPLE:
2572 return "Apriori Sample";
2573 case APRIORILINE:
2574 return "Apriori Line";
2575 }
2576 throw IException(IException::Programmer,
2577 "Invalid measure column passed to measureColumnToString", _FILEINFO_);
2578 }
2579
2580
2581 ControlNet *QnetTool::controlNet() {
2582 return m_controlNet;
2583 }
2584
2585
2586 const ControlNet *QnetTool::controlNet() const {
2587 return m_controlNet;
2588 }
2589
2590
2591 SerialNumberList *QnetTool::serialNumberList() {
2592 return m_serialNumberList;
2593 }
2594
2595
2596 const SerialNumberList *QnetTool::serialNumberList() const {
2597 return m_serialNumberList;
2598 }
2599
2600
2601 Workspace *QnetTool::workspace() const {
2602 return m_workspace;
2603 }
2604
2605
2618
2619 QString s;
2620
2621 SurfacePoint aprioriPoint = m_editPoint->GetAprioriSurfacePoint();
2622 if (aprioriPoint.GetLatitude().degrees() == Null) {
2623 s = "Apriori Latitude: Null";
2624 }
2625 else {
2626 s = "Apriori Latitude: " +
2627 QString::number(aprioriPoint.GetLatitude().degrees());
2628 }
2629 m_pointAprioriLatitude->setText(s);
2630 if (aprioriPoint.GetLongitude().degrees() == Null) {
2631 s = "Apriori Longitude: Null";
2632 }
2633 else {
2634 s = "Apriori Longitude: " +
2635 QString::number(aprioriPoint.GetLongitude().degrees());
2636 }
2637 m_pointAprioriLongitude->setText(s);
2638 if (aprioriPoint.GetLocalRadius().meters() == Null) {
2639 s = "Apriori Radius: Null";
2640 }
2641 else {
2642 s = "Apriori Radius: " +
2643 QString::number(aprioriPoint.GetLocalRadius().meters(),'f',2) +
2644 " <meters>";
2645 }
2646 m_pointAprioriRadius->setText(s);
2647
2648 if (aprioriPoint.Valid()) {
2649 if (aprioriPoint.GetLatSigmaDistance().meters() == Null) {
2650 s = "Apriori Latitude Sigma: Null";
2651 }
2652 else {
2653 s = "Apriori Latitude Sigma: " +
2654 QString::number(aprioriPoint.GetLatSigmaDistance().meters()) +
2655 " <meters>";
2656 }
2657 m_pointAprioriLatitudeSigma->setText(s);
2658 if (aprioriPoint.GetLonSigmaDistance().meters() == Null) {
2659 s = "Apriori Longitude Sigma: Null";
2660 }
2661 else {
2662 s = "Apriori Longitude Sigma: " +
2663 QString::number(aprioriPoint.GetLonSigmaDistance().meters()) +
2664 " <meters>";
2665 }
2666 m_pointAprioriLongitudeSigma->setText(s);
2667 if (aprioriPoint.GetLocalRadiusSigma().meters() == Null) {
2668 s = "Apriori Radius Sigma: Null";
2669 }
2670 else {
2671 s = "Apriori Radius Sigma: " +
2672 QString::number(aprioriPoint.GetLocalRadiusSigma().meters()) +
2673 " <meters>";
2674 }
2675 m_pointAprioriRadiusSigma->setText(s);
2676 }
2677 else {
2678 s = "Apriori Latitude Sigma: Null";
2679 m_pointAprioriLatitudeSigma->setText(s);
2680 s = "Apriori Longitude Sigma: Null";
2681 m_pointAprioriLongitudeSigma->setText(s);
2682 s = "Apriori Radius Sigma: Null";
2683 m_pointAprioriRadiusSigma->setText(s);
2684 }
2685
2686
2687 SurfacePoint point = m_editPoint->GetAdjustedSurfacePoint();
2688 if (point.GetLatitude().degrees() == Null) {
2689 s = "Adjusted Latitude: Null";
2690 }
2691 else {
2692 s = "Adjusted Latitude: " + QString::number(point.GetLatitude().degrees());
2693 }
2694 m_pointLatitude->setText(s);
2695 if (point.GetLongitude().degrees() == Null) {
2696 s = "Adjusted Longitude: Null";
2697 }
2698 else {
2699 s = "Adjusted Longitude: " + QString::number(point.GetLongitude().degrees());
2700 }
2701 m_pointLongitude->setText(s);
2702 if (point.GetLocalRadius().meters() == Null) {
2703 s = "Adjusted Radius: Null";
2704 }
2705 else {
2706 s = "Adjusted Radius: " +
2707 QString::number(point.GetLocalRadius().meters(),'f',2) + " <meters>";
2708 }
2709 m_pointRadius->setText(s);
2710
2711
2712
2713 }
2714
2715
2716
2727 int curIndex = m_rightCombo->currentIndex();
2728 if (curIndex < m_rightCombo->count() - 1) {
2729 // update the right measure list index and select that measure
2730 m_rightCombo->setCurrentIndex(curIndex + 1);
2731 selectRightMeasure(curIndex+1);
2732 }
2733 }
2734
2735
2746 int curIndex = m_rightCombo->currentIndex();
2747 if (curIndex > 0) {
2748 // update the right measure list index and select that measure
2749 m_rightCombo->setCurrentIndex(curIndex - 1);
2750 selectRightMeasure(curIndex-1);
2751 }
2752 }
2753
2754
2755
2768 QString file = m_pointFiles[index];
2769
2770 QString serial = m_serialNumberList->serialNumber(file);
2771
2772 // Make sure to clear out leftMeasure before making a copy of the selected
2773 // measure.
2774 if (m_leftMeasure != NULL) {
2775 delete m_leftMeasure;
2776 m_leftMeasure = NULL;
2777 }
2778 m_leftMeasure = new ControlMeasure();
2779 // Find measure for each file
2780 *m_leftMeasure = *((*m_editPoint)[serial]);
2781
2782 // If m_leftCube is not null, delete before creating new one
2783 m_leftCube.reset(new Cube(file, "r"));
2784
2785 // Update left measure of pointEditor
2786 m_pointEditor->setLeftMeasure (m_leftMeasure, m_leftCube.data(),
2787 m_editPoint->GetId());
2789
2790 }
2791
2792
2803 QString file = m_pointFiles[index];
2804
2805 QString serial = m_serialNumberList->serialNumber(file);
2806
2807 // Make sure to clear out rightMeasure before making a copy of the selected
2808 // measure.
2809 if (m_rightMeasure != NULL) {
2810 delete m_rightMeasure;
2811 m_rightMeasure = NULL;
2812 }
2813 m_rightMeasure = new ControlMeasure();
2814 // Find measure for each file
2815 *m_rightMeasure = *((*m_editPoint)[serial]);
2816
2817 // If m_rightCube is not null, delete before creating new one
2818 m_rightCube.reset(new Cube(file, "r"));
2819
2820 // Update right measure of pointEditor
2821 m_pointEditor->setRightMeasure (m_rightMeasure, m_rightCube.data(),
2822 m_editPoint->GetId());
2824
2825 }
2826
2827
2828
2829
2846
2847 // Set editLock measure box correctly
2848 m_lockLeftMeasure->setChecked(IsMeasureLocked(
2849 m_leftMeasure->GetCubeSerialNumber()));
2850 // Set ignore measure box correctly
2851 m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2852
2853 QString s = "Reference: ";
2854 if (m_editPoint->IsReferenceExplicit() &&
2855 (QString(m_leftMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2856 s += "True";
2857 }
2858 else {
2859 s += "False";
2860 }
2861 m_leftReference->setText(s);
2862
2863 s = "Measure Type: ";
2864 if (m_leftMeasure->GetType() == ControlMeasure::Candidate) s+= "Candidate";
2865 if (m_leftMeasure->GetType() == ControlMeasure::Manual) s+= "Manual";
2866 if (m_leftMeasure->GetType() == ControlMeasure::RegisteredPixel) s+= "RegisteredPixel";
2867 if (m_leftMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s+= "RegisteredSubPixel";
2868 m_leftMeasureType->setText(s);
2869
2870 if (m_leftMeasure->GetSampleResidual() == Null) {
2871 s = "Sample Residual: Null";
2872 }
2873 else {
2874 s = "Sample Residual: " + QString::number(m_leftMeasure->GetSampleResidual());
2875 }
2876 m_leftSampError->setText(s);
2877 if (m_leftMeasure->GetLineResidual() == Null) {
2878 s = "Line Residual: Null";
2879 }
2880 else {
2881 s = "Line Residual: " + QString::number(m_leftMeasure->GetLineResidual());
2882 }
2883 m_leftLineError->setText(s);
2884
2885 if (m_leftMeasure->GetSampleShift() == Null) {
2886 s = "Sample Shift: Null";
2887 }
2888 else {
2889 s = "Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2890 }
2891 m_leftSampShift->setText(s);
2892
2893 if (m_leftMeasure->GetLineShift() == Null) {
2894 s = "Line Shift: Null";
2895 }
2896 else {
2897 s = "Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2898 }
2899 m_leftLineShift->setText(s);
2900
2901 double goodnessOfFit = m_leftMeasure->GetLogData(
2902 ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
2903 if (goodnessOfFit == Null) {
2904 s = "Goodness of Fit: Null";
2905 }
2906 else {
2907 s = "Goodness of Fit: " + QString::number(goodnessOfFit);
2908 }
2909 m_leftGoodness->setText(s);
2910
2911 }
2912
2913
2914
2934
2935 // Set editLock measure box correctly
2936 m_lockRightMeasure->setChecked(IsMeasureLocked(
2937 m_rightMeasure->GetCubeSerialNumber()));
2938 // Set ignore measure box correctly
2939 m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2940
2941 QString s = "Reference: ";
2942 if (m_editPoint->IsReferenceExplicit() &&
2943 (QString(m_rightMeasure->GetCubeSerialNumber()) == m_editPoint->GetReferenceSN())) {
2944 s += "True";
2945 }
2946 else {
2947 s += "False";
2948 }
2949
2950 m_rightReference->setText(s);
2951
2952 s = "Measure Type: ";
2953 if (m_rightMeasure->GetType() == ControlMeasure::Candidate) s+= "Candidate";
2954 if (m_rightMeasure->GetType() == ControlMeasure::Manual) s+= "Manual";
2955 if (m_rightMeasure->GetType() == ControlMeasure::RegisteredPixel) s+= "RegisteredPixel";
2956 if (m_rightMeasure->GetType() == ControlMeasure::RegisteredSubPixel) s+= "RegisteredSubPixel";
2957 m_rightMeasureType->setText(s);
2958
2959 if (m_rightMeasure->GetSampleResidual() == Null) {
2960 s = "Sample Residual: Null";
2961 }
2962 else {
2963 s = "Sample Residual: " + QString::number(m_rightMeasure->GetSampleResidual());
2964 }
2965 m_rightSampError->setText(s);
2966 if (m_rightMeasure->GetLineResidual() == Null) {
2967 s = "Line Residual: Null";
2968 }
2969 else {
2970 s = "Line Residual: " + QString::number(m_rightMeasure->GetLineResidual());
2971 }
2972 m_rightLineError->setText(s);
2973
2974 if (m_rightMeasure->GetSampleShift() == Null) {
2975 s = "Sample Shift: Null";
2976 }
2977 else {
2978 s = "Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2979 }
2980 m_rightSampShift->setText(s);
2981
2982 if (m_rightMeasure->GetLineShift() == Null) {
2983 s = "Line Shift: Null";
2984 }
2985 else {
2986 s = "Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2987 }
2988 m_rightLineShift->setText(s);
2989
2990 double goodnessOfFit = m_rightMeasure->GetLogData(
2991 ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
2992 if (goodnessOfFit == Null) {
2993 s = "Goodness of Fit: Null";
2994 }
2995 else {
2996 s = "Goodness of Fit: " + QString::number(goodnessOfFit);
2997 }
2998 m_rightGoodness->setText(s);
2999
3000 }
3001
3002
3018
3019 // Create list of list box of all files highlighting those that
3020 // contain the point, but that do not already have a measure.
3021 QStringList pointFiles;
3022
3023 // Initialize camera for all images in control network,
3024 // TODO:: Needs to be moved to QnetFileTool.cpp
3025 Camera *cam;
3026
3027 // Use lat/lon of first measure
3028 double lat;
3029 double lon;
3030
3031 ControlMeasure m = *(m_editPoint->GetRefMeasure());
3032 int camIndex = m_serialNumberList->serialNumberIndex(m.GetCubeSerialNumber());
3033 cam = m_controlNet->Camera(camIndex);
3034 //cam = m.Camera();
3035 cam->SetImage(m.GetSample(),m.GetLine());
3036 lat = cam->UniversalLatitude();
3037 lon = cam->UniversalLongitude();
3038
3039 for (int i=0; i<m_serialNumberList->size(); i++) {
3040 cam = m_controlNet->Camera(i);
3041 if (m_serialNumberList->serialNumber(i) == m_groundSN) continue;
3042 if (cam->SetUniversalGround(lat,lon)) {
3043 // Make sure point is within image boundary
3044 double samp = cam->Sample();
3045 double line = cam->Line();
3046 if (samp >= 1 && samp <= cam->Samples() &&
3047 line >= 1 && line <= cam->Lines()) {
3048 pointFiles<<m_serialNumberList->fileName(i);
3049 }
3050 }
3051 }
3052
3053 QnetNewMeasureDialog *newMeasureDialog = new QnetNewMeasureDialog(this);
3054 newMeasureDialog->setFiles(*m_editPoint,pointFiles);
3055 if (newMeasureDialog->exec()) {
3056 QStringList selectedFiles = newMeasureDialog->selectedFiles();
3057 foreach (QString selectedFile, selectedFiles) {
3058 // Create measure for any file selected
3060 // Find serial number for this file
3061 QString sn = m_serialNumberList->serialNumber(selectedFile);
3062 m->SetCubeSerialNumber(sn);
3063 int camIndex =
3064 m_serialNumberList->fileNameIndex(selectedFile);
3065 cam = m_controlNet->Camera(camIndex);
3066 cam->SetUniversalGround(lat,lon);
3067 m->SetCoordinate(cam->Sample(),cam->Line());
3068 m->SetAprioriSample(cam->Sample());
3069 m->SetAprioriLine(cam->Line());
3070 m->SetType(ControlMeasure::Manual);
3071 m->SetChooserName(Application::UserName());
3072 m_editPoint->Add(m);
3073 }
3074 loadPoint();
3075 m_qnetTool->setVisible(true);
3076 m_qnetTool->raise();
3077
3079 m_pointEditor->templateFileName());
3080
3081
3082 // emit signal so the nav tool can update edit point
3083 emit editPointChanged(m_editPoint->GetId());
3085 }
3086 }
3087
3088
3099 bool QnetTool::eventFilter(QObject *o, QEvent *e) {
3100 if(e->type() != QEvent::Leave) return false;
3101 if(o == m_leftCombo->view()) {
3103 m_leftCombo->hidePopup();
3104 }
3105 if (o == m_rightCombo->view()) {
3107 m_rightCombo->hidePopup();
3108 }
3109 return true;
3110 }
3111
3112
3120 void QnetTool::paintViewport(MdiCubeViewport *vp, QPainter *painter) {
3121 drawAllMeasurments (vp,painter);
3122
3123 }
3124
3125
3139 void QnetTool::paintAllViewports(QString pointId) {
3140
3141 // Take care of drawing things on all viewPorts.
3142 // Calling update will cause the Tool class to call all registered tools
3143 // if point has been deleted, this will remove it from the main window
3144 MdiCubeViewport *vp;
3145 for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3146 vp = (*(cubeViewportList()))[i];
3147 vp->viewport()->update();
3148 }
3149 }
3150
3173 void QnetTool::drawAllMeasurments(MdiCubeViewport *vp, QPainter *painter) {
3174 // Without a controlnetwork there are no points, or if new net, no points
3175 if (m_controlNet == 0 || m_controlNet->GetNumPoints() == 0) return;
3176
3177 // Don't show the measurments on cubes not in the serial number list
3178 // TODO: Should we show them anyway
3179 // TODO: Should we add the SN to the viewPort
3180 QString serialNumber = SerialNumber::Compose(*vp->cube(), true);
3181
3182 if (serialNumber == m_groundSN) {
3183 drawGroundMeasures(vp, painter);
3184 return;
3185 }
3186 if (!m_controlNet->GetCubeSerials().contains(
3187 serialNumber)) return;
3188 if (!m_serialNumberList->hasSerialNumber(serialNumber)) return;
3189 QList<ControlMeasure *> measures =
3190 m_controlNet->GetMeasuresInCube(serialNumber);
3191 // loop through all measures contained in this cube
3192 for (int i = 0; i < measures.count(); i++) {
3193 ControlMeasure *m = measures[i];
3194 // Find the measurments on the viewport
3195 double samp = m->GetSample();
3196 double line = m->GetLine();
3197 int x, y;
3198 vp->cubeToViewport(samp, line, x, y);
3199 // if the point is ignored,
3200 if (m->Parent()->IsIgnored()) {
3201 painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3202 }
3203 // point is not ignored, but measure matching this image is ignored,
3204 else if (m->IsIgnored()) {
3205 painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3206 }
3207 // Neither point nor measure is not ignored and the measure is fixed,
3208 else if (m->Parent()->GetType() != ControlPoint::Free) {
3209 painter->setPen(Qt::magenta);// set point marker magenta
3210 }
3211 else {
3212 painter->setPen(Qt::green); // set all other point markers green
3213 }
3214 // draw points
3215 painter->drawLine(x - 5, y, x + 5, y);
3216 painter->drawLine(x, y - 5, x, y + 5);
3217 }
3218 // if QnetTool is open,
3219 if (m_editPoint != NULL) {
3220 // and the selected point is in the image,
3221 if (m_editPoint->HasSerialNumber(serialNumber)) {
3222 // find the measurement
3223 double samp = (*m_editPoint)[serialNumber]->GetSample();
3224 double line = (*m_editPoint)[serialNumber]->GetLine();
3225 int x, y;
3226 vp->cubeToViewport(samp, line, x, y);
3227 // set point marker red
3228 QBrush brush(Qt::red);
3229 // set point marker bold - line width 2
3230 QPen pen(brush, 2);
3231 // draw the selected point in each image last so it's on top of the rest of the points
3232 painter->setPen(pen);
3233 painter->drawLine(x - 5, y, x + 5, y);
3234 painter->drawLine(x, y - 5, x, y + 5);
3235 }
3236 }
3237 }
3238
3239
3240
3241
3251 void QnetTool::drawGroundMeasures(MdiCubeViewport *vp, QPainter *painter) {
3252
3253 // loop through control network looking for fixed and constrained points
3254 for (int i = 0; i < m_controlNet->GetNumPoints(); i++) {
3255 ControlPoint &p = *((*m_controlNet)[i]);
3256 if (p.GetType() == ControlPoint::Free) continue;
3257 if (!p.HasAprioriCoordinates()) continue;
3258
3259 // Find the measure on the ground image
3260 if (m_groundGmap->SetGround(p.GetAprioriSurfacePoint().GetLatitude(),
3261 p.GetAprioriSurfacePoint().GetLongitude())) {
3262 double samp = m_groundGmap->Sample();
3263 double line = m_groundGmap->Line();
3264 int x, y;
3265 vp->cubeToViewport(samp, line, x, y);
3266 // if the point is ignored,
3267 if (p.IsIgnored()) {
3268 painter->setPen(QColor(255, 255, 0)); // set point marker yellow
3269 }
3270 else if (p.GetType() != ControlPoint::Free) {
3271 painter->setPen(Qt::magenta);// set point marker magenta
3272 }
3273 else if (&p == m_editPoint) {
3274 // set point marker red
3275 QBrush brush(Qt::red);
3276 // set point marker bold - line width 2
3277 QPen pen(brush, 2);
3278 }
3279 else {
3280 painter->setPen(Qt::green); // set all other point markers green
3281 }
3282 // draw points
3283 painter->drawLine(x - 5, y, x + 5, y);
3284 painter->drawLine(x, y - 5, x, y + 5);
3285 }
3286 }
3287 }
3288
3289
3290
3304
3305 if (m_templateModified) {
3306 int r = QMessageBox::warning(m_qnetTool, tr("OK to continue?"),
3307 tr("The currently opened registration template has been modified.\n"
3308 "Save changes?"),
3309 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
3310 QMessageBox::Yes);
3311
3312 if (r == QMessageBox::Yes)
3314 else if (r == QMessageBox::Cancel)
3315 return false;
3316 }
3317
3318 return true;
3319 }
3320
3321
3328
3329 if (!okToContinue())
3330 return;
3331
3332 QString filename = QFileDialog::getOpenFileName(m_qnetTool,
3333 "Select a registration template", ".",
3334 "Registration template files (*.def *.pvl);;All files (*)");
3335
3336 if (filename.isEmpty())
3337 return;
3338
3339 if (m_pointEditor->setTemplateFile(filename)) {
3340 loadTemplateFile(filename);
3341 }
3342 }
3343
3344
3351
3352 QFile file(FileName(fn).expanded());
3353 if (!file.open(QIODevice::ReadOnly)) {
3354 QString msg = "Failed to open template file \"" + fn + "\"";
3355 QMessageBox::warning(m_qnetTool, "IO Error", msg);
3356 return;
3357 }
3358
3359 QTextStream stream(&file);
3360 m_templateEditor->setText(stream.readAll());
3361 file.close();
3362
3363 QScrollBar * sb = m_templateEditor->verticalScrollBar();
3364 sb->setValue(sb->minimum());
3365
3366 m_templateModified = false;
3367 m_saveTemplateFile->setEnabled(false);
3368 m_templateFileNameLabel->setText("Template File: " + fn);
3369 }
3370
3371
3374 m_templateModified = true;
3375 m_saveTemplateFile->setEnabled(true);
3376 }
3377
3378
3381
3382 if (!m_templateModified)
3383 return;
3384
3385 QString filename = m_pointEditor->templateFileName();
3386
3387 writeTemplateFile(filename);
3388 }
3389
3390
3393
3394 QString filename = QFileDialog::getSaveFileName(m_qnetTool,
3395 "Save registration template", ".",
3396 "Registration template files (*.def *.pvl);;All files (*)");
3397
3398 if (filename.isEmpty())
3399 return;
3400
3401 writeTemplateFile(filename);
3402 }
3403
3404
3411
3412 QString contents = m_templateEditor->toPlainText();
3413
3414 // catch errors in Pvl format when populating pvl object
3415 stringstream ss;
3416 ss << contents;
3417 try {
3418 Pvl pvl;
3419 ss >> pvl;
3420 }
3421 catch(IException &e) {
3422 QString message = e.toString();
3423 QMessageBox::warning(m_qnetTool, "Error", message);
3424 return;
3425 }
3426
3427 QString expandedFileName(FileName(fn).expanded());
3428
3429 QFile file(expandedFileName);
3430
3431 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
3432 QString msg = "Failed to save template file to \"" + fn + "\"\nDo you "
3433 "have permission?";
3434 QMessageBox::warning(m_qnetTool, "IO Error", msg);
3435 return;
3436 }
3437
3438 // now save contents
3439 QTextStream stream(&file);
3440 stream << contents;
3441 file.close();
3442
3443 if (m_pointEditor->setTemplateFile(fn)) {
3444 m_templateModified = false;
3445 m_saveTemplateFile->setEnabled(false);
3446 m_templateFileNameLabel->setText("Template File: " + fn);
3447 }
3448 }
3449
3450
3465 try{
3466 // Get the template file from the ControlPointEditor object
3467 Pvl templatePvl(m_pointEditor->templateFileName());
3468 // Create registration dialog window using PvlEditDialog class
3469 // to view and/or edit the template
3470 PvlEditDialog registrationDialog(templatePvl);
3471 registrationDialog.setWindowTitle("View or Edit Template File: "
3472 + templatePvl.fileName());
3473 registrationDialog.resize(550,360);
3474 registrationDialog.exec();
3475 }
3476 catch (IException &e) {
3477 QString message = e.toString();
3478 QMessageBox::information(m_qnetTool, "Error", message);
3479 }
3480 }
3481
3482
3483
3491 m_pointEditor->saveChips();
3492 }
3493
3494
3495 void QnetTool::showHideTemplateEditor() {
3496
3497 if (!m_templateEditorWidget)
3498 return;
3499
3500 m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
3501 }
3502
3503
3504
3517 void QnetTool::updatePointInfo(QString pointId) {
3518 if (m_editPoint == NULL) return;
3519 if (pointId != m_editPoint->GetId()) return;
3520 // The edit point has been changed by SetApriori, so m_editPoint needs
3521 // to possibly update some values. Need to retain measures from m_editPoint
3522 // because they might have been updated, but not yet saved to the network
3523 // ("Save Point").
3524 ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
3525 m_editPoint->SetEditLock(updatedPoint->IsEditLocked());
3526 m_editPoint->SetIgnored(updatedPoint->IsIgnored());
3527 m_editPoint->SetAprioriSurfacePoint(updatedPoint->GetAprioriSurfacePoint());
3528
3529 // Set EditLock box correctly
3530 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
3531
3532 // Set ignore box correctly
3533 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
3534
3536
3537 }
3538
3539
3540
3541
3558
3559
3560 // Check point being edited, make sure it still exists, if not ???
3561 // Update ignored checkbox??
3562 if (m_editPoint != NULL) {
3563 try {
3564 QString id = m_ptIdValue->text().remove("Point ID: ");
3565 m_controlNet->GetPoint(id);
3566 }
3567 catch (IException &) {
3568 delete m_editPoint;
3569 m_editPoint = NULL;
3570 emit editPointChanged("");
3571 m_qnetTool->setVisible(false);
3572 m_measureWindow->setVisible(false);
3573 }
3574 }
3575
3576 if (m_editPoint == NULL) {
3578 }
3579 else {
3580 paintAllViewports(m_editPoint->GetId());
3581 }
3582 }
3583
3584
3592 void QnetTool::showNavWindow(bool checked){
3593 emit showNavTool();
3594 }
3595
3609 QWidget *QnetTool::createToolBarWidget (QStackedWidget *parent) {
3610 QWidget *hbox = new QWidget(parent);
3611
3612 QToolButton *showNavToolButton = new QToolButton();
3613 showNavToolButton->setText("Show Nav Tool");
3614 showNavToolButton->setToolTip("Shows the Navigation Tool Window");
3615 QString text =
3616 "<b>Function:</b> This button will bring up the Navigation Tool window that allows \
3617 the user to view, modify, ignore, delete, or filter points and cubes.";
3618 showNavToolButton->setWhatsThis(text);
3619 connect(showNavToolButton,SIGNAL(clicked(bool)),this,SLOT(showNavWindow(bool)));
3620
3621 QHBoxLayout *layout = new QHBoxLayout(hbox);
3622 layout->setMargin(0);
3623 layout->addWidget(showNavToolButton);
3624 layout->addStretch(1);
3625 hbox->setLayout(layout);
3626 return hbox;
3627 }
3628
3629
3630
3631
3651
3652 QString filter = "Isis cubes (*.cub *.cub.*);;";
3653 filter += "Detached labels (*.lbl);;";
3654 filter += "All (*)";
3655
3656 QString ground = QFileDialog::getOpenFileName((QWidget*)parent(),
3657 "Open ground source",
3658 ".",
3659 filter);
3660 if (ground.isEmpty()) return;
3661
3662 // First off, find serial number of new ground, it is needed for a couple of error checks.
3663 QString newGroundSN = SerialNumber::Compose(ground, true);
3664
3665 // If new ground same file as old ground file simply set as active window.
3666 if (m_groundOpen && m_groundFile == FileName(ground).name()) {
3667 // See if ground source is already opened in a cubeviewport. If so, simply
3668 // activate the viewport and return.
3669 MdiCubeViewport *vp;
3670 for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3671 vp = (*(cubeViewportList()))[i];
3672 if (vp->cube()->fileName() == ground) {
3673 m_workspace->mdiArea()->setActiveSubWindow(
3674 (QMdiSubWindow *)vp->parentWidget()->parent());
3675 return;
3676 }
3677 }
3678 }
3679
3680 // Make sure there are not serial number conflicts. If there are serial number conflicts,
3681 // simply return, retaining current ground source.
3682 if (newGroundSN != m_groundSN && m_serialNumberList->hasSerialNumber(newGroundSN)) {
3683 // TODO If it already exists, are the files different? Now what?
3684 // For now, do not allow.
3685 QString message = "A cube in the cube list has the same serial number as this ground file. ";
3686 message += "If this ground source is a level 1, un-projected cube, it is probably included ";
3687 message += "in the cube list. If the ground source is a projected version of a cube in ";
3688 message += "the list and has the Instrument Group in the labels, the un-projected and ";
3689 message += "projected cube will have the same serial number. \n";
3690 message += "Because of duplicate serial numbers this cube cannot be used as a ground ";
3691 message += "source.\n\n";
3692 message += "NOTE: If this cube is the reference cube you can select points in ";
3693 message += "the Navigator window, then select the Set Apriori button to use this cube to ";
3694 message += "set the apriori latitude, longitude and radius.";
3695 QMessageBox::critical(m_qnetTool, "Cannot set ground source", message);
3696 return;
3697 }
3698
3699 // So far, so good. If previous ground, clear out ground source info.
3700 if (m_groundOpen) {
3701 // ....otherwise if new ground source, close old. We only want a single
3702 // ground source opened at once. Delete old ground source from left/right
3703 // combo if it's there, and delete from serial number list.
3704 clearGroundSource ();
3705 }
3706
3707 QApplication::setOverrideCursor(Qt::WaitCursor);
3708
3709 // Create new ground cube, if failure, there will be not ground source, clear all ground
3710 // source data. (Cannot call clearGroundSource because it assumes a ground was successfully
3711 // loaded)
3712 m_groundCube.reset(NULL);
3713 m_groundGmap.reset(NULL);
3714
3715 try {
3716 QScopedPointer<Cube> newGroundCube(new Cube(ground, "r"));
3717 QScopedPointer<UniversalGroundMap> newGroundGmap(new UniversalGroundMap(*newGroundCube));
3718
3719 m_groundFile = FileName(newGroundCube->fileName()).name();
3720 m_groundCube.reset(newGroundCube.take());
3721 m_groundGmap.reset(newGroundGmap.take());
3722
3723 m_serialNumberList->add(ground, true);
3724 }
3725 catch (IException &e) {
3726 QApplication::restoreOverrideCursor();
3727 QMessageBox::critical(m_qnetTool, "Error", e.toString());
3728
3729 m_groundFile.clear();
3730
3731 // Re-load point w/o ground source
3732 if (m_editPoint) {
3733 loadPoint();
3734 }
3735
3736 emit refreshNavList();
3737 return;
3738 }
3739
3740 m_groundSN = newGroundSN;
3741 m_groundSourceFile = ground;
3742 m_groundOpen = true;
3743
3744 m_workspace->addCubeViewport(m_groundCube.data());
3745
3746 // Get viewport so connect can be made when ground source viewport closed to clean up
3747 // ground source
3748 MdiCubeViewport *vp;
3749 for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3750 vp = (*(cubeViewportList()))[i];
3751 if (vp->cube()->fileName() == ground) {
3752 connect(vp, SIGNAL(viewportClosed(CubeViewport *)),
3753 this, SLOT(groundViewportClosed(CubeViewport *)), Qt::UniqueConnection);
3754 }
3755 }
3756
3757 if (!m_demOpen) {
3758 // If there isn't a radius source already open and there is a point selected
3759 if (m_editPoint != NULL) {
3761 }
3762
3763 // Determine file type of ground for setting AprioriSurfacePointSource
3764 // and AprioriRadiusSource.
3765 else if (m_groundCube->hasTable("ShapeModelStatistics")) {
3766 m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
3767 if (!m_demOpen) {
3768 m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3769 m_radiusSourceFile = ground;
3770 }
3771 }
3772 // Is this a level 1 or level 2?
3773 else {
3774 try {
3775 ProjectionFactory::CreateFromCube(*m_groundCube);
3776 m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Basemap;
3777 if (!m_demOpen) {
3778 m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3779 m_radiusSourceFile = "";
3780 }
3781 }
3782 catch (IException &) {
3783 try {
3784 CameraFactory::Create(*m_groundCube);
3785 m_groundSurfacePointSource = ControlPoint::SurfacePointSource::Reference;
3786 if (!m_demOpen) {
3787 PvlGroup kernels = m_groundCube->group("Kernels");
3788 QString shapeFile = kernels ["ShapeModel"];
3789 if (shapeFile.contains("dem")) {
3790 m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3791 m_radiusSourceFile = shapeFile;
3792 }
3793 else {
3794 m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3795 // Find pck file from Kernels group
3796 m_radiusSourceFile = (QString) kernels["TargetAttitudeShape"];
3797 }
3798 }
3799 }
3800 catch (IException &) {
3801 QString message = "Cannot create either Camera or Projections ";
3802 message += "for the ground source file. Check the validity of the ";
3803 message += " cube labels. The cube must either be projected or ";
3804 message += " run through spiceinit.";
3805 QMessageBox::critical(m_qnetTool, "Error", message);
3806 // Clear out everything relating to ground source
3807 clearGroundSource ();
3808 QApplication::restoreOverrideCursor();
3809 emit refreshNavList();
3810 return;
3811 }
3812 }
3813 }
3814 }
3815
3816 if (m_editPoint != NULL &&
3817 (m_editPoint->GetType() != ControlPoint::Free)) loadPoint();
3818
3819
3820 emit refreshNavList();
3821 QApplication::restoreOverrideCursor();
3822 }
3823
3824
3833
3834 if (m_groundFile.isEmpty()) {
3835 QString message = "You must enter a ground source before opening a Dem.";
3836 QMessageBox::critical(m_qnetTool, "Error", message);
3837 return;
3838 }
3839
3840 QString filter = "Isis cubes (*.cub *.cub.*);;";
3841 filter += "Detached labels (*.lbl);;";
3842 filter += "All (*)";
3843 QString dem = QFileDialog::getOpenFileName((QWidget*)parent(),
3844 "Open DEM",
3845 ".",
3846 filter);
3847 if (dem.isEmpty()) return;
3848
3849 initDem(dem);
3850
3851 }
3852
3861 //Get the reference image's shape model
3862 QString referenceSN = m_editPoint->GetReferenceSN();
3863 QString referenceFileName = m_serialNumberList->fileName(referenceSN);
3864 QScopedPointer<Cube> referenceCube(new Cube(referenceFileName, "r"));
3865 PvlGroup kernels = referenceCube->group("Kernels");
3866 QString shapeFile = kernels["ShapeModel"];
3867
3868 // If the reference measure has a shape model cube then set that as the radius
3869 // This will NOT WORK for shape model files (not the default of Null or Ellipsoid)
3870 // that are not cubes
3871 if (shapeFile.contains(".cub")) {
3872 if (shapeFile.contains("dem")) {
3873 m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3874 }
3875 else {
3876 m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3877 }
3878
3879 m_radiusSourceFile = shapeFile;
3880
3881 // Open shape file for reading radius later
3882 initDem(shapeFile); //This will write the labels for us
3883 }
3884
3885 // If no shape model then use the ABC of the target body
3886 else {
3887 m_groundRadiusSource = ControlPoint::RadiusSource::Ellipsoid;
3888 Spice *refSpice = new Spice(*referenceCube);
3889 Distance refRadii[3];
3890 refSpice->radii(refRadii);
3891 m_demFile = QString::number(refRadii[0].meters()) + ", " +
3892 QString::number(refRadii[1].meters()) + ", " +
3893 QString::number(refRadii[2].meters());
3894
3895 m_radiusSourceFile = "";
3896
3897 // Write out the labels
3898 m_groundFileNameLabel->setText("Ground Source File: " + m_groundFile);
3899 m_radiusFileNameLabel->setText("Radius Source: " + m_demFile);
3900 }
3901 }
3902
3903 void QnetTool::initDem (QString demFile) {
3904
3905 // If a DEM is already opened, check if new is same as old. If new,
3906 // close old, open new.
3907 QApplication::setOverrideCursor(Qt::WaitCursor);
3908 if (m_demOpen) {
3909 if (m_demFile == demFile) {
3910 QApplication::restoreOverrideCursor();
3911 return;
3912 }
3913
3914 m_demCube.reset(NULL);
3915 m_demFile.clear();
3916 }
3917
3918 try {
3919 QScopedPointer<Cube> newDemCube(new Cube(demFile, "r"));
3920
3921 m_demFile = FileName(newDemCube->fileName()).name();
3922 m_demCube.reset(newDemCube.take());
3923 }
3924 catch (IException &e) {
3925 QMessageBox::critical(m_qnetTool, "Error", e.toString());
3926 QApplication::restoreOverrideCursor();
3927 return;
3928 }
3929 m_demOpen = true;
3930
3931 // Make sure this is a dem
3932 if (!m_demCube->hasTable("ShapeModelStatistics")) {
3933 QString message = m_demFile + " is not a DEM.";
3934 QMessageBox::critical(m_qnetTool, "Error", message);
3935 m_demCube.reset(NULL);
3936 m_demOpen = false;
3937 m_demFile.clear();
3938 QApplication::restoreOverrideCursor();
3939 return;
3940 }
3941 m_groundRadiusSource = ControlPoint::RadiusSource::DEM;
3942 m_groundFileNameLabel->setText("Ground Source File: " + m_groundFile);
3943 m_radiusFileNameLabel->setText("Radius Source File: " + m_demFile);
3944 m_radiusSourceFile = demFile;
3945
3946 QApplication::restoreOverrideCursor();
3947 }
3948
3949
3950
3958
3959 // Only continue to clearGroundSource if the viewport is not already closed
3960 // Otherwise, it could be called twice
3961 clearGroundSource();
3962 }
3963
3964
3965
3966 void QnetTool::clearGroundSource () {
3967
3968 m_leftCombo->removeItem(m_leftCombo->findText(m_groundFile));
3969 m_rightCombo->removeItem(m_rightCombo->findText(m_groundFile));
3970
3971 // Close viewport containing ground source
3972 MdiCubeViewport *vp;
3973 for (int i=0; i<(int)cubeViewportList()->size(); i++) {
3974 vp = (*(cubeViewportList()))[i];
3975 if (vp->cube() == m_groundCube.data()) {
3976 // disconnect signal to avoid recursive situartion. When a viewport is closed, a signal
3977 // is emitted which would then call groundViewportClosed, then this method again.
3978 disconnect(vp, SIGNAL(viewportClosed(CubeViewport *)),
3979 this, SLOT(groundViewportClosed(CubeViewport *)));
3980 vp->parentWidget()->parentWidget()->close();
3981 QApplication::processEvents();
3982 break;
3983 }
3984 }
3985 // If we could not find the ground source in the open viewports, user might
3986 // have closed the viewport , reset ground source variables and re-open.
3987 m_groundOpen = false;
3988 m_groundCube.take();
3989 m_groundFile.clear();
3990 m_groundGmap.reset(NULL);
3991
3992 m_groundFileNameLabel->setText("Ground Source File: ");
3993 if (!m_demOpen) {
3994 m_radiusFileNameLabel->setText("Radius Source File: " + m_demFile);
3995 }
3996
3997 // Remove from serial number list
3998 m_serialNumberList->remove(m_groundSN);
3999
4000 // If the loaded point is a fixed point, see if there is a temporary measure
4001 // holding the coordinate information for the currentground source. If so,
4002 // delete this measure and re-load point
4003 if (m_editPoint && m_editPoint->GetType() != ControlPoint::Free &&
4004 m_editPoint->HasSerialNumber(m_groundSN)) {
4005 m_editPoint->Delete(m_groundSN);
4006 m_groundSN = "";
4007 loadPoint();
4008 }
4009 else {
4010 m_groundSN = "";
4011 }
4012 }
4013
4014
4015
4016
4017
4025 double QnetTool::demRadius(double latitude, double longitude) {
4026
4027 if (!m_demOpen) return Null;
4028
4029 UniversalGroundMap *demMap = new UniversalGroundMap(*m_demCube);
4030 if (!demMap->SetUniversalGround(latitude, longitude)) {
4031 delete demMap;
4032 demMap = NULL;
4033 return Null;
4034 }
4035
4036 // Use bilinear interpolation to read radius from DEM
4037 // Use bilinear interpolation from dem
4038 Interpolator *interp = new Interpolator(Interpolator::BiLinearType);
4039
4040 // Buffer used to read from the model
4041 Portal *portal = new Portal(interp->Samples(), interp->Lines(),
4042 m_demCube->pixelType(),
4043 interp->HotSample(), interp->HotLine());
4044 portal->SetPosition(demMap->Sample(), demMap->Line(), 1);
4045 m_demCube->read(*portal);
4046 double radius = interp->Interpolate(demMap->Sample(), demMap->Line(),
4047 portal->DoubleBuffer());
4048 delete demMap;
4049 demMap = NULL;
4050 delete interp;
4051 interp = NULL;
4052 delete portal;
4053 portal = NULL;
4054
4055// cout.width(15);
4056// cout.precision(4);
4057// cout<<"DEM Radius = "<<fixed<<radius<<endl;
4058 return radius;
4059 }
4060
4061
4062
4069
4070 QColor qc = Qt::red;
4071 QPalette p = m_savePoint->palette();
4072 p.setColor(QPalette::ButtonText,qc);
4073 m_savePoint->setPalette(p);
4074
4075 }
4076
4077
4078
4091 bool QnetTool::IsMeasureLocked (QString serialNumber) {
4092
4093 if (m_editPoint == NULL) return false;
4094
4095 // Reference implicitly editLocked
4096 if (m_editPoint->IsEditLocked() && m_editPoint->IsReferenceExplicit() &&
4097 (m_editPoint->GetReferenceSN() == serialNumber)) {
4098 return true;
4099 }
4100 // Return measures explicit editLocked value
4101 else {
4102 return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
4103 }
4104
4105 }
4106
4107
4108
4115 FileName config("$HOME/.Isis/qnet/QnetTool.config");
4116 QSettings settings(config.expanded(), QSettings::NativeFormat);
4117 QPoint pos = settings.value("pos", QPoint(300, 100)).toPoint();
4118 QSize size = settings.value("size", QSize(900, 500)).toSize();
4119 m_qnetTool->resize(size);
4120 m_qnetTool->move(pos);
4121 }
4122
4123
4131 /*We do not want to write the settings unless the window is
4132 visible at the time of closing the application*/
4133 if(!m_qnetTool->isVisible()) return;
4134 FileName config("$HOME/.Isis/qnet/QnetTool.config");
4135 QSettings settings(config.expanded(), QSettings::NativeFormat);
4136 settings.setValue("pos", m_qnetTool->pos());
4137 settings.setValue("size", m_qnetTool->size());
4138 }
4139
4140
4141
4142 void QnetTool::enterWhatsThisMode() {
4143 QWhatsThis::enterWhatsThisMode();
4144 }
4145
4146
4147}
double degrees() const
Get the angle in units of Degrees.
Definition Angle.h:232
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition Angle.h:56
static QString UserName()
Returns the user name.
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
a control measurement
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
static QString MeasureTypeToString(MeasureType type)
Return the String Control Measure type.
@ Manual
Hand Measured (e.g., qnet)
@ Candidate
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
@ RegisteredSubPixel
Registered to sub-pixel (e.g., pointreg)
@ RegisteredPixel
Registered to whole pixel (e.g.,pointreg)
@ GoodnessOfFit
GoodnessOfFit is pointreg information for reference measures.
a control network
Definition ControlNet.h:258
Point Editor Widget.
A single control point.
Status
This is a return status for many of the mutating (setter) method calls.
@ PointLocked
This is returned when the operation requires Edit Lock to be false but it is currently true.
Status SetChooserName(QString name)
Set the point's chooser name.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
PointType GetType() const
PointType
These are the valid 'types' of point.
@ Constrained
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
@ Free
A Free point is a Control Point that identifies common measurements between two or more cubes.
@ Fixed
A Fixed point is a Control Point whose lat/lon is well established and should not be changed.
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
QString GetId() const
Return the Id of the control point.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
IO Handler for Isis Cubes.
Definition Cube.h:168
Widget to display Isis cubes for qt apps.
Distance measurement, usually in meters.
Definition Distance.h:34
@ Meters
The distance is being specified in meters.
Definition Distance.h:43
double meters() const
Get the distance in meters.
Definition Distance.cpp:85
File name manipulation and expansion.
Definition FileName.h:100
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition FileName.cpp:162
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Pixel interpolator.
This class is designed to encapsulate the concept of a Latitude.
Definition Latitude.h:51
This class is designed to encapsulate the concept of a Longitude.
Definition Longitude.h:40
Base class for the Qisis main windows.
Definition MainWindow.h:24
Cube display widget for certain Isis MDI applications.
Buffer for containing a two dimensional section of an image.
Definition Portal.h:36
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
void openDem()
Open a DEM for ground source radii.
void updateNet(QString cNetFileName)
Updates the Control Network displayed in the Qnet Tool title bar.
QGroupBox * createLeftMeasureGroupBox()
Definition QnetTool.cpp:331
void addMeasure()
Add measure to point.
void loadTemplateFile(QString)
Updates the current template file being used.
void refresh()
Refresh all necessary widgets in QnetTool including the PointEditor and CubeViewports.
void saveTemplateFile()
save the file opened in the template editor
void updateLeftMeasureInfo()
void openReferenceRadius()
Open a radius source using the shape model of the reference measure of m_editPoint.
void updatePointInfo(QString pointId)
Update the current editPoint information in the Point Editor labels.
void setPointType(int pointType)
Set the point type.
bool checkReference()
Change which measure is the reference.
Definition QnetTool.cpp:866
void paintViewport(MdiCubeViewport *cvp, QPainter *painter)
Take care of drawing things on a viewPort.
void loadPoint()
Load point into QnetTool.
void saveTemplateFileAs()
save the contents of template editor to a file chosen by the user
void modifyPoint(ControlPoint *point)
Modify control point.
void setLockPoint(bool ignore)
Set point's "EditLock" keyword to the value of the input parameter.
void previousRightMeasure()
Selects the previous right measure when activated by key shortcut.
QnetTool(QWidget *parent)
Consructs the Qnet Tool window.
Definition QnetTool.cpp:67
void setIgnoreRightMeasure(bool ignore)
Set the "Ignore" keyword of the measure shown in the right viewport to the value of the input paramet...
QSplitter * createTopSplitter()
creates everything above the ControlPointEdit
Definition QnetTool.cpp:236
void viewTemplateFile()
Allows the user to view the template file that is currently set.
void setIgnorePoint(bool ignore)
Set point's "Ignore" keyword to the value of the input parameter.
bool findPointLocation()
Attempt to find the control point's location on the ground source.
void selectLeftMeasure(int index)
Select left measure.
void writeTemplateFile(QString)
write the contents of the template editor to the file provided.
void setIgnoreLeftMeasure(bool ignore)
Set the "Ignore" keyword of the measure shown in the left viewport to the value of the input paramete...
void colorizeSaveButton()
Turn "Save Point" button text to red.
void createQnetTool(QWidget *parent)
create the main window for editing control points
Definition QnetTool.cpp:131
void savePoint()
Save edit point to the Control Network.
bool IsMeasureLocked(QString serialNumber)
Check for implicitly locked measure in m_editPoint.
void setLockRightMeasure(bool ignore)
Set the "EditLock" keyword of the measure shown in the right viewport to the value of the input param...
void drawAllMeasurments(MdiCubeViewport *vp, QPainter *painter)
Draw all measurments which are on this viewPort.
void saveAsNet()
Signal to save the control net.
void showNavWindow(bool checked)
Emits a signal to displays the Navigation window.
void groundViewportClosed(CubeViewport *)
Slot called when the ground source cube viewport is closed.
void loadMeasureTable()
Load measure information into the measure table.
void nextRightMeasure()
Selects the next right measure when activated by key shortcut.
void createFixedPoint(double lat, double lon)
Create new Fixed control point.
void writeSettings() const
This method is called when the Main window is closed or hidden to write the size and location setting...
void createActions()
Creates the menu actions for Qnet Tool.
Definition QnetTool.cpp:507
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
Handle mouse events on CubeViewport.
void openGround()
Open a ground source for selecting fixed points.
double demRadius(double latitude, double longitude)
Return a radius values from the dem using bilinear interpolation.
void setLockLeftMeasure(bool ignore)
Set the "EditLock" keyword of the measure shown in the left viewport to the value of the input parame...
void selectRightMeasure(int index)
Select right measure.
void saveChips()
Slot which calls ControlPointEditor slot to save chips.
QWidget * createToolBarWidget(QStackedWidget *parent)
This method creates the widgets for the tool bar.
void createTemplateEditorWidget()
Creates the Widget which contains the template editor and its toolbar.
Definition QnetTool.cpp:477
void deletePoint(ControlPoint *point)
Delete control point.
void paintAllViewports(QString pointId)
This method will repaint the given Point ID in each viewport Note: The pointId parameter is here even...
void createMenus()
Customize dropdown menus below title bar.
Definition QnetTool.cpp:628
void createPoint(double lat, double lon)
Create new control point.
void drawGroundMeasures(MdiCubeViewport *vp, QPainter *painter)
Draw all Fixed or Constrained points on the ground source viewport.
QGroupBox * createControlPointGroupBox()
Definition QnetTool.cpp:265
QGroupBox * createRightMeasureGroupBox()
Creates the right measure group box.
Definition QnetTool.cpp:404
void readSettings()
This method is called from the constructor so that when the Main window is created,...
bool okToContinue()
Allows user to set a new template file.
void measureSaved()
This method is connected with the measureSaved() signal from ControlPointEdit.
Definition QnetTool.cpp:726
void saveNet()
Signal to save control net.
void setTemplateModified()
called when the template file is modified by the template editor
QAction * toolPadAction(ToolPad *pad)
Adds the Tie tool action to the tool pad.
void updateSurfacePointInfo()
Update the Surface Point Information in the QnetTool window.
void updateRightMeasureInfo()
void loadGroundMeasure()
Load ground measure into right side and add to file combo boxes.
ControlMeasure * createTemporaryGroundMeasure()
Create a temporary measure to hold the ground point info for ground source.
bool eventFilter(QObject *o, QEvent *e)
Event filter for QnetTool.
void openTemplateFile()
prompt user for a registration template file to open.
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
Serial Number list generator.
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
void remove(const QString &sn)
Remove the specified serial number from the list.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
int size() const
How many serial number / filename combos are in the list.
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
int fileNameIndex(const QString &filename)
Return a list index given a filename.
QString fileName(const QString &sn)
Return a filename given a serial number.
Obtain SPICE information for a spacecraft.
Definition Spice.h:283
Pixel value mapper.
Definition Stretch.h:58
This class defines a body-fixed surface point.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Distance GetLocalRadius() const
Return the radius of the surface point.
Base class for the Qisis tools.
Definition Tool.h:67
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition Tool.cpp:390
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition Tool.h:197
QString toolIconDir() const
returns the path to the icon directory.
Definition Tool.h:113
Universal Ground Map.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.