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