11 #include "ControlPointEditWidget.h"
20 #include <QFileDialog>
22 #include <QFormLayout>
24 #include <QHBoxLayout>
26 #include <QMainWindow>
27 #include <QMessageBox>
29 #include <QPushButton>
33 #include <QTableWidget>
35 #include <QVBoxLayout>
37 #include "Application.h"
40 #include "ControlMeasureEditWidget.h"
41 #include "ControlMeasure.h"
42 #include "ControlMeasureLogData.h"
43 #include "ControlNet.h"
44 #include "ControlPoint.h"
45 #include "DeleteControlPointDialog.h"
46 #include "Directory.h"
48 #include "IException.h"
50 #include "Longitude.h"
51 #include "MainWindow.h"
52 #include "MdiCubeViewport.h"
53 #include "NewControlPointDialog.h"
54 #include "NewGroundSourceLocationDialog.h"
57 #include "PvlEditDialog.h"
58 #include "SerialNumber.h"
59 #include "SerialNumberList.h"
61 #include "ShapeList.h"
62 #include "SpecialPixel.h"
64 #include "TemplateList.h"
66 #include "UniversalGroundMap.h"
67 #include "ViewportMainWindow.h"
68 #include "Workspace.h"
81 bool addMeasures) :
QWidget(parent) {
83 m_directory = directory;
98 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
106 ControlPointEditWidget::~ControlPointEditWidget () {
111 QString ControlPointEditWidget::editPointId() {
121 ControlPoint *ControlPointEditWidget::editPoint() {
123 ControlPoint *result = NULL;
158 setWindowTitle(
"Control Point Editor");
159 setObjectName(
"ControlPointEditWidget");
169 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
178 QPushButton *addMeasure = NULL;
180 addMeasure =
new QPushButton(
"Add Measure(s) to Point");
181 addMeasure->setToolTip(
"Add a new measure to the edit control point.");
182 addMeasure->setWhatsThis(
"This allows a new control measure to be added "
183 "to the currently edited control point. A selection "
184 "box with all cubes from the input list will be "
185 "displayed with those that intersect with the "
186 "control point highlighted.");
188 connect(addMeasure, SIGNAL(clicked()),
this, SLOT(addMeasure()));
193 m_reloadPoint->setWhatsThis(
"Reload the measures for the control point"
194 " in the Chip Viewports to its saved values. ");
199 m_savePoint->setToolTip(
"Save the edit control point to the control network. "
200 "<strong>Shortcut: P</strong>");
201 m_savePoint->setWhatsThis(
"Save the edit control point to the control "
202 "network which is loaded into memory in its entirety. "
203 "When a control point is selected for editing, "
204 "a copy of the point is made so that the original control "
205 "point remains in the network.");
209 m_saveNet =
new QPushButton (
"Save Control Net");
211 m_saveNet->setToolTip(
"Save current control network. "
212 "<strong>Shortcut: S</strong>");
213 m_savePoint->setWhatsThis(
"Save the control network.");
220 QHBoxLayout * saveMeasureLayout =
new QHBoxLayout;
222 saveMeasureLayout->addWidget(addMeasure);
228 saveMeasureLayout->insertStretch(-1);
237 "registration template. Refer to $ISISROOT/doc/documents/"
238 "PatternMatch/PatternMatch.html for a description of the "
239 "contents of this file.");
243 foreach(
Template *templateFile, *templateList){
248 QFormLayout *templateFileLayout =
new QFormLayout();
257 QVBoxLayout * centralLayout =
new QVBoxLayout;
260 centralLayout->addLayout(templateFileLayout);
262 centralLayout->addStretch();
264 centralLayout->addLayout(saveMeasureLayout);
267 centralWidget->setLayout(centralLayout);
269 QScrollArea *scrollArea =
new QScrollArea();
270 scrollArea->setObjectName(
"ControlPointEditWidgetScroll");
271 scrollArea->setWidget(centralWidget);
272 scrollArea->setWidgetResizable(
true);
273 centralWidget->adjustSize();
275 QHBoxLayout *mainLayout =
new QHBoxLayout;
276 mainLayout->addWidget(scrollArea);
277 setLayout(mainLayout);
292 QHBoxLayout * measureLayout =
new QHBoxLayout;
296 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
298 groupBoxesLayout->addStretch();
299 groupBoxesLayout->addLayout(measureLayout);
302 groupBoxesWidget->setLayout(groupBoxesLayout);
306 QSplitter * topSplitter =
new QSplitter;
307 topSplitter->addWidget(groupBoxesWidget);
328 m_numMeasures =
new QLabel;
330 m_aprioriLatitude =
new QLabel;
331 m_aprioriLongitude =
new QLabel;
332 m_aprioriRadius =
new QLabel;
340 connect(
this, SIGNAL(ignorePointChanged()),
m_ignorePoint, SLOT(toggle()));
343 for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
347 QFormLayout *pointTypeLayout =
new QFormLayout;
356 QFormLayout *groundSourceLayout =
new QFormLayout;
358 QFormLayout *radiusSourceLayout =
new QFormLayout;
361 QVBoxLayout * mainLayout =
new QVBoxLayout;
363 mainLayout->addWidget(m_numMeasures);
364 mainLayout->addLayout(groundSourceLayout);
365 mainLayout->addLayout(radiusSourceLayout);
366 mainLayout->addWidget(m_aprioriLatitude);
367 mainLayout->addWidget(m_aprioriLongitude);
368 mainLayout->addWidget(m_aprioriRadius);
371 mainLayout->addLayout(pointTypeLayout);
374 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
375 groupBox->setLayout(mainLayout);
390 m_leftCombo->setToolTip(
"Choose left control measure");
391 m_leftCombo->setWhatsThis(
"Choose left control measure identified by "
401 connect(
this, SIGNAL(ignoreLeftChanged()),
405 QVBoxLayout * leftLayout =
new QVBoxLayout;
412 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
413 leftGroupBox->setLayout(leftLayout);
435 m_rightCombo->setToolTip(
"Choose right control measure. "
436 "<strong>Shortcuts: PageUp/PageDown</strong>");
437 m_rightCombo->setWhatsThis(
"Choose right control measure identified by "
439 "Note: PageUp selects previous measure; "
440 "PageDown selects next meausure.");
442 m_rightCombo->view()->setSelectionMode(QAbstractItemView::SingleSelection);
446 m_rightCombo->view()->setDragDropMode(QAbstractItemView::InternalMove);
450 QShortcut *nextMeasure =
new QShortcut(Qt::Key_PageDown,
this);
452 QShortcut *prevMeasure =
new QShortcut(Qt::Key_PageUp,
this);
463 connect(
this, SIGNAL(ignoreRightChanged()),
469 QVBoxLayout * rightLayout =
new QVBoxLayout;
476 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
477 rightGroupBox->setLayout(rightLayout);
479 return rightGroupBox;
491 toolBar->addSeparator();
499 QVBoxLayout *mainLayout =
new QVBoxLayout;
500 mainLayout->addWidget(toolBar);
518 QString whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point "
519 "<p><b>Shortcut:</b> Alt+F4 </p>";
523 m_showHideTemplateEditor =
new QAction(QIcon(
FileName(
"base/icons/view_text.png").expanded()),
524 "&View/edit registration template",
this);
525 m_showHideTemplateEditor->setCheckable(
true);
526 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
527 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
528 whatsThis =
"<b>Function:</b> Displays the curent registration template. "
529 "The user may edit and save changes under a chosen filename.";
530 m_showHideTemplateEditor->setWhatsThis(whatsThis);
531 connect(m_showHideTemplateEditor, SIGNAL(triggered()),
this,
535 "Save registration chips",
this);
536 m_saveChips->setToolTip(
"Save registration chips");
537 m_saveChips->setStatusTip(
"Save registration chips");
538 whatsThis =
"<b>Function:</b> Save registration chips to file. "
539 "Each chip: pattern, search, fit will be saved to a separate file.";
544 "&Open registration template",
this);
547 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as "
548 "the registration template";
553 "&Save template file",
this);
561 "&Save template as...",
this);
586 if (latitude ==
Null || longitude ==
Null) {
600 cam->
SetImage(m.GetSample(),m.GetLine());
615 foreach (
ShapeList *shapeList, shapeLists) {
616 foreach (
Shape *shape, *shapeList) {
622 shapeNamesNoPoint<<shape->
fileName();
630 if (shapeNamesNoPoint.count() > 0) {
681 QString strippedCnetFilename = cnetDirs.value(cnetDirs.length() -1);
685 setWindowTitle(
"Control Point Editor- Control Network File: " +
m_cnetFileName);
705 setWindowTitle(
"Control Point Editor- Control Network File: " +
m_cnetFileName);
762 return groundMeasure;
779 cam->
SetImage(m.GetSample(),m.GetLine());
785 if (!m_groundGmap->SetUniversalGround(lat,lon)) {
786 QString message =
"This point does not exist on the ground source.\n";
787 message +=
"Latitude = " + QString::number(lat);
788 message +=
" Longitude = " + QString::number(lon);
789 message +=
"\n A ground measure will not be created.";
790 QMessageBox::warning(
this,
"Warning", message);
796 groundMeasure->
SetCoordinate(m_groundGmap->Sample(), m_groundGmap->Line());
800 return groundMeasure;
816 ControlPoint::SurfacePointSource::Source groundSourceType =
817 ControlPoint::SurfacePointSource::None;
819 bool success =
false;
834 else if (
m_editPoint->HasAprioriSurfacePointSourceFile()) {
842 groundSourceType =
m_editPoint->GetAprioriSurfacePointSource();
856 QScopedPointer<Cube> groundCube(
new Cube(groundFile,
"r"));
857 m_groundGmap.reset(NULL);
858 QScopedPointer<UniversalGroundMap> newGroundGmap(
new UniversalGroundMap(*groundCube));
859 m_groundGmap.reset(newGroundGmap.take());
897 QFileInfo oldFile(groundFile.
expanded());
900 newGroundFile =
FileName(newFile.absoluteFilePath());
908 QString message =
"Ground Source file " + groundFile.
expanded();
909 message +=
" doesn't exist. Has the file moved? Would you like to enter a new location for"
910 " this ground source?";
911 int ret = QMessageBox::question(
this,
"Ground Source not found", message);
912 if (ret == QMessageBox::Yes) {
915 "New Ground Source Location", dir);
916 if (dialog->exec() == QDialog::Accepted) {
925 QFileInfo oldFile(groundFile.
expanded());
927 newGroundFile = newFile.absoluteFilePath();
933 newGroundFile = NULL;
939 newGroundFile = NULL;
943 return newGroundFile;
954 for (
int i = 0; i <
m_controlNet->GetNumPoints(); i++ ) {
957 FileName groundFile(cp->GetAprioriSurfacePointSourceFile());
958 QFileInfo oldFile(groundFile.
expanded());
960 groundFile = newFile.absoluteFilePath();
977 QString referenceSN =
m_editPoint->GetReferenceSN();
979 QScopedPointer<Cube> referenceCube(
new Cube(referenceFileName,
"r"));
980 PvlGroup kernels = referenceCube->group(
"Kernels");
981 QString shapeFile = kernels[
"ShapeModel"];
986 if (shapeFile.contains(
".cub")) {
987 if (shapeFile.contains(
"dem")) {
988 m_radiusSourceType = ControlPoint::RadiusSource::DEM;
991 m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
994 m_radiusFilename = shapeFile;
999 m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
1002 refSpice->
radii(refRadii);
1003 m_demFile = QString::number(refRadii[0].meters()) +
", " +
1004 QString::number(refRadii[1].meters()) +
", " +
1005 QString::number(refRadii[2].meters());
1007 m_radiusFilename =
"";
1024 if (m_demFile == demFile) {
1028 m_demCube.reset(NULL);
1032 QApplication::setOverrideCursor(Qt::WaitCursor);
1034 QScopedPointer<Cube> newDemCube(
new Cube(demFile,
"r"));
1037 m_demCube.reset(newDemCube.take());
1040 QMessageBox::critical(
this,
"Error", e.
toString());
1041 QApplication::restoreOverrideCursor();
1047 if (!m_demCube->hasTable(
"ShapeModelStatistics")) {
1048 QString message = m_demFile +
" is not a DEM.";
1049 QMessageBox::critical(
this,
"Error", message);
1050 m_demCube.reset(NULL);
1053 QApplication::restoreOverrideCursor();
1056 m_radiusSourceType = ControlPoint::RadiusSource::DEM;
1057 m_radiusFilename = demFile;
1059 QApplication::restoreOverrideCursor();
1087 m_demCube->pixelType(),
1090 m_demCube->read(*portal);
1157 m_groundGmap.reset(NULL);
1180 if (controlPoint->Parent() == NULL) {
1184 colorizeAllSaveButtons(
"red");
1191 colorizeAllSaveButtons(
"black");
1198 void ControlPointEditWidget::colorizeAllSaveButtons(QString color) {
1200 if (color ==
"black") {
1206 else if (color ==
"red") {
1239 QString ptId(
"Point ID: ");
1240 ptId += (QString) CPId;
1247 QString ptsize =
"Number of Measures: " +
1249 m_numMeasures->setText(ptsize);
1274 if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1284 if (
m_editPoint->HasAprioriSurfacePointSourceFile()) {
1290 if (!aprioriSurfacePointFile.
toString().isEmpty()) {
1294 QColor(Qt::darkGreen), Qt::ForegroundRole);
1296 QFont(
"DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1305 QColor(Qt::green), Qt::ForegroundRole);
1307 QFont(
"DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1325 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1335 if (groundMeasure) {
1344 for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
1362 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1371 item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
1372 m_model->appendRow(item);
1378 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1379 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1386 int rightIndex = -1;
1388 QString referenceSerialNumber;
1391 referenceSerialNumber =
m_editPoint->GetReferenceSN();
1395 if (!serialNumber.isEmpty() && serialNumber != referenceSerialNumber) {
1398 if (leftIndex == -1) {
1399 if (rightIndex == 0) {
1408 if (leftIndex == -1) {
1409 if (rightIndex == 0) {
1421 if (rightIndex <= 0) {
1422 if (leftIndex == 0) {
1431 if (rightIndex >
m_editPoint->GetNumMeasures()-1) rightIndex = 0;
1440 this->setVisible(
true);
1456 bool isGroundSource) {
1470 double samp = cam->
Sample();
1471 double line = cam->
Line();
1472 if (samp >= 1 && samp <= cam->Samples() &&
1473 line >= 1 && line <= cam->Lines()) {
1485 newPointDialog->
setFiles(pointFiles);
1493 if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1494 radiusSourceFiles<<shape->
fileName();
1497 newPointDialog->setRadiusSource(radiusSourceFiles);
1502 if (newPointDialog->exec() == QDialog::Accepted) {
1510 QString message =
"A ControlPoint with Point Id = [" + newPoint->
GetId();
1511 message +=
"] already exists. Re-enter Point Id for this ControlPoint.";
1512 QMessageBox::warning(
this,
"New Point Id", message);
1522 QStringList selectedFiles = newPointDialog->selectedFiles();
1523 foreach (QString selectedFile, selectedFiles) {
1533 m->SetAprioriSample(cam->
Sample());
1534 m->SetAprioriLine(cam->
Line());
1545 if (isGroundPoint) {
1558 emit controlPointAdded(newPoint->
GetId());
1580 DeleteControlPointDialog *deletePointDialog =
new DeleteControlPointDialog;
1582 deletePointDialog->pointIdValue->setText(CPId);
1585 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1588 deletePointDialog->fileList->addItem(file);
1591 if (deletePointDialog->exec()) {
1593 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1596 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1600 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1601 QString message =
"You have selected all measures in this point to be deleted. This "
1602 "control point will be deleted. Do you want to delete this control point?";
1603 int response = QMessageBox::question(
this,
1604 "Delete control point", message,
1605 QMessageBox::Yes | QMessageBox::No,
1608 if (response == QMessageBox::No) {
1617 QMessageBox::information(
this,
"EditLocked Point",
1618 "This point is EditLocked and cannot be deleted.");
1630 int lockedMeasures = 0;
1631 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1632 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1633 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1637 (
m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
1639 QString message =
"You are trying to delete the Reference measure."
1640 " Do you really want to delete the Reference measure?";
1641 switch (QMessageBox::question(
this,
1642 "Delete Reference measure?", message,
1643 "&Yes",
"&No", 0, 0)) {
1651 if (numDeleted == 1) {
1658 if (
m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
1663 if (lockedMeasures > 0) {
1664 QMessageBox::information(
this,
"EditLocked Measures",
1665 QString::number(lockedMeasures) +
" / "
1667 deletePointDialog->fileList->selectedItems().size()) +
1668 " measures are EditLocked and were not deleted.");
1678 emit cnetModified();
1764 QString message =
"You are saving changes to a measure on an ignored ";
1765 message +=
"point. Do you want to set Ignore = False on the point and ";
1766 message +=
"both measures?";
1767 switch (QMessageBox::question(
this,
"Save Measure", message,
"&Yes",
"&No", 0, 0)) {
1771 emit ignorePointChanged();
1774 emit ignoreLeftChanged();
1778 emit ignoreRightChanged();
1786 bool savedAMeasure =
false;
1792 savedAMeasure =
true;
1795 if (rightChangeOk) {
1798 savedAMeasure =
true;
1809 QString message =
"This control point is edit locked. The Apriori latitude, longitude and ";
1810 message +=
"radius cannot be updated. You must first unlock the point by clicking the ";
1811 message +=
"check box above labeled \"Edit Lock Point\".";
1812 QMessageBox::warning(
this,
"Point Locked", message);
1816 QString message =
"This is a Constrained or Fixed point and the reference measure is ";
1817 message +=
"Ignored. Unset the Ignore flag on the reference measure before saving.";
1818 QMessageBox::warning(
this,
"Point Locked", message);
1821 updateGroundPosition();
1833 if (savedAMeasure) {
1858 if (*m == *origMeasure)
return false;
1862 QString side =
"right";
1875 QString message =
"The " + side +
" measure is editLocked ";
1876 message +=
"for editing. Do you want to set EditLock = False for this ";
1877 message +=
"measure?";
1878 int response = QMessageBox::question(
this,
"Save Measure",
1879 message, QMessageBox::Yes | QMessageBox::No);
1881 if (response == QMessageBox::Yes) {
1882 m->SetEditLock(
false);
1883 if (side ==
"left") {
1896 if (origMeasure->IsIgnored() && m->IsIgnored()) {
1897 QString message =
"The " + side +
"measure is ignored. ";
1898 message +=
"Do you want to set Ignore = False on the measure?";
1899 switch (QMessageBox::question(
this,
"Save Measure", message,
"&Yes",
"&No", 0, 0)) {
1902 m->SetIgnored(
false);
1903 if (side ==
"left") {
1904 emit ignoreLeftChanged();
1907 emit ignoreRightChanged();
1919 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
1920 QString message =
"You are making a change to the reference measure. You ";
1921 message +=
"may need to move all of the other measures to match the new ";
1922 message +=
" coordinate of the reference measure. Do you really want to ";
1923 message +=
" change the reference measure's location? ";
1924 switch(QMessageBox::question(
this,
"Save Measure",
1925 message,
"&Yes",
"&No", 0, 0)){
1934 origLeftMeasure->GetLine());
1941 QString message =
"This point already contains a reference measure. ";
1942 message +=
"Would you like to replace it with the measure on the left?";
1943 int response = QMessageBox::question(
this,
1944 "Save Measure", message,
1945 QMessageBox::Yes | QMessageBox::No,
1948 if (response == QMessageBox::Yes) {
1956 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
1957 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1959 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1974 if (side ==
"left") {
2002 QString message =
"This point already contains a reference measure. ";
2003 message +=
"Would you like to replace it with the measure on the left?";
2004 int response = QMessageBox::question(
this,
2005 "Match Tool Save Measure", message,
2006 QMessageBox::Yes | QMessageBox::No,
2009 if (response == QMessageBox::Yes) {
2017 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
2018 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2020 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2045 void ControlPointEditWidget::updateGroundPosition() {
2056 m_groundGmap->SetImage(groundMeasure->GetSample(), groundMeasure->GetLine());
2058 double lat = m_groundGmap->UniversalLatitude();
2059 double lon = m_groundGmap->UniversalLongitude();
2064 m_radiusFilename.clear();
2067 m_demCube.reset(NULL);
2073 m_radiusFilename = shape->cube()->externalCubeFileName().toString();
2080 m_radiusSourceType =
m_editPoint->GetAprioriRadiusSource();
2094 if (radius ==
Null) {
2095 QString msg =
"Could not read radius from DEM, will default to "
2096 "local radius of reference measure.";
2097 QMessageBox::warning(
this,
"Warning", msg);
2100 radius =
m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2103 m_editPoint->SetAprioriRadiusSource(ControlPoint::RadiusSource::None);
2106 QString message =
"Error trying to get radius at this pt. "
2107 "Lat/Lon does not fall on the reference measure. "
2108 "Cannot save this measure.";
2109 QMessageBox::critical(
this,
"Error",message);
2113 m_editPoint->SetAprioriRadiusSource(m_radiusSourceType);
2114 m_editPoint->SetAprioriRadiusSourceFile(m_radiusFilename);
2120 radius =
m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2123 QString message =
"Error trying to get radius at this pt. "
2124 "Lat/Lon does not fall on the reference measure. "
2125 "Cannot save this measure.";
2126 QMessageBox::critical(
this,
"Error",message);
2136 SurfacePoint aprioriPt =
m_editPoint->GetAprioriSurfacePoint();
2137 Distance latSigma = aprioriPt.GetLatSigmaDistance();
2138 Distance lonSigma = aprioriPt.GetLonSigmaDistance();
2139 Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
2143 aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
2153 catch (IException &e) {
2154 QString message =
"Unable to set Apriori Surface Point.\n";
2155 message +=
"Latitude = " + QString::number(lat);
2156 message +=
" Longitude = " + QString::number(lon);
2157 message +=
" Radius = " + QString::number(radius) +
"\n";
2158 message += e.toString();
2159 QMessageBox::critical(
this,
"Error",message);
2164 QString fullGroundFilename;
2172 m_editPoint->SetAprioriSurfacePointSourceFile(fullGroundFilename);
2229 emit cnetModified();
2261 QString message =
"The reference measure is Ignored. Unset the Ignore flag on the ";
2262 message +=
"reference measure before setting the point type to Constrained or Fixed.";
2263 QMessageBox::warning(
m_parent,
"Ignored Reference Measure", message);
2269 QString message =
"This control point is edit locked. The point type cannot be changed. You ";
2270 message +=
"must first unlock the point by clicking the check box above labeled ";
2271 message +=
"\"Edit Lock Point\".";
2272 QMessageBox::warning(
m_parent,
"Point Locked", message);
2287 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
2344 QString message =
"Unable to change Ignored on point. Set EditLock ";
2345 message +=
" to False.";
2346 QMessageBox::critical(
this,
"Error", message);
2371 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
2372 " before changing a measure.");
2387 emit measureChanged();
2419 emit measureChanged();
2441 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
2442 " before changing a measure.");
2456 emit measureChanged();
2489 emit measureChanged();
2505 if (curIndex < m_rightCombo->count() - 1) {
2554 QString message =
"Make sure the correct cube is opened.\n\n";
2556 QMessageBox::critical(
this,
"Error", message);
2603 QString message =
"Make sure the correct cube is opened.\n\n";
2605 QMessageBox::critical(
this,
"Error", message);
2658 QString s =
"Reference: ";
2668 s =
"Measure Type: ";
2704 QString s =
"Reference: ";
2715 s =
"Measure Type: ";
2737 if(e->type() != QEvent::Leave)
return false;
2759 int r = QMessageBox::warning(
this, tr(
"OK to continue?"),
2760 tr(
"The currently opened registration template has been modified.\n"
2762 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2765 if (r == QMessageBox::Yes)
2767 else if (r == QMessageBox::Cancel)
2785 QString filename = QFileDialog::getOpenFileName(
this,
2786 "Select a registration template",
".",
2787 "Registration template files (*.def *.pvl);;All files (*)");
2789 if (filename.isEmpty())
2805 QFile file(
FileName((QString) fn).expanded());
2806 if (!file.open(QIODevice::ReadOnly)) {
2807 QString msg =
"Failed to open template file \"" + fn +
"\"";
2808 QMessageBox::warning(
this,
"IO Error", msg);
2812 QTextStream stream(&file);
2817 sb->setValue(sb->minimum());
2854 QString filename = QFileDialog::getSaveFileName(
this,
2855 "Save registration template",
".",
2856 "Registration template files (*.def *.pvl);;All files (*)");
2858 if (filename.isEmpty())
2883 QMessageBox::warning(
this,
"Error", message);
2887 QString expandedFileName(
FileName((QString) fn).expanded());
2889 QFile file(expandedFileName);
2891 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2892 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2894 QMessageBox::warning(
this,
"IO Error", msg);
2899 QTextStream stream(&file);
2930 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2932 registrationDialog.resize(550,360);
2933 registrationDialog.exec();
2937 QMessageBox::information(
this,
"Error", message);
2972 if(templateList->
type() ==
"registrations") {
2973 for(
int i = 0; i < templateList->size(); i++) {
2975 +
"/" +
FileName(templateList->at(i)->fileName()).
name());
2989 QString expandedFileName = filename;
2990 if(!filename.startsWith(
"$base")){
2992 +
"/registrations/" + filename;
3007 if(fileName.startsWith(
"$base")) {
3011 int size = components.size();
3012 int index =
m_templateComboBox->findText(components[size - 2] +
"/" + components[size - 1]);
3036 s =
"Apriori Latitude: Null";
3039 s =
"Apriori Latitude: " +
3042 m_aprioriLatitude->setText(s);
3044 s =
"Apriori Longitude: Null";
3047 s =
"Apriori Longitude: " +
3050 m_aprioriLongitude->setText(s);
3052 s =
"Apriori Radius: Null";
3055 s =
"Apriori Radius: " +
3059 m_aprioriRadius->setText(s);
3107 QColor qc = Qt::red;
3109 p.setColor(QPalette::ButtonText,qc);
3129 QColor qc = Qt::red;
3131 p.setColor(QPalette::ButtonText,qc);
3155 (
m_editPoint->GetReferenceSN() == serialNumber)) {
3160 return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
3194 void ControlPointEditWidget::showHelp() {
3197 helpDialog->setWindowTitle(
"Match Tool Help");
3199 QVBoxLayout *mainLayout =
new QVBoxLayout;
3200 helpDialog->setLayout(mainLayout);
3202 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3203 mainLayout->addWidget(matchTitle);
3205 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
3206 "registration points between cubes. These "
3207 "points contain sample, line postions only, no latitude or "
3208 "longitude values are used or recorded.");
3209 matchSubtitle->setWordWrap(
true);
3210 mainLayout->addWidget(matchSubtitle);
3212 QTabWidget *tabArea =
new QTabWidget;
3213 tabArea->setDocumentMode(
true);
3214 mainLayout->addWidget(tabArea);
3217 QScrollArea *overviewTab =
new QScrollArea;
3218 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3219 overviewTab->setWidgetResizable(
true);
3221 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3222 overviewContainer->setLayout(overviewLayout);
3224 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3225 overviewLayout->addWidget(purposeTitle);
3227 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
3228 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3229 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3230 "tool can be used on any images including ones that do not contain a camera model "
3231 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3232 "This also means that the tool differs from the <i>qnet</i> control point network "
3233 "application in that no latitude or longitude values are ever used or recorded "
3234 "(regardless if the image has a camera model in Isis).</p>"
3235 "<p>The output control point network that this tool generates is primarily used 1) as "
3236 "input for an image-wide sample/line translation to register one image to another by "
3237 "'moving' pixel locations - refer to the documentation for applications such as "
3238 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3239 "measurements in other spreadsheet or plotting packages to visualize magnitude "
3240 "and direction of varying translations of the images relative to one another.</p> "
3241 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3242 "can be used to visually evaluate and edit the control point network created by "
3243 "<i>coreg</i>.</p> "
3244 "<p>The format of the output point network file is binary. This tool uses the Isis control "
3245 " network framework to create, co-register and save all control points and pixel "
3246 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3247 "a readable PVL format."
3248 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3249 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3250 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3251 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3252 purposeText->setWordWrap(
true);
3253 overviewLayout->addWidget(purposeText);
3255 overviewTab->setWidget(overviewContainer);
3258 QScrollArea *quickTab =
new QScrollArea;
3259 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3260 quickTab->setWidgetResizable(
true);
3262 QVBoxLayout *quickLayout =
new QVBoxLayout;
3263 quickContainer->setLayout(quickLayout);
3265 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3266 quickLayout->addWidget(quickTitle);
3268 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3269 quickLayout->addWidget(quickSubTitle);
3273 QLabel *quickPrep =
new QLabel(
"<p><ul>"
3274 "<li>Open the cubes with overlapping areas for choosing control points</li>"
3275 "<li>Choose the match tool <img src=\"" + toolIconDir +
3276 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3277 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3278 quickPrep->setWordWrap(
true);
3279 quickLayout->addWidget(quickPrep);
3281 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
3282 "of the main window contains file action buttons and a help button:");
3283 morePrep->setWordWrap(
true);
3284 quickLayout->addWidget(morePrep);
3286 QLabel *fileButtons =
new QLabel(
"<p><ul>"
3287 "<li><img src=\"" + toolIconDir +
"/fileopen.png\" width=22 height=22> Open an existing "
3288 "control network <b>Note:</b> If you do not open an existing network, a new one will "
3290 "<li><img src=\"" + toolIconDir +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
3291 "control network as ...</li>"
3292 "<li><img src=\"" + toolIconDir +
"/mActionFileSave.png\" width=22 height=22> Save "
3293 "control network to current file</li>"
3294 "<li><img src=\"" + toolIconDir +
"/help-contents.png\" width=22 height=22> Show Help "
3296 fileButtons->setWordWrap(
true);
3297 quickLayout->addWidget(fileButtons);
3299 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3300 quickLayout->addWidget(quickFunctionTitle);
3302 QLabel *quickFunction =
new QLabel(
3303 "The match tool window will be shown once "
3304 "you click in a cube viewport window using one of the following "
3305 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3306 quickFunction->setWordWrap(
true);
3307 quickLayout->addWidget(quickFunction);
3309 QLabel *quickDesc =
new QLabel(
"<p><ul>"
3310 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3311 "All cubes in the control point must be displayed before loading the point</li>"
3312 "<li>Middle Click - Delete the control point closest to the click</li>"
3313 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3314 quickDesc->setWordWrap(
true);
3315 quickDesc->setOpenExternalLinks(
true);
3316 quickLayout->addWidget(quickDesc);
3318 quickTab->setWidget(quickContainer);
3321 QScrollArea *controlPointTab =
new QScrollArea;
3322 controlPointTab->setWidgetResizable(
true);
3323 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3325 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3326 controlPointContainer->setLayout(controlPointLayout);
3328 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3329 controlPointLayout->addWidget(controlPointTitle);
3331 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
3332 "is activated, the mouse buttons have the following function in the "
3333 "cube viewports of the main qview window:</h3>");
3334 mouseLabel->setWordWrap(
true);
3335 mouseLabel->setScaledContents(
true);
3336 controlPointLayout->addWidget(mouseLabel);
3338 QLabel *controlPointDesc =
new QLabel(
"<ul>"
3339 "<li>Left click - Edit the closest control point <b>Note:</b> "
3340 "All cubes in the control point must be displayed before loading the point</li>"
3341 "<li>Middle click - Delete the closest control point</li>"
3342 "<li>Right click - Create new control point at cursor location. This will bring up a new "
3343 "point dialog which allows you to enter a point id and will list all cube viewports, "
3344 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3345 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3346 "control point into the control point editor window which will allow the control measure "
3347 "positions to be refined.</li>");
3348 controlPointDesc->setWordWrap(
true);
3349 controlPointLayout->addWidget(controlPointDesc);
3351 QLabel *controlPointEditing =
new QLabel(
3352 "<h4>Changing Control Measure Locations</h4>"
3353 "<p>Both the left and right control measure positions can be adjusted by:"
3355 "<li>Move the cursor location under the crosshair by clicking the left mouse "
3357 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3358 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3360 "<h4>Other Point Editor Functions</h4>"
3361 "<p>Along the right border of the window:</p>"
3363 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3364 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3365 "match the left view's zoom factor. "
3366 "<b>Note:</b> Zooming is controlled from the left view.</li>"
3367 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3368 "its original orientation</li>"
3369 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3370 "or entering degrees </li>"
3371 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3372 "point locations visible within the view</li>"
3373 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3375 "<li><strong>Circle:</strong> Draw circle which may help center measure "
3376 "on a crater</li></ul"
3377 "<p>Below the left view:</p>"
3378 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3379 "left view window using the \"Blink Start\" button <img src=\"" + toolIconDir +
3380 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3381 toolIconDir +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3382 "and right views and the keyboard arrow keys may be used to move the both views while "
3384 "<li><strong>Register:</strong> Sub-pixel register the right view to "
3385 "the left view. A default registration template is used for setting parameters "
3386 "passed to the sub-pixel registration tool. The user may load in a predefined "
3387 "template or edit the current loaded template to influence successful "
3388 "co-registration results. For more information regarding the pattern matching "
3389 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3390 "document and the <i>autoregtemplate</i> application.</li>"
3391 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3392 "line positions under the crosshairs.</li>"
3393 "<li><strong>Save Point:</strong> Save the control point to the control network.</li>"
3395 controlPointEditing->setWordWrap(
true);
3396 controlPointLayout->addWidget(controlPointEditing);
3398 controlPointTab->setWidget(controlPointContainer);
3400 tabArea->addTab(overviewTab,
"&Overview");
3401 tabArea->addTab(quickTab,
"&Quick Start");
3402 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3404 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3406 buttonsLayout->addStretch();
3408 QPushButton *closeButton =
new QPushButton(
"&Close");
3409 closeButton->setIcon(QIcon(
FileName(
"$base/icons/guiStop.png").expanded()));
3410 closeButton->setDefault(
true);
3411 connect(closeButton, SIGNAL(clicked()),
3412 helpDialog, SLOT(close()));
3413 buttonsLayout->addWidget(closeButton);
3415 mainLayout->addLayout(buttonsLayout);