Isis 3 Programmer Reference
StereoTool.cpp
1 #include "StereoTool.h"
2 
3 #include <iomanip>
4 #include <cmath>
5 #include <vector>
6 
7 #include <QAction>
8 #include <QCheckBox>
9 #include <QComboBox>
10 #include <QFileDialog>
11 #include <QInputDialog>
12 #include <QMenuBar>
13 #include <QMessageBox>
14 #include <QStackedWidget>
15 
16 #include "AbstractPlotTool.h"
17 #include "Application.h"
18 #include "AutoReg.h"
19 #include "AutoRegFactory.h"
20 #include "BundleAdjust.h"
21 #include "ControlMeasure.h"
22 #include "ControlNet.h"
23 #include "ControlPoint.h"
24 #include "ControlPointEdit.h"
25 #include "CubePlotCurve.h"
26 #include "Distance.h"
27 #include "FileName.h"
28 #include "History.h"
29 #include "IException.h"
30 #include "IString.h"
31 #include "iTime.h"
32 #include "Latitude.h"
33 #include "Longitude.h"
34 #include "MainWindow.h"
35 #include "MdiCubeViewport.h"
36 #include "PlotCurve.h"
37 #include "PlotWindow.h"
38 #include "ProfileDialog.h"
39 #include "PvlEditDialog.h"
40 #include "PvlObject.h"
41 #include "Projection.h"
42 #include "QIsisApplication.h"
43 #include "RubberBandTool.h"
44 #include "SerialNumber.h"
45 #include "Stereo.h"
46 #include "SurfacePoint.h"
47 #include "Target.h"
48 #include "ToolPad.h"
49 #include "UniversalGroundMap.h"
50 
51 
52 using namespace std;
53 
54 
55 namespace Isis {
56  // initialize static
57 /* !!!! TODOS !!!!
58 
59 1. If DEM radius comboBox, update to DEM , when?
60 
61 
62 */
63 
64 
65 
66  QString StereoTool::lastPtIdValue = "";
67 
74  StereoTool::StereoTool(QWidget *parent) : AbstractPlotTool(parent) {
75 
76  m_editPoint = NULL;
77  m_startPoint = NULL;
78  m_endPoint = NULL;
79 
80  m_serialNumberList = NULL;
81  m_controlNet = NULL;
82  m_leftCube = NULL;
83  m_rightCube = NULL;
84  m_leftGM = NULL;
85  m_rightGM = NULL;
86 
87  m_profileDialog = NULL;
88 
89  m_showWarning = true;
90 
91  m_targetRadius = Distance(0., Distance::Meters);
92  m_baseRadius = Distance(0., Distance::Meters);
93 
94  createStereoTool(parent);
95  connect( this, SIGNAL( toolActivated() ), this, SLOT( activateTool() ) );
96  }
97 
98 
104 
105  m_stereoTool = new QMainWindow(parent);
106  m_stereoTool->setWindowTitle("Elevation Calculator (via stereo pairs)");
107 
108  createMenus();
109 
110  // Place everything in a grid
111  QGridLayout *gridLayout = new QGridLayout();
112  //gridLayout->setSizeConstraint(QLayout::SetFixedSize);
113  // ??? Very tacky-hardcoded to ChipViewport size of ControlPointEdit + xtra.
114  // Is there a better way to do this?
115  gridLayout->setColumnMinimumWidth(0, 310);
116  gridLayout->setColumnMinimumWidth(1, 310);
117  // grid row
118  int row = 0;
119 
120  m_ptIdValue = new QLabel();
121  gridLayout->addWidget(m_ptIdValue, row++, 0);
122 
123  m_leftCubeLabel = new QLabel();
124  m_rightCubeLabel = new QLabel();
125  gridLayout->addWidget(m_leftCubeLabel, row, 0);
126  gridLayout->addWidget(m_rightCubeLabel, row++, 1);
127 
128  m_pointEditor = new ControlPointEdit(NULL, parent, true);
129  gridLayout->addWidget(m_pointEditor, row++, 0, 1, 3);
130  connect( m_pointEditor, SIGNAL( measureSaved() ), this, SLOT( measureSaved() ) );
131  m_pointEditor->show();
132  connect(this,
133  SIGNAL( stretchChipViewport(Stretch *, CubeViewport *) ),
134  m_pointEditor,
135  SIGNAL( stretchChipViewport(Stretch *, CubeViewport *) ) );
136 
137  m_elevationLabel = new QLabel;
138  m_elevationLabel->setToolTip("Calculated elevation in meters.");
139  m_elevationLabel->setWhatsThis("Calculated elevation based on parallax.");
140  m_elevationErrorLabel = new QLabel;
141  m_elevationErrorLabel->setToolTip(
142  "Error in calculated elevation in meters.");
143  m_elevationErrorLabel->setWhatsThis("Error in calculated elevation.");
144  gridLayout->addWidget(m_elevationLabel, row, 0);
145  gridLayout->addWidget(m_elevationErrorLabel, row++, 1);
146 
147  m_baseRadiiLabel = new QLabel;
148  m_baseRadiiLabel->setToolTip("Subtracted from the calculated radius to "
149  "determine elevation.");
150 // m_baseRadiiLabel->setToolTip("Local Radius");
151  m_leftDemRadiiLabel = new QLabel;
152  m_leftDemRadiiLabel->setToolTip("Left Cube DEM Radius");
153  m_rightDemRadiiLabel = new QLabel;
154  m_rightDemRadiiLabel->setToolTip("Right Cube DEM Radius");
155  gridLayout->addWidget(m_baseRadiiLabel, row, 0);
156  gridLayout->addWidget(m_leftDemRadiiLabel, row, 1);
157  gridLayout->addWidget(m_rightDemRadiiLabel, row++, 2);
158 
159 // QPushButton *elevationButton = new QPushButton("Calculate Elevation");
160 // connect(elevationButton, SIGNAL(clicked() ),
161 // this, SLOT(calculateElevation() ));
162 // gridLayout->addWidget(elevationButton, row++, 1);
163 
164  QWidget *cw = new QWidget();
165  cw->setLayout(gridLayout);
166  m_stereoTool->setCentralWidget(cw);
167 
168  connect( this, SIGNAL( editPointChanged() ), this, SLOT( paintAllViewports() ) );
169 
170  }
171 
172 
179 
180  m_save = new QAction(m_stereoTool);
181  m_save->setText("Save Elevation Data...");
182  QString whatsThis =
183  "<b>Function:</b> Saves the elevation calulations to current file.";
184  m_save->setWhatsThis(whatsThis);
185  connect( m_save, SIGNAL( triggered() ), this, SLOT( saveElevations() ) );
186  m_save->setDisabled(true);
187 
188  QAction *saveAs = new QAction(m_stereoTool);
189  saveAs->setText("Save Elevation Data As...");
190  whatsThis =
191  "<b>Function:</b> Saves the elevation calulations to a file.";
192  saveAs->setWhatsThis(whatsThis);
193  connect( saveAs, SIGNAL( triggered() ), this, SLOT( saveAsElevations() ) );
194 
195  QAction *closeStereoTool = new QAction(m_stereoTool);
196  closeStereoTool->setText("&Close");
197  closeStereoTool->setShortcut(Qt::ALT + Qt::Key_F4);
198  whatsThis =
199  "<b>Function:</b> Closes the Stereo Tool window for this point \
200  <p><b>Shortcut:</b> Alt+F4 </p>";
201  closeStereoTool->setWhatsThis(whatsThis);
202  connect( closeStereoTool, SIGNAL( triggered() ), m_stereoTool, SLOT( close() ) );
203 
204  QMenu *fileMenu = m_stereoTool->menuBar()->addMenu("&File");
205  fileMenu->addAction(m_save);
206  fileMenu->addAction(saveAs);
207  fileMenu->addAction(closeStereoTool);
208 
209  QAction *templateFile = new QAction(m_stereoTool);
210  templateFile->setText("&Set registration template");
211  whatsThis =
212  "<b>Function:</b> Allows user to select a new file to set as the registration template";
213  templateFile->setWhatsThis(whatsThis);
214  connect( templateFile, SIGNAL( triggered() ), this, SLOT( setTemplateFile() ) );
215 
216  QAction *viewTemplate = new QAction(m_stereoTool);
217  viewTemplate->setText("&View/edit registration template");
218  whatsThis =
219  "<b>Function:</b> Displays the curent registration template. \
220  The user may edit and save changes under a chosen filename.";
221  viewTemplate->setWhatsThis(whatsThis);
222  connect( viewTemplate, SIGNAL( triggered() ), this, SLOT( viewTemplateFile() ) );
223 
224 
225  QMenu *optionMenu = m_stereoTool->menuBar()->addMenu("&Options");
226  QMenu *regMenu = optionMenu->addMenu("&Registration");
227 
228  regMenu->addAction(templateFile);
229  regMenu->addAction(viewTemplate);
230  // registrationMenu->addAction(interestOp);
231 
232  QAction *showHelpAct = new QAction("stereo tool &Help", m_stereoTool);
233  showHelpAct->setIcon(QPixmap(toolIconDir() + "/help-contents.png") );
234  connect( showHelpAct, SIGNAL( triggered() ), this, SLOT( showHelp() ));
235 
236  QMenu *helpMenu = m_stereoTool->menuBar()->addMenu("&Help");
237  helpMenu->addAction(showHelpAct);
238 
239  }
240 
241 
242 
251  QAction *action = new QAction(pad);
252  action->setIcon( QPixmap(toolIconDir() + "/3d-glasses-icon.png") );
253  action->setToolTip("Stereo");
254  action->setWhatsThis("<strong>Functionality:</strong> "
255  "<ul>"
256  "<li>Calculate elevation at a single point by creating a "
257  "control point between the image pair. "
258  "<ul>"
259  "<h4><strong>Control Point mouse Button Functions:</strong></h4>"
260  "<li>Left: Edit closest point.</li>"
261  "<li>Middle: Delete closest point.</li>"
262  "<li>Right: Create new point at cursor position.</li></ul>"
263  "<li>Left click and drag will create an elevation profile "
264  "after you create the start and end control points. A dialog "
265  "box will be shown to assist.</li>"
266  "<li>Right click and drag will create an elevation profile "
267  "between previously created control points.</li></ul>");
268  return action;
269  }
270 
271 
272 
280  QWidget *StereoTool::createToolBarWidget(QStackedWidget *parent) {
281  QWidget *hbox = new QWidget(parent);
282 
283  QLabel *boxLabel = new QLabel("Local Radius:");
284  m_radiusBox = new QComboBox(hbox);
285  m_radiusBox->addItem("Ellipsoid Equitorial Radius");
286  m_radiusBox->addItem("DEM Radius");
287  m_radiusBox->addItem("Custom Radius");
288  m_radiusBox->setToolTip("Source for local radius");
289  QString text =
290  "<b>Function: </b>Source for the local radius used for elevation "
291  "calculations.";
292  m_radiusBox->setWhatsThis(text);
293  connect( m_radiusBox, SIGNAL( activated(int) ),
294  this, SLOT( updateRadiusLineEdit() ));
295 
296  m_radiusLineEdit = new QLineEdit(hbox);
297  QDoubleValidator *dval = new QDoubleValidator(hbox);
298  m_radiusLineEdit->setValidator(dval);
299  m_radiusLineEdit->setReadOnly(true);
300  m_radiusLineEdit->setToolTip("Custom local radius used for elevation "
301  "calculations. To enter a value, set box to "
302  "the left to \"Custom Radius\"");
303  text =
304  "<b>Function: </b>Custom local radius used to calculate elevations. "
305  "This can be changed by selecting \"Custom Radius\" in the box to "
306  "the left.";
307  m_radiusLineEdit->setWhatsThis(text);
308 // connect(m_radiusLineEdit, SIGNAL(textEdited(QString) ),
309 // this, SLOT(userBaseRadius(QString) ));
310  connect( m_radiusLineEdit, SIGNAL( editingFinished() ),
311  this, SLOT( userBaseRadius() ));
312  // Do not enable unless radius box set to Custom Radius
313  m_radiusLineEdit->setEnabled(false);
314 
315  QLabel *radiusUnit = new QLabel("Meters");
316 
317  QToolButton *helpButton = new QToolButton(hbox);
318  helpButton->setIcon( QPixmap(toolIconDir() + "/help-contents.png") );
319  helpButton->setToolTip("Help");
320  helpButton->setIconSize( QSize(22, 22) );
321  connect( helpButton, SIGNAL( clicked() ), this, SLOT( showHelp() ));
322 
323  QHBoxLayout *layout = new QHBoxLayout;
324  layout->setMargin(0);
325  layout->addWidget(AbstractPlotTool::createToolBarWidget(parent) );
326  layout->addWidget(boxLabel);
327  layout->addWidget(m_radiusBox);
328  layout->addWidget(m_radiusLineEdit);
329  layout->addWidget(radiusUnit);
330  layout->addStretch();
331  layout->addWidget(helpButton);
332  hbox->setLayout(layout);
333 
334  readSettings();
335 
336  return hbox;
337  }
338 
339 
340 
341  void StereoTool::activateTool() {
342 
343  warningDialog();
344  }
345 
346 
347 
349  return new PlotWindow("Elevation Profile", PlotCurve::PixelNumber,
351  qobject_cast<QWidget *>( parent() ) );
352 
353  }
354 
355 
356 
358  }
359 
360 
361 
362  void StereoTool::warningDialog() {
363 
364  if (m_showWarning) {
365  QDialog *warningDialog = new QDialog(m_stereoTool);
366 
367  QVBoxLayout *mainLayout = new QVBoxLayout;
368  warningDialog->setLayout(mainLayout);
369 
370  QLabel *warningsText = new QLabel("<p><strong>Warning:</strong> "
371  "The camera orientations are very critical for correct results. "
372  "Poor orientations will result in bad elevation measurements. The "
373  "camera orientations can be corrected with the programs "
374  "<i>jigsaw, deltack, or qtie.");
375  warningsText->setWordWrap(true);
376  mainLayout->addWidget(warningsText);
377  QCheckBox *showWarning = new QCheckBox("Do not show this message again");
378  showWarning->setChecked(false);
379  mainLayout->addWidget(showWarning);
380 
381  QPushButton *okButton = new QPushButton("OK");
382  mainLayout->addStretch();
383  mainLayout->addWidget(okButton);
384  connect( okButton, SIGNAL( clicked() ), warningDialog, SLOT( accept() ));
385 
386  if ( warningDialog->exec() ) {
387  if ( showWarning->isChecked() ) m_showWarning = false;
388  }
389  writeSettings();
390  }
391 
392  }
393 
394 
395 
396  void StereoTool::showHelp() {
397 
398  QDialog *helpDialog = new QDialog(m_stereoTool);
399  helpDialog->setWindowTitle("Stereo Tool Help");
400 
401  QVBoxLayout *mainLayout = new QVBoxLayout;
402  helpDialog->setLayout(mainLayout);
403 
404  QLabel *stereoTitle = new QLabel("<h2>Stereo Tool</h2>");
405  mainLayout->addWidget(stereoTitle);
406 
407  QLabel *stereoSubtitle = new QLabel("A tool for calculating point elevations "
408  "and elevation profiles using stereo pairs "
409  "of cubes.");
410  stereoSubtitle->setWordWrap(true);
411  mainLayout->addWidget(stereoSubtitle);
412 
413  QTabWidget *tabArea = new QTabWidget;
414  tabArea->setDocumentMode(true);
415  mainLayout->addWidget(tabArea);
416 
417  // TAB 1 - Overview
418  QScrollArea *overviewTab = new QScrollArea;
419  overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
420  overviewTab->setWidgetResizable(true);
421  QWidget *overviewContainer = new QWidget;
422  QVBoxLayout *overviewLayout = new QVBoxLayout;
423  overviewContainer->setLayout(overviewLayout);
424 
425  QLabel *purposeTitle = new QLabel("<h2>Purpose</h2>");
426  overviewLayout->addWidget(purposeTitle);
427 
428  QLabel *purposeText = new QLabel("<p>This tool will use parallax from a "
429  "stereo pair of cubes to calculate elevations at chosen control points "
430  "or create elevation profiles between two chosen control points. "
431  "Elevations are computed from points between the left and right cubes. "
432  "Vectors from the target (planet center) to the spacecraft and target "
433  "to the surface registration points are computed for each point. From "
434  "these points, the elevation is computed.");
435  purposeText->setWordWrap(true);
436  overviewLayout->addWidget(purposeText);
437 
438  QLabel *warningsTitle = new QLabel("<h2>Warnings</h2>");
439  overviewLayout->addWidget(warningsTitle);
440 
441  QLabel *warningsText = new QLabel("<p>The camera orientations are very "
442  "critical for correct results. Poor orientations will result in "
443  "bad elevation measurements. The camera orientations can be corrected "
444  "with the programs <i>jigsaw, deltack, or qtie.");
445  warningsText->setWordWrap(true);
446  overviewLayout->addWidget(warningsText);
447 
448  overviewTab->setWidget(overviewContainer);
449 
450  // TAB 2 - Quick Start
451  QScrollArea *quickTab = new QScrollArea;
452  quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
453  quickTab->setWidgetResizable(true);
454  QWidget *quickContainer = new QWidget;
455  QVBoxLayout *quickLayout = new QVBoxLayout;
456  quickContainer->setLayout(quickLayout);
457 
458  QLabel *quickTitle = new QLabel("<h2>Quick Start</h2>");
459  quickLayout->addWidget(quickTitle);
460 
461  QLabel *quickSubTitle = new QLabel("<h3>Preparation:</h3>");
462  quickLayout->addWidget(quickSubTitle);
463 
464  QLabel *quickPrep = new QLabel("<p><ul>"
465  "<li>Open the two cubes of a stereo pair</li>"
466  "<li>Link the two displayed cube windows</li>");
467  quickPrep->setWordWrap(true);
468  quickLayout->addWidget(quickPrep);
469 
470  QLabel *quickFunctionTitle = new QLabel("<h3>Cube Viewport Functions:</h3>");
471  quickLayout->addWidget(quickFunctionTitle);
472 
473  QLabel *quickFunction = new QLabel(
474  "The stereo tool window will be shown once "
475  "you click on a cube viewport window using one of the following "
476  "cube viewport functions.");
477  quickFunction->setWordWrap(true);
478  quickLayout->addWidget(quickFunction);
479 
480  QLabel *quickDesc = new QLabel("<p><ul>"
481  "<li>Calculate elevation at a single point by creating a "
482  "control point between the image pair by right clicking in the cube "
483  "viewport window on the location you are interested in. Once the "
484  "control point is refined, click the \"Save Measure\" button in "
485  "the Stereo Tool window and the elevation will be calculated. The elevation "
486  "reported is relative to the radius which is defined on the toolbar.</li>"
487  "<li>Left click and drag will create an elevation profile "
488  "after you create the start and end control points. A dialog "
489  "box will be shown to assist in creating the control points.</li>"
490  "<li>Right click and drag will create an elevation profile "
491  "between two previously created control points.</li></ul>"
492  "<p><strong>Note:</strong> The quality of the profiles is dependent on the registration "
493  "between the two images at each point along the profile. Registration "
494  "parameters can be changed under Options->Registration mentu of the "
495  "Elevation Calculator window. A discussion of these parameters can be found at: "
496  "<a href=\"http://isis.astrogeology.usgs.gov/documents/PatternMatch/PatternMatch.html\">"
497  "Pattern Matching</a>");
498  quickDesc->setWordWrap(true);
499  quickDesc->setOpenExternalLinks(true);
500  quickLayout->addWidget(quickDesc);
501 
502  quickTab->setWidget(quickContainer);
503 
504  // TAB 3 - Control Point Editing
505  QScrollArea *controlPointTab = new QScrollArea;
506  controlPointTab->setWidgetResizable(true);
507  controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
508  QWidget *controlPointContainer = new QWidget;
509  QVBoxLayout *controlPointLayout = new QVBoxLayout;
510  controlPointContainer->setLayout(controlPointLayout);
511 
512  QLabel *controlPointTitle = new QLabel("<h2>Control Point Editing</h2>");
513  controlPointLayout->addWidget(controlPointTitle);
514 
515  QLabel *mouseLabel = new QLabel("<p><h3>When the \"Stereo\" tool "
516  "is activated, the mouse buttons have the following function in the "
517  "cube viewports of the main qview window:</h3>");
518  mouseLabel->setWordWrap(true);
519  mouseLabel->setScaledContents(true);
520  controlPointLayout->addWidget(mouseLabel);
521 
522  QLabel *controlPointDesc = new QLabel("<ul>"
523  "<li>Left click - Edit the closest control point</li>"
524  "<li>Middle click - Delete the closest control point</li>"
525  "<li>Right click - Create new control point at cursor location</li>"
526  "<li>Left click and drag - Create an elevation profile "
527  "after you create the start and end control points. A dialog "
528  "box will be shown to assist in creating the control points.</li>"
529  "<li>Right click and drag - Create an elevation profile "
530  "between two previously created control points.</li></ul>");
531  controlPointDesc->setWordWrap(true);
532  controlPointLayout->addWidget(controlPointDesc);
533 
534  QLabel *controlPointEditing = new QLabel(
535  "<h4>Changing Measure Locations</h4>"
536  "<p>The measure location can be adjusted by:"
537  "<ul>"
538  "<li>Move the cursor location under the crosshair by clicking the left mouse "
539  "button</li>"
540  "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
541  "<li>Move 1 pixel at a time by using arrow buttons above the right view</li>"
542  "</ul></p>"
543  "<h4>Other Point Editor Functions</h4>"
544  "<p>Along the right border of the window:</p>"
545  "<ul>"
546  "<li><strong>Geom:</strong> Geometrically match the right view to the left"
547  "view</li>"
548  "<li><strong>Rotate:</strong> Rotate the right view using either the dial"
549  "or entering degrees </li>"
550  "<li><strong>Show control points:</strong> Draw crosshairs at all control"
551  "point locations visible within the view</li>"
552  "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire"
553  "view</li>"
554  "<li><strong>Circle:</strong> Draw circle which may help center measure"
555  "on a crater</li></ul"
556  "<p>Below the left view:</p>"
557  "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the"
558  "left view window using the \"Blink Start\" button (with play icon) and "
559  "\"Blink Stop\" button (with stop icon). Both arrow keys above the right view "
560  "and the keyboard arrow keys may be used to move the right view while"
561  "blinking.</li>"
562  "<li><strong>Find:</strong> Center the right view so that the same latitude "
563  "longitude is under the crosshair as the left view.</li></ul"
564  "<p>Below the right view:</p>"
565  "<ul><li><strong>Register:</strong> Sub-pixel register the the right view to"
566  "the left view.</li>"
567  "<li><strong>Save Measure:</strong> Save the control point under the"
568  "crosshairs and calculated elevation.</li></ul>");
569  controlPointEditing->setWordWrap(true);
570  controlPointLayout->addWidget(controlPointEditing);
571 
572  controlPointTab->setWidget(controlPointContainer);
573 
574 
575 
576  tabArea->addTab(overviewTab, "&Overview");
577  tabArea->addTab(quickTab, "&Quick Start");
578  tabArea->addTab(controlPointTab, "&Control Point Editing");
579 
580  QHBoxLayout *buttonsLayout = new QHBoxLayout;
581  // Flush the buttons to the right
582  buttonsLayout->addStretch();
583 
584  QPushButton *closeButton = new QPushButton("&Close");
585  closeButton->setIcon( QPixmap( toolIconDir() + "/guiStop.png" ) );
586  closeButton->setDefault(true);
587  connect( closeButton, SIGNAL( clicked() ),
588  helpDialog, SLOT( close() ) );
589  buttonsLayout->addWidget(closeButton);
590 
591  mainLayout->addLayout(buttonsLayout);
592 
593  helpDialog->show();
594 
595 
596  }
597 
598 
599 
600  void StereoTool::userBaseRadius() {
601  // TODO test validity
602  try {
603  m_baseRadius = Distance(m_radiusLineEdit->text().toDouble(),
605 
606  // If stereo Tool visible and has valid point, update elevation and
607  // save new elevation to point
608  if (m_stereoTool->isVisible() && m_editPoint != NULL) {
609  calculateElevation();
610  }
611  }
612  catch (IException &e) {
613  QString message = "Invalid base radius entered.";
614  message += e.toString();
615  m_radiusLineEdit->setText("");
616  QMessageBox::critical(m_stereoTool, "Error", message);
617  m_baseRadius = Distance(0., Distance::Meters);
618  return;
619  }
620 
621  }
622 
623 
624 
625  void StereoTool::updateRadiusLineEdit() {
626 
627 
628  if ( m_radiusBox->currentText() == "Ellipsoid Equitorial Radius" ) {
629  if ( m_targetRadius.isValid() ) {
630  m_radiusLineEdit->setText( QString::number( m_targetRadius.meters(), 'f',
631  6) );
632  m_baseRadius = m_targetRadius;
633  }
634  else {
635  m_radiusLineEdit->setText("");
636  }
637  m_radiusLineEdit->setReadOnly(true);
638  m_radiusLineEdit->setEnabled(false);
639  }
640  else if ( m_radiusBox->currentText() == "DEM Radius" ) {
641  // If cubes set, make sure they have an elevation model
642  if (m_leftCube) {
643  m_leftCube->camera()->IgnoreElevationModel(false);
644  if ( m_leftCube->camera()->target()->shape()->name() == "Ellipsoid" ) {
645  QString message = "No valid Dem on cube. Run <i>spicinit</i> using a "
646  "dem shape model. The local radius will default back to the ellipsoid.";
647  QMessageBox::warning(m_stereoTool, "Warning", message);
648  m_radiusBox->setCurrentIndex(0);
649 
650  m_radiusLineEdit->setReadOnly(true);
651  m_radiusLineEdit->setEnabled(false);
652  return;
653  }
654  }
655  m_radiusLineEdit->setText("");
656  m_radiusLineEdit->setReadOnly(true);
657  m_radiusLineEdit->setEnabled(false);
658  m_baseRadius = Distance(0., Distance::Meters);
659  }
660  else { // "Custom Radius"
661  m_radiusLineEdit->setReadOnly(false);
662  m_radiusLineEdit->setEnabled(true);
663  }
664 
665  // If stereo Tool visible and has valid point, update elevation
666  if ( m_stereoTool->isVisible() && m_editPoint != NULL ) {
667  calculateElevation();
668  }
669  }
670 
671 
672 
673  void StereoTool::setupFiles() {
674 
675  /* TODO
676  .5 Get vector of all linked viewports
677  1. If no files linked or > 2 linked, print errror & return
678  2. Check if new files
679  if yes: clear old
680  if no: return
681 
682  */
683  m_linkedViewports.clear();
684  for (int i = 0; i < (int) cubeViewportList()->size(); i++) {
685  if ( (*( cubeViewportList() ) )[i]->isLinked() )
686  m_linkedViewports.push_back( (*( cubeViewportList() ) )[i]);
687  }
688 
689  if ( m_linkedViewports.size() < 2 ) {
690  IString message = "Two cube viewports containing a stereo pair "
691  "need to be linked.";
692  throw IException(IException::User, message, _FILEINFO_);
693  }
694  if ( m_linkedViewports.size() > 2 ) {
695  IString message = "Only two cube viewports containing a stereo pair "
696  "may be linked.";
697  throw IException(IException::User, message, _FILEINFO_);
698  }
699 
700  // If linked viewports contain the same cubes, simply return,
701  // all data should be retained.
702  if ( m_linkedViewports.at(0)->cube() == m_leftCube ||
703  m_linkedViewports.at(0)->cube() == m_rightCube ) {
704  if ( m_linkedViewports.at(1)->cube() == m_leftCube ||
705  m_linkedViewports.at(1)->cube() == m_rightCube ) {
706  return;
707  }
708  }
709 
710  // Control net already exists, make sure new cubes are the same target
711  // as the current control net.
712  if (m_controlNet) {
713  if ( m_controlNet->GetTarget() !=
714  m_linkedViewports.at(0)->cube()->camera()->target()->name() ) {
715  // Allow opportunity to save current data before clearing for new
716  // target.
717  QString message = "You have changed targets. All data must be re-set";
718  message += " for new target. Would you like to save your current";
719  message += " points before resetting?";
720  int response = QMessageBox::question(m_stereoTool,
721  "Save current points", message,
722  QMessageBox::Yes | QMessageBox::No,
723  QMessageBox::Yes);
724  if (response == QMessageBox::Yes) {
726  }
727  m_stereoTool->setVisible(false);
728  clearNetData();
729  m_controlNet = new ControlNet();
730  m_controlNet->SetTarget(*m_linkedViewports.at(0)->cube()->label());
731  m_serialNumberList = new SerialNumberList(false);
732  }
733  }
734  else {
735  m_controlNet = new ControlNet();
736  m_controlNet->SetTarget(
737  m_linkedViewports.at(0)->cube()->camera()->target()->name() );
738  m_serialNumberList = new SerialNumberList(false);
739  }
740 
741 
742  // TODO: For now simply clear & set always, but should check if cubes are
743  // not new.
744  clearFiles();
745  setFiles( m_linkedViewports.at(0)->cube(), m_linkedViewports.at(1)->cube() );
746 
747  }
748 
749 
750 
761  m_stereoTool->setVisible(false);
762 
763  if (m_leftGM) {
764  delete m_leftGM;
765  m_leftGM = NULL;
766  }
767  if (m_rightGM) {
768  delete m_rightGM;
769  m_rightGM = NULL;
770  }
771 
772  }
773 
774 
775 
783  void StereoTool::setFiles(Cube *leftCube, Cube *rightCube) {
784 
785  // Save off base map cube, but add matchCube to serial number list
786  m_leftCube = leftCube;
787  m_rightCube = rightCube;
788 
789  QString leftName = FileName( m_leftCube->fileName() ).name();
790  QString rightName = FileName( m_rightCube->fileName() ).name();
791  // Update cube name labels
792  m_leftCubeLabel->setText(leftName);
793  m_rightCubeLabel->setText(rightName);
794 
795  m_leftSN = SerialNumber::Compose(*m_leftCube);
796  m_rightSN = SerialNumber::Compose(*m_rightCube);
797 
798  // TODO Do I need list?
799  if ( !m_serialNumberList->hasSerialNumber(m_leftSN) ) {
800  m_serialNumberList->add( m_leftCube->fileName() );
801  }
802  if ( !m_serialNumberList->hasSerialNumber(m_rightSN) ) {
803  m_serialNumberList->add( m_rightCube->fileName() );
804  }
805 
806  try {
807  PvlGroup pvlRadii = Target::radiiGroup(m_controlNet->GetTarget());
808  m_targetRadius = Distance(pvlRadii["EquatorialRadius"], Distance::Meters);
809  }
810  catch(IException &e) {
811  QString message = "Could not determine target radius.";
812  QMessageBox::critical(m_stereoTool,"Error",message);
813  m_baseRadius = Distance(0., Distance::Meters);
814  updateRadiusLineEdit();
815  return;
816  }
817  updateRadiusLineEdit();
818 
819  // Save off universal ground maps
820  try {
821  m_leftGM = new UniversalGroundMap(*m_leftCube);
822  }
823  catch (IException &e) {
824  QString message = "Cannot initialize universal ground map for " +
825  m_leftCube->fileName() + ".\n";
826  message += e.toString();
827  QMessageBox::critical(m_stereoTool, "Error", message);
828  return;
829  }
830  try {
831  m_rightGM = new UniversalGroundMap(*m_rightCube);
832  }
833  catch (IException &e) {
834  QString message = "Cannot initialize universal ground map for" +
835  m_rightCube->fileName() + ".\n";
836  message += e.toString();
837  QMessageBox::critical(m_stereoTool, "Error", message);
838  return;
839  }
840 
841 
842  }
843 
844 
845 
851 
852  double samp = m_editPoint->GetMeasure(Left)->GetSample();
853  double line = m_editPoint->GetMeasure(Left)->GetLine();
854  m_leftGM->SetImage(samp, line);
855  double lat = m_leftGM->UniversalLatitude();
856  double lon = m_leftGM->UniversalLongitude();
857 
858  m_rightGM->SetGround(
860  try {
861  m_editPoint->SetAprioriSurfacePoint(SurfacePoint (
863  m_targetRadius ) );
864  }
865  catch (IException &e) {
866  QString message = "Unable to set Apriori Surface Point.\n";
867  message += "Latitude = " + QString::number(lat);
868  message += " Longitude = " + QString::number(lon);
869  message += " Radius = " + QString::number(m_targetRadius.meters(), 'f',
870  6) + "\n";
871  message += e.toString();
872  QMessageBox::critical(m_stereoTool, "Error", message);
873  }
874 
875  calculateElevation();
876  emit editPointChanged();
877  }
878 
879 
880 
887  rubberBandTool()->enable(RubberBandTool::LineMode);
888  rubberBandTool()->enablePoints();
889  rubberBandTool()->enableAllClicks();
890  rubberBandTool()->setDrawActiveViewportOnly(true);
891  }
892 
893 
894 
895  void StereoTool::rubberBandComplete() {
896 
897 // clearProfile();
898 
899  try {
900  setupFiles();
901  }
902  catch (IException &e) {
903  QString message = e.toString();
904  QMessageBox::critical(m_stereoTool, "Error setting stereo pair", message);
905  rubberBandTool()->clear();
906  return;
907  }
908 
909  MdiCubeViewport *cvp = cubeViewport();
910  if (cvp == NULL)
911  return;
912 
913  QString file = cvp->cube()->fileName();
914  QString sn;
915  try {
916  sn = m_serialNumberList->serialNumber(file);
917  }
918  catch (IException &e) {
919  QString message = "This cube is not linked as a stereo pair. Make ";
920  message += "sure you have two stereo pair cube viewports linked.";
921  QMessageBox::critical(m_stereoTool,"Viewport not linked", message);
922  return;
923  }
924 
925  if ( rubberBandTool()->figureIsPoint() ) {
926  double samp, line;
927  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
928  rubberBandTool()->vertices()[0].ry(),
929  samp, line );
930  if ( rubberBandTool()->mouseButton() & Qt::LeftButton ) {
931  if ( !m_controlNet || m_controlNet->GetNumMeasures() == 0 ) {
932  QString message = "No points exist for editing. Create points ";
933  message += "using the right mouse button.";
934  QMessageBox::information(m_stereoTool, "Warning", message);
935  return;
936  }
937  // Find closest control point in network
938  ControlPoint *point;
939  try {
940  point = m_controlNet->FindClosest(sn, samp, line);
941  }
942  catch (IException &e) {
943  QString message = "No points found for editing. Create points ";
944  message += "using the right mouse button.";
945  message += e.toString();
946  QMessageBox::critical(m_stereoTool, "Error", message);
947  return;
948  }
949  modifyPoint(point);
950  }
951  else if ( rubberBandTool()->mouseButton() & Qt::MidButton ) {
952  if ( !m_controlNet || m_controlNet->GetNumPoints() == 0 ) {
953  QString message = "No points exist for deleting. Create points ";
954  message += "using the right mouse button.";
955  QMessageBox::warning(m_stereoTool, "Warning", message);
956  return;
957  }
958 
959  // Find closest control point in network
960  ControlPoint *point =
961  m_controlNet->FindClosest(sn, samp, line);
962  // TODO: test for errors and reality
963  if (point == NULL) {
964  QString message = "No points exist for deleting. Create points ";
965  message += "using the right mouse button.";
966  QMessageBox::information(m_stereoTool, "Warning", message);
967  return;
968  }
969  deletePoint(point);
970  }
971  else if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
972  double lat, lon;
973  if (cvp->cube() == m_leftCube) {
974  m_leftGM->SetImage(samp, line);
975  lat = m_leftGM->UniversalLatitude();
976  lon = m_leftGM->UniversalLongitude();
977  }
978  else {
979  m_rightGM->SetImage(samp, line);
980  lat = m_rightGM->UniversalLatitude();
981  lon = m_rightGM->UniversalLongitude();
982  }
983  try {
984  createPoint(lat, lon);
985  }
986  catch (IException &e) {
987  QString message = "Cannot create control point.\n\n";
988  message += e.toString();
989  QMessageBox::critical(m_stereoTool, "Error", message);
990  m_startPoint = NULL;
991  rubberBandTool()->clear();
992  return;
993  }
994  }
995  }
996  // RubberBand line drawn:
997  else {
998  m_startPoint = NULL;
999  m_endPoint = NULL;
1000  // Right click/drag: Find closest end points
1001  if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
1002  double samp, line;
1003  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
1004  rubberBandTool()->vertices()[0].ry(),
1005  samp, line );
1006  try {
1007  m_startPoint = m_controlNet->FindClosest(sn, samp, line);
1008  }
1009  catch (IException &e) {
1010  QString message = "Cannot find start point for profile. Either ";
1011  message += "create end points individually using the right mouse ";
1012  message += "button. Or, create profile end points by clicking and ";
1013  message += "dragging with the right mouse button.\n\n";
1014  message += e.toString();
1015  QMessageBox::critical(m_stereoTool, "Error", message);
1016  m_startPoint = NULL;
1017  rubberBandTool()->clear();
1018  return;
1019  }
1020  cvp->viewportToCube( rubberBandTool()->vertices()[1].rx(),
1021  rubberBandTool()->vertices()[1].ry(),
1022  samp, line );
1023  try {
1024  m_endPoint = m_controlNet->FindClosest(sn, samp, line);
1025  if ( m_startPoint->GetId() == m_endPoint->GetId() ) {
1026  throw IException(IException::User, "No End Point",
1027  _FILEINFO_);
1028  }
1029  }
1030  catch (IException &e) {
1031  QString message = "Cannot find end point for profile. Either ";
1032  message += "create end points individually using the right mouse ";
1033  message += "button. Or, create profile end points by clicking and ";
1034  message += "dragging with the right mouse button.\n\n";
1035  message += e.toString();
1036  QMessageBox::critical(m_stereoTool, "Error", message);
1037  m_startPoint = NULL;
1038  m_endPoint = NULL;
1039  rubberBandTool()->clear();
1040  return;
1041  }
1042  profile();
1043  }
1044  else {
1045  // Left click/drag: Create control points at the line endpoints.
1046  m_profileDialog = new ProfileDialog();
1047  connect( m_profileDialog, SIGNAL( createStart() ),
1048  this, SLOT( createStartPoint() ) );
1049  connect( m_profileDialog, SIGNAL( createEnd() ),
1050  this, SLOT( createEndPoint() ) );
1051  connect( m_profileDialog, SIGNAL( accepted() ),
1052  this, SLOT( profile() ) );
1053  connect( m_profileDialog, SIGNAL( accepted() ),
1054  this, SLOT( profile() ) );
1055  connect( m_profileDialog, SIGNAL( rejected() ),
1056  this, SLOT( clearProfile() ) );
1057  m_profileDialog->show();
1058  m_profileDialog->activateWindow();
1059  }
1060  }
1061  }
1062 
1063 
1064 
1065  void StereoTool::clearProfile() {
1066  m_startPoint = NULL;
1067  m_endPoint = NULL;
1068  rubberBandTool()->clear();
1069  delete m_profileDialog;
1070  m_profileDialog = NULL;
1071  }
1072 
1073 
1074 
1075  void StereoTool::createStartPoint() {
1076  MdiCubeViewport *cvp = cubeViewport();
1077  if (cvp == NULL)
1078  return;
1079 
1080  double samp, line;
1081  double lat, lon;
1082  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
1083  rubberBandTool()->vertices()[0].ry(),
1084  samp, line );
1085  if ( cvp->cube() == m_leftCube ) {
1086  m_leftGM->SetImage(samp, line);
1087  lat = m_leftGM->UniversalLatitude();
1088  lon = m_leftGM->UniversalLongitude();
1089  }
1090  else {
1091  m_rightGM->SetImage(samp, line);
1092  lat = m_rightGM->UniversalLatitude();
1093  lon = m_rightGM->UniversalLongitude();
1094  }
1095  try {
1096  createPoint(lat, lon);
1097  }
1098  catch (IException &e) {
1099  QString message = "Cannot create control point.\n\n";
1100  message += e.toString();
1101  QMessageBox::critical(m_stereoTool, "Error", message);
1102  delete m_profileDialog;
1103  m_profileDialog = NULL;
1104  rubberBandTool()->clear();
1105  return;
1106  }
1107  m_startPoint = m_editPoint;
1108  }
1109 
1110 
1111 
1112  void StereoTool::createEndPoint() {
1113  MdiCubeViewport *cvp = cubeViewport();
1114  if (cvp == NULL)
1115  return;
1116 
1117  double samp, line;
1118  double lat, lon;
1119  cvp->viewportToCube( rubberBandTool()->vertices()[1].rx(),
1120  rubberBandTool()->vertices()[1].ry(),
1121  samp, line );
1122  if ( cvp->cube() == m_leftCube ) {
1123  m_leftGM->SetImage(samp, line);
1124  lat = m_leftGM->UniversalLatitude();
1125  lon = m_leftGM->UniversalLongitude();
1126  }
1127  else {
1128  m_rightGM->SetImage(samp, line);
1129  lat = m_rightGM->UniversalLatitude();
1130  lon = m_rightGM->UniversalLongitude();
1131  }
1132  try {
1133  createPoint(lat, lon);
1134  }
1135  catch (IException &e) {
1136  QString message = "Cannot create control point.\n\n";
1137  message += e.toString();
1138  QMessageBox::critical(m_stereoTool, "Error", message);
1139  m_startPoint = NULL;
1140  delete m_profileDialog;
1141  m_profileDialog = NULL;
1142  rubberBandTool()->clear();
1143  return;
1144  }
1145  m_endPoint = m_editPoint;
1146 
1147  }
1148 
1149 
1150 
1163  void StereoTool::createPoint(double lat, double lon) {
1164 
1165  // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1166 
1167  double leftSamp = 0, leftLine = 0;
1168  double rightSamp = 0, rightLine = 0;
1169 
1170  // Make sure point exists on both linked cubes
1171  if ( m_leftGM->SetUniversalGround(lat, lon) ) {
1172  leftSamp = m_leftGM->Sample();
1173  leftLine = m_leftGM->Line();
1174 
1175  // Make sure point is on Right cube
1176  if ( m_rightGM->SetUniversalGround(lat, lon) ) {
1177  // Make sure point on Right cube
1178  rightSamp = m_rightGM->Sample();
1179  rightLine = m_rightGM->Line();
1180  if ( rightSamp < 1 || rightSamp > m_rightCube->sampleCount() ||
1181  rightLine < 1 || rightLine > m_rightCube->lineCount() ) {
1182  IString message = "Point does not exist on cube, " +
1183  m_rightCube->fileName() + ".";
1184  throw IException(IException::User, message, _FILEINFO_);
1185 // QString message = "Point does not exist on cube, " +
1186 // QString(m_rightCube->fileName().c_str() ) + ".";
1187 // QMessageBox::critical(m_stereoTool, "Error", message);
1188 // return;
1189  }
1190  }
1191  else {
1192  IString message = "Point does not exist on cube, " +
1193  m_rightCube->fileName() + ".";
1194  throw IException(IException::User, message, _FILEINFO_);
1195 // QString message = "Point does not exist on cube, " +
1196 // QString(m_rightCube->fileName().c_str() ) + ".";
1197 // QMessageBox::critical(m_stereoTool, "Error", message);
1198 // return;
1199  }
1200  }
1201  else {
1202  IString message = "Point does not exist on cube, " +
1203  m_leftCube->fileName() + ".";
1204  throw IException(IException::User, message, _FILEINFO_);
1205 // QString message = "Point does not exist on cube, " +
1206 // QString(m_leftCube->fileName().c_str() ) + ".";
1207 // QMessageBox::critical(m_stereoTool, "Error", message);
1208 // return;
1209  }
1210 
1211  // Point is on both Left and Right cubes, create new control point
1212  ControlPoint *newPoint = NULL;
1213  // Prompt for point Id
1214  bool goodId = false;
1215  while (!goodId) {
1216  bool ok = false;
1217  QString id = QInputDialog::getText(m_stereoTool,
1218  "Point ID", "Enter Point ID:",
1219  QLineEdit::Normal, lastPtIdValue,
1220  &ok);
1221  if (!ok)
1222  // user clicked "Cancel"
1223  {
1224  return;
1225  }
1226  if ( ok && id.isEmpty() ) {
1227  // user clicked "Ok" but did not enter a point ID
1228  QString message = "You must enter a point Id.";
1229  QMessageBox::warning(m_stereoTool, "Warning", message);
1230  }
1231  else {
1232  // Make sure Id doesn't already exist
1233  newPoint = new ControlPoint(id);
1234  if ( m_controlNet->GetNumPoints() > 0 &&
1235  m_controlNet->ContainsPoint(newPoint->GetId() ) ) {
1236  QString message = "A ControlPoint with Point Id = [" +
1237  newPoint->GetId() +
1238  "] already exists. Re-enter unique Point Id.";
1239  QMessageBox::warning(m_stereoTool, "Unique Point Id", message);
1240  }
1241  else {
1242  goodId = true;
1243  lastPtIdValue = id;
1244  }
1245  }
1246  }
1247 
1248  newPoint->SetType(ControlPoint::Free);
1251  m_targetRadius) );
1252 
1253  // Set first measure to Left
1254  ControlMeasure *mLeft = new ControlMeasure;
1255  mLeft->SetCubeSerialNumber(m_leftSN);
1256  mLeft->SetCoordinate(leftSamp, leftLine);
1258  mLeft->SetDateTime();
1260  newPoint->Add(mLeft);
1261  // Second measure is Right measure
1262  ControlMeasure *mRight = new ControlMeasure;
1263  mRight->SetCubeSerialNumber(m_rightSN);
1264  mRight->SetCoordinate(rightSamp, rightLine);
1266  mRight->SetDateTime();
1268  newPoint->Add(mRight);
1269 
1270  // Add new control point to control network
1271  m_controlNet->AddPoint(newPoint);
1272  // Read newly added point
1273  m_editPoint = m_controlNet->GetPoint( (QString) newPoint->GetId() );
1274  // Load new point in StereoTool
1275  loadPoint();
1276  m_stereoTool->setVisible(true);
1277  m_stereoTool->raise();
1278 
1279  emit editPointChanged();
1280  }
1281 
1282 
1295 
1296  m_editPoint = point;
1297  // Change point in viewport to red so user can see what point they are
1298  // about to delete.
1299  emit editPointChanged();
1300 
1301  //loadPoint();
1302 
1303  m_controlNet->DeletePoint( m_editPoint->GetId() );
1304  m_stereoTool->setVisible(false);
1305  m_editPoint = NULL;
1306 
1307  emit editPointChanged();
1308  }
1309 
1310 
1318 
1319  m_editPoint = point;
1320  loadPoint();
1321  m_stereoTool->setVisible(true);
1322  m_stereoTool->raise();
1323  emit editPointChanged();
1324  }
1325 
1326 
1333 
1334  // Initialize pointEditor with measures
1335  m_pointEditor->setLeftMeasure( m_editPoint->GetMeasure(Left), m_leftCube,
1336  m_editPoint->GetId() );
1337  m_pointEditor->setRightMeasure( m_editPoint->GetMeasure(Right),
1338  m_rightCube, m_editPoint->GetId() );
1339 
1340  // Write pointId
1341  QString ptId = "Point ID: " + m_editPoint->GetId();
1342  m_ptIdValue->setText(ptId);
1343 
1344  updateLabels();
1345  }
1346 
1347 
1348 
1349  void StereoTool::paintProfile(MdiCubeViewport *vp, QPainter *painter,
1350  QString serialNumber) {
1351 
1352  // Draw profile
1353  int x1, y1, x2, y2;
1354  //MdiCubeViewport *cvp = cubeViewport();
1355  vp->cubeToViewport( m_startPoint->GetMeasure(serialNumber)->GetSample(),
1356  m_startPoint->GetMeasure(serialNumber)->GetLine(),
1357  x1, y1 );
1358  vp->cubeToViewport( m_endPoint->GetMeasure(serialNumber)->GetSample(),
1359  m_endPoint->GetMeasure(serialNumber)->GetLine(),
1360  x2, y2 );
1361  painter->setPen(Qt::green); // set all other point markers green
1362  painter->drawLine(x1, y1, x2, y2);
1363 
1364  }
1365 
1366 
1367 
1375  void StereoTool::paintViewport(MdiCubeViewport *vp, QPainter *painter) {
1376 
1377  AbstractPlotTool::paintViewport(vp, painter);
1378 
1379  // Make sure we have points to draw
1380  if ( m_controlNet == NULL || m_controlNet->GetNumPoints() == 0 )
1381  return;
1382 
1383  QString serialNumber = SerialNumber::Compose(*vp->cube(), true);
1384 
1385  // If viewport serial number not found in control net, return
1386  if ( !m_controlNet->GetCubeSerials().contains(
1387  serialNumber) ) return;
1388 
1389  // Draw profile if it exists
1390 // if (m_startPoint != NULL && m_endPoint != NULL) {
1391 // paintProfile(vp, painter, serialNumber);
1392 // }
1393 
1394  // Get all measures for this viewport
1395  QList<ControlMeasure *> measures =
1396  m_controlNet->GetMeasuresInCube(serialNumber);
1397  // loop through all measures contained in this cube
1398  for (int i = 0; i < measures.count(); i++) {
1399  ControlMeasure *m = measures[i];
1400  // Find the measurments on the viewport
1401  double samp = m->GetSample();
1402  double line = m->GetLine();
1403  int x, y;
1404  vp->cubeToViewport(samp, line, x, y);
1405  // if the point is ignored,
1406  if ( m->Parent()->IsIgnored() ) {
1407  painter->setPen( QColor(255, 255, 0) ); // set point marker yellow
1408  }
1409  // point is not ignored, but measure matching this image is ignored,
1410  else if ( m->IsIgnored() ) {
1411  painter->setPen( QColor(255, 255, 0) ); // set point marker yellow
1412  }
1413  // Neither point nor measure is not ignored and the measure is fixed,
1414  else if ( m->Parent()->GetType() != ControlPoint::Free) {
1415  painter->setPen(Qt::magenta);// set point marker magenta
1416  }
1417  else {
1418  painter->setPen(Qt::green); // set all other point markers green
1419  }
1420  // draw points
1421  painter->drawLine(x - 5, y, x + 5, y);
1422  painter->drawLine(x, y - 5, x, y + 5);
1423  }
1424 
1425  // if StereoTool is open,
1426  if ( m_editPoint != NULL ) {
1427  // and the selected point is in the image,
1428  if ( m_editPoint->HasSerialNumber(serialNumber) ) {
1429  // find the measurement
1430  double samp = (*m_editPoint)[serialNumber]->GetSample();
1431  double line = (*m_editPoint)[serialNumber]->GetLine();
1432  int x, y;
1433  vp->cubeToViewport(samp, line, x, y);
1434  // set point marker red
1435  QBrush brush(Qt::red);
1436  // set point marker bold - line width 2
1437  QPen pen(brush, 2);
1438  // draw the selected point in each image last so it's on top of the rest of the points
1439  painter->setPen(pen);
1440  painter->drawLine(x - 5, y, x + 5, y);
1441  painter->drawLine(x, y - 5, x, y + 5);
1442  }
1443  }
1444 
1445  }
1446 
1447 
1448 
1454 
1455  // Take care of drawing things on all viewPorts.
1456  // Calling update will cause the Tool class to call all registered tools
1457  // if point has been deleted, this will remove it from the main window
1458  MdiCubeViewport *vp;
1459  for (int i = 0; i < (int) cubeViewportList()->size(); i++) {
1460  vp = (*( cubeViewportList() ) )[i];
1461  vp->viewport()->update();
1462  }
1463  }
1464 
1465 
1466 
1467  void StereoTool::calculateElevation() {
1468  calculateElevation(m_editPoint);
1469  }
1470 
1471 
1472 
1477  void StereoTool::calculateElevation(ControlPoint *point) {
1478 
1479  double elevation=0., elevationError=0.;
1480  Camera *leftCamera = m_leftCube->camera();
1481 
1482  // If the local radius combo box is set to DEM, get the dem radius
1483  // First, SetImage using the Elevation model, before turning off
1484  // to get camera angles.
1485  if ( m_radiusBox->currentText() == "DEM Radius" ) {
1486  leftCamera->IgnoreElevationModel(false);
1487  leftCamera->SetImage( (*point)[Left]->GetSample(),
1488  (*point)[Left]->GetLine() );
1489  m_baseRadius = leftCamera->LocalRadius( leftCamera->GetLatitude(),
1490  leftCamera->GetLongitude() );
1491  if ( !m_baseRadius.isValid() ) {
1492  QString message = "Invalid Dem radius, defaulting to ellipsoidal.";
1493  QMessageBox::warning(m_stereoTool, "Invalid Dem radius", message);
1494  m_baseRadius = m_targetRadius;
1495  }
1496  }
1497 
1498  leftCamera->IgnoreElevationModel(true);
1499  leftCamera->SetImage( (*point)[Left]->GetSample(),
1500  (*point)[Left]->GetLine() );
1501  Camera *rightCamera = m_rightCube->camera();
1502  rightCamera->IgnoreElevationModel(true);
1503  rightCamera->SetImage( (*point)[Right]->GetSample(),
1504  (*point)[Right]->GetLine() );
1505 
1506  double radius, lat, lon, sepang;
1507  if ( Stereo::elevation( *leftCamera, *rightCamera, radius, lat, lon, sepang,
1508  elevationError ) ) {
1509  elevation = radius - m_baseRadius.meters();
1510 // cout<<setprecision(15)<<"radius = "<<radius<<" baseRadius = "<<m_baseRadius.meters()<<" elevation = "<<elevation<<endl;
1511  }
1512  leftCamera->IgnoreElevationModel(false);
1513  rightCamera->IgnoreElevationModel(false);
1514 
1515  // Save elevation and error info to the left ControlMeasure FocalPlaneComputeX/Y.
1516  // TODO: Find better way - This is not a good way to do this, using
1517  // ControlMeasure to save other values. Save The baseRadius in Diameter
1518  point->GetMeasure(Left)->SetFocalPlaneMeasured(elevation, elevationError);
1519  point->GetMeasure(Left)->SetDiameter(m_baseRadius.meters() );
1520  updateLabels();
1521 
1522  return;
1523  }
1524 
1525 
1526 
1535  QString filename = QFileDialog::getOpenFileName( m_stereoTool,
1536  "Select a registration template", ".",
1537  "Registration template files (*.def *.pvl);;All files (*)" );
1538 
1539  if ( filename.isEmpty() )
1540  return;
1541 
1542  m_pointEditor->setTemplateFile(filename);
1543  }
1544 
1545 
1559  try {
1560  // Get the template file from the ControlPointEditor object
1561  Pvl templatePvl( m_pointEditor->templateFileName() );
1562  // Create registration dialog window using PvlEditDialog class
1563  // to view and/or edit the template
1564  PvlEditDialog registrationDialog(templatePvl);
1565  registrationDialog.setWindowTitle( "View or Edit Template File: "
1566  + templatePvl.fileName() );
1567  registrationDialog.resize(550, 360);
1568  registrationDialog.exec();
1569  }
1570  catch (IException &e) {
1571  QString message = e.toString();
1572  QMessageBox::warning(m_stereoTool, "Error", message);
1573  }
1574  }
1575 
1576 
1583 
1584  QString fn = QFileDialog::getSaveFileName( m_stereoTool,
1585  "Choose filename to save under",
1586  ".",
1587  "CSV Files (*.csv)" );
1588  QString filename;
1589 
1590  //Make sure the filename is valid
1591  if ( !fn.isEmpty() ) {
1592  if ( !fn.endsWith(".csv") ) {
1593  filename = fn + ".csv";
1594  }
1595  else {
1596  filename = fn;
1597  }
1598  }
1599  //The user cancelled, or the filename is empty
1600  else {
1601  return;
1602  }
1603 
1604  m_currentFile.setFileName(filename);
1605 
1606  m_save->setEnabled(true);
1607  saveElevations();
1608  }
1609 
1610 
1611 
1612  void StereoTool::saveElevations() {
1613 
1614  if ( m_currentFile.fileName().isEmpty() ) return;
1615 
1616  bool success = m_currentFile.open(QIODevice::WriteOnly);
1617  if (!success) {
1618  QMessageBox::critical(m_stereoTool, "Error",
1619  "Cannot open file, please check permissions");
1620  m_currentFile.setFileName("");
1621  m_save->setDisabled(true);
1622  return;
1623  }
1624 
1625  QTextStream text(&m_currentFile);
1626  QString header = "Point ID, Latitude, Longitude, Radius, ";
1627  header += "Elevation, Elevation Error, ";
1628  header += "Image 1, Sample, Line, Image 2, Sample, Line";
1629  text << header << endl;
1630 
1631  QString leftFile = FileName( m_leftCube->fileName() ).name();
1632  QString rightFile = FileName( m_rightCube->fileName() ).name();
1633  QString data;
1634  for (int i = 0; i < m_controlNet->GetNumPoints(); i++) {
1635  ControlPoint &p = *( (*m_controlNet)[i] );
1636  SurfacePoint apriori = p.GetAprioriSurfacePoint();
1637  data = p.GetId() + "," +
1638  QString::number( apriori.GetLatitude().degrees() ) + "," +
1639  QString::number( apriori.GetLongitude().degrees() ) + "," +
1640  QString::number( p.GetMeasure(Left)->GetDiameter(), 'f', 6 ) +
1641  "," +
1642  QString::number( p.GetMeasure(Left)->GetFocalPlaneMeasuredX(), 'f',
1643  6 ) + "," +
1644  QString::number( p.GetMeasure(Left)->GetFocalPlaneMeasuredY(), 'f',
1645  6 ) + "," + leftFile + "," +
1646  QString::number( p.GetMeasure(Left)->GetSample() ) + "," +
1647  QString::number( p.GetMeasure(Left)->GetLine() ) + "," +
1648  rightFile + "," +
1649  QString::number( p.GetMeasure(Right)->GetSample() ) + "," +
1650  QString::number( p.GetMeasure(Right)->GetLine() );
1651  text << data << endl;
1652  }
1653  m_currentFile.close();
1654 
1655  }
1656 
1657 
1658 
1659  void StereoTool::clearNetData() {
1660 
1661  delete m_controlNet;
1662  m_controlNet = NULL;
1663  delete m_serialNumberList;
1664  m_serialNumberList = NULL;
1665 
1666  }
1667 
1668 
1669 
1670  void StereoTool::profile() {
1671 
1672 // (*m_startPoint)[Left]->SetCoordinate(1361.92,1317.9433);
1673 // (*m_endPoint)[Left]->SetCoordinate(1188.43,2763.23);
1674 // (*m_startPoint)[Right]->SetCoordinate(867.04,2141.16);
1675 // (*m_endPoint)[Right]->SetCoordinate(731.82,2666.75);
1676 
1677  // Delete the profile dialog
1678  if (m_profileDialog) {
1679  delete m_profileDialog;
1680  m_profileDialog = NULL;
1681  }
1682 
1683 // calculateElevation(m_startPoint);
1684 // calculateElevation(m_endPoint);
1685 
1686  QPointF leftStart( (*m_startPoint)[Left]->GetSample(),
1687  (*m_startPoint)[Left]->GetLine() );
1688  QPointF leftEnd( (*m_endPoint)[Left]->GetSample(),
1689  (*m_endPoint)[Left]->GetLine() );
1690 
1691  QPointF rightStart( (*m_startPoint)[Right]->GetSample(),
1692  (*m_startPoint)[Right]->GetLine() );
1693  QPointF rightEnd( (*m_endPoint)[Right]->GetSample(),
1694  (*m_endPoint)[Right]->GetLine() );
1695 
1696  // Convert these to screen coordinates for updating the rubberband
1697  QList< QList<QPoint> > rubberBandVertices;
1698  QList<QPoint> rubberBand1;
1699  int sx, sy, ex, ey;
1700  m_linkedViewports.at(0)->cubeToViewport( (*m_startPoint)[Left]->GetSample(),
1701  (*m_startPoint)[Left]->GetLine(), sx, sy);
1702  m_linkedViewports.at(0)->cubeToViewport( (*m_endPoint)[Left]->GetSample(),
1703  (*m_endPoint)[Left]->GetLine(), ex, ey);
1704  rubberBand1.push_back( QPoint(sx, sy) );
1705  rubberBand1.push_back( QPoint(ex, ey) );
1706 
1707  rubberBandVertices.push_back(rubberBand1);
1708 
1709  QList<QPoint> rubberBand2;
1710  m_linkedViewports.at(1)->cubeToViewport( (*m_startPoint)[Right]->GetSample(),
1711  (*m_startPoint)[Right]->GetLine(), sx, sy);
1712  m_linkedViewports.at(1)->cubeToViewport( (*m_endPoint)[Right]->GetSample(),
1713  (*m_endPoint)[Right]->GetLine(), ex, ey);
1714  rubberBand2.push_back( QPoint(sx, sy) );
1715  rubberBand2.push_back( QPoint(ex, ey) );
1716 
1717  rubberBandVertices.push_back(rubberBand2);
1718 
1719  // Create line for left image
1720  QLineF leftProfile(leftStart,leftEnd);
1721  QLineF rightProfile(rightStart,rightEnd);
1722 
1723  // Determine shortest line, we will step through shortest line,
1724  // finding the matching position on the longer line.
1725  QLineF longProfile, shortProfile;
1726  Cube *longCube, *shortCube;
1727  if ( leftProfile.length() > rightProfile.length() ) {
1728  longProfile = leftProfile;
1729  longCube = m_leftCube;
1730  shortProfile = rightProfile;
1731  shortCube = m_rightCube;
1732  }
1733  else {
1734  longProfile = rightProfile;
1735  longCube = m_rightCube;
1736  shortProfile = leftProfile;
1737  shortCube = m_leftCube;
1738  }
1739 
1740  QVector<QPointF> profileData;
1741  double elevation = 0.;
1742  double elevationError = 0.;
1743 
1744  Pvl regDef = m_pointEditor->templateFileName();
1745  AutoReg *ar = AutoRegFactory::Create(regDef);
1746 
1747  int failureCount = 0;
1748  QApplication::setOverrideCursor(Qt::WaitCursor);
1749 
1750  for (int i = 0; i <= (int) shortProfile.length(); i++) {
1751  double shortSamp=0, shortLine=0, longSamp=0, longLine=0;
1752  try {
1753  shortSamp = shortProfile.pointAt( 1/shortProfile.length() * i ).x();
1754  shortLine = shortProfile.pointAt( 1/shortProfile.length() * i ).y();
1755 
1756  longSamp = longProfile.pointAt( 1/shortProfile.length() * i ).x();
1757  longLine = longProfile.pointAt( 1/shortProfile.length() * i ).y();
1758 
1759  // Coreg
1760  ar->PatternChip()->TackCube(shortSamp, shortLine);
1761  ar->PatternChip()->Load(*shortCube);
1762  ar->SearchChip()->TackCube(longSamp, longLine);
1763  ar->SearchChip()->Load( *longCube, *( ar->PatternChip() ), *shortCube );
1764  ar->Register();
1765 // AutoReg::RegisterStatus status = ar->Register();
1766  if ( ar->Success() ) {
1767  longSamp = ar->CubeSample();
1768  longLine = ar->CubeLine();
1769 
1770  // If the local radius combo box is set to DEM, get the dem radius
1771  // First, SetImage using the Elevation model, before turning off
1772  // to get camera angles.
1773  if ( m_radiusBox->currentText() == "DEM Radius" ) {
1774  shortCube->camera()->IgnoreElevationModel(false);
1775  shortCube->camera()->SetImage(shortSamp, shortLine);
1776  m_baseRadius = shortCube->camera()->LocalRadius(
1777  shortCube->camera()->GetLatitude(),
1778  shortCube->camera()->GetLongitude() );
1779  if ( !m_baseRadius.isValid() ) {
1780  QString message = "Invalid Dem radius, defaulting to ellipsoidal.";
1781  QMessageBox::warning(m_stereoTool, "Invalid Dem radius", message);
1782  m_baseRadius = m_targetRadius;
1783  }
1784  }
1785 
1786  shortCube->camera()->IgnoreElevationModel(true);
1787  longCube->camera()->IgnoreElevationModel(true);
1788 
1789  shortCube->camera()->SetImage(shortSamp, shortLine);
1790  longCube->camera()->SetImage(longSamp,longLine);
1791  double radius, lat, lon, sepang;
1792  if (Stereo::elevation( *shortCube->camera(), *longCube->camera(),
1793  radius, lat, lon, sepang, elevationError) )
1794  elevation = radius - m_baseRadius.meters();
1795  profileData.append( QPointF(i, elevation) );
1796 // elevations.push_back(elevation);
1797 // pixels.push_back(i);
1798  }
1799  else {
1800  failureCount++;
1801  }
1802  }
1803  catch (IException &e) {
1804  QString message = "Error registering cubes along profile line.\n";
1805  message += "Image 1 Sample = " + QString::number(shortSamp);
1806  message += " Line = " + QString::number(shortLine);
1807  message += "\nImage 2 Sample = " + QString::number(longSamp);
1808  message += " Line = " + QString::number(longLine) + "\n\n";
1809  message += e.toString();
1810  QMessageBox::critical(m_stereoTool, "Error", message);
1811  rubberBandTool()->clear();
1812  }
1813 
1814  }
1815  QApplication::restoreOverrideCursor();
1816 
1817 // cout<<"Registration attempts = "<<(int)shortLength<<" failures = "<<failureCount<<endl;
1818  QString message = "Registration attempts (pixels on line) = " +
1819  QString::number( (int)shortProfile.length() ) +
1820  "\n\nRegistration failures = " +
1821  QString::number(failureCount) +
1822  "\n\nYou can adjust registration parameters in the "
1823  "\"Options\" menu in the Elevation Calculator window. "
1824  "Select \"Options\", then \"Registration\", then either "
1825  "\"Select registration template\" or "
1826  "\"View/edit registration template\".";
1827  QMessageBox::information(m_stereoTool, "Registration Report", message);
1828 
1829  if ( ( (int)shortProfile.length() + 1 - failureCount ) < 2 ) {
1830  QString message = "Cannot create profile, all auto-registration between ";
1831  message += "the left and right cubes along the profile failed. Try ";
1832  message += "adjusting the registration parameters.";
1833  QMessageBox::critical(m_stereoTool, "Error", message);
1834  return;
1835  }
1836  PlotWindow *plotWindow = selectedWindow(true);
1837  plotWindow->setAxisLabel(0,"Elevation (meters)");
1840 // plotCurve->setData(&pixels[0], &elevations[0], pixels.size() );
1841  plotCurve->setData( new QwtPointSeriesData(profileData) );
1842  plotCurve->setTitle("Elevations (Meters)");
1843  plotCurve->setPen( QPen(Qt::white) );
1844  plotCurve->setColor(Qt::white);
1845  // Create vertices for rubberband based on refined profile end points
1846 
1847  // TODO: This needs to be changed to band displayed???
1848  QList<int> bands;
1849  bands.push_back(1);
1850  bands.push_back(1);
1851  plotCurve->setSource(m_linkedViewports, rubberBandVertices, bands);
1852  plotWindow->add(plotCurve);
1853 
1854  delete m_profileDialog;
1855  m_profileDialog = NULL;
1856 // m_startPoint = NULL;
1857 // m_endPoint = NULL;
1858 // rubberBandTool()->clear();
1859 
1860  }
1861 
1862 
1863 
1864  void StereoTool::updateLabels() {
1865  // Empty elevation info if nothing there
1866  QString elevationLabel, elevationErrorLabel;
1867  QString baseRadiiLabel, leftDemRadiiLabel, rightDemRadiiLabel;
1868  if ( m_editPoint->GetMeasure(Left)->GetFocalPlaneMeasuredX() != Isis::Null ) {
1869  elevationLabel = "Elevation: " +
1870  QString::number( m_editPoint->GetMeasure(Left)->
1871  GetFocalPlaneMeasuredX(), 'f', 6 );
1872  elevationErrorLabel = "Elevation Error: " +
1873  QString::number( m_editPoint->GetMeasure(Left)->
1874  GetFocalPlaneMeasuredY(), 'f', 6 );
1875  baseRadiiLabel = "Local Radii: " + QString::number(
1876  m_baseRadius.meters(), 'f', 6 );
1877 
1878  Camera *leftCamera = m_leftCube->camera();
1879  leftCamera->SetImage( (*m_editPoint)[Left]->GetSample(),
1880  (*m_editPoint)[Left]->GetLine() );
1881  double leftDemRadii =
1882  leftCamera->GetSurfacePoint().GetLocalRadius().meters();
1883  leftDemRadiiLabel = "Left DEM Radii: " +
1884  QString::number(leftDemRadii, 'f', 6);
1885 
1886  Camera *rightCamera = m_rightCube->camera();
1887  rightCamera->SetImage( (*m_editPoint)[Right]->GetSample(),
1888  (*m_editPoint)[Right]->GetLine() );
1889  double rightDemRadii =
1890  rightCamera->GetSurfacePoint().GetLocalRadius().meters();
1891  rightDemRadiiLabel = "Right DEM Radii: " +
1892  QString::number(rightDemRadii, 'f', 6);
1893  }
1894  else {
1895  elevationLabel = "Elevation: ";
1896  elevationErrorLabel = "Elevation Error: ";
1897  baseRadiiLabel = "Local Radii: ";
1898  leftDemRadiiLabel = "Left DEM Radii: ";
1899  rightDemRadiiLabel = "Right DEM Radii: ";
1900  }
1901  m_elevationLabel->setText(elevationLabel);
1902  m_elevationErrorLabel->setText(elevationErrorLabel);
1903  m_baseRadiiLabel->setText(baseRadiiLabel);
1904  m_leftDemRadiiLabel->setText(leftDemRadiiLabel);
1905  m_rightDemRadiiLabel->setText(rightDemRadiiLabel);
1906  }
1907 
1908 
1909 
1910  void StereoTool::readSettings() {
1911  FileName config("$HOME/.Isis/qview/Stereo Tool.config");
1912  QSettings settings(config.expanded(),
1913  QSettings::NativeFormat);
1914  m_showWarning = settings.value("showWarning", true).toBool();
1915 
1916  }
1917 
1918 
1919 
1920  void StereoTool::writeSettings() {
1921  FileName config("$HOME/.Isis/qview/Stereo Tool.config");
1922  QSettings settings(config.expanded(),
1923  QSettings::NativeFormat);
1924  settings.setValue("showWarning", m_showWarning);
1925 
1926  }
1927 }
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:148
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Cube display widget for certain Isis MDI applications.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
void IgnoreElevationModel(bool ignore)
This allows you to ignore the cube elevation model and use the ellipse.
Definition: Sensor.cpp:75
void measureSaved()
Save control measures under crosshairs of ChipViewports.
Definition: StereoTool.cpp:850
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
double Line() const
Returns the current line value of the camera model or projection.
void setFiles(Cube *leftCube, Cube *rightCube)
Setup the stereo cubes.
Definition: StereoTool.cpp:783
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
Cube * cube() const
Definition: CubeViewport.h:348
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
PlotWindow * createWindow()
This needs to be implemented by children to instantiate a plot window of the appropriate child class ...
Definition: StereoTool.cpp:348
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
File name manipulation and expansion.
Definition: FileName.h:116
Universal Ground Map.
Camera * camera()
Return a camera associated with the cube.
Definition: Cube.cpp:1166
void createPoint(double lat, double lon)
Create control point at given lat,lon.
void setSource(CubeViewport *cvp, QList< QPoint > screenPoints, int band=-1)
Tell this plot curve from where its data originated.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube&#39;s serial number.
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
int sampleCount() const
Definition: Cube.cpp:1452
QString serialNumber(const QString &filename)
Return a serial number given a filename.
Namespace for the standard library.
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition: Chip.cpp:204
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:63
QWidget * createToolBarWidget(QStackedWidget *parent)
Attaches this tool to the toolbar.
Definition: StereoTool.cpp:280
void paintAllViewports()
This method will repaint the control measures in each viewport.
void setDrawActiveViewportOnly(bool activeOnly=false)
This called to set whether rubber band is drawn on active viewport only rather than all linked viewpo...
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
Definition: AutoReg.cpp:600
void createStereoTool(QWidget *parent)
Design the StereoTool widget.
Definition: StereoTool.cpp:103
Chip * SearchChip()
Return pointer to search chip.
Definition: AutoReg.h:223
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
void cubeToViewport(double sample, double line, int &x, int &y) const
Turns a cube into a viewport.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance measurement, usually in meters.
Definition: Distance.h:47
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
void clearFiles()
New files selected, clean up old file info.
Definition: StereoTool.cpp:760
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:249
QWidget * createToolBarWidget(QStackedWidget *parent)
This provides the standard plot tool options, such as selecting an active plot window.
A Free point is a Control Point that identifies common measurements between two or more cubes...
Definition: ControlPoint.h:399
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
void clear()
clears the rubber band!
Status SetDiameter(double diameter)
Set the crater diameter at the coordinate.
double CubeSample() const
Return the search chip cube sample that best matched.
Definition: AutoReg.h:356
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:282
void setRightMeasure(ControlMeasure *rightMeasure, Cube *rightCube, QString pointId)
Set the measure displayed in the right ChipViewport.
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:170
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
void viewTemplateFile()
Allows the user to view the template file that is currently set.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:73
a control network
Definition: ControlNet.h:271
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename...
Hand Measured (e.g., qnet)
void modifyPoint(ControlPoint *point)
Modify given control point.
QString GetId() const
Return the Id of the control point.
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1290
bool SetGround(Latitude lat, Longitude lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
Pixel value mapper.
Definition: Stretch.h:72
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
Chip * PatternChip()
Return pointer to pattern chip.
Definition: AutoReg.h:218
This is a plot curve with information relating it to a particular cube or region of a cube...
Definition: CubePlotCurve.h:68
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
Status SetAprioriSurfacePoint(SurfacePoint aprioriSP)
This updates the apriori surface point.
static PvlGroup radiiGroup(QString target)
Creates a Pvl Group with keywords TargetName, EquitorialRadius, and PolarRadius.
Definition: Target.cpp:393
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
double CubeLine() const
Return the search chip cube line that best matched.
Definition: AutoReg.h:361
A single control point.
Definition: ControlPoint.h:369
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:204
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:615
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
Definition: Sensor.cpp:260
void setColor(const QColor &color)
Set the color of this curve and it&#39;s markers.
Definition: PlotCurve.cpp:97
bool Success() const
Return whether the match algorithm succeeded or not.
Definition: AutoReg.h:334
void setAxisLabel(int axisId, QString title)
Sets the plots given axis title to the given string.
Definition: PlotWindow.cpp:208
Container for cube-like labels.
Definition: Pvl.h:135
The data is a pixel #.
Definition: PlotCurve.h:79
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Definition: Chip.cpp:225
Auto Registration class.
Definition: AutoReg.h:183
Status SetType(PointType newType)
Updates the control point&#39;s type.
void paintViewport(MdiCubeViewport *cvp, QPainter *painter)
Repaint the given CubeViewport.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
void loadPoint()
Load control point into the ControlPointEdit widget.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
virtual void paintViewport(MdiCubeViewport *vp, QPainter *painter)
This method allows each plot window to paint any information it wants onto the cube viewports...
static AutoReg * Create(Pvl &pvl)
Create an AutoReg object using a PVL specification.
void setTemplateFile()
Allows user to set a new template file.
void deletePoint(ControlPoint *point)
Delete given control point.
void setData(QwtSeriesData< QPointF > *data)
This method sets the data for the curve, then sets the value for the markers associated with the curv...
Definition: PlotCurve.cpp:109
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:537
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Status SetFocalPlaneMeasured(double x, double y)
Set the focal plane x/y for the measured line/sample.
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
void createMenus()
Create the menus for StereoTool.
Definition: StereoTool.cpp:178
void saveAsElevations()
Save the elevation information to file.
The data is an elevation (in meters).
Definition: PlotCurve.h:71
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
void detachCurves()
This will be called when the selected plot window changes.
Definition: StereoTool.cpp:357
PlotWindow * selectedWindow(bool createIfNeeded=true)
Get the &#39;active&#39; plot window (the window selected by the user to contain new curves).
int lineCount() const
Definition: Cube.cpp:1379
static QString UserName()
Returns the user name.
Isis exception class.
Definition: IException.h:107
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition: Sensor.cpp:270
Adds specific functionality to C++ strings.
Definition: IString.h:181
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
a control measurement
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
Definition: PvlEditDialog.h:39
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
QAction * toolPadAction(ToolPad *pad)
Put the StereoTool icon on the main window Toolpad.
Definition: StereoTool.cpp:250
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
The distance is being specified in meters.
Definition: Distance.h:56
Point Editor Widget.
Status SetDateTime()
Date Time - Creation Time.
double Sample() const
Returns the current line value of the camera model or projection.
void setPen(const QPen &pen)
Sets the plot pen to the passed-in pen.
Definition: PlotCurve.cpp:340
PointType GetType() const
Parent class for plotting tools which provides common functionality.
Serial Number list generator.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
Definition: PlotWindow.cpp:436
Distance GetLocalRadius() const
Return the radius of the surface point.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
void enableRubberBandTool()
This methods enables the RubberBandTool, it also sets the RubberBandTool to allow points and to allow...
Definition: StereoTool.cpp:886
Latitude GetLatitude() const
Returns a planetocentric latitude object at the surface intersection point in body fixed...
Definition: Sensor.cpp:236
double GetDiameter() const
Return the diameter of the crater in pixels (0 implies no crater)
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
void setLeftMeasure(ControlMeasure *leftMeasure, Cube *leftCube, QString pointId)
Set the measure displayed in the left ChipViewport.
IO Handler for Isis Cubes.
Definition: Cube.h:170
void enable(RubberBandMode mode, bool showIndicatorColors=false)
This is called when changing modes or turning on.