1 #include "StereoTool.h"
10 #include <QFileDialog>
11 #include <QInputDialog>
13 #include <QMessageBox>
14 #include <QStackedWidget>
16 #include "AbstractPlotTool.h"
24 #include "ControlPointEdit.h"
34 #include "MainWindow.h"
38 #include "ProfileDialog.h"
39 #include "PvlEditDialog.h"
43 #include "RubberBandTool.h"
66 QString StereoTool::lastPtIdValue =
"";
80 m_serialNumberList = NULL;
87 m_profileDialog = NULL;
95 connect(
this, SIGNAL( toolActivated() ),
this, SLOT( activateTool() ) );
106 m_stereoTool->setWindowTitle(
"Elevation Calculator (via stereo pairs)");
111 QGridLayout *gridLayout =
new QGridLayout();
115 gridLayout->setColumnMinimumWidth(0, 310);
116 gridLayout->setColumnMinimumWidth(1, 310);
120 m_ptIdValue =
new QLabel();
121 gridLayout->addWidget(m_ptIdValue, row++, 0);
123 m_leftCubeLabel =
new QLabel();
124 m_rightCubeLabel =
new QLabel();
125 gridLayout->addWidget(m_leftCubeLabel, row, 0);
126 gridLayout->addWidget(m_rightCubeLabel, row++, 1);
129 gridLayout->addWidget(m_pointEditor, row++, 0, 1, 3);
131 m_pointEditor->show();
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);
147 m_baseRadiiLabel =
new QLabel;
148 m_baseRadiiLabel->setToolTip(
"Subtracted from the calculated radius to "
149 "determine elevation.");
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);
165 cw->setLayout(gridLayout);
166 m_stereoTool->setCentralWidget(cw);
168 connect(
this, SIGNAL( editPointChanged() ),
this, SLOT(
paintAllViewports() ) );
180 m_save =
new QAction(m_stereoTool);
181 m_save->setText(
"Save Elevation Data...");
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);
189 saveAs->setText(
"Save Elevation Data As...");
191 "<b>Function:</b> Saves the elevation calulations to a file.";
192 saveAs->setWhatsThis(whatsThis);
196 closeStereoTool->setText(
"&Close");
197 closeStereoTool->setShortcut(Qt::ALT + Qt::Key_F4);
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() ) );
204 QMenu *fileMenu = m_stereoTool->menuBar()->addMenu(
"&File");
205 fileMenu->addAction(m_save);
206 fileMenu->addAction(saveAs);
207 fileMenu->addAction(closeStereoTool);
210 templateFile->setText(
"&Set registration template");
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() ) );
217 viewTemplate->setText(
"&View/edit registration template");
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() ) );
225 QMenu *optionMenu = m_stereoTool->menuBar()->addMenu(
"&Options");
226 QMenu *regMenu = optionMenu->addMenu(
"&Registration");
228 regMenu->addAction(templateFile);
229 regMenu->addAction(viewTemplate);
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() ));
236 QMenu *helpMenu = m_stereoTool->menuBar()->addMenu(
"&Help");
237 helpMenu->addAction(showHelpAct);
252 action->setIcon( QPixmap(
toolIconDir() +
"/3d-glasses-icon.png") );
253 action->setToolTip(
"Stereo");
254 action->setWhatsThis(
"<strong>Functionality:</strong> "
256 "<li>Calculate elevation at a single point by creating a "
257 "control point between the image pair. "
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>");
283 QLabel *boxLabel =
new QLabel(
"Local Radius:");
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");
290 "<b>Function: </b>Source for the local radius used for elevation "
292 m_radiusBox->setWhatsThis(text);
293 connect( m_radiusBox, SIGNAL( activated(
int) ),
294 this, SLOT( updateRadiusLineEdit() ));
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\"");
304 "<b>Function: </b>Custom local radius used to calculate elevations. "
305 "This can be changed by selecting \"Custom Radius\" in the box to "
307 m_radiusLineEdit->setWhatsThis(text);
310 connect( m_radiusLineEdit, SIGNAL( editingFinished() ),
311 this, SLOT( userBaseRadius() ));
313 m_radiusLineEdit->setEnabled(
false);
315 QLabel *radiusUnit =
new QLabel(
"Meters");
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() ));
323 QHBoxLayout *layout =
new QHBoxLayout;
324 layout->setMargin(0);
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);
341 void StereoTool::activateTool() {
351 qobject_cast<QWidget *>( parent() ) );
362 void StereoTool::warningDialog() {
367 QVBoxLayout *mainLayout =
new QVBoxLayout;
368 warningDialog->setLayout(mainLayout);
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);
381 QPushButton *okButton =
new QPushButton(
"OK");
382 mainLayout->addStretch();
383 mainLayout->addWidget(okButton);
384 connect( okButton, SIGNAL( clicked() ), warningDialog, SLOT( accept() ));
386 if ( warningDialog->exec() ) {
387 if ( showWarning->isChecked() ) m_showWarning =
false;
396 void StereoTool::showHelp() {
399 helpDialog->setWindowTitle(
"Stereo Tool Help");
401 QVBoxLayout *mainLayout =
new QVBoxLayout;
402 helpDialog->setLayout(mainLayout);
404 QLabel *stereoTitle =
new QLabel(
"<h2>Stereo Tool</h2>");
405 mainLayout->addWidget(stereoTitle);
407 QLabel *stereoSubtitle =
new QLabel(
"A tool for calculating point elevations "
408 "and elevation profiles using stereo pairs "
410 stereoSubtitle->setWordWrap(
true);
411 mainLayout->addWidget(stereoSubtitle);
413 QTabWidget *tabArea =
new QTabWidget;
414 tabArea->setDocumentMode(
true);
415 mainLayout->addWidget(tabArea);
418 QScrollArea *overviewTab =
new QScrollArea;
419 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
420 overviewTab->setWidgetResizable(
true);
422 QVBoxLayout *overviewLayout =
new QVBoxLayout;
423 overviewContainer->setLayout(overviewLayout);
425 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
426 overviewLayout->addWidget(purposeTitle);
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);
438 QLabel *warningsTitle =
new QLabel(
"<h2>Warnings</h2>");
439 overviewLayout->addWidget(warningsTitle);
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);
448 overviewTab->setWidget(overviewContainer);
451 QScrollArea *quickTab =
new QScrollArea;
452 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
453 quickTab->setWidgetResizable(
true);
455 QVBoxLayout *quickLayout =
new QVBoxLayout;
456 quickContainer->setLayout(quickLayout);
458 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
459 quickLayout->addWidget(quickTitle);
461 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
462 quickLayout->addWidget(quickSubTitle);
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);
470 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
471 quickLayout->addWidget(quickFunctionTitle);
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);
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);
502 quickTab->setWidget(quickContainer);
505 QScrollArea *controlPointTab =
new QScrollArea;
506 controlPointTab->setWidgetResizable(
true);
507 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
509 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
510 controlPointContainer->setLayout(controlPointLayout);
512 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
513 controlPointLayout->addWidget(controlPointTitle);
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);
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);
534 QLabel *controlPointEditing =
new QLabel(
535 "<h4>Changing Measure Locations</h4>"
536 "<p>The measure location can be adjusted by:"
538 "<li>Move the cursor location under the crosshair by clicking the left mouse "
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>"
543 "<h4>Other Point Editor Functions</h4>"
544 "<p>Along the right border of the window:</p>"
546 "<li><strong>Geom:</strong> Geometrically match the right view to the left"
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"
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"
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);
572 controlPointTab->setWidget(controlPointContainer);
576 tabArea->addTab(overviewTab,
"&Overview");
577 tabArea->addTab(quickTab,
"&Quick Start");
578 tabArea->addTab(controlPointTab,
"&Control Point Editing");
580 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
582 buttonsLayout->addStretch();
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);
591 mainLayout->addLayout(buttonsLayout);
600 void StereoTool::userBaseRadius() {
603 m_baseRadius =
Distance(m_radiusLineEdit->text().toDouble(),
608 if (m_stereoTool->isVisible() && m_editPoint != NULL) {
609 calculateElevation();
613 QString message =
"Invalid base radius entered.";
615 m_radiusLineEdit->setText(
"");
616 QMessageBox::critical(m_stereoTool,
"Error", message);
625 void StereoTool::updateRadiusLineEdit() {
628 if ( m_radiusBox->currentText() ==
"Ellipsoid Equitorial Radius" ) {
629 if ( m_targetRadius.
isValid() ) {
630 m_radiusLineEdit->setText( QString::number( m_targetRadius.
meters(),
'f',
632 m_baseRadius = m_targetRadius;
635 m_radiusLineEdit->setText(
"");
637 m_radiusLineEdit->setReadOnly(
true);
638 m_radiusLineEdit->setEnabled(
false);
640 else if ( m_radiusBox->currentText() ==
"DEM Radius" ) {
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);
650 m_radiusLineEdit->setReadOnly(
true);
651 m_radiusLineEdit->setEnabled(
false);
655 m_radiusLineEdit->setText(
"");
656 m_radiusLineEdit->setReadOnly(
true);
657 m_radiusLineEdit->setEnabled(
false);
661 m_radiusLineEdit->setReadOnly(
false);
662 m_radiusLineEdit->setEnabled(
true);
666 if ( m_stereoTool->isVisible() && m_editPoint != NULL ) {
667 calculateElevation();
673 void StereoTool::setupFiles() {
683 m_linkedViewports.clear();
689 if ( m_linkedViewports.size() < 2 ) {
690 IString message =
"Two cube viewports containing a stereo pair "
691 "need to be linked.";
694 if ( m_linkedViewports.size() > 2 ) {
695 IString message =
"Only two cube viewports containing a stereo pair "
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 ) {
713 if ( m_controlNet->GetTarget() !=
714 m_linkedViewports.at(0)->cube()->camera()->target()->name() ) {
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,
724 if (response == QMessageBox::Yes) {
727 m_stereoTool->setVisible(
false);
730 m_controlNet->SetTarget(*m_linkedViewports.at(0)->cube()->label());
736 m_controlNet->SetTarget(
737 m_linkedViewports.at(0)->cube()->camera()->target()->name() );
745 setFiles( m_linkedViewports.at(0)->cube(), m_linkedViewports.at(1)->cube() );
761 m_stereoTool->setVisible(
false);
786 m_leftCube = leftCube;
787 m_rightCube = rightCube;
792 m_leftCubeLabel->setText(leftName);
793 m_rightCubeLabel->setText(rightName);
803 m_serialNumberList->
add( m_rightCube->
fileName() );
806 std::vector<Distance> targetRadius = m_controlNet->GetTargetRadii();
807 m_targetRadius =
Distance(targetRadius[0]);
809 if ( !m_targetRadius.
isValid() ) {
810 QString message =
"Could not determine target radius.";
811 QMessageBox::critical(m_stereoTool,
"Error",message);
813 updateRadiusLineEdit();
816 updateRadiusLineEdit();
823 QString message =
"Cannot initialize universal ground map for " +
826 QMessageBox::critical(m_stereoTool,
"Error", message);
833 QString message =
"Cannot initialize universal ground map for" +
836 QMessageBox::critical(m_stereoTool,
"Error", message);
851 double samp = m_editPoint->
GetMeasure(Left)->GetSample();
852 double line = m_editPoint->
GetMeasure(Left)->GetLine();
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',
871 QMessageBox::critical(m_stereoTool,
"Error", message);
874 calculateElevation();
875 emit editPointChanged();
886 rubberBandTool()->
enable(RubberBandTool::LineMode);
887 rubberBandTool()->enablePoints();
888 rubberBandTool()->enableAllClicks();
894 void StereoTool::rubberBandComplete() {
903 QMessageBox::critical(m_stereoTool,
"Error setting stereo pair", message);
904 rubberBandTool()->
clear();
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);
924 if ( rubberBandTool()->figureIsPoint() ) {
927 rubberBandTool()->vertices()[0].ry(),
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);
939 point = m_controlNet->FindClosest(sn, samp, line);
942 QString message =
"No points found for editing. Create points ";
943 message +=
"using the right mouse button.";
945 QMessageBox::critical(m_stereoTool,
"Error", message);
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);
960 m_controlNet->FindClosest(sn, samp, line);
963 QString message =
"No points exist for deleting. Create points ";
964 message +=
"using the right mouse button.";
965 QMessageBox::information(m_stereoTool,
"Warning", message);
970 else if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
972 if (cvp->
cube() == m_leftCube) {
986 QString message =
"Cannot create control point.\n\n";
988 QMessageBox::critical(m_stereoTool,
"Error", message);
990 rubberBandTool()->
clear();
1000 if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
1003 rubberBandTool()->vertices()[0].ry(),
1006 m_startPoint = m_controlNet->FindClosest(sn, samp, line);
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";
1014 QMessageBox::critical(m_stereoTool,
"Error", message);
1015 m_startPoint = NULL;
1016 rubberBandTool()->
clear();
1020 rubberBandTool()->vertices()[1].ry(),
1023 m_endPoint = m_controlNet->FindClosest(sn, samp, line);
1024 if ( m_startPoint->
GetId() == m_endPoint->
GetId() ) {
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";
1035 QMessageBox::critical(m_stereoTool,
"Error", message);
1036 m_startPoint = NULL;
1038 rubberBandTool()->
clear();
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();
1064 void StereoTool::clearProfile() {
1065 m_startPoint = NULL;
1067 rubberBandTool()->
clear();
1068 delete m_profileDialog;
1069 m_profileDialog = NULL;
1074 void StereoTool::createStartPoint() {
1082 rubberBandTool()->vertices()[0].ry(),
1084 if ( cvp->
cube() == m_leftCube ) {
1098 QString message =
"Cannot create control point.\n\n";
1100 QMessageBox::critical(m_stereoTool,
"Error", message);
1101 delete m_profileDialog;
1102 m_profileDialog = NULL;
1103 rubberBandTool()->
clear();
1106 m_startPoint = m_editPoint;
1111 void StereoTool::createEndPoint() {
1119 rubberBandTool()->vertices()[1].ry(),
1121 if ( cvp->
cube() == m_leftCube ) {
1135 QString message =
"Cannot create control point.\n\n";
1137 QMessageBox::critical(m_stereoTool,
"Error", message);
1138 m_startPoint = NULL;
1139 delete m_profileDialog;
1140 m_profileDialog = NULL;
1141 rubberBandTool()->
clear();
1144 m_endPoint = m_editPoint;
1166 double leftSamp = 0, leftLine = 0;
1167 double rightSamp = 0, rightLine = 0;
1171 leftSamp = m_leftGM->
Sample();
1172 leftLine = m_leftGM->
Line();
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, " +
1191 IString message =
"Point does not exist on cube, " +
1201 IString message =
"Point does not exist on cube, " +
1213 bool goodId =
false;
1216 QString
id = QInputDialog::getText(m_stereoTool,
1217 "Point ID",
"Enter Point ID:",
1218 QLineEdit::Normal, lastPtIdValue,
1225 if ( ok &&
id.isEmpty() ) {
1227 QString message =
"You must enter a point Id.";
1228 QMessageBox::warning(m_stereoTool,
"Warning", message);
1233 if ( m_controlNet->GetNumPoints() > 0 &&
1234 m_controlNet->ContainsPoint(newPoint->
GetId() ) ) {
1235 QString message =
"A ControlPoint with Point Id = [" +
1237 "] already exists. Re-enter unique Point Id.";
1238 QMessageBox::warning(m_stereoTool,
"Unique Point Id", message);
1259 newPoint->
Add(mLeft);
1267 newPoint->
Add(mRight);
1270 m_controlNet->AddPoint(newPoint);
1272 m_editPoint = m_controlNet->GetPoint( (QString) newPoint->
GetId() );
1275 m_stereoTool->setVisible(
true);
1276 m_stereoTool->raise();
1278 emit editPointChanged();
1295 m_editPoint = point;
1298 emit editPointChanged();
1302 m_controlNet->DeletePoint( m_editPoint->
GetId() );
1303 m_stereoTool->setVisible(
false);
1306 emit editPointChanged();
1318 m_editPoint = point;
1320 m_stereoTool->setVisible(
true);
1321 m_stereoTool->raise();
1322 emit editPointChanged();
1335 m_editPoint->
GetId() );
1337 m_rightCube, m_editPoint->
GetId() );
1340 QString ptId =
"Point ID: " + m_editPoint->
GetId();
1341 m_ptIdValue->setText(ptId);
1349 QString serialNumber) {
1355 m_startPoint->
GetMeasure(serialNumber)->GetLine(),
1358 m_endPoint->
GetMeasure(serialNumber)->GetLine(),
1360 painter->setPen(Qt::green);
1361 painter->drawLine(x1, y1, x2, y2);
1379 if ( m_controlNet == NULL || m_controlNet->GetNumPoints() == 0 )
1385 if ( !m_controlNet->GetCubeSerials().contains(
1386 serialNumber) )
return;
1395 m_controlNet->GetMeasuresInCube(serialNumber);
1397 for (
int i = 0; i < measures.count(); i++) {
1400 double samp = m->GetSample();
1401 double line = m->GetLine();
1405 if ( m->Parent()->IsIgnored() ) {
1406 painter->setPen( QColor(255, 255, 0) );
1409 else if ( m->IsIgnored() ) {
1410 painter->setPen( QColor(255, 255, 0) );
1414 painter->setPen(Qt::magenta);
1417 painter->setPen(Qt::green);
1420 painter->drawLine(x - 5, y, x + 5, y);
1421 painter->drawLine(x, y - 5, x, y + 5);
1425 if ( m_editPoint != NULL ) {
1429 double samp = (*m_editPoint)[serialNumber]->GetSample();
1430 double line = (*m_editPoint)[serialNumber]->GetLine();
1434 QBrush brush(Qt::red);
1438 painter->setPen(pen);
1439 painter->drawLine(x - 5, y, x + 5, y);
1440 painter->drawLine(x, y - 5, x, y + 5);
1460 vp->viewport()->update();
1466 void StereoTool::calculateElevation() {
1467 calculateElevation(m_editPoint);
1478 double elevation=0., elevationError=0.;
1484 if ( m_radiusBox->currentText() ==
"DEM Radius" ) {
1486 leftCamera->
SetImage( (*point)[Left]->GetSample(),
1487 (*point)[Left]->GetLine() );
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;
1498 leftCamera->
SetImage( (*point)[Left]->GetSample(),
1499 (*point)[Left]->GetLine() );
1502 rightCamera->
SetImage( (*point)[Right]->GetSample(),
1503 (*point)[Right]->GetLine() );
1505 double radius, lat, lon, sepang;
1506 if ( Stereo::elevation( *leftCamera, *rightCamera, radius, lat, lon, sepang,
1507 elevationError ) ) {
1508 elevation = radius - m_baseRadius.
meters();
1534 QString filename = QFileDialog::getOpenFileName( m_stereoTool,
1535 "Select a registration template",
".",
1536 "Registration template files (*.def *.pvl);;All files (*)" );
1538 if ( filename.isEmpty() )
1560 Pvl templatePvl( m_pointEditor->templateFileName() );
1564 registrationDialog.setWindowTitle(
"View or Edit Template File: "
1565 + templatePvl.fileName() );
1566 registrationDialog.resize(550, 360);
1567 registrationDialog.exec();
1571 QMessageBox::warning(m_stereoTool,
"Error", message);
1583 QString fn = QFileDialog::getSaveFileName( m_stereoTool,
1584 "Choose filename to save under",
1586 "CSV Files (*.csv)" );
1590 if ( !fn.isEmpty() ) {
1591 if ( !fn.endsWith(
".csv") ) {
1592 filename = fn +
".csv";
1603 m_currentFile.setFileName(filename);
1605 m_save->setEnabled(
true);
1611 void StereoTool::saveElevations() {
1613 if ( m_currentFile.fileName().isEmpty() )
return;
1615 bool success = m_currentFile.open(QIODevice::WriteOnly);
1617 QMessageBox::critical(m_stereoTool,
"Error",
1618 "Cannot open file, please check permissions");
1619 m_currentFile.setFileName(
"");
1620 m_save->setDisabled(
true);
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;
1633 for (
int i = 0; i < m_controlNet->GetNumPoints(); i++) {
1636 data = p.
GetId() +
"," +
1641 QString::number( p.
GetMeasure(Left)->GetFocalPlaneMeasuredX(),
'f',
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() ) +
"," +
1648 QString::number( p.
GetMeasure(Right)->GetSample() ) +
"," +
1649 QString::number( p.
GetMeasure(Right)->GetLine() );
1650 text << data << endl;
1652 m_currentFile.close();
1658 void StereoTool::clearNetData() {
1660 delete m_controlNet;
1661 m_controlNet = NULL;
1662 delete m_serialNumberList;
1663 m_serialNumberList = NULL;
1669 void StereoTool::profile() {
1677 if (m_profileDialog) {
1678 delete m_profileDialog;
1679 m_profileDialog = NULL;
1685 QPointF leftStart( (*m_startPoint)[Left]->GetSample(),
1686 (*m_startPoint)[Left]->GetLine() );
1687 QPointF leftEnd( (*m_endPoint)[Left]->GetSample(),
1688 (*m_endPoint)[Left]->GetLine() );
1690 QPointF rightStart( (*m_startPoint)[Right]->GetSample(),
1691 (*m_startPoint)[Right]->GetLine() );
1692 QPointF rightEnd( (*m_endPoint)[Right]->GetSample(),
1693 (*m_endPoint)[Right]->GetLine() );
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) );
1706 rubberBandVertices.push_back(rubberBand1);
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) );
1716 rubberBandVertices.push_back(rubberBand2);
1719 QLineF leftProfile(leftStart,leftEnd);
1720 QLineF rightProfile(rightStart,rightEnd);
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;
1733 longProfile = rightProfile;
1734 longCube = m_rightCube;
1735 shortProfile = leftProfile;
1736 shortCube = m_leftCube;
1740 double elevation = 0.;
1741 double elevationError = 0.;
1743 Pvl regDef = m_pointEditor->templateFileName();
1746 int failureCount = 0;
1747 QApplication::setOverrideCursor(Qt::WaitCursor);
1749 for (
int i = 0; i <= (int) shortProfile.length(); i++) {
1750 double shortSamp=0, shortLine=0, longSamp=0, longLine=0;
1752 shortSamp = shortProfile.pointAt( 1/shortProfile.length() * i ).x();
1753 shortLine = shortProfile.pointAt( 1/shortProfile.length() * i ).y();
1755 longSamp = longProfile.pointAt( 1/shortProfile.length() * i ).x();
1756 longLine = longProfile.pointAt( 1/shortProfile.length() * i ).y();
1772 if ( m_radiusBox->currentText() ==
"DEM Radius" ) {
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;
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) );
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";
1809 QMessageBox::critical(m_stereoTool,
"Error", message);
1810 rubberBandTool()->
clear();
1814 QApplication::restoreOverrideCursor();
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);
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);
1840 plotCurve->
setData(
new QwtPointSeriesData(profileData) );
1841 plotCurve->setTitle(
"Elevations (Meters)");
1842 plotCurve->
setPen( QPen(Qt::white) );
1850 plotCurve->
setSource(m_linkedViewports, rubberBandVertices, bands);
1851 plotWindow->
add(plotCurve);
1853 delete m_profileDialog;
1854 m_profileDialog = NULL;
1863 void StereoTool::updateLabels() {
1865 QString elevationLabel, elevationErrorLabel;
1866 QString baseRadiiLabel, leftDemRadiiLabel, rightDemRadiiLabel;
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 );
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);
1886 rightCamera->
SetImage( (*m_editPoint)[Right]->GetSample(),
1887 (*m_editPoint)[Right]->GetLine() );
1888 double rightDemRadii =
1890 rightDemRadiiLabel =
"Right DEM Radii: " +
1891 QString::number(rightDemRadii,
'f', 6);
1894 elevationLabel =
"Elevation: ";
1895 elevationErrorLabel =
"Elevation Error: ";
1896 baseRadiiLabel =
"Local Radii: ";
1897 leftDemRadiiLabel =
"Left DEM Radii: ";
1898 rightDemRadiiLabel =
"Right DEM Radii: ";
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);
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();
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);
This class defines a body-fixed surface point.
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Cube display widget for certain Isis MDI applications.
PointType GetType() const
void IgnoreElevationModel(bool ignore)
This allows you to ignore the cube elevation model and use the ellipse.
const double Null
Value for an Isis Null pixel.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
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.
QString name() const
Gets the shape name.
File name manipulation and expansion.
Distance GetLocalRadius() const
Return the radius of the surface point.
Camera * camera()
Return a camera associated with the cube.
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...
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
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.
This class is designed to encapsulate the concept of a Latitude.
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
Chip * SearchChip()
Return pointer to search chip.
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
Widget to display Isis cubes for qt apps.
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.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
A Free point is a Control Point that identifies common measurements between two or more cubes...
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
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.
This class is designed to encapsulate the concept of a Longitude.
Target * target() const
Returns a pointer to the target object.
double meters() const
Get the distance in meters.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Cube * cube() const
Return the cube associated with viewport.
double CubeSample() const
Return the search chip cube sample that best matched.
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)
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.
Chip * PatternChip()
Return pointer to pattern chip.
This is a plot curve with information relating it to a particular cube or region of a cube...
bool Success() const
Return whether the match algorithm succeeded or not.
#define _FILEINFO_
Macro for the filename and line number.
bool isValid() const
Test if this distance has been initialized or not.
A type of error that could only have occurred due to a mistake on the user's part (e...
Status SetAprioriSurfacePoint(SurfacePoint aprioriSP)
This updates the apriori 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
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's markers.
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
void setAxisLabel(int axisId, QString title)
Sets the plots given axis title to the given string.
Container for cube-like labels.
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Status SetType(PointType newType)
Updates the control point's type.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance LocalRadius() const
Returns the local radius at the intersection point.
static AutoReg * Create(Pvl &pvl)
Create an AutoReg object using a PVL specification.
void setData(QwtSeriesData< QPointF > *data)
This method sets the data for the curve, then sets the value for the markers associated with the curv...
Status SetFocalPlaneMeasured(double x, double y)
Set the focal plane x/y for the measured line/sample.
The data is an elevation (in meters).
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)
QString toString() const
Returns a string representation of this exception.
static QString UserName()
Returns the user name.
Adds specific functionality to C++ strings.
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.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
QString fileName() const
Returns the opened cube's filename.
The distance is being specified in meters.
Status SetDateTime()
Date Time - Creation Time.
void setPen(const QPen &pen)
Sets the plot pen to the passed-in pen.
ShapeModel * shape() const
Return the shape.
Serial Number list generator.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
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's serial number.
double CubeLine() const
Return the search chip cube line that best matched.
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.