3 #include "ControlPointEditWidget.h"
12 #include <QFileDialog>
13 #include <QFormLayout>
15 #include <QHBoxLayout>
17 #include <QMainWindow>
18 #include <QMessageBox>
20 #include <QPushButton>
24 #include <QTableWidget>
26 #include <QVBoxLayout>
31 #include "ControlMeasureEditWidget.h"
36 #include "DeleteControlPointDialog.h"
42 #include "MainWindow.h"
44 #include "NewControlPointDialog.h"
47 #include "PvlEditDialog.h"
51 #include "ShapeList.h"
55 #include "ViewportMainWindow.h"
69 bool addMeasures) :
QWidget(parent) {
71 m_directory = directory;
83 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
88 ControlPointEditWidget::~ControlPointEditWidget () {
123 setWindowTitle(
"Control Point Editor");
124 setObjectName(
"ControlPointEditWidget");
134 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
144 QPushButton *addMeasure = NULL;
146 addMeasure =
new QPushButton(
"Add Measure(s) to Point");
147 addMeasure->setToolTip(
"Add a new measure to the edit control point.");
148 addMeasure->setWhatsThis(
"This allows a new control measure to be added "
149 "to the currently edited control point. A selection "
150 "box with all cubes from the input list will be "
151 "displayed with those that intersect with the "
152 "control point highlighted.");
154 connect(addMeasure, SIGNAL(clicked()),
this, SLOT(addMeasure()));
158 m_savePoint->setToolTip(
"Save the edit control point to the control "
160 m_savePoint->setWhatsThis(
"Save the edit control point to the control "
161 "network which is loaded into memory in its entirety. "
162 "When a control point is selected for editing, "
163 "a copy of the point is made so that the original control "
164 "point remains in the network.");
168 m_saveNet =
new QPushButton (
"Save Control Net");
169 m_saveNet->setToolTip(
"Save the control network.");
170 m_savePoint->setWhatsThis(
"Save the control network.");
177 QHBoxLayout * saveMeasureLayout =
new QHBoxLayout;
179 saveMeasureLayout->addWidget(addMeasure);
182 saveMeasureLayout->addStretch();
198 "registration template. Refer to $ISISROOT/doc/documents/"
199 "PatternMatch/PatternMatch.html for a description of the "
200 "contents of this file.");
202 QVBoxLayout * centralLayout =
new QVBoxLayout;
207 centralLayout->addStretch();
209 centralLayout->addLayout(saveMeasureLayout);
212 centralWidget->setLayout(centralLayout);
214 QScrollArea *scrollArea =
new QScrollArea();
215 scrollArea->setObjectName(
"ControlPointEditWidgetScroll");
216 scrollArea->setWidget(centralWidget);
217 scrollArea->setWidgetResizable(
true);
218 centralWidget->adjustSize();
220 QHBoxLayout *mainLayout =
new QHBoxLayout;
221 mainLayout->addWidget(scrollArea);
222 setLayout(mainLayout);
237 QHBoxLayout * measureLayout =
new QHBoxLayout;
241 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
243 groupBoxesLayout->addStretch();
244 groupBoxesLayout->addLayout(measureLayout);
247 groupBoxesWidget->setLayout(groupBoxesLayout);
251 QSplitter * topSplitter =
new QSplitter;
252 topSplitter->addWidget(groupBoxesWidget);
274 m_numMeasures =
new QLabel;
285 connect(
this, SIGNAL(ignorePointChanged()),
m_ignorePoint, SLOT(toggle()));
292 for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
296 QFormLayout *pointTypeLayout =
new QFormLayout;
298 pointTypeLayout->addRow(
"PointType:",
m_pointType);
303 QVBoxLayout * mainLayout =
new QVBoxLayout;
305 mainLayout->addWidget(m_numMeasures);
308 mainLayout->addLayout(pointTypeLayout);
314 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
315 groupBox->setLayout(mainLayout);
330 m_leftCombo->setToolTip(
"Choose left control measure");
331 m_leftCombo->setWhatsThis(
"Choose left control measure identified by "
341 connect(
this, SIGNAL(ignoreLeftChanged()),
345 QVBoxLayout * leftLayout =
new QVBoxLayout;
352 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
353 leftGroupBox->setLayout(leftLayout);
371 m_rightCombo->setToolTip(
"Choose right control measure");
372 m_rightCombo->setWhatsThis(
"Choose right control measure identified by "
375 m_rightCombo->view()->setSelectionMode(QAbstractItemView::SingleSelection);
379 m_rightCombo->view()->setDragDropMode(QAbstractItemView::InternalMove);
383 QShortcut *nextMeasure =
new QShortcut(Qt::Key_PageDown,
this);
385 QShortcut *prevMeasure =
new QShortcut(Qt::Key_PageUp,
this);
396 connect(
this, SIGNAL(ignoreRightChanged()),
402 QVBoxLayout * rightLayout =
new QVBoxLayout;
409 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
410 rightGroupBox->setLayout(rightLayout);
412 return rightGroupBox;
424 toolBar->addSeparator();
432 QVBoxLayout *mainLayout =
new QVBoxLayout;
433 mainLayout->addWidget(toolBar);
451 QString whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point "
452 "<p><b>Shortcut:</b> Alt+F4 </p>";
456 m_showHideTemplateEditor =
new QAction(QIcon(
FileName(
"base/icons/view_text.png").expanded()),
457 "&View/edit registration template",
this);
458 m_showHideTemplateEditor->setCheckable(
true);
459 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
460 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
461 whatsThis =
"<b>Function:</b> Displays the curent registration template. "
462 "The user may edit and save changes under a chosen filename.";
463 m_showHideTemplateEditor->setWhatsThis(whatsThis);
464 connect(m_showHideTemplateEditor, SIGNAL(triggered()),
this,
468 "Save registration chips",
this);
469 m_saveChips->setToolTip(
"Save registration chips");
470 m_saveChips->setStatusTip(
"Save registration chips");
471 whatsThis =
"<b>Function:</b> Save registration chips to file. "
472 "Each chip: pattern, search, fit will be saved to a separate file.";
477 "&Open registration template",
this);
480 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as "
481 "the registration template";
486 "&Save template file",
this);
494 "&Save template as...",
this);
535 setWindowTitle(
"Control Point Editor- Control Network File: " +
m_cnetFileName);
557 if (!groundFile.fileExists()) {
561 QString message =
"Ground Source file " + groundFile.expanded();
562 message +=
" doesn't exist";
563 QMessageBox::critical(
this,
"Warning", message);
571 QScopedPointer<Cube> groundCube(
new Cube(groundFile,
"r"));
588 cam->
SetImage(m.GetSample(),m.GetLine());
595 if (!groundMap->SetUniversalGround(lat,lon)) {
596 QString message =
"This point does not exist on the ground source.\n";
597 message +=
"Latitude = " + QString::number(lat);
598 message +=
" Longitude = " + QString::number(lon);
599 message +=
"\n A ground measure will not be created.";
600 QMessageBox::warning(
this,
"Warning", message);
609 groundMeasure->
SetCoordinate(groundMap->Sample(), groundMap->Line());
618 return groundMeasure;
641 this->setVisible(
true);
672 QString ptId(
"Point ID: ");
673 ptId += (QString) CPId;
679 groundFile =
m_editPoint->GetAprioriSurfacePointSourceFile();
683 QString ptsize =
"Number of Measures: " +
685 m_numMeasures->setText(ptsize);
698 m_pointCubes.clear();
713 QString message =
"Cannot create ground measure on ground source file ";
714 message += groundFile;
715 QMessageBox::warning(
this,
"Warning", message);
720 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
730 QString tempFileName =
FileName(file).name();
734 item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
735 m_model->appendRow(item);
741 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
742 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
774 if (leftIndex < 0 ) leftIndex = 0;
779 if (leftIndex == 0) {
788 if (rightIndex >
m_editPoint->GetNumMeasures()-1) rightIndex = 0;
799 void ControlPointEditWidget::createControlPoint(
double latitude,
double longitude,
Cube *cube,
800 bool isGroundSource) {
814 double samp = cam->
Sample();
815 double line = cam->
Line();
816 if (samp >= 1 && samp <= cam->Samples() &&
817 line >= 1 && line <= cam->Lines()) {
829 foreach (ShapeList *shapeList, shapeLists) {
830 foreach (Shape *shape, *shapeList) {
831 UniversalGroundMap *gmap =
new UniversalGroundMap(*(shape->cube()));
832 if (gmap->SetUniversalGround(latitude, longitude)) {
833 shapeNames<<shape->displayProperties()->displayName();
836 shapeNamesNoPoint<<shape->displayProperties()->displayName();
838 nameToShapeMap[shape->displayProperties()->displayName()] = shape;
843 int numberShapesWithPoint = shapeNames.count();
844 shapeNames<<shapeNamesNoPoint;
848 NewControlPointDialog *newPointDialog =
850 newPointDialog->setFiles(pointFiles);
851 newPointDialog->setGroundSource(shapeNames, numberShapesWithPoint);
852 if (newPointDialog->exec()) {
854 ControlPoint *newPoint =
860 QString message =
"A ControlPoint with Point Id = [" + newPoint->GetId();
861 message +=
"] already exists. Re-enter Point Id for this ControlPoint.";
862 QMessageBox::warning(
this,
"New Point Id", message);
866 createControlPoint(latitude, longitude);
872 QStringList selectedFiles = newPointDialog->selectedFiles();
873 foreach (QString selectedFile, selectedFiles) {
875 ControlMeasure *m =
new ControlMeasure;
878 m->SetCubeSerialNumber(sn);
883 m->SetAprioriSample(cam->
Sample());
884 m->SetAprioriLine(cam->
Line());
896 Shape *shape = nameToShapeMap[newPointDialog->groundSource()];
898 if (shape->shapeType() == Shape::Dem ||
899 shape->shapeType() == Shape::Basemap) {
900 newPoint->SetAprioriSurfacePointSource(ControlPoint::SurfacePointSource::Basemap);
902 else if (shape->shapeType() == Shape::Unprojected) {
906 newPoint->SetAprioriSurfacePointSourceFile(shape->fileName());
933 emit controlPointAdded(newPoint->GetId());
938 void ControlPointEditWidget::deletePoint(ControlPoint *controlPoint) {
961 deletePointDialog->pointIdValue->setText(CPId);
964 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
965 ControlMeasure &m = *(*m_editPoint)[i];
967 deletePointDialog->fileList->addItem(file);
970 if (deletePointDialog->exec()) {
972 int numDeleted = deletePointDialog->fileList->selectedItems().count();
975 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
979 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
980 QString message =
"You have selected all measures in this point to be deleted. This "
981 "control point will be deleted. Do you want to delete this control point?";
982 int response = QMessageBox::question(
this,
983 "Delete control point", message,
984 QMessageBox::Yes | QMessageBox::No,
987 if (response == QMessageBox::No) {
999 QMessageBox::information(
this,
"EditLocked Point",
1000 "This point is EditLocked and cannot be deleted.");
1014 int lockedMeasures = 0;
1015 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1016 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1017 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1021 (
m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
1022 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1023 QString message =
"You are trying to delete the Reference measure."
1024 " Do you really want to delete the Reference measure?";
1025 switch (QMessageBox::question(
this,
1026 "Delete Reference measure?", message,
1027 "&Yes",
"&No", 0, 0)) {
1035 if (numDeleted == 1) {
1042 if (
m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
1047 if (lockedMeasures > 0) {
1048 QMessageBox::information(
this,
"EditLocked Measures",
1049 QString::number(lockedMeasures) +
" / "
1051 deletePointDialog->fileList->selectedItems().size()) +
1052 " measures are EditLocked and were not deleted.");
1152 QString message =
"You are saving changes to a measure on an ignored ";
1153 message +=
"point. Do you want to set Ignore = False on the point and ";
1154 message +=
"both measures?";
1155 switch (QMessageBox::question(
this,
"Match Tool Save Measure",
1156 message,
"&Yes",
"&No", 0, 0)) {
1160 emit ignorePointChanged();
1163 emit ignoreLeftChanged();
1167 emit ignoreRightChanged();
1175 bool savedAMeasure =
false;
1181 savedAMeasure =
true;
1184 if (rightChangeOk) {
1187 savedAMeasure =
true;
1199 if (savedAMeasure) {
1231 if (*m == *origMeasure)
return false;
1235 QString side =
"right";
1248 QString message =
"The " + side +
" measure is editLocked ";
1249 message +=
"for editing. Do you want to set EditLock = False for this ";
1250 message +=
"measure?";
1251 int response = QMessageBox::question(
this,
"Match Tool Save Measure",
1252 message, QMessageBox::Yes | QMessageBox::No);
1254 if (response == QMessageBox::Yes) {
1255 m->SetEditLock(
false);
1256 if (side ==
"left") {
1269 if (origMeasure->IsIgnored() && m->IsIgnored()) {
1270 QString message =
"The " + side +
"measure is ignored. ";
1271 message +=
"Do you want to set Ignore = False on the measure?";
1272 switch(QMessageBox::question(
this,
"Match Tool Save Measure",
1273 message,
"&Yes",
"&No", 0, 0)){
1276 m->SetIgnored(
false);
1277 if (side ==
"left") {
1278 emit ignoreLeftChanged();
1281 emit ignoreRightChanged();
1293 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
1294 QString message =
"You are making a change to the reference measure. You ";
1295 message +=
"may need to move all of the other measures to match the new ";
1296 message +=
" coordinate of the reference measure. Do you really want to ";
1297 message +=
" change the reference measure's location? ";
1298 switch(QMessageBox::question(
this,
"Match Tool Save Measure",
1299 message,
"&Yes",
"&No", 0, 0)){
1312 QString message =
"This point already contains a reference measure. ";
1313 message +=
"Would you like to replace it with the measure on the left?";
1314 int response = QMessageBox::question(
this,
1315 "Match Tool Save Measure", message,
1316 QMessageBox::Yes | QMessageBox::No,
1319 if (response == QMessageBox::Yes) {
1323 QString fname =
FileName(file).name();
1327 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
1328 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1330 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1345 if (side ==
"left") {
1373 QString message =
"This point already contains a reference measure. ";
1374 message +=
"Would you like to replace it with the measure on the left?";
1375 int response = QMessageBox::question(
this,
1376 "Match Tool Save Measure", message,
1377 QMessageBox::Yes | QMessageBox::No,
1380 if (response == QMessageBox::Yes) {
1384 QString fname =
FileName(file).name();
1388 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
1389 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1391 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1437 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1485 #if 0 //TODO 2014-07-22 TLS cnetsuite Handle ground control points SOON
1486 void ControlPointEditWidget::setPointType (
int pointType) {
1494 QString message =
"The reference measure is Ignored. Unset the Ignore flag on the ";
1495 message +=
"reference measure before setting the point type to Constrained or Fixed.";
1496 QMessageBox::warning(
m_parent,
"Ignored Reference Measure", message);
1501 bool unloadGround =
false;
1508 QString message =
"This control point is edit locked. The point type cannot be changed. You ";
1509 message +=
"must first unlock the point by clicking the check box above labeled ";
1510 message +=
"\"Edit Lock Point\".";
1511 QMessageBox::warning(
m_parent,
"Point Locked", message);
1522 else if (unloadGround) {
1572 QString message =
"Unable to change Ignored on point. Set EditLock ";
1573 message +=
" to False.";
1574 QMessageBox::critical(
this,
"Error", message);
1599 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1600 " before changing a measure.");
1615 emit measureChanged();
1647 emit measureChanged();
1669 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1670 " before changing a measure.");
1684 emit measureChanged();
1717 emit measureChanged();
1750 for (
int row=0; row<
m_editPoint->GetNumMeasures(); row++) {
1755 QTableWidgetItem *tableItem =
new QTableWidgetItem(QString(file));
1761 tableItem =
new QTableWidgetItem();
1762 tableItem->setData(0,m.GetSample());
1765 tableItem =
new QTableWidgetItem();
1766 tableItem->setData(0,m.GetLine());
1769 if (m.GetAprioriSample() ==
Null) {
1770 tableItem =
new QTableWidgetItem(
"Null");
1773 tableItem =
new QTableWidgetItem();
1774 tableItem->setData(0,m.GetAprioriSample());
1778 if (m.GetAprioriLine() ==
Null) {
1779 tableItem =
new QTableWidgetItem(
"Null");
1782 tableItem =
new QTableWidgetItem();
1783 tableItem->setData(0,m.GetAprioriLine());
1787 if (m.GetSampleResidual() ==
Null) {
1788 tableItem =
new QTableWidgetItem(QString(
"Null"));
1791 tableItem =
new QTableWidgetItem();
1792 tableItem->setData(0,m.GetSampleResidual());
1796 if (m.GetLineResidual() ==
Null) {
1797 tableItem =
new QTableWidgetItem(QString(
"Null"));
1800 tableItem =
new QTableWidgetItem();
1801 tableItem->setData(0,m.GetLineResidual());
1806 tableItem =
new QTableWidgetItem(QString(
"Null"));
1809 tableItem =
new QTableWidgetItem();
1814 double sampleShift = m.GetSampleShift();
1815 if (sampleShift ==
Null) {
1816 tableItem =
new QTableWidgetItem(QString(
"Null"));
1819 tableItem =
new QTableWidgetItem();
1820 tableItem->setData(0,sampleShift);
1824 double lineShift = m.GetLineShift();
1825 if (lineShift ==
Null) {
1826 tableItem =
new QTableWidgetItem(QString(
"Null"));
1829 tableItem =
new QTableWidgetItem();
1830 tableItem->setData(0,lineShift);
1834 double pixelShift = m.GetPixelShift();
1835 if (pixelShift ==
Null) {
1836 tableItem =
new QTableWidgetItem(QString(
"Null"));
1839 tableItem =
new QTableWidgetItem();
1840 tableItem->setData(0,pixelShift);
1844 double goodnessOfFit = m.GetLogData(
1846 if (goodnessOfFit ==
Null) {
1847 tableItem =
new QTableWidgetItem(QString(
"Null"));
1850 tableItem =
new QTableWidgetItem();
1851 tableItem->setData(0,goodnessOfFit);
1855 if (m.IsIgnored()) tableItem =
new QTableWidgetItem(
"True");
1856 if (!m.IsIgnored()) tableItem =
new QTableWidgetItem(
"False");
1860 tableItem =
new QTableWidgetItem(
"True");
1862 tableItem =
new QTableWidgetItem(
"False");
1865 tableItem =
new QTableWidgetItem(
1909 case SAMPLERESIDUAL:
1910 return "Sample Residual";
1912 return "Line Residual";
1913 case RESIDUALMAGNITUDE:
1914 return "Residual Magnitude";
1916 return "Sample Shift";
1918 return "Line Shift";
1920 return "Pixel Shift";
1922 return "Goodness of Fit";
1928 return "Measure Type";
1930 return "Apriori Sample";
1932 return "Apriori Line";
1935 "Invalid measure column passed to measureColumnToString",
_FILEINFO_);
1951 if (curIndex < m_rightCombo->count() - 1) {
2001 QString message =
"Make sure the correct cube is opened.\n\n";
2003 QMessageBox::critical(
this,
"Error", message);
2050 QString message =
"Make sure the correct cube is opened.\n\n";
2052 QMessageBox::critical(
this,
"Error", message);
2106 QString s =
"Reference: ";
2116 s =
"Measure Type: ";
2152 QString s =
"Reference: ";
2163 s =
"Measure Type: ";
2185 if(e->type() != QEvent::Leave)
return false;
2207 int r = QMessageBox::warning(
this, tr(
"OK to continue?"),
2208 tr(
"The currently opened registration template has been modified.\n"
2210 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2213 if (r == QMessageBox::Yes)
2215 else if (r == QMessageBox::Cancel)
2233 QString filename = QFileDialog::getOpenFileName(
this,
2234 "Select a registration template",
".",
2235 "Registration template files (*.def *.pvl);;All files (*)");
2237 if (filename.isEmpty())
2253 QFile file(
FileName((QString) fn).expanded());
2254 if (!file.open(QIODevice::ReadOnly)) {
2255 QString msg =
"Failed to open template file \"" + fn +
"\"";
2256 QMessageBox::warning(
this,
"IO Error", msg);
2260 QTextStream stream(&file);
2265 sb->setValue(sb->minimum());
2303 QString filename = QFileDialog::getSaveFileName(
this,
2304 "Save registration template",
".",
2305 "Registration template files (*.def *.pvl);;All files (*)");
2307 if (filename.isEmpty())
2332 QMessageBox::warning(
this,
"Error", message);
2336 QString expandedFileName(
FileName((QString) fn).expanded());
2338 QFile file(expandedFileName);
2340 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2341 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2343 QMessageBox::warning(
this,
"IO Error", msg);
2348 QTextStream stream(&file);
2380 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2381 + templatePvl.fileName());
2382 registrationDialog.resize(550,360);
2383 registrationDialog.exec();
2387 QMessageBox::information(
this,
"Error", message);
2439 m_editPoint->SetEditLock(updatedPoint.IsEditLocked());
2440 m_editPoint->SetIgnored(updatedPoint.IsIgnored());
2495 QColor qc = Qt::red;
2497 p.setColor(QPalette::ButtonText,qc);
2512 QColor qc = Qt::red;
2514 p.setColor(QPalette::ButtonText,qc);
2537 (
m_editPoint->GetReferenceSN() == serialNumber)) {
2542 return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
2562 emit saveControlNet();
2572 void ControlPointEditWidget::readSettings() {
2573 FileName config(
"$HOME/.Isis/qview/ControlPointEditWidget.config");
2574 QSettings settings(config.expanded(),
2575 QSettings::NativeFormat);
2576 QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
2577 QSize size = settings.value(
"size", QSize(900, 500)).toSize();
2589 void ControlPointEditWidget::writeSettings()
const {
2592 if (!this->isVisible())
return;
2593 FileName config(
"$HOME/.Isis/qview/ControlPointEditWidget.config");
2594 QSettings settings(config.expanded(),
2595 QSettings::NativeFormat);
2596 settings.setValue(
"pos", this->pos());
2597 settings.setValue(
"size", this->size());
2614 void ControlPointEditWidget::showHelp() {
2617 helpDialog->setWindowTitle(
"Match Tool Help");
2619 QVBoxLayout *mainLayout =
new QVBoxLayout;
2620 helpDialog->setLayout(mainLayout);
2622 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
2623 mainLayout->addWidget(matchTitle);
2625 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
2626 "registration points between cubes. These "
2627 "points contain sample, line postions only, no latitude or "
2628 "longitude values are used or recorded.");
2629 matchSubtitle->setWordWrap(
true);
2630 mainLayout->addWidget(matchSubtitle);
2632 QTabWidget *tabArea =
new QTabWidget;
2633 tabArea->setDocumentMode(
true);
2634 mainLayout->addWidget(tabArea);
2637 QScrollArea *overviewTab =
new QScrollArea;
2638 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2639 overviewTab->setWidgetResizable(
true);
2641 QVBoxLayout *overviewLayout =
new QVBoxLayout;
2642 overviewContainer->setLayout(overviewLayout);
2644 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
2645 overviewLayout->addWidget(purposeTitle);
2647 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
2648 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
2649 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
2650 "tool can be used on any images including ones that do not contain a camera model "
2651 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
2652 "This also means that the tool differs from the <i>qnet</i> control point network "
2653 "application in that no latitude or longitude values are ever used or recorded "
2654 "(regardless if the image has a camera model in Isis).</p>"
2655 "<p>The output control point network that this tool generates is primarily used 1) as "
2656 "input for an image-wide sample/line translation to register one image to another by "
2657 "'moving' pixel locations - refer to the documentation for applications such as "
2658 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
2659 "measurements in other spreadsheet or plotting packages to visualize magnitude "
2660 "and direction of varying translations of the images relative to one another.</p> "
2661 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
2662 "can be used to visually evaluate and edit the control point network created by "
2663 "<i>coreg</i>.</p> "
2664 "<p>The format of the output point network file is binary. This tool uses the Isis control "
2665 " network framework to create, co-register and save all control points and pixel "
2666 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
2667 "a readable PVL format."
2668 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
2669 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
2670 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
2671 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
2672 purposeText->setWordWrap(
true);
2673 overviewLayout->addWidget(purposeText);
2675 overviewTab->setWidget(overviewContainer);
2678 QScrollArea *quickTab =
new QScrollArea;
2679 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2680 quickTab->setWidgetResizable(
true);
2682 QVBoxLayout *quickLayout =
new QVBoxLayout;
2683 quickContainer->setLayout(quickLayout);
2685 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
2686 quickLayout->addWidget(quickTitle);
2688 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
2689 quickLayout->addWidget(quickSubTitle);
2691 QString toolIconDir =
FileName(
"$base/icons").expanded();
2693 QLabel *quickPrep =
new QLabel(
"<p><ul>"
2694 "<li>Open the cubes with overlapping areas for choosing control points</li>"
2695 "<li>Choose the match tool <img src=\"" + toolIconDir +
2696 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
2697 "from the toolpad on the right side of the <i>qview</i> main window</li>");
2698 quickPrep->setWordWrap(
true);
2699 quickLayout->addWidget(quickPrep);
2701 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
2702 "of the main window contains file action buttons and a help button:");
2703 morePrep->setWordWrap(
true);
2704 quickLayout->addWidget(morePrep);
2706 QLabel *fileButtons =
new QLabel(
"<p><ul>"
2707 "<li><img src=\"" + toolIconDir +
"/fileopen.png\" width=22 height=22> Open an existing "
2708 "control network <b>Note:</b> If you do not open an existing network, a new one will "
2710 "<li><img src=\"" + toolIconDir +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
2711 "control network as ...</li>"
2712 "<li><img src=\"" + toolIconDir +
"/mActionFileSave.png\" width=22 height=22> Save "
2713 "control network to current file</li>"
2714 "<li><img src=\"" + toolIconDir +
"/help-contents.png\" width=22 height=22> Show Help "
2716 fileButtons->setWordWrap(
true);
2717 quickLayout->addWidget(fileButtons);
2719 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
2720 quickLayout->addWidget(quickFunctionTitle);
2722 QLabel *quickFunction =
new QLabel(
2723 "The match tool window will be shown once "
2724 "you click in a cube viewport window using one of the following "
2725 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
2726 quickFunction->setWordWrap(
true);
2727 quickLayout->addWidget(quickFunction);
2729 QLabel *quickDesc =
new QLabel(
"<p><ul>"
2730 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
2731 "All cubes in the control point must be displayed before loading the point</li>"
2732 "<li>Middle Click - Delete the control point closest to the click</li>"
2733 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
2734 quickDesc->setWordWrap(
true);
2735 quickDesc->setOpenExternalLinks(
true);
2736 quickLayout->addWidget(quickDesc);
2738 quickTab->setWidget(quickContainer);
2741 QScrollArea *controlPointTab =
new QScrollArea;
2742 controlPointTab->setWidgetResizable(
true);
2743 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2745 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
2746 controlPointContainer->setLayout(controlPointLayout);
2748 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
2749 controlPointLayout->addWidget(controlPointTitle);
2751 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
2752 "is activated, the mouse buttons have the following function in the "
2753 "cube viewports of the main qview window:</h3>");
2754 mouseLabel->setWordWrap(
true);
2755 mouseLabel->setScaledContents(
true);
2756 controlPointLayout->addWidget(mouseLabel);
2758 QLabel *controlPointDesc =
new QLabel(
"<ul>"
2759 "<li>Left click - Edit the closest control point <b>Note:</b> "
2760 "All cubes in the control point must be displayed before loading the point</li>"
2761 "<li>Middle click - Delete the closest control point</li>"
2762 "<li>Right click - Create new control point at cursor location. This will bring up a new "
2763 "point dialog which allows you to enter a point id and will list all cube viewports, "
2764 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
2765 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
2766 "control point into the control point editor window which will allow the control measure "
2767 "positions to be refined.</li>");
2768 controlPointDesc->setWordWrap(
true);
2769 controlPointLayout->addWidget(controlPointDesc);
2771 QLabel *controlPointEditing =
new QLabel(
2772 "<h4>Changing Control Measure Locations</h4>"
2773 "<p>Both the left and right control measure positions can be adjusted by:"
2775 "<li>Move the cursor location under the crosshair by clicking the left mouse "
2777 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
2778 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
2780 "<h4>Other Point Editor Functions</h4>"
2781 "<p>Along the right border of the window:</p>"
2783 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
2784 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
2785 "match the left view's zoom factor. "
2786 "<b>Note:</b> Zooming is controlled from the left view.</li>"
2787 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
2788 "its original orientation</li>"
2789 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
2790 "or entering degrees </li>"
2791 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
2792 "point locations visible within the view</li>"
2793 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
2795 "<li><strong>Circle:</strong> Draw circle which may help center measure "
2796 "on a crater</li></ul"
2797 "<p>Below the left view:</p>"
2798 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
2799 "left view window using the \"Blink Start\" button <img src=\"" + toolIconDir +
2800 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
2801 toolIconDir +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
2802 "and right views and the keyboard arrow keys may be used to move the both views while "
2804 "<li><strong>Register:</strong> Sub-pixel register the right view to "
2805 "the left view. A default registration template is used for setting parameters "
2806 "passed to the sub-pixel registration tool. The user may load in a predefined "
2807 "template or edit the current loaded template to influence successful "
2808 "co-registration results. For more information regarding the pattern matching "
2809 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
2810 "document and the <i>autoregtemplate</i> application.</li>"
2811 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
2812 "line positions under the crosshairs.</li>"
2813 "<li><strong>Save Point:</strong> Save the control point to the control network.</li>"
2815 controlPointEditing->setWordWrap(
true);
2816 controlPointLayout->addWidget(controlPointEditing);
2818 controlPointTab->setWidget(controlPointContainer);
2820 tabArea->addTab(overviewTab,
"&Overview");
2821 tabArea->addTab(quickTab,
"&Quick Start");
2822 tabArea->addTab(controlPointTab,
"&Control Point Editing");
2824 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
2826 buttonsLayout->addStretch();
2828 QPushButton *closeButton =
new QPushButton(
"&Close");
2829 closeButton->setIcon(QIcon(
FileName(
"$base/icons/guiStop.png").expanded()));
2830 closeButton->setDefault(
true);
2831 connect(closeButton, SIGNAL(clicked()),
2832 helpDialog, SLOT(close()));
2833 buttonsLayout->addWidget(closeButton);
2835 mainLayout->addLayout(buttonsLayout);
This class defines a body-fixed surface point.
This represents an ISIS control net in a project-based GUI interface.
Status SetType(MeasureType type)
Set how the coordinate was obtained.
PointType GetType() const
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
const double Null
Value for an Isis Null pixel.
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
double degrees() const
Get the angle in units of Degrees.
File name manipulation and expansion.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
int size() const
How many serial number / filename combos are in the list.
double GetResidualMagnitude() const
Return Residual magnitude.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
PointType
These are the valid 'types' of point.
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
double GetNumericalValue() const
Get the value associated with this log data.
int fileNameIndex(const QString &filename)
Return a list index given a filename.
Widget to display Isis cubes for qt apps.
Registered to whole pixel (e.g.,pointreg)
Registered to sub-pixel (e.g., pointreg)
This error is for when a programmer made an API call that was illegal.
Project * project() const
Gets the Project for this directory.
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.
QString fileName(const QString &sn)
Return a filename given a serial number.
bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
QString GetId() const
Return the Id of the control point.
Hand Measured (e.g., qnet)
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
#define _FILEINFO_
Macro for the filename and line number.
double Sample()
Returns the current sample number.
QString fileName() const
Access the name of the control network file associated with this Control.
Container for cube-like labels.
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Status
This is a return status for many of the mutating (setter) method calls.
GoodnessOfFit is pointreg information for reference measures.
double Line()
Returns the current line number.
QString toString() const
Returns a string representation of this exception.
static QString UserName()
Returns the user name.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
Serial Number list generator.
QString GetChooserName() const
Return the chooser name.
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
static QString MeasureTypeToString(MeasureType type)
Return the String Control Measure type.
This is returned when the operation requires Edit Lock to be false but it is currently true...
IO Handler for Isis Cubes.