Isis 3.0 Programmer Reference
Back | Home
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  std::vector<Distance> targetRadius = m_controlNet->GetTargetRadii();
807  m_targetRadius = Distance(targetRadius[0]);
808  // If radius combo box set to ellipsoid, update the radius line edit
809  if ( !m_targetRadius.isValid() ) {
810  QString message = "Could not determine target radius.";
811  QMessageBox::critical(m_stereoTool,"Error",message);
812  m_baseRadius = Distance(0., Distance::Meters);
813  updateRadiusLineEdit();
814  return;
815  }
816  updateRadiusLineEdit();
817 
818  // Save off universal ground maps
819  try {
820  m_leftGM = new UniversalGroundMap(*m_leftCube);
821  }
822  catch (IException &e) {
823  QString message = "Cannot initialize universal ground map for " +
824  m_leftCube->fileName() + ".\n";
825  message += e.toString();
826  QMessageBox::critical(m_stereoTool, "Error", message);
827  return;
828  }
829  try {
830  m_rightGM = new UniversalGroundMap(*m_rightCube);
831  }
832  catch (IException &e) {
833  QString message = "Cannot initialize universal ground map for" +
834  m_rightCube->fileName() + ".\n";
835  message += e.toString();
836  QMessageBox::critical(m_stereoTool, "Error", message);
837  return;
838  }
839 
840 
841  }
842 
843 
844 
850 
851  double samp = m_editPoint->GetMeasure(Left)->GetSample();
852  double line = m_editPoint->GetMeasure(Left)->GetLine();
853  m_leftGM->SetImage(samp, line);
854  double lat = m_leftGM->UniversalLatitude();
855  double lon = m_leftGM->UniversalLongitude();
856 
857  m_rightGM->SetGround(
859  try {
860  m_editPoint->SetAprioriSurfacePoint(SurfacePoint (
862  m_targetRadius ) );
863  }
864  catch (IException &e) {
865  QString message = "Unable to set Apriori Surface Point.\n";
866  message += "Latitude = " + QString::number(lat);
867  message += " Longitude = " + QString::number(lon);
868  message += " Radius = " + QString::number(m_targetRadius.meters(), 'f',
869  6) + "\n";
870  message += e.toString();
871  QMessageBox::critical(m_stereoTool, "Error", message);
872  }
873 
874  calculateElevation();
875  emit editPointChanged();
876  }
877 
878 
879 
886  rubberBandTool()->enable(RubberBandTool::LineMode);
887  rubberBandTool()->enablePoints();
888  rubberBandTool()->enableAllClicks();
889  rubberBandTool()->setDrawActiveViewportOnly(true);
890  }
891 
892 
893 
894  void StereoTool::rubberBandComplete() {
895 
896 // clearProfile();
897 
898  try {
899  setupFiles();
900  }
901  catch (IException &e) {
902  QString message = e.toString();
903  QMessageBox::critical(m_stereoTool, "Error setting stereo pair", message);
904  rubberBandTool()->clear();
905  return;
906  }
907 
908  MdiCubeViewport *cvp = cubeViewport();
909  if (cvp == NULL)
910  return;
911 
912  QString file = cvp->cube()->fileName();
913  QString sn;
914  try {
915  sn = m_serialNumberList->serialNumber(file);
916  }
917  catch (IException &e) {
918  QString message = "This cube is not linked as a stereo pair. Make ";
919  message += "sure you have two stereo pair cube viewports linked.";
920  QMessageBox::critical(m_stereoTool,"Viewport not linked", message);
921  return;
922  }
923 
924  if ( rubberBandTool()->figureIsPoint() ) {
925  double samp, line;
926  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
927  rubberBandTool()->vertices()[0].ry(),
928  samp, line );
929  if ( rubberBandTool()->mouseButton() & Qt::LeftButton ) {
930  if ( !m_controlNet || m_controlNet->GetNumMeasures() == 0 ) {
931  QString message = "No points exist for editing. Create points ";
932  message += "using the right mouse button.";
933  QMessageBox::information(m_stereoTool, "Warning", message);
934  return;
935  }
936  // Find closest control point in network
937  ControlPoint *point;
938  try {
939  point = m_controlNet->FindClosest(sn, samp, line);
940  }
941  catch (IException &e) {
942  QString message = "No points found for editing. Create points ";
943  message += "using the right mouse button.";
944  message += e.toString();
945  QMessageBox::critical(m_stereoTool, "Error", message);
946  return;
947  }
948  modifyPoint(point);
949  }
950  else if ( rubberBandTool()->mouseButton() & Qt::MidButton ) {
951  if ( !m_controlNet || m_controlNet->GetNumPoints() == 0 ) {
952  QString message = "No points exist for deleting. Create points ";
953  message += "using the right mouse button.";
954  QMessageBox::warning(m_stereoTool, "Warning", message);
955  return;
956  }
957 
958  // Find closest control point in network
959  ControlPoint *point =
960  m_controlNet->FindClosest(sn, samp, line);
961  // TODO: test for errors and reality
962  if (point == NULL) {
963  QString message = "No points exist for deleting. Create points ";
964  message += "using the right mouse button.";
965  QMessageBox::information(m_stereoTool, "Warning", message);
966  return;
967  }
968  deletePoint(point);
969  }
970  else if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
971  double lat, lon;
972  if (cvp->cube() == m_leftCube) {
973  m_leftGM->SetImage(samp, line);
974  lat = m_leftGM->UniversalLatitude();
975  lon = m_leftGM->UniversalLongitude();
976  }
977  else {
978  m_rightGM->SetImage(samp, line);
979  lat = m_rightGM->UniversalLatitude();
980  lon = m_rightGM->UniversalLongitude();
981  }
982  try {
983  createPoint(lat, lon);
984  }
985  catch (IException &e) {
986  QString message = "Cannot create control point.\n\n";
987  message += e.toString();
988  QMessageBox::critical(m_stereoTool, "Error", message);
989  m_startPoint = NULL;
990  rubberBandTool()->clear();
991  return;
992  }
993  }
994  }
995  // RubberBand line drawn:
996  else {
997  m_startPoint = NULL;
998  m_endPoint = NULL;
999  // Right click/drag: Find closest end points
1000  if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
1001  double samp, line;
1002  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
1003  rubberBandTool()->vertices()[0].ry(),
1004  samp, line );
1005  try {
1006  m_startPoint = m_controlNet->FindClosest(sn, samp, line);
1007  }
1008  catch (IException &e) {
1009  QString message = "Cannot find start point for profile. Either ";
1010  message += "create end points individually using the right mouse ";
1011  message += "button. Or, create profile end points by clicking and ";
1012  message += "dragging with the right mouse button.\n\n";
1013  message += e.toString();
1014  QMessageBox::critical(m_stereoTool, "Error", message);
1015  m_startPoint = NULL;
1016  rubberBandTool()->clear();
1017  return;
1018  }
1019  cvp->viewportToCube( rubberBandTool()->vertices()[1].rx(),
1020  rubberBandTool()->vertices()[1].ry(),
1021  samp, line );
1022  try {
1023  m_endPoint = m_controlNet->FindClosest(sn, samp, line);
1024  if ( m_startPoint->GetId() == m_endPoint->GetId() ) {
1025  throw IException(IException::User, "No End Point",
1026  _FILEINFO_);
1027  }
1028  }
1029  catch (IException &e) {
1030  QString message = "Cannot find end point for profile. Either ";
1031  message += "create end points individually using the right mouse ";
1032  message += "button. Or, create profile end points by clicking and ";
1033  message += "dragging with the right mouse button.\n\n";
1034  message += e.toString();
1035  QMessageBox::critical(m_stereoTool, "Error", message);
1036  m_startPoint = NULL;
1037  m_endPoint = NULL;
1038  rubberBandTool()->clear();
1039  return;
1040  }
1041  profile();
1042  }
1043  else {
1044  // Left click/drag: Create control points at the line endpoints.
1045  m_profileDialog = new ProfileDialog();
1046  connect( m_profileDialog, SIGNAL( createStart() ),
1047  this, SLOT( createStartPoint() ) );
1048  connect( m_profileDialog, SIGNAL( createEnd() ),
1049  this, SLOT( createEndPoint() ) );
1050  connect( m_profileDialog, SIGNAL( accepted() ),
1051  this, SLOT( profile() ) );
1052  connect( m_profileDialog, SIGNAL( accepted() ),
1053  this, SLOT( profile() ) );
1054  connect( m_profileDialog, SIGNAL( rejected() ),
1055  this, SLOT( clearProfile() ) );
1056  m_profileDialog->show();
1057  m_profileDialog->activateWindow();
1058  }
1059  }
1060  }
1061 
1062 
1063 
1064  void StereoTool::clearProfile() {
1065  m_startPoint = NULL;
1066  m_endPoint = NULL;
1067  rubberBandTool()->clear();
1068  delete m_profileDialog;
1069  m_profileDialog = NULL;
1070  }
1071 
1072 
1073 
1074  void StereoTool::createStartPoint() {
1075  MdiCubeViewport *cvp = cubeViewport();
1076  if (cvp == NULL)
1077  return;
1078 
1079  double samp, line;
1080  double lat, lon;
1081  cvp->viewportToCube( rubberBandTool()->vertices()[0].rx(),
1082  rubberBandTool()->vertices()[0].ry(),
1083  samp, line );
1084  if ( cvp->cube() == m_leftCube ) {
1085  m_leftGM->SetImage(samp, line);
1086  lat = m_leftGM->UniversalLatitude();
1087  lon = m_leftGM->UniversalLongitude();
1088  }
1089  else {
1090  m_rightGM->SetImage(samp, line);
1091  lat = m_rightGM->UniversalLatitude();
1092  lon = m_rightGM->UniversalLongitude();
1093  }
1094  try {
1095  createPoint(lat, lon);
1096  }
1097  catch (IException &e) {
1098  QString message = "Cannot create control point.\n\n";
1099  message += e.toString();
1100  QMessageBox::critical(m_stereoTool, "Error", message);
1101  delete m_profileDialog;
1102  m_profileDialog = NULL;
1103  rubberBandTool()->clear();
1104  return;
1105  }
1106  m_startPoint = m_editPoint;
1107  }
1108 
1109 
1110 
1111  void StereoTool::createEndPoint() {
1112  MdiCubeViewport *cvp = cubeViewport();
1113  if (cvp == NULL)
1114  return;
1115 
1116  double samp, line;
1117  double lat, lon;
1118  cvp->viewportToCube( rubberBandTool()->vertices()[1].rx(),
1119  rubberBandTool()->vertices()[1].ry(),
1120  samp, line );
1121  if ( cvp->cube() == m_leftCube ) {
1122  m_leftGM->SetImage(samp, line);
1123  lat = m_leftGM->UniversalLatitude();
1124  lon = m_leftGM->UniversalLongitude();
1125  }
1126  else {
1127  m_rightGM->SetImage(samp, line);
1128  lat = m_rightGM->UniversalLatitude();
1129  lon = m_rightGM->UniversalLongitude();
1130  }
1131  try {
1132  createPoint(lat, lon);
1133  }
1134  catch (IException &e) {
1135  QString message = "Cannot create control point.\n\n";
1136  message += e.toString();
1137  QMessageBox::critical(m_stereoTool, "Error", message);
1138  m_startPoint = NULL;
1139  delete m_profileDialog;
1140  m_profileDialog = NULL;
1141  rubberBandTool()->clear();
1142  return;
1143  }
1144  m_endPoint = m_editPoint;
1145 
1146  }
1147 
1148 
1149 
1162  void StereoTool::createPoint(double lat, double lon) {
1163 
1164  // TODO: ADD AUTOSEED OPTION (CHECKBOX?)
1165 
1166  double leftSamp = 0, leftLine = 0;
1167  double rightSamp = 0, rightLine = 0;
1168 
1169  // Make sure point exists on both linked cubes
1170  if ( m_leftGM->SetUniversalGround(lat, lon) ) {
1171  leftSamp = m_leftGM->Sample();
1172  leftLine = m_leftGM->Line();
1173 
1174  // Make sure point is on Right cube
1175  if ( m_rightGM->SetUniversalGround(lat, lon) ) {
1176  // Make sure point on Right cube
1177  rightSamp = m_rightGM->Sample();
1178  rightLine = m_rightGM->Line();
1179  if ( rightSamp < 1 || rightSamp > m_rightCube->sampleCount() ||
1180  rightLine < 1 || rightLine > m_rightCube->lineCount() ) {
1181  IString message = "Point does not exist on cube, " +
1182  m_rightCube->fileName() + ".";
1183  throw IException(IException::User, message, _FILEINFO_);
1184 // QString message = "Point does not exist on cube, " +
1185 // QString(m_rightCube->fileName().c_str() ) + ".";
1186 // QMessageBox::critical(m_stereoTool, "Error", message);
1187 // return;
1188  }
1189  }
1190  else {
1191  IString message = "Point does not exist on cube, " +
1192  m_rightCube->fileName() + ".";
1193  throw IException(IException::User, message, _FILEINFO_);
1194 // QString message = "Point does not exist on cube, " +
1195 // QString(m_rightCube->fileName().c_str() ) + ".";
1196 // QMessageBox::critical(m_stereoTool, "Error", message);
1197 // return;
1198  }
1199  }
1200  else {
1201  IString message = "Point does not exist on cube, " +
1202  m_leftCube->fileName() + ".";
1203  throw IException(IException::User, message, _FILEINFO_);
1204 // QString message = "Point does not exist on cube, " +
1205 // QString(m_leftCube->fileName().c_str() ) + ".";
1206 // QMessageBox::critical(m_stereoTool, "Error", message);
1207 // return;
1208  }
1209 
1210  // Point is on both Left and Right cubes, create new control point
1211  ControlPoint *newPoint = NULL;
1212  // Prompt for point Id
1213  bool goodId = false;
1214  while (!goodId) {
1215  bool ok = false;
1216  QString id = QInputDialog::getText(m_stereoTool,
1217  "Point ID", "Enter Point ID:",
1218  QLineEdit::Normal, lastPtIdValue,
1219  &ok);
1220  if (!ok)
1221  // user clicked "Cancel"
1222  {
1223  return;
1224  }
1225  if ( ok && id.isEmpty() ) {
1226  // user clicked "Ok" but did not enter a point ID
1227  QString message = "You must enter a point Id.";
1228  QMessageBox::warning(m_stereoTool, "Warning", message);
1229  }
1230  else {
1231  // Make sure Id doesn't already exist
1232  newPoint = new ControlPoint(id);
1233  if ( m_controlNet->GetNumPoints() > 0 &&
1234  m_controlNet->ContainsPoint(newPoint->GetId() ) ) {
1235  QString message = "A ControlPoint with Point Id = [" +
1236  newPoint->GetId() +
1237  "] already exists. Re-enter unique Point Id.";
1238  QMessageBox::warning(m_stereoTool, "Unique Point Id", message);
1239  }
1240  else {
1241  goodId = true;
1242  lastPtIdValue = id;
1243  }
1244  }
1245  }
1246 
1247  newPoint->SetType(ControlPoint::Free);
1250  m_targetRadius) );
1251 
1252  // Set first measure to Left
1253  ControlMeasure *mLeft = new ControlMeasure;
1254  mLeft->SetCubeSerialNumber(m_leftSN);
1255  mLeft->SetCoordinate(leftSamp, leftLine);
1257  mLeft->SetDateTime();
1259  newPoint->Add(mLeft);
1260  // Second measure is Right measure
1261  ControlMeasure *mRight = new ControlMeasure;
1262  mRight->SetCubeSerialNumber(m_rightSN);
1263  mRight->SetCoordinate(rightSamp, rightLine);
1265  mRight->SetDateTime();
1267  newPoint->Add(mRight);
1268 
1269  // Add new control point to control network
1270  m_controlNet->AddPoint(newPoint);
1271  // Read newly added point
1272  m_editPoint = m_controlNet->GetPoint( (QString) newPoint->GetId() );
1273  // Load new point in StereoTool
1274  loadPoint();
1275  m_stereoTool->setVisible(true);
1276  m_stereoTool->raise();
1277 
1278  emit editPointChanged();
1279  }
1280 
1281 
1294 
1295  m_editPoint = point;
1296  // Change point in viewport to red so user can see what point they are
1297  // about to delete.
1298  emit editPointChanged();
1299 
1300  //loadPoint();
1301 
1302  m_controlNet->DeletePoint( m_editPoint->GetId() );
1303  m_stereoTool->setVisible(false);
1304  m_editPoint = NULL;
1305 
1306  emit editPointChanged();
1307  }
1308 
1309 
1317 
1318  m_editPoint = point;
1319  loadPoint();
1320  m_stereoTool->setVisible(true);
1321  m_stereoTool->raise();
1322  emit editPointChanged();
1323  }
1324 
1325 
1332 
1333  // Initialize pointEditor with measures
1334  m_pointEditor->setLeftMeasure( m_editPoint->GetMeasure(Left), m_leftCube,
1335  m_editPoint->GetId() );
1336  m_pointEditor->setRightMeasure( m_editPoint->GetMeasure(Right),
1337  m_rightCube, m_editPoint->GetId() );
1338 
1339  // Write pointId
1340  QString ptId = "Point ID: " + m_editPoint->GetId();
1341  m_ptIdValue->setText(ptId);
1342 
1343  updateLabels();
1344  }
1345 
1346 
1347 
1348  void StereoTool::paintProfile(MdiCubeViewport *vp, QPainter *painter,
1349  QString serialNumber) {
1350 
1351  // Draw profile
1352  int x1, y1, x2, y2;
1353  //MdiCubeViewport *cvp = cubeViewport();
1354  vp->cubeToViewport( m_startPoint->GetMeasure(serialNumber)->GetSample(),
1355  m_startPoint->GetMeasure(serialNumber)->GetLine(),
1356  x1, y1 );
1357  vp->cubeToViewport( m_endPoint->GetMeasure(serialNumber)->GetSample(),
1358  m_endPoint->GetMeasure(serialNumber)->GetLine(),
1359  x2, y2 );
1360  painter->setPen(Qt::green); // set all other point markers green
1361  painter->drawLine(x1, y1, x2, y2);
1362 
1363  }
1364 
1365 
1366 
1374  void StereoTool::paintViewport(MdiCubeViewport *vp, QPainter *painter) {
1375 
1376  AbstractPlotTool::paintViewport(vp, painter);
1377 
1378  // Make sure we have points to draw
1379  if ( m_controlNet == NULL || m_controlNet->GetNumPoints() == 0 )
1380  return;
1381 
1382  QString serialNumber = SerialNumber::Compose(*vp->cube(), true);
1383 
1384  // If viewport serial number not found in control net, return
1385  if ( !m_controlNet->GetCubeSerials().contains(
1386  serialNumber) ) return;
1387 
1388  // Draw profile if it exists
1389 // if (m_startPoint != NULL && m_endPoint != NULL) {
1390 // paintProfile(vp, painter, serialNumber);
1391 // }
1392 
1393  // Get all measures for this viewport
1394  QList<ControlMeasure *> measures =
1395  m_controlNet->GetMeasuresInCube(serialNumber);
1396  // loop through all measures contained in this cube
1397  for (int i = 0; i < measures.count(); i++) {
1398  ControlMeasure *m = measures[i];
1399  // Find the measurments on the viewport
1400  double samp = m->GetSample();
1401  double line = m->GetLine();
1402  int x, y;
1403  vp->cubeToViewport(samp, line, x, y);
1404  // if the point is ignored,
1405  if ( m->Parent()->IsIgnored() ) {
1406  painter->setPen( QColor(255, 255, 0) ); // set point marker yellow
1407  }
1408  // point is not ignored, but measure matching this image is ignored,
1409  else if ( m->IsIgnored() ) {
1410  painter->setPen( QColor(255, 255, 0) ); // set point marker yellow
1411  }
1412  // Neither point nor measure is not ignored and the measure is fixed,
1413  else if ( m->Parent()->GetType() != ControlPoint::Free) {
1414  painter->setPen(Qt::magenta);// set point marker magenta
1415  }
1416  else {
1417  painter->setPen(Qt::green); // set all other point markers green
1418  }
1419  // draw points
1420  painter->drawLine(x - 5, y, x + 5, y);
1421  painter->drawLine(x, y - 5, x, y + 5);
1422  }
1423 
1424  // if StereoTool is open,
1425  if ( m_editPoint != NULL ) {
1426  // and the selected point is in the image,
1427  if ( m_editPoint->HasSerialNumber(serialNumber) ) {
1428  // find the measurement
1429  double samp = (*m_editPoint)[serialNumber]->GetSample();
1430  double line = (*m_editPoint)[serialNumber]->GetLine();
1431  int x, y;
1432  vp->cubeToViewport(samp, line, x, y);
1433  // set point marker red
1434  QBrush brush(Qt::red);
1435  // set point marker bold - line width 2
1436  QPen pen(brush, 2);
1437  // draw the selected point in each image last so it's on top of the rest of the points
1438  painter->setPen(pen);
1439  painter->drawLine(x - 5, y, x + 5, y);
1440  painter->drawLine(x, y - 5, x, y + 5);
1441  }
1442  }
1443 
1444  }
1445 
1446 
1447 
1453 
1454  // Take care of drawing things on all viewPorts.
1455  // Calling update will cause the Tool class to call all registered tools
1456  // if point has been deleted, this will remove it from the main window
1457  MdiCubeViewport *vp;
1458  for (int i = 0; i < (int) cubeViewportList()->size(); i++) {
1459  vp = (*( cubeViewportList() ) )[i];
1460  vp->viewport()->update();
1461  }
1462  }
1463 
1464 
1465 
1466  void StereoTool::calculateElevation() {
1467  calculateElevation(m_editPoint);
1468  }
1469 
1470 
1471 
1476  void StereoTool::calculateElevation(ControlPoint *point) {
1477 
1478  double elevation=0., elevationError=0.;
1479  Camera *leftCamera = m_leftCube->camera();
1480 
1481  // If the local radius combo box is set to DEM, get the dem radius
1482  // First, SetImage using the Elevation model, before turning off
1483  // to get camera angles.
1484  if ( m_radiusBox->currentText() == "DEM Radius" ) {
1485  leftCamera->IgnoreElevationModel(false);
1486  leftCamera->SetImage( (*point)[Left]->GetSample(),
1487  (*point)[Left]->GetLine() );
1488  m_baseRadius = leftCamera->LocalRadius( leftCamera->GetLatitude(),
1489  leftCamera->GetLongitude() );
1490  if ( !m_baseRadius.isValid() ) {
1491  QString message = "Invalid Dem radius, defaulting to ellipsoidal.";
1492  QMessageBox::warning(m_stereoTool, "Invalid Dem radius", message);
1493  m_baseRadius = m_targetRadius;
1494  }
1495  }
1496 
1497  leftCamera->IgnoreElevationModel(true);
1498  leftCamera->SetImage( (*point)[Left]->GetSample(),
1499  (*point)[Left]->GetLine() );
1500  Camera *rightCamera = m_rightCube->camera();
1501  rightCamera->IgnoreElevationModel(true);
1502  rightCamera->SetImage( (*point)[Right]->GetSample(),
1503  (*point)[Right]->GetLine() );
1504 
1505  double radius, lat, lon, sepang;
1506  if ( Stereo::elevation( *leftCamera, *rightCamera, radius, lat, lon, sepang,
1507  elevationError ) ) {
1508  elevation = radius - m_baseRadius.meters();
1509 // cout<<setprecision(15)<<"radius = "<<radius<<" baseRadius = "<<m_baseRadius.meters()<<" elevation = "<<elevation<<endl;
1510  }
1511  leftCamera->IgnoreElevationModel(false);
1512  rightCamera->IgnoreElevationModel(false);
1513 
1514  // Save elevation and error info to the left ControlMeasure FocalPlaneComputeX/Y.
1515  // TODO: Find better way - This is not a good way to do this, using
1516  // ControlMeasure to save other values. Save The baseRadius in Diameter
1517  point->GetMeasure(Left)->SetFocalPlaneMeasured(elevation, elevationError);
1518  point->GetMeasure(Left)->SetDiameter(m_baseRadius.meters() );
1519  updateLabels();
1520 
1521  return;
1522  }
1523 
1524 
1525 
1534  QString filename = QFileDialog::getOpenFileName( m_stereoTool,
1535  "Select a registration template", ".",
1536  "Registration template files (*.def *.pvl);;All files (*)" );
1537 
1538  if ( filename.isEmpty() )
1539  return;
1540 
1541  m_pointEditor->setTemplateFile(filename);
1542  }
1543 
1544 
1558  try {
1559  // Get the template file from the ControlPointEditor object
1560  Pvl templatePvl( m_pointEditor->templateFileName() );
1561  // Create registration dialog window using PvlEditDialog class
1562  // to view and/or edit the template
1563  PvlEditDialog registrationDialog(templatePvl);
1564  registrationDialog.setWindowTitle( "View or Edit Template File: "
1565  + templatePvl.fileName() );
1566  registrationDialog.resize(550, 360);
1567  registrationDialog.exec();
1568  }
1569  catch (IException &e) {
1570  QString message = e.toString();
1571  QMessageBox::warning(m_stereoTool, "Error", message);
1572  }
1573  }
1574 
1575 
1582 
1583  QString fn = QFileDialog::getSaveFileName( m_stereoTool,
1584  "Choose filename to save under",
1585  ".",
1586  "CSV Files (*.csv)" );
1587  QString filename;
1588 
1589  //Make sure the filename is valid
1590  if ( !fn.isEmpty() ) {
1591  if ( !fn.endsWith(".csv") ) {
1592  filename = fn + ".csv";
1593  }
1594  else {
1595  filename = fn;
1596  }
1597  }
1598  //The user cancelled, or the filename is empty
1599  else {
1600  return;
1601  }
1602 
1603  m_currentFile.setFileName(filename);
1604 
1605  m_save->setEnabled(true);
1606  saveElevations();
1607  }
1608 
1609 
1610 
1611  void StereoTool::saveElevations() {
1612 
1613  if ( m_currentFile.fileName().isEmpty() ) return;
1614 
1615  bool success = m_currentFile.open(QIODevice::WriteOnly);
1616  if (!success) {
1617  QMessageBox::critical(m_stereoTool, "Error",
1618  "Cannot open file, please check permissions");
1619  m_currentFile.setFileName("");
1620  m_save->setDisabled(true);
1621  return;
1622  }
1623 
1624  QTextStream text(&m_currentFile);
1625  QString header = "Point ID, Latitude, Longitude, Radius, ";
1626  header += "Elevation, Elevation Error, ";
1627  header += "Image 1, Sample, Line, Image 2, Sample, Line";
1628  text << header << endl;
1629 
1630  QString leftFile = FileName( m_leftCube->fileName() ).name();
1631  QString rightFile = FileName( m_rightCube->fileName() ).name();
1632  QString data;
1633  for (int i = 0; i < m_controlNet->GetNumPoints(); i++) {
1634  ControlPoint &p = *( (*m_controlNet)[i] );
1635  SurfacePoint apriori = p.GetAprioriSurfacePoint();
1636  data = p.GetId() + "," +
1637  QString::number( apriori.GetLatitude().degrees() ) + "," +
1638  QString::number( apriori.GetLongitude().degrees() ) + "," +
1639  QString::number( p.GetMeasure(Left)->GetDiameter(), 'f', 6 ) +
1640  "," +
1641  QString::number( p.GetMeasure(Left)->GetFocalPlaneMeasuredX(), 'f',
1642  6 ) + "," +
1643  QString::number( p.GetMeasure(Left)->GetFocalPlaneMeasuredY(), 'f',
1644  6 ) + "," + leftFile + "," +
1645  QString::number( p.GetMeasure(Left)->GetSample() ) + "," +
1646  QString::number( p.GetMeasure(Left)->GetLine() ) + "," +
1647  rightFile + "," +
1648  QString::number( p.GetMeasure(Right)->GetSample() ) + "," +
1649  QString::number( p.GetMeasure(Right)->GetLine() );
1650  text << data << endl;
1651  }
1652  m_currentFile.close();
1653 
1654  }
1655 
1656 
1657 
1658  void StereoTool::clearNetData() {
1659 
1660  delete m_controlNet;
1661  m_controlNet = NULL;
1662  delete m_serialNumberList;
1663  m_serialNumberList = NULL;
1664 
1665  }
1666 
1667 
1668 
1669  void StereoTool::profile() {
1670 
1671 // (*m_startPoint)[Left]->SetCoordinate(1361.92,1317.9433);
1672 // (*m_endPoint)[Left]->SetCoordinate(1188.43,2763.23);
1673 // (*m_startPoint)[Right]->SetCoordinate(867.04,2141.16);
1674 // (*m_endPoint)[Right]->SetCoordinate(731.82,2666.75);
1675 
1676  // Delete the profile dialog
1677  if (m_profileDialog) {
1678  delete m_profileDialog;
1679  m_profileDialog = NULL;
1680  }
1681 
1682 // calculateElevation(m_startPoint);
1683 // calculateElevation(m_endPoint);
1684 
1685  QPointF leftStart( (*m_startPoint)[Left]->GetSample(),
1686  (*m_startPoint)[Left]->GetLine() );
1687  QPointF leftEnd( (*m_endPoint)[Left]->GetSample(),
1688  (*m_endPoint)[Left]->GetLine() );
1689 
1690  QPointF rightStart( (*m_startPoint)[Right]->GetSample(),
1691  (*m_startPoint)[Right]->GetLine() );
1692  QPointF rightEnd( (*m_endPoint)[Right]->GetSample(),
1693  (*m_endPoint)[Right]->GetLine() );
1694 
1695  // Convert these to screen coordinates for updating the rubberband
1696  QList< QList<QPoint> > rubberBandVertices;
1697  QList<QPoint> rubberBand1;
1698  int sx, sy, ex, ey;
1699  m_linkedViewports.at(0)->cubeToViewport( (*m_startPoint)[Left]->GetSample(),
1700  (*m_startPoint)[Left]->GetLine(), sx, sy);
1701  m_linkedViewports.at(0)->cubeToViewport( (*m_endPoint)[Left]->GetSample(),
1702  (*m_endPoint)[Left]->GetLine(), ex, ey);
1703  rubberBand1.push_back( QPoint(sx, sy) );
1704  rubberBand1.push_back( QPoint(ex, ey) );
1705 
1706  rubberBandVertices.push_back(rubberBand1);
1707 
1708  QList<QPoint> rubberBand2;
1709  m_linkedViewports.at(1)->cubeToViewport( (*m_startPoint)[Right]->GetSample(),
1710  (*m_startPoint)[Right]->GetLine(), sx, sy);
1711  m_linkedViewports.at(1)->cubeToViewport( (*m_endPoint)[Right]->GetSample(),
1712  (*m_endPoint)[Right]->GetLine(), ex, ey);
1713  rubberBand2.push_back( QPoint(sx, sy) );
1714  rubberBand2.push_back( QPoint(ex, ey) );
1715 
1716  rubberBandVertices.push_back(rubberBand2);
1717 
1718  // Create line for left image
1719  QLineF leftProfile(leftStart,leftEnd);
1720  QLineF rightProfile(rightStart,rightEnd);
1721 
1722  // Determine shortest line, we will step through shortest line,
1723  // finding the matching position on the longer line.
1724  QLineF longProfile, shortProfile;
1725  Cube *longCube, *shortCube;
1726  if ( leftProfile.length() > rightProfile.length() ) {
1727  longProfile = leftProfile;
1728  longCube = m_leftCube;
1729  shortProfile = rightProfile;
1730  shortCube = m_rightCube;
1731  }
1732  else {
1733  longProfile = rightProfile;
1734  longCube = m_rightCube;
1735  shortProfile = leftProfile;
1736  shortCube = m_leftCube;
1737  }
1738 
1739  QVector<QPointF> profileData;
1740  double elevation = 0.;
1741  double elevationError = 0.;
1742 
1743  Pvl regDef = m_pointEditor->templateFileName();
1744  AutoReg *ar = AutoRegFactory::Create(regDef);
1745 
1746  int failureCount = 0;
1747  QApplication::setOverrideCursor(Qt::WaitCursor);
1748 
1749  for (int i = 0; i <= (int) shortProfile.length(); i++) {
1750  double shortSamp=0, shortLine=0, longSamp=0, longLine=0;
1751  try {
1752  shortSamp = shortProfile.pointAt( 1/shortProfile.length() * i ).x();
1753  shortLine = shortProfile.pointAt( 1/shortProfile.length() * i ).y();
1754 
1755  longSamp = longProfile.pointAt( 1/shortProfile.length() * i ).x();
1756  longLine = longProfile.pointAt( 1/shortProfile.length() * i ).y();
1757 
1758  // Coreg
1759  ar->PatternChip()->TackCube(shortSamp, shortLine);
1760  ar->PatternChip()->Load(*shortCube);
1761  ar->SearchChip()->TackCube(longSamp, longLine);
1762  ar->SearchChip()->Load( *longCube, *( ar->PatternChip() ), *shortCube );
1763  ar->Register();
1764 // AutoReg::RegisterStatus status = ar->Register();
1765  if ( ar->Success() ) {
1766  longSamp = ar->CubeSample();
1767  longLine = ar->CubeLine();
1768 
1769  // If the local radius combo box is set to DEM, get the dem radius
1770  // First, SetImage using the Elevation model, before turning off
1771  // to get camera angles.
1772  if ( m_radiusBox->currentText() == "DEM Radius" ) {
1773  shortCube->camera()->IgnoreElevationModel(false);
1774  shortCube->camera()->SetImage(shortSamp, shortLine);
1775  m_baseRadius = shortCube->camera()->LocalRadius(
1776  shortCube->camera()->GetLatitude(),
1777  shortCube->camera()->GetLongitude() );
1778  if ( !m_baseRadius.isValid() ) {
1779  QString message = "Invalid Dem radius, defaulting to ellipsoidal.";
1780  QMessageBox::warning(m_stereoTool, "Invalid Dem radius", message);
1781  m_baseRadius = m_targetRadius;
1782  }
1783  }
1784 
1785  shortCube->camera()->IgnoreElevationModel(true);
1786  longCube->camera()->IgnoreElevationModel(true);
1787 
1788  shortCube->camera()->SetImage(shortSamp, shortLine);
1789  longCube->camera()->SetImage(longSamp,longLine);
1790  double radius, lat, lon, sepang;
1791  if (Stereo::elevation( *shortCube->camera(), *longCube->camera(),
1792  radius, lat, lon, sepang, elevationError) )
1793  elevation = radius - m_baseRadius.meters();
1794  profileData.append( QPointF(i, elevation) );
1795 // elevations.push_back(elevation);
1796 // pixels.push_back(i);
1797  }
1798  else {
1799  failureCount++;
1800  }
1801  }
1802  catch (IException &e) {
1803  QString message = "Error registering cubes along profile line.\n";
1804  message += "Image 1 Sample = " + QString::number(shortSamp);
1805  message += " Line = " + QString::number(shortLine);
1806  message += "\nImage 2 Sample = " + QString::number(longSamp);
1807  message += " Line = " + QString::number(longLine) + "\n\n";
1808  message += e.toString();
1809  QMessageBox::critical(m_stereoTool, "Error", message);
1810  rubberBandTool()->clear();
1811  }
1812 
1813  }
1814  QApplication::restoreOverrideCursor();
1815 
1816 // cout<<"Registration attempts = "<<(int)shortLength<<" failures = "<<failureCount<<endl;
1817  QString message = "Registration attempts (pixels on line) = " +
1818  QString::number( (int)shortProfile.length() ) +
1819  "\n\nRegistration failures = " +
1820  QString::number(failureCount) +
1821  "\n\nYou can adjust registration parameters in the "
1822  "\"Options\" menu in the Elevation Calculator window. "
1823  "Select \"Options\", then \"Registration\", then either "
1824  "\"Select registration template\" or "
1825  "\"View/edit registration template\".";
1826  QMessageBox::information(m_stereoTool, "Registration Report", message);
1827 
1828  if ( ( (int)shortProfile.length() + 1 - failureCount ) < 2 ) {
1829  QString message = "Cannot create profile, all auto-registration between ";
1830  message += "the left and right cubes along the profile failed. Try ";
1831  message += "adjusting the registration parameters.";
1832  QMessageBox::critical(m_stereoTool, "Error", message);
1833  return;
1834  }
1835  PlotWindow *plotWindow = selectedWindow(true);
1836  plotWindow->setAxisLabel(0,"Elevation (meters)");
1839 // plotCurve->setData(&pixels[0], &elevations[0], pixels.size() );
1840  plotCurve->setData( new QwtPointSeriesData(profileData) );
1841  plotCurve->setTitle("Elevations (Meters)");
1842  plotCurve->setPen( QPen(Qt::white) );
1843  plotCurve->setColor(Qt::white);
1844  // Create vertices for rubberband based on refined profile end points
1845 
1846  // TODO: This needs to be changed to band displayed???
1847  QList<int> bands;
1848  bands.push_back(1);
1849  bands.push_back(1);
1850  plotCurve->setSource(m_linkedViewports, rubberBandVertices, bands);
1851  plotWindow->add(plotCurve);
1852 
1853  delete m_profileDialog;
1854  m_profileDialog = NULL;
1855 // m_startPoint = NULL;
1856 // m_endPoint = NULL;
1857 // rubberBandTool()->clear();
1858 
1859  }
1860 
1861 
1862 
1863  void StereoTool::updateLabels() {
1864  // Empty elevation info if nothing there
1865  QString elevationLabel, elevationErrorLabel;
1866  QString baseRadiiLabel, leftDemRadiiLabel, rightDemRadiiLabel;
1867  if ( m_editPoint->GetMeasure(Left)->GetFocalPlaneMeasuredX() != Isis::Null ) {
1868  elevationLabel = "Elevation: " +
1869  QString::number( m_editPoint->GetMeasure(Left)->
1870  GetFocalPlaneMeasuredX(), 'f', 6 );
1871  elevationErrorLabel = "Elevation Error: " +
1872  QString::number( m_editPoint->GetMeasure(Left)->
1873  GetFocalPlaneMeasuredY(), 'f', 6 );
1874  baseRadiiLabel = "Local Radii: " + QString::number(
1875  m_baseRadius.meters(), 'f', 6 );
1876 
1877  Camera *leftCamera = m_leftCube->camera();
1878  leftCamera->SetImage( (*m_editPoint)[Left]->GetSample(),
1879  (*m_editPoint)[Left]->GetLine() );
1880  double leftDemRadii =
1881  leftCamera->GetSurfacePoint().GetLocalRadius().meters();
1882  leftDemRadiiLabel = "Left DEM Radii: " +
1883  QString::number(leftDemRadii, 'f', 6);
1884 
1885  Camera *rightCamera = m_rightCube->camera();
1886  rightCamera->SetImage( (*m_editPoint)[Right]->GetSample(),
1887  (*m_editPoint)[Right]->GetLine() );
1888  double rightDemRadii =
1889  rightCamera->GetSurfacePoint().GetLocalRadius().meters();
1890  rightDemRadiiLabel = "Right DEM Radii: " +
1891  QString::number(rightDemRadii, 'f', 6);
1892  }
1893  else {
1894  elevationLabel = "Elevation: ";
1895  elevationErrorLabel = "Elevation Error: ";
1896  baseRadiiLabel = "Local Radii: ";
1897  leftDemRadiiLabel = "Left DEM Radii: ";
1898  rightDemRadiiLabel = "Right DEM Radii: ";
1899  }
1900  m_elevationLabel->setText(elevationLabel);
1901  m_elevationErrorLabel->setText(elevationErrorLabel);
1902  m_baseRadiiLabel->setText(baseRadiiLabel);
1903  m_leftDemRadiiLabel->setText(leftDemRadiiLabel);
1904  m_rightDemRadiiLabel->setText(rightDemRadiiLabel);
1905  }
1906 
1907 
1908 
1909  void StereoTool::readSettings() {
1910  FileName config("$HOME/.Isis/qview/Stereo Tool.config");
1911  QSettings settings(config.expanded(),
1912  QSettings::NativeFormat);
1913  m_showWarning = settings.value("showWarning", true).toBool();
1914 
1915  }
1916 
1917 
1918 
1919  void StereoTool::writeSettings() {
1920  FileName config("$HOME/.Isis/qview/Stereo Tool.config");
1921  QSettings settings(config.expanded(),
1922  QSettings::NativeFormat);
1923  settings.setValue("showWarning", m_showWarning);
1924 
1925  }
1926 }
1927 
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:86
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Cube display widget for certain Isis MDI applications.
PointType GetType() const
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
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:849
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:109
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.
double Sample() const
Returns the current line value of the camera model or projection.
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:245
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:454
File name manipulation and expansion.
Definition: FileName.h:111
Universal Ground Map.
Distance GetLocalRadius() const
Return the radius of the surface point.
Camera * camera()
Return a camera associated with the cube.
Definition: Cube.cpp:1118
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.
Latitude GetLatitude() const
Returns a planetocentric latitude object at the surface intersection point in body fixed...
Definition: Sensor.cpp:236
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
Definition: Sensor.cpp:260
QString serialNumber(const QString &filename)
Return a serial number given a filename.
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:59
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:217
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:121
double Line() const
Returns the current line value of the camera model or projection.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance measurement, usually in meters.
Definition: Distance.h:47
void clearFiles()
New files selected, clean up old file info.
Definition: StereoTool.cpp:760
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
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:369
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
void clear()
clears the rubber band!
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
Status SetDiameter(double diameter)
Set the crater diameter at the coordinate.
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:166
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1277
int sampleCount() const
Definition: Cube.cpp:1404
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
void viewTemplateFile()
Allows the user to view the template file that is currently set.
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:69
Cube * cube() const
Return the cube associated with viewport.
Definition: CubeViewport.h:228
a control network
Definition: ControlNet.h:207
double CubeSample() const
Return the search chip cube sample that best matched.
Definition: AutoReg.h:350
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename...
QString GetId() const
Return the Id of the control point.
Hand Measured (e.g., qnet)
void modifyPoint(ControlPoint *point)
Modify given control point.
bool SetGround(Latitude lat, Longitude lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Pixel value mapper.
Definition: Stretch.h:72
Chip * PatternChip()
Return pointer to pattern chip.
Definition: AutoReg.h:212
This is a plot curve with information relating it to a particular cube or region of a cube...
Definition: CubePlotCurve.h:68
bool Success() const
Return whether the match algorithm succeeded or not.
Definition: AutoReg.h:328
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:204
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
Status SetAprioriSurfacePoint(SurfacePoint aprioriSP)
This updates the apriori surface point.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
A single control point.
Definition: ControlPoint.h:339
void viewportToCube(int x, int y, double &sample, double &line) const
Convert a viewport x/y to a cube sample/line (may be outside the cube)
void setColor(const QColor &color)
Set the color of this curve and it&#39;s markers.
Definition: PlotCurve.cpp:97
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition: Sensor.cpp:270
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:177
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...
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:282
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
Status SetFocalPlaneMeasured(double x, double y)
Set the focal plane x/y for the measured line/sample.
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
void cubeToViewport(double sample, double line, int &x, int &y) const
Convert a cube sample/line to a viewport x/y (may be outside the viewport)
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).
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
static QString UserName()
Returns the user name.
Isis exception class.
Definition: IException.h:99
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
Adds specific functionality to C++ strings.
Definition: IString.h:179
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
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.
QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1160
The distance is being specified in meters.
Definition: Distance.h:56
Point Editor Widget.
Status SetDateTime()
Date Time - Creation Time.
void setPen(const QPen &pen)
Sets the plot pen to the passed-in pen.
Definition: PlotCurve.cpp:340
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:592
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
int lineCount() const
Definition: Cube.cpp:1331
double GetDiameter() const
Return the diameter of the crater in pixels (0 implies no crater)
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube&#39;s serial number.
double CubeLine() const
Return the search chip cube line that best matched.
Definition: AutoReg.h:355
void enableRubberBandTool()
This methods enables the RubberBandTool, it also sets the RubberBandTool to allow points and to allow...
Definition: StereoTool.cpp:885
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:158
void enable(RubberBandMode mode, bool showIndicatorColors=false)
This is called when changing modes or turning on.

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:29:58