11#include <QInputDialog>
14#include <QStackedWidget>
16#include "AbstractPlotTool.h"
17#include "Application.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"
29#include "IException.h"
34#include "MainWindow.h"
35#include "MdiCubeViewport.h"
38#include "ProfileDialog.h"
39#include "PvlEditDialog.h"
41#include "Projection.h"
42#include "QIsisApplication.h"
43#include "RubberBandTool.h"
44#include "SerialNumber.h"
46#include "SurfacePoint.h"
49#include "UniversalGroundMap.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() {
398 QDialog *helpDialog =
new QDialog(m_stereoTool);
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);
421 QWidget *overviewContainer =
new QWidget;
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);
454 QWidget *quickContainer =
new QWidget;
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=\"https://astrogeology.usgs.gov/docs/concepts/control-networks/pattern-matching/\">"
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);
508 QWidget *controlPointContainer =
new QWidget;
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();
612 catch (IException &e) {
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" ) {
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);
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);
729 m_controlNet =
new ControlNet();
730 m_controlNet->SetTarget(*m_linkedViewports.at(0)->cube()->label());
731 m_serialNumberList =
new SerialNumberList(
false);
735 m_controlNet =
new ControlNet();
736 m_controlNet->SetTarget(
737 m_linkedViewports.at(0)->cube()->camera()->target()->name() );
738 m_serialNumberList =
new SerialNumberList(
false);
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;
789 QString leftName =
FileName( m_leftCube->fileName() ).
name();
790 QString rightName =
FileName( m_rightCube->fileName() ).
name();
792 m_leftCubeLabel->setText(leftName);
793 m_rightCubeLabel->setText(rightName);
799 if ( !m_serialNumberList->hasSerialNumber(m_leftSN) ) {
800 m_serialNumberList->add( m_leftCube->fileName() );
802 if ( !m_serialNumberList->hasSerialNumber(m_rightSN) ) {
803 m_serialNumberList->add( m_rightCube->fileName() );
811 QString message =
"Could not determine target radius.";
812 QMessageBox::critical(m_stereoTool,
"Error",message);
814 updateRadiusLineEdit();
817 updateRadiusLineEdit();
824 QString message =
"Cannot initialize universal ground map for " +
825 m_leftCube->fileName() +
".\n";
827 QMessageBox::critical(m_stereoTool,
"Error", message);
834 QString message =
"Cannot initialize universal ground map for" +
835 m_rightCube->fileName() +
".\n";
837 QMessageBox::critical(m_stereoTool,
"Error", message);
852 double samp = m_editPoint->GetMeasure(Left)->GetSample();
853 double line = m_editPoint->GetMeasure(Left)->GetLine();
854 m_leftGM->SetImage(samp, line);
855 double lat = m_leftGM->UniversalLatitude();
856 double lon = m_leftGM->UniversalLongitude();
858 m_rightGM->SetGround(
866 QString message =
"Unable to set Apriori Surface Point.\n";
867 message +=
"Latitude = " + QString::number(lat);
868 message +=
" Longitude = " + QString::number(lon);
869 message +=
" Radius = " + QString::number(m_targetRadius.meters(),
'f',
872 QMessageBox::critical(m_stereoTool,
"Error", message);
875 calculateElevation();
876 emit editPointChanged();
887 rubberBandTool()->enable(RubberBandTool::LineMode);
888 rubberBandTool()->enablePoints();
889 rubberBandTool()->enableAllClicks();
890 rubberBandTool()->setDrawActiveViewportOnly(
true);
895 void StereoTool::rubberBandComplete() {
904 QMessageBox::critical(m_stereoTool,
"Error setting stereo pair", message);
905 rubberBandTool()->
clear();
916 sn = m_serialNumberList->serialNumber(file);
918 catch (IException &e) {
919 QString message =
"This cube is not linked as a stereo pair. Make ";
920 message +=
"sure you have two stereo pair cube viewports linked.";
921 QMessageBox::critical(m_stereoTool,
"Viewport not linked", message);
925 if ( rubberBandTool()->figureIsPoint() ) {
928 rubberBandTool()->vertices()[0].ry(),
930 if ( rubberBandTool()->mouseButton() & Qt::LeftButton ) {
931 if ( !m_controlNet || m_controlNet->GetNumMeasures() == 0 ) {
932 QString message =
"No points exist for editing. Create points ";
933 message +=
"using the right mouse button.";
934 QMessageBox::information(m_stereoTool,
"Warning", message);
940 point = m_controlNet->FindClosest(sn, samp, line);
942 catch (IException &e) {
943 QString message =
"No points found for editing. Create points ";
944 message +=
"using the right mouse button.";
946 QMessageBox::critical(m_stereoTool,
"Error", message);
951 else if ( rubberBandTool()->mouseButton() & Qt::MiddleButton ) {
952 if ( !m_controlNet || m_controlNet->GetNumPoints() == 0 ) {
953 QString message =
"No points exist for deleting. Create points ";
954 message +=
"using the right mouse button.";
955 QMessageBox::warning(m_stereoTool,
"Warning", message);
960 ControlPoint *point =
961 m_controlNet->FindClosest(sn, samp, line);
964 QString message =
"No points exist for deleting. Create points ";
965 message +=
"using the right mouse button.";
966 QMessageBox::information(m_stereoTool,
"Warning", message);
971 else if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
973 if (cvp->
cube() == m_leftCube) {
974 m_leftGM->SetImage(samp, line);
975 lat = m_leftGM->UniversalLatitude();
976 lon = m_leftGM->UniversalLongitude();
979 m_rightGM->SetImage(samp, line);
980 lat = m_rightGM->UniversalLatitude();
981 lon = m_rightGM->UniversalLongitude();
986 catch (IException &e) {
987 QString message =
"Cannot create control point.\n\n";
989 QMessageBox::critical(m_stereoTool,
"Error", message);
991 rubberBandTool()->clear();
1001 if ( rubberBandTool()->mouseButton() & Qt::RightButton ) {
1004 rubberBandTool()->vertices()[0].ry(),
1007 m_startPoint = m_controlNet->FindClosest(sn, samp, line);
1009 catch (IException &e) {
1010 QString message =
"Cannot find start point for profile. Either ";
1011 message +=
"create end points individually using the right mouse ";
1012 message +=
"button. Or, create profile end points by clicking and ";
1013 message +=
"dragging with the right mouse button.\n\n";
1015 QMessageBox::critical(m_stereoTool,
"Error", message);
1016 m_startPoint = NULL;
1017 rubberBandTool()->clear();
1021 rubberBandTool()->vertices()[1].ry(),
1024 m_endPoint = m_controlNet->FindClosest(sn, samp, line);
1025 if ( m_startPoint->GetId() == m_endPoint->GetId() ) {
1030 catch (IException &e) {
1031 QString message =
"Cannot find end point for profile. Either ";
1032 message +=
"create end points individually using the right mouse ";
1033 message +=
"button. Or, create profile end points by clicking and ";
1034 message +=
"dragging with the right mouse button.\n\n";
1036 QMessageBox::critical(m_stereoTool,
"Error", message);
1037 m_startPoint = NULL;
1039 rubberBandTool()->clear();
1046 m_profileDialog =
new ProfileDialog();
1047 connect( m_profileDialog, SIGNAL( createStart() ),
1048 this, SLOT( createStartPoint() ) );
1049 connect( m_profileDialog, SIGNAL( createEnd() ),
1050 this, SLOT( createEndPoint() ) );
1051 connect( m_profileDialog, SIGNAL( accepted() ),
1052 this, SLOT( profile() ) );
1053 connect( m_profileDialog, SIGNAL( accepted() ),
1054 this, SLOT( profile() ) );
1055 connect( m_profileDialog, SIGNAL( rejected() ),
1056 this, SLOT( clearProfile() ) );
1057 m_profileDialog->show();
1058 m_profileDialog->activateWindow();
1065 void StereoTool::clearProfile() {
1066 m_startPoint = NULL;
1068 rubberBandTool()->clear();
1069 delete m_profileDialog;
1070 m_profileDialog = NULL;
1075 void StereoTool::createStartPoint() {
1083 rubberBandTool()->vertices()[0].ry(),
1085 if ( cvp->
cube() == m_leftCube ) {
1086 m_leftGM->SetImage(samp, line);
1087 lat = m_leftGM->UniversalLatitude();
1088 lon = m_leftGM->UniversalLongitude();
1091 m_rightGM->SetImage(samp, line);
1092 lat = m_rightGM->UniversalLatitude();
1093 lon = m_rightGM->UniversalLongitude();
1098 catch (IException &e) {
1099 QString message =
"Cannot create control point.\n\n";
1101 QMessageBox::critical(m_stereoTool,
"Error", message);
1102 delete m_profileDialog;
1103 m_profileDialog = NULL;
1104 rubberBandTool()->clear();
1107 m_startPoint = m_editPoint;
1112 void StereoTool::createEndPoint() {
1120 rubberBandTool()->vertices()[1].ry(),
1122 if ( cvp->
cube() == m_leftCube ) {
1123 m_leftGM->SetImage(samp, line);
1124 lat = m_leftGM->UniversalLatitude();
1125 lon = m_leftGM->UniversalLongitude();
1128 m_rightGM->SetImage(samp, line);
1129 lat = m_rightGM->UniversalLatitude();
1130 lon = m_rightGM->UniversalLongitude();
1135 catch (IException &e) {
1136 QString message =
"Cannot create control point.\n\n";
1138 QMessageBox::critical(m_stereoTool,
"Error", message);
1139 m_startPoint = NULL;
1140 delete m_profileDialog;
1141 m_profileDialog = NULL;
1142 rubberBandTool()->clear();
1145 m_endPoint = m_editPoint;
1167 double leftSamp = 0, leftLine = 0;
1168 double rightSamp = 0, rightLine = 0;
1171 if ( m_leftGM->SetUniversalGround(lat, lon) ) {
1172 leftSamp = m_leftGM->Sample();
1173 leftLine = m_leftGM->Line();
1176 if ( m_rightGM->SetUniversalGround(lat, lon) ) {
1178 rightSamp = m_rightGM->Sample();
1179 rightLine = m_rightGM->Line();
1180 if ( rightSamp < 1 || rightSamp > m_rightCube->sampleCount() ||
1181 rightLine < 1 || rightLine > m_rightCube->lineCount() ) {
1182 IString message =
"Point does not exist on cube, " +
1183 m_rightCube->fileName() +
".";
1192 IString message =
"Point does not exist on cube, " +
1193 m_rightCube->fileName() +
".";
1202 IString message =
"Point does not exist on cube, " +
1203 m_leftCube->fileName() +
".";
1214 bool goodId =
false;
1217 QString
id = QInputDialog::getText(m_stereoTool,
1218 "Point ID",
"Enter Point ID:",
1219 QLineEdit::Normal, lastPtIdValue,
1226 if ( ok &&
id.isEmpty() ) {
1228 QString message =
"You must enter a point Id.";
1229 QMessageBox::warning(m_stereoTool,
"Warning", message);
1234 if ( m_controlNet->GetNumPoints() > 0 &&
1235 m_controlNet->ContainsPoint(newPoint->
GetId() ) ) {
1236 QString message =
"A ControlPoint with Point Id = [" +
1238 "] already exists. Re-enter unique Point Id.";
1239 QMessageBox::warning(m_stereoTool,
"Unique Point Id", message);
1260 newPoint->
Add(mLeft);
1268 newPoint->
Add(mRight);
1271 m_controlNet->AddPoint(newPoint);
1273 m_editPoint = m_controlNet->GetPoint( (QString) newPoint->
GetId() );
1276 m_stereoTool->setVisible(
true);
1277 m_stereoTool->raise();
1279 emit editPointChanged();
1296 m_editPoint = point;
1299 emit editPointChanged();
1303 m_controlNet->DeletePoint( m_editPoint->GetId() );
1304 m_stereoTool->setVisible(
false);
1307 emit editPointChanged();
1319 m_editPoint = point;
1321 m_stereoTool->setVisible(
true);
1322 m_stereoTool->raise();
1323 emit editPointChanged();
1335 m_pointEditor->setLeftMeasure( m_editPoint->GetMeasure(Left), m_leftCube,
1336 m_editPoint->GetId() );
1337 m_pointEditor->setRightMeasure( m_editPoint->GetMeasure(Right),
1338 m_rightCube, m_editPoint->GetId() );
1341 QString ptId =
"Point ID: " + m_editPoint->GetId();
1342 m_ptIdValue->setText(ptId);
1350 QString serialNumber) {
1356 m_startPoint->
GetMeasure(serialNumber)->GetLine(),
1359 m_endPoint->
GetMeasure(serialNumber)->GetLine(),
1361 painter->setPen(Qt::green);
1362 painter->drawLine(x1, y1, x2, y2);
1380 if ( m_controlNet == NULL || m_controlNet->GetNumPoints() == 0 )
1386 if ( !m_controlNet->GetCubeSerials().contains(
1387 serialNumber) )
return;
1396 m_controlNet->GetMeasuresInCube(serialNumber);
1398 for (
int i = 0; i < measures.count(); i++) {
1401 double samp = m->GetSample();
1402 double line = m->GetLine();
1406 if ( m->Parent()->IsIgnored() ) {
1407 painter->setPen( QColor(255, 255, 0) );
1410 else if ( m->IsIgnored() ) {
1411 painter->setPen( QColor(255, 255, 0) );
1415 painter->setPen(Qt::magenta);
1418 painter->setPen(Qt::green);
1421 painter->drawLine(x - 5, y, x + 5, y);
1422 painter->drawLine(x, y - 5, x, y + 5);
1426 if ( m_editPoint != NULL ) {
1428 if ( m_editPoint->HasSerialNumber(serialNumber) ) {
1430 double samp = (*m_editPoint)[serialNumber]->GetSample();
1431 double line = (*m_editPoint)[serialNumber]->GetLine();
1435 QBrush brush(Qt::red);
1439 painter->setPen(pen);
1440 painter->drawLine(x - 5, y, x + 5, y);
1441 painter->drawLine(x, y - 5, x, y + 5);
1461 vp->viewport()->update();
1467 void StereoTool::calculateElevation() {
1468 calculateElevation(m_editPoint);
1479 double elevation=0., elevationError=0.;
1480 Camera *leftCamera = m_leftCube->camera();
1485 if ( m_radiusBox->currentText() ==
"DEM Radius" ) {
1487 leftCamera->
SetImage( (*point)[Left]->GetSample(),
1488 (*point)[Left]->GetLine() );
1491 if ( !m_baseRadius.isValid() ) {
1492 QString message =
"Invalid Dem radius, defaulting to ellipsoidal.";
1493 QMessageBox::warning(m_stereoTool,
"Invalid Dem radius", message);
1494 m_baseRadius = m_targetRadius;
1499 leftCamera->
SetImage( (*point)[Left]->GetSample(),
1500 (*point)[Left]->GetLine() );
1501 Camera *rightCamera = m_rightCube->camera();
1503 rightCamera->
SetImage( (*point)[Right]->GetSample(),
1504 (*point)[Right]->GetLine() );
1506 double radius, lat, lon, sepang;
1507 if ( Stereo::elevation( *leftCamera, *rightCamera, radius, lat, lon, sepang,
1508 elevationError ) ) {
1509 elevation = radius - m_baseRadius.meters();
1535 QString filename = QFileDialog::getOpenFileName( m_stereoTool,
1536 "Select a registration template",
".",
1537 "Registration template files (*.def *.pvl);;All files (*)" );
1539 if ( filename.isEmpty() )
1542 m_pointEditor->setTemplateFile(filename);
1561 Pvl templatePvl( m_pointEditor->templateFileName() );
1565 registrationDialog.setWindowTitle(
"View or Edit Template File: "
1567 registrationDialog.resize(550, 360);
1568 registrationDialog.exec();
1572 QMessageBox::warning(m_stereoTool,
"Error", message);
1584 QString fn = QFileDialog::getSaveFileName( m_stereoTool,
1585 "Choose filename to save under",
1587 "CSV Files (*.csv)" );
1591 if ( !fn.isEmpty() ) {
1592 if ( !fn.endsWith(
".csv") ) {
1593 filename = fn +
".csv";
1604 m_currentFile.setFileName(filename);
1606 m_save->setEnabled(
true);
1612 void StereoTool::saveElevations() {
1614 if ( m_currentFile.fileName().isEmpty() )
return;
1616 bool success = m_currentFile.open(QIODevice::WriteOnly);
1618 QMessageBox::critical(m_stereoTool,
"Error",
1619 "Cannot open file, please check permissions");
1620 m_currentFile.setFileName(
"");
1621 m_save->setDisabled(
true);
1625 QTextStream text(&m_currentFile);
1626 QString header =
"Point ID, Latitude, Longitude, Radius, ";
1627 header +=
"Elevation, Elevation Error, ";
1628 header +=
"Image 1, Sample, Line, Image 2, Sample, Line";
1629 text << header << Qt::endl;
1634 for (
int i = 0; i < m_controlNet->GetNumPoints(); i++) {
1637 data = p.
GetId() +
"," +
1642 QString::number( p.
GetMeasure(Left)->GetFocalPlaneMeasuredX(),
'f',
1644 QString::number( p.
GetMeasure(Left)->GetFocalPlaneMeasuredY(),
'f',
1645 6 ) +
"," + leftFile +
"," +
1646 QString::number( p.
GetMeasure(Left)->GetSample() ) +
"," +
1647 QString::number( p.
GetMeasure(Left)->GetLine() ) +
"," +
1649 QString::number( p.
GetMeasure(Right)->GetSample() ) +
"," +
1650 QString::number( p.
GetMeasure(Right)->GetLine() );
1651 text << data << Qt::endl;
1653 m_currentFile.close();
1659 void StereoTool::clearNetData() {
1661 delete m_controlNet;
1662 m_controlNet = NULL;
1663 delete m_serialNumberList;
1664 m_serialNumberList = NULL;
1670 void StereoTool::profile() {
1678 if (m_profileDialog) {
1679 delete m_profileDialog;
1680 m_profileDialog = NULL;
1686 QPointF leftStart( (*m_startPoint)[Left]->GetSample(),
1687 (*m_startPoint)[Left]->GetLine() );
1688 QPointF leftEnd( (*m_endPoint)[Left]->GetSample(),
1689 (*m_endPoint)[Left]->GetLine() );
1691 QPointF rightStart( (*m_startPoint)[Right]->GetSample(),
1692 (*m_startPoint)[Right]->GetLine() );
1693 QPointF rightEnd( (*m_endPoint)[Right]->GetSample(),
1694 (*m_endPoint)[Right]->GetLine() );
1697 QList< QList<QPoint> > rubberBandVertices;
1698 QList<QPoint> rubberBand1;
1700 m_linkedViewports.at(0)->cubeToViewport( (*m_startPoint)[Left]->GetSample(),
1701 (*m_startPoint)[Left]->GetLine(), sx, sy);
1702 m_linkedViewports.at(0)->cubeToViewport( (*m_endPoint)[Left]->GetSample(),
1703 (*m_endPoint)[Left]->GetLine(), ex, ey);
1704 rubberBand1.push_back( QPoint(sx, sy) );
1705 rubberBand1.push_back( QPoint(ex, ey) );
1707 rubberBandVertices.push_back(rubberBand1);
1709 QList<QPoint> rubberBand2;
1710 m_linkedViewports.at(1)->cubeToViewport( (*m_startPoint)[Right]->GetSample(),
1711 (*m_startPoint)[Right]->GetLine(), sx, sy);
1712 m_linkedViewports.at(1)->cubeToViewport( (*m_endPoint)[Right]->GetSample(),
1713 (*m_endPoint)[Right]->GetLine(), ex, ey);
1714 rubberBand2.push_back( QPoint(sx, sy) );
1715 rubberBand2.push_back( QPoint(ex, ey) );
1717 rubberBandVertices.push_back(rubberBand2);
1720 QLineF leftProfile(leftStart,leftEnd);
1721 QLineF rightProfile(rightStart,rightEnd);
1725 QLineF longProfile, shortProfile;
1726 Cube *longCube, *shortCube;
1727 if ( leftProfile.length() > rightProfile.length() ) {
1728 longProfile = leftProfile;
1729 longCube = m_leftCube;
1730 shortProfile = rightProfile;
1731 shortCube = m_rightCube;
1734 longProfile = rightProfile;
1735 longCube = m_rightCube;
1736 shortProfile = leftProfile;
1737 shortCube = m_leftCube;
1740 QVector<QPointF> profileData;
1741 double elevation = 0.;
1742 double elevationError = 0.;
1744 Pvl regDef = m_pointEditor->templateFileName();
1747 int failureCount = 0;
1748 QApplication::setOverrideCursor(Qt::WaitCursor);
1750 for (
int i = 0; i <= (int) shortProfile.length(); i++) {
1751 double shortSamp=0, shortLine=0, longSamp=0, longLine=0;
1753 shortSamp = shortProfile.pointAt( 1/shortProfile.length() * i ).x();
1754 shortLine = shortProfile.pointAt( 1/shortProfile.length() * i ).y();
1756 longSamp = longProfile.pointAt( 1/shortProfile.length() * i ).x();
1757 longLine = longProfile.pointAt( 1/shortProfile.length() * i ).y();
1773 if ( m_radiusBox->currentText() ==
"DEM Radius" ) {
1779 if ( !m_baseRadius.isValid() ) {
1780 QString message =
"Invalid Dem radius, defaulting to ellipsoidal.";
1781 QMessageBox::warning(m_stereoTool,
"Invalid Dem radius", message);
1782 m_baseRadius = m_targetRadius;
1791 double radius, lat, lon, sepang;
1792 if (Stereo::elevation( *shortCube->
camera(), *longCube->
camera(),
1793 radius, lat, lon, sepang, elevationError) )
1794 elevation = radius - m_baseRadius.meters();
1795 profileData.append( QPointF(i, elevation) );
1803 catch (IException &e) {
1804 QString message =
"Error registering cubes along profile line.\n";
1805 message +=
"Image 1 Sample = " + QString::number(shortSamp);
1806 message +=
" Line = " + QString::number(shortLine);
1807 message +=
"\nImage 2 Sample = " + QString::number(longSamp);
1808 message +=
" Line = " + QString::number(longLine) +
"\n\n";
1810 QMessageBox::critical(m_stereoTool,
"Error", message);
1811 rubberBandTool()->clear();
1815 QApplication::restoreOverrideCursor();
1818 QString message =
"Registration attempts (pixels on line) = " +
1819 QString::number( (
int)shortProfile.length() ) +
1820 "\n\nRegistration failures = " +
1821 QString::number(failureCount) +
1822 "\n\nYou can adjust registration parameters in the "
1823 "\"Options\" menu in the Elevation Calculator window. "
1824 "Select \"Options\", then \"Registration\", then either "
1825 "\"Select registration template\" or "
1826 "\"View/edit registration template\".";
1827 QMessageBox::information(m_stereoTool,
"Registration Report", message);
1829 if ( ( (
int)shortProfile.length() + 1 - failureCount ) < 2 ) {
1830 QString message =
"Cannot create profile, all auto-registration between ";
1831 message +=
"the left and right cubes along the profile failed. Try ";
1832 message +=
"adjusting the registration parameters.";
1833 QMessageBox::critical(m_stereoTool,
"Error", message);
1841 plotCurve->
setData(
new QwtPointSeriesData(profileData) );
1842 plotCurve->setTitle(
"Elevations (Meters)");
1843 plotCurve->
setPen( QPen(Qt::white) );
1851 plotCurve->
setSource(m_linkedViewports, rubberBandVertices, bands);
1852 plotWindow->
add(plotCurve);
1854 delete m_profileDialog;
1855 m_profileDialog = NULL;
1864 void StereoTool::updateLabels() {
1866 QString elevationLabel, elevationErrorLabel;
1867 QString baseRadiiLabel, leftDemRadiiLabel, rightDemRadiiLabel;
1868 if ( m_editPoint->GetMeasure(Left)->GetFocalPlaneMeasuredX() !=
Isis::Null ) {
1869 elevationLabel =
"Elevation: " +
1870 QString::number( m_editPoint->GetMeasure(Left)->
1871 GetFocalPlaneMeasuredX(),
'f', 6 );
1872 elevationErrorLabel =
"Elevation Error: " +
1873 QString::number( m_editPoint->GetMeasure(Left)->
1874 GetFocalPlaneMeasuredY(),
'f', 6 );
1875 baseRadiiLabel =
"Local Radii: " + QString::number(
1876 m_baseRadius.meters(),
'f', 6 );
1878 Camera *leftCamera = m_leftCube->camera();
1879 leftCamera->
SetImage( (*m_editPoint)[Left]->GetSample(),
1880 (*m_editPoint)[Left]->GetLine() );
1881 double leftDemRadii =
1883 leftDemRadiiLabel =
"Left DEM Radii: " +
1884 QString::number(leftDemRadii,
'f', 6);
1886 Camera *rightCamera = m_rightCube->camera();
1887 rightCamera->
SetImage( (*m_editPoint)[Right]->GetSample(),
1888 (*m_editPoint)[Right]->GetLine() );
1889 double rightDemRadii =
1891 rightDemRadiiLabel =
"Right DEM Radii: " +
1892 QString::number(rightDemRadii,
'f', 6);
1895 elevationLabel =
"Elevation: ";
1896 elevationErrorLabel =
"Elevation Error: ";
1897 baseRadiiLabel =
"Local Radii: ";
1898 leftDemRadiiLabel =
"Left DEM Radii: ";
1899 rightDemRadiiLabel =
"Right DEM Radii: ";
1901 m_elevationLabel->setText(elevationLabel);
1902 m_elevationErrorLabel->setText(elevationErrorLabel);
1903 m_baseRadiiLabel->setText(baseRadiiLabel);
1904 m_leftDemRadiiLabel->setText(leftDemRadiiLabel);
1905 m_rightDemRadiiLabel->setText(rightDemRadiiLabel);
1910 void StereoTool::readSettings() {
1911 FileName config(
"$HOME/.Isis/qview/Stereo Tool.config");
1912 QSettings settings(config.expanded(),
1913 QSettings::NativeFormat);
1914 m_showWarning = settings.value(
"showWarning",
true).toBool();
1920 void StereoTool::writeSettings() {
1921 FileName config(
"$HOME/.Isis/qview/Stereo Tool.config");
1922 QSettings settings(config.expanded(),
1923 QSettings::NativeFormat);
1924 settings.setValue(
"showWarning", m_showWarning);
double degrees() const
Get the angle in units of Degrees.
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
static QString UserName()
Returns the user name.
static AutoReg * Create(Pvl &pvl)
Create an AutoReg object using a PVL specification.
double CubeLine() const
Return the search chip cube line that best matched.
bool Success() const
Return whether the match algorithm succeeded or not.
Chip * SearchChip()
Return pointer to search chip.
double CubeSample() const
Return the search chip cube sample that best matched.
Chip * PatternChip()
Return pointer to pattern chip.
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
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 SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
@ Manual
Hand Measured (e.g., qnet)
Status SetFocalPlaneMeasured(double x, double y)
Set the focal plane x/y for the measured line/sample.
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Status SetDiameter(double diameter)
Set the crater diameter at the coordinate.
Status SetDateTime()
Date Time - Creation Time.
double GetDiameter() const
Return the diameter of the crater in pixels (0 implies no crater)
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
Status SetAprioriSurfacePoint(SurfacePoint aprioriSP)
This updates the apriori surface point.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
PointType GetType() const
@ Free
A Free point is a Control Point that identifies common measurements between two or more cubes.
Status SetType(PointType newType)
Updates the control point's type.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
QString GetId() const
Return the Id of the control point.
IO Handler for Isis Cubes.
Camera * camera()
Return a camera associated with the cube.
virtual QString fileName() const
Returns the opened cube's filename.
void setSource(CubeViewport *cvp, QList< QPoint > screenPoints, int band=-1)
Tell this plot curve from where its data originated.
Widget to display Isis cubes for qt apps.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
void cubeToViewport(double sample, double line, int &x, int &y) const
Turns a cube into a viewport.
Distance measurement, usually in meters.
@ Meters
The distance is being specified in meters.
double meters() const
Get the distance in meters.
File name manipulation and expansion.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
QString toString() const
Returns a string representation of this exception.
Adds specific functionality to C++ strings.
This class is designed to encapsulate the concept of a Latitude.
This class is designed to encapsulate the concept of a Longitude.
Cube display widget for certain Isis MDI applications.
void setColor(const QColor &color)
Set the color of this curve and it's markers.
void setData(QwtSeriesData< QPointF > *data)
This method sets the data for the curve, then sets the value for the markers associated with the curv...
@ Elevation
The data is an elevation (in meters).
@ PixelNumber
The data is a pixel #.
void setPen(const QPen &pen)
Sets the plot pen to the passed-in pen.
void setAxisLabel(int axisId, QString title)
Sets the plots given axis title to the given string.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
QString fileName() const
Returns the filename used to initialise the Pvl object.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file.
Contains multiple PvlContainers.
Container for cube-like labels.
virtual SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
Latitude GetLatitude() const
Returns a planetocentric latitude object at the surface intersection point in body fixed.
void IgnoreElevationModel(bool ignore)
This allows you to ignore the cube elevation model and use the ellipse.
Distance LocalRadius() const
Returns the local radius at the intersection point.
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
This class defines a body-fixed surface point.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Distance GetLocalRadius() const
Return the radius of the surface point.
static PvlGroup radiiGroup(QString target)
Creates a Pvl Group with keywords TargetName, EquitorialRadius, and PolarRadius.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.