3 #include "ControlPointEditWidget.h" 12 #include <QFileDialog> 14 #include <QFormLayout> 16 #include <QHBoxLayout> 18 #include <QMainWindow> 19 #include <QMessageBox> 21 #include <QPushButton> 25 #include <QTableWidget> 27 #include <QVBoxLayout> 32 #include "ControlMeasureEditWidget.h" 37 #include "DeleteControlPointDialog.h" 43 #include "MainWindow.h" 45 #include "NewControlPointDialog.h" 46 #include "NewGroundSourceLocationDialog.h" 49 #include "PvlEditDialog.h" 53 #include "ShapeList.h" 59 #include "ViewportMainWindow.h" 73 bool addMeasures) :
QWidget(parent) {
75 m_directory = directory;
90 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
98 ControlPointEditWidget::~ControlPointEditWidget () {
103 QString ControlPointEditWidget::editPointId() {
113 ControlPoint *ControlPointEditWidget::editPoint() {
115 ControlPoint *result = NULL;
150 setWindowTitle(
"Control Point Editor");
151 setObjectName(
"ControlPointEditWidget");
161 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
170 QPushButton *addMeasure = NULL;
172 addMeasure =
new QPushButton(
"Add Measure(s) to Point");
173 addMeasure->setToolTip(
"Add a new measure to the edit control point.");
174 addMeasure->setWhatsThis(
"This allows a new control measure to be added " 175 "to the currently edited control point. A selection " 176 "box with all cubes from the input list will be " 177 "displayed with those that intersect with the " 178 "control point highlighted.");
180 connect(addMeasure, SIGNAL(clicked()),
this, SLOT(addMeasure()));
185 m_reloadPoint->setWhatsThis(
"Reload the measures for the control point" 186 " in the Chip Viewports to its saved values. ");
191 m_savePoint->setToolTip(
"Save the edit control point to the control network. " 192 "<strong>Shortcut: P</strong>");
193 m_savePoint->setWhatsThis(
"Save the edit control point to the control " 194 "network which is loaded into memory in its entirety. " 195 "When a control point is selected for editing, " 196 "a copy of the point is made so that the original control " 197 "point remains in the network.");
201 m_saveNet =
new QPushButton (
"Save Control Net");
203 m_saveNet->setToolTip(
"Save current control network. " 204 "<strong>Shortcut: S</strong>");
205 m_savePoint->setWhatsThis(
"Save the control network.");
212 QHBoxLayout * saveMeasureLayout =
new QHBoxLayout;
214 saveMeasureLayout->addWidget(addMeasure);
220 saveMeasureLayout->insertStretch(-1);
229 "registration template. Refer to $ISISROOT/doc/documents/" 230 "PatternMatch/PatternMatch.html for a description of the " 231 "contents of this file.");
235 foreach(
Template *templateFile, *templateList){
240 QFormLayout *templateFileLayout =
new QFormLayout();
249 QVBoxLayout * centralLayout =
new QVBoxLayout;
252 centralLayout->addLayout(templateFileLayout);
254 centralLayout->addStretch();
256 centralLayout->addLayout(saveMeasureLayout);
259 centralWidget->setLayout(centralLayout);
261 QScrollArea *scrollArea =
new QScrollArea();
262 scrollArea->setObjectName(
"ControlPointEditWidgetScroll");
263 scrollArea->setWidget(centralWidget);
264 scrollArea->setWidgetResizable(
true);
265 centralWidget->adjustSize();
267 QHBoxLayout *mainLayout =
new QHBoxLayout;
268 mainLayout->addWidget(scrollArea);
269 setLayout(mainLayout);
284 QHBoxLayout * measureLayout =
new QHBoxLayout;
288 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
290 groupBoxesLayout->addStretch();
291 groupBoxesLayout->addLayout(measureLayout);
294 groupBoxesWidget->setLayout(groupBoxesLayout);
298 QSplitter * topSplitter =
new QSplitter;
299 topSplitter->addWidget(groupBoxesWidget);
320 m_numMeasures =
new QLabel;
322 m_aprioriLatitude =
new QLabel;
323 m_aprioriLongitude =
new QLabel;
324 m_aprioriRadius =
new QLabel;
332 connect(
this, SIGNAL(ignorePointChanged()),
m_ignorePoint, SLOT(toggle()));
335 for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
339 QFormLayout *pointTypeLayout =
new QFormLayout;
348 QFormLayout *groundSourceLayout =
new QFormLayout;
350 QFormLayout *radiusSourceLayout =
new QFormLayout;
353 QVBoxLayout * mainLayout =
new QVBoxLayout;
355 mainLayout->addWidget(m_numMeasures);
356 mainLayout->addLayout(groundSourceLayout);
357 mainLayout->addLayout(radiusSourceLayout);
358 mainLayout->addWidget(m_aprioriLatitude);
359 mainLayout->addWidget(m_aprioriLongitude);
360 mainLayout->addWidget(m_aprioriRadius);
363 mainLayout->addLayout(pointTypeLayout);
366 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
367 groupBox->setLayout(mainLayout);
382 m_leftCombo->setToolTip(
"Choose left control measure");
383 m_leftCombo->setWhatsThis(
"Choose left control measure identified by " 393 connect(
this, SIGNAL(ignoreLeftChanged()),
397 QVBoxLayout * leftLayout =
new QVBoxLayout;
404 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
405 leftGroupBox->setLayout(leftLayout);
427 m_rightCombo->setToolTip(
"Choose right control measure. " 428 "<strong>Shortcuts: PageUp/PageDown</strong>");
429 m_rightCombo->setWhatsThis(
"Choose right control measure identified by " 431 "Note: PageUp selects previous measure; " 432 "PageDown selects next meausure.");
434 m_rightCombo->view()->setSelectionMode(QAbstractItemView::SingleSelection);
438 m_rightCombo->view()->setDragDropMode(QAbstractItemView::InternalMove);
442 QShortcut *nextMeasure =
new QShortcut(Qt::Key_PageDown,
this);
444 QShortcut *prevMeasure =
new QShortcut(Qt::Key_PageUp,
this);
455 connect(
this, SIGNAL(ignoreRightChanged()),
461 QVBoxLayout * rightLayout =
new QVBoxLayout;
468 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
469 rightGroupBox->setLayout(rightLayout);
471 return rightGroupBox;
483 toolBar->addSeparator();
491 QVBoxLayout *mainLayout =
new QVBoxLayout;
492 mainLayout->addWidget(toolBar);
510 QString whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point " 511 "<p><b>Shortcut:</b> Alt+F4 </p>";
515 m_showHideTemplateEditor =
new QAction(QIcon(
FileName(
"base/icons/view_text.png").expanded()),
516 "&View/edit registration template",
this);
517 m_showHideTemplateEditor->setCheckable(
true);
518 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
519 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
520 whatsThis =
"<b>Function:</b> Displays the curent registration template. " 521 "The user may edit and save changes under a chosen filename.";
522 m_showHideTemplateEditor->setWhatsThis(whatsThis);
523 connect(m_showHideTemplateEditor, SIGNAL(triggered()),
this,
527 "Save registration chips",
this);
528 m_saveChips->setToolTip(
"Save registration chips");
529 m_saveChips->setStatusTip(
"Save registration chips");
530 whatsThis =
"<b>Function:</b> Save registration chips to file. " 531 "Each chip: pattern, search, fit will be saved to a separate file.";
536 "&Open registration template",
this);
539 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as " 540 "the registration template";
545 "&Save template file",
this);
553 "&Save template as...",
this);
578 if (latitude ==
Null || longitude ==
Null) {
592 cam->
SetImage(m.GetSample(),m.GetLine());
607 foreach (
ShapeList *shapeList, shapeLists) {
608 foreach (
Shape *shape, *shapeList) {
614 shapeNamesNoPoint<<shape->
fileName();
622 if (shapeNamesNoPoint.count() > 0) {
673 QString strippedCnetFilename = cnetDirs.value(cnetDirs.length() -1);
677 setWindowTitle(
"Control Point Editor- Control Network File: " +
m_cnetFileName);
697 setWindowTitle(
"Control Point Editor- Control Network File: " +
m_cnetFileName);
754 return groundMeasure;
771 cam->
SetImage(m.GetSample(),m.GetLine());
777 if (!m_groundGmap->SetUniversalGround(lat,lon)) {
778 QString message =
"This point does not exist on the ground source.\n";
779 message +=
"Latitude = " + QString::number(lat);
780 message +=
" Longitude = " + QString::number(lon);
781 message +=
"\n A ground measure will not be created.";
782 QMessageBox::warning(
this,
"Warning", message);
788 groundMeasure->
SetCoordinate(m_groundGmap->Sample(), m_groundGmap->Line());
792 return groundMeasure;
808 ControlPoint::SurfacePointSource::Source groundSourceType =
809 ControlPoint::SurfacePointSource::None;
811 bool success =
false;
826 else if (
m_editPoint->HasAprioriSurfacePointSourceFile()) {
834 groundSourceType =
m_editPoint->GetAprioriSurfacePointSource();
848 QScopedPointer<Cube> groundCube(
new Cube(groundFile,
"r"));
849 m_groundGmap.reset(NULL);
850 QScopedPointer<UniversalGroundMap> newGroundGmap(
new UniversalGroundMap(*groundCube));
851 m_groundGmap.reset(newGroundGmap.take());
889 QFileInfo oldFile(groundFile.
expanded());
892 newGroundFile =
FileName(newFile.absoluteFilePath());
900 QString message =
"Ground Source file " + groundFile.
expanded();
901 message +=
" doesn't exist. Has the file moved? Would you like to enter a new location for" 902 " this ground source?";
903 int ret = QMessageBox::question(
this,
"Ground Source not found", message);
904 if (ret == QMessageBox::Yes) {
907 "New Ground Source Location", dir);
908 if (dialog->exec() == QDialog::Accepted) {
917 QFileInfo oldFile(groundFile.
expanded());
919 newGroundFile = newFile.absoluteFilePath();
920 m_editPoint->SetAprioriSurfacePointSourceFile(newGroundFile.toString());
925 newGroundFile = NULL;
931 newGroundFile = NULL;
935 return newGroundFile;
946 for (
int i = 0; i <
m_controlNet->GetNumPoints(); i++ ) {
949 FileName groundFile(cp->GetAprioriSurfacePointSourceFile());
950 QFileInfo oldFile(groundFile.expanded());
952 groundFile = newFile.absoluteFilePath();
969 QString referenceSN =
m_editPoint->GetReferenceSN();
971 QScopedPointer<Cube> referenceCube(
new Cube(referenceFileName,
"r"));
972 PvlGroup kernels = referenceCube->group(
"Kernels");
973 QString shapeFile = kernels[
"ShapeModel"];
978 if (shapeFile.contains(
".cub")) {
979 if (shapeFile.contains(
"dem")) {
980 m_radiusSourceType = ControlPoint::RadiusSource::DEM;
983 m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
986 m_radiusFilename = shapeFile;
991 m_radiusSourceType = ControlPoint::RadiusSource::Ellipsoid;
994 refSpice->
radii(refRadii);
995 m_demFile = QString::number(refRadii[0].meters()) +
", " +
996 QString::number(refRadii[1].meters()) +
", " +
997 QString::number(refRadii[2].meters());
999 m_radiusFilename =
"";
1016 if (m_demFile == demFile) {
1020 m_demCube.reset(NULL);
1024 QApplication::setOverrideCursor(Qt::WaitCursor);
1026 QScopedPointer<Cube> newDemCube(
new Cube(demFile,
"r"));
1028 m_demFile =
FileName(newDemCube->fileName()).name();
1029 m_demCube.reset(newDemCube.take());
1032 QMessageBox::critical(
this,
"Error", e.
toString());
1033 QApplication::restoreOverrideCursor();
1039 if (!m_demCube->hasTable(
"ShapeModelStatistics")) {
1040 QString message = m_demFile +
" is not a DEM.";
1041 QMessageBox::critical(
this,
"Error", message);
1042 m_demCube.reset(NULL);
1045 QApplication::restoreOverrideCursor();
1048 m_radiusSourceType = ControlPoint::RadiusSource::DEM;
1049 m_radiusFilename = demFile;
1051 QApplication::restoreOverrideCursor();
1079 m_demCube->pixelType(),
1082 m_demCube->read(*portal);
1149 m_groundGmap.reset(NULL);
1172 if (controlPoint->Parent() == NULL) {
1176 colorizeAllSaveButtons(
"red");
1183 colorizeAllSaveButtons(
"black");
1190 void ControlPointEditWidget::colorizeAllSaveButtons(QString color) {
1192 if (color ==
"black") {
1198 else if (color ==
"red") {
1231 QString ptId(
"Point ID: ");
1232 ptId += (QString) CPId;
1239 QString ptsize =
"Number of Measures: " +
1241 m_numMeasures->setText(ptsize);
1266 if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1276 if (
m_editPoint->HasAprioriSurfacePointSourceFile()) {
1282 if (!aprioriSurfacePointFile.
toString().isEmpty()) {
1286 QColor(Qt::darkGreen), Qt::ForegroundRole);
1288 QFont(
"DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1297 QColor(Qt::green), Qt::ForegroundRole);
1299 QFont(
"DejaVu Sans", 10, QFont::Bold), Qt::FontRole);
1317 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1327 if (groundMeasure) {
1336 for (
int i=0; i<ControlPoint::PointTypeCount; i++) {
1354 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1363 item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
1364 m_model->appendRow(item);
1370 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1371 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1378 int rightIndex = -1;
1380 QString referenceSerialNumber;
1383 referenceSerialNumber =
m_editPoint->GetReferenceSN();
1387 if (!serialNumber.isEmpty() && serialNumber != referenceSerialNumber) {
1390 if (leftIndex == -1) {
1391 if (rightIndex == 0) {
1400 if (leftIndex == -1) {
1401 if (rightIndex == 0) {
1413 if (rightIndex <= 0) {
1414 if (leftIndex == 0) {
1423 if (rightIndex >
m_editPoint->GetNumMeasures()-1) rightIndex = 0;
1432 this->setVisible(
true);
1448 bool isGroundSource) {
1462 double samp = cam->
Sample();
1463 double line = cam->
Line();
1464 if (samp >= 1 && samp <= cam->Samples() &&
1465 line >= 1 && line <= cam->Lines()) {
1477 newPointDialog->
setFiles(pointFiles);
1485 if (shape->radiusSource() == ControlPoint::RadiusSource::DEM) {
1486 radiusSourceFiles<<shape->
fileName();
1489 newPointDialog->setRadiusSource(radiusSourceFiles);
1494 if (newPointDialog->exec() == QDialog::Accepted) {
1502 QString message =
"A ControlPoint with Point Id = [" + newPoint->
GetId();
1503 message +=
"] already exists. Re-enter Point Id for this ControlPoint.";
1504 QMessageBox::warning(
this,
"New Point Id", message);
1514 QStringList selectedFiles = newPointDialog->selectedFiles();
1515 foreach (QString selectedFile, selectedFiles) {
1525 m->SetAprioriSample(cam->
Sample());
1526 m->SetAprioriLine(cam->
Line());
1537 if (isGroundPoint) {
1550 emit controlPointAdded(newPoint->
GetId());
1572 DeleteControlPointDialog *deletePointDialog =
new DeleteControlPointDialog;
1574 deletePointDialog->pointIdValue->setText(CPId);
1577 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
1580 deletePointDialog->fileList->addItem(file);
1583 if (deletePointDialog->exec()) {
1585 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1588 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1592 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1593 QString message =
"You have selected all measures in this point to be deleted. This " 1594 "control point will be deleted. Do you want to delete this control point?";
1595 int response = QMessageBox::question(
this,
1596 "Delete control point", message,
1597 QMessageBox::Yes | QMessageBox::No,
1600 if (response == QMessageBox::No) {
1609 QMessageBox::information(
this,
"EditLocked Point",
1610 "This point is EditLocked and cannot be deleted.");
1622 int lockedMeasures = 0;
1623 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1624 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1625 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1629 (
m_editPoint->GetRefMeasure()->GetCubeSerialNumber() ==
1630 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1631 QString message =
"You are trying to delete the Reference measure." 1632 " Do you really want to delete the Reference measure?";
1633 switch (QMessageBox::question(
this,
1634 "Delete Reference measure?", message,
1635 "&Yes",
"&No", 0, 0)) {
1643 if (numDeleted == 1) {
1650 if (
m_editPoint->Delete(i) == ControlMeasure::MeasureLocked) {
1655 if (lockedMeasures > 0) {
1656 QMessageBox::information(
this,
"EditLocked Measures",
1657 QString::number(lockedMeasures) +
" / " 1659 deletePointDialog->fileList->selectedItems().size()) +
1660 " measures are EditLocked and were not deleted.");
1670 emit cnetModified();
1756 QString message =
"You are saving changes to a measure on an ignored ";
1757 message +=
"point. Do you want to set Ignore = False on the point and ";
1758 message +=
"both measures?";
1759 switch (QMessageBox::question(
this,
"Save Measure", message,
"&Yes",
"&No", 0, 0)) {
1763 emit ignorePointChanged();
1766 emit ignoreLeftChanged();
1770 emit ignoreRightChanged();
1778 bool savedAMeasure =
false;
1784 savedAMeasure =
true;
1787 if (rightChangeOk) {
1790 savedAMeasure =
true;
1801 QString message =
"This control point is edit locked. The Apriori latitude, longitude and ";
1802 message +=
"radius cannot be updated. You must first unlock the point by clicking the ";
1803 message +=
"check box above labeled \"Edit Lock Point\".";
1804 QMessageBox::warning(
this,
"Point Locked", message);
1808 QString message =
"This is a Constrained or Fixed point and the reference measure is ";
1809 message +=
"Ignored. Unset the Ignore flag on the reference measure before saving.";
1810 QMessageBox::warning(
this,
"Point Locked", message);
1813 updateGroundPosition();
1825 if (savedAMeasure) {
1850 if (*m == *origMeasure)
return false;
1854 QString side =
"right";
1867 QString message =
"The " + side +
" measure is editLocked ";
1868 message +=
"for editing. Do you want to set EditLock = False for this ";
1869 message +=
"measure?";
1870 int response = QMessageBox::question(
this,
"Save Measure",
1871 message, QMessageBox::Yes | QMessageBox::No);
1873 if (response == QMessageBox::Yes) {
1874 m->SetEditLock(
false);
1875 if (side ==
"left") {
1888 if (origMeasure->IsIgnored() && m->IsIgnored()) {
1889 QString message =
"The " + side +
"measure is ignored. ";
1890 message +=
"Do you want to set Ignore = False on the measure?";
1891 switch (QMessageBox::question(
this,
"Save Measure", message,
"&Yes",
"&No", 0, 0)) {
1894 m->SetIgnored(
false);
1895 if (side ==
"left") {
1896 emit ignoreLeftChanged();
1899 emit ignoreRightChanged();
1911 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
1912 QString message =
"You are making a change to the reference measure. You ";
1913 message +=
"may need to move all of the other measures to match the new ";
1914 message +=
" coordinate of the reference measure. Do you really want to ";
1915 message +=
" change the reference measure's location? ";
1916 switch(QMessageBox::question(
this,
"Save Measure",
1917 message,
"&Yes",
"&No", 0, 0)){
1926 origLeftMeasure->GetLine());
1933 QString message =
"This point already contains a reference measure. ";
1934 message +=
"Would you like to replace it with the measure on the left?";
1935 int response = QMessageBox::question(
this,
1936 "Save Measure", message,
1937 QMessageBox::Yes | QMessageBox::No,
1940 if (response == QMessageBox::Yes) {
1948 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
1949 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1951 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1966 if (side ==
"left") {
1994 QString message =
"This point already contains a reference measure. ";
1995 message +=
"Would you like to replace it with the measure on the left?";
1996 int response = QMessageBox::question(
this,
1997 "Match Tool Save Measure", message,
1998 QMessageBox::Yes | QMessageBox::No,
2001 if (response == QMessageBox::Yes) {
2009 QVariant font =
m_leftCombo->itemData(iref,Qt::FontRole);
2010 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2012 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
2037 void ControlPointEditWidget::updateGroundPosition() {
2048 m_groundGmap->SetImage(groundMeasure->GetSample(), groundMeasure->GetLine());
2050 double lat = m_groundGmap->UniversalLatitude();
2051 double lon = m_groundGmap->UniversalLongitude();
2056 m_radiusFilename.clear();
2059 m_demCube.reset(NULL);
2065 m_radiusFilename = shape->cube()->externalCubeFileName().toString();
2072 m_radiusSourceType =
m_editPoint->GetAprioriRadiusSource();
2086 if (radius ==
Null) {
2087 QString msg =
"Could not read radius from DEM, will default to " 2088 "local radius of reference measure.";
2089 QMessageBox::warning(
this,
"Warning", msg);
2092 radius =
m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2095 m_editPoint->SetAprioriRadiusSource(ControlPoint::RadiusSource::None);
2098 QString message =
"Error trying to get radius at this pt. " 2099 "Lat/Lon does not fall on the reference measure. " 2100 "Cannot save this measure.";
2101 QMessageBox::critical(
this,
"Error",message);
2105 m_editPoint->SetAprioriRadiusSource(m_radiusSourceType);
2106 m_editPoint->SetAprioriRadiusSourceFile(m_radiusFilename);
2112 radius =
m_editPoint->GetRefMeasure()->Camera()->LocalRadius().meters();
2115 QString message =
"Error trying to get radius at this pt. " 2116 "Lat/Lon does not fall on the reference measure. " 2117 "Cannot save this measure.";
2118 QMessageBox::critical(
this,
"Error",message);
2128 SurfacePoint aprioriPt =
m_editPoint->GetAprioriSurfacePoint();
2129 Distance latSigma = aprioriPt.GetLatSigmaDistance();
2130 Distance lonSigma = aprioriPt.GetLonSigmaDistance();
2131 Distance radiusSigma = aprioriPt.GetLocalRadiusSigma();
2135 aprioriPt.SetSphericalSigmasDistance(latSigma, lonSigma, radiusSigma);
2145 catch (IException &e) {
2146 QString message =
"Unable to set Apriori Surface Point.\n";
2147 message +=
"Latitude = " + QString::number(lat);
2148 message +=
" Longitude = " + QString::number(lon);
2149 message +=
" Radius = " + QString::number(radius) +
"\n";
2150 message += e.toString();
2151 QMessageBox::critical(
this,
"Error",message);
2156 QString fullGroundFilename;
2164 m_editPoint->SetAprioriSurfacePointSourceFile(fullGroundFilename);
2221 emit cnetModified();
2253 QString message =
"The reference measure is Ignored. Unset the Ignore flag on the ";
2254 message +=
"reference measure before setting the point type to Constrained or Fixed.";
2255 QMessageBox::warning(
m_parent,
"Ignored Reference Measure", message);
2261 QString message =
"This control point is edit locked. The point type cannot be changed. You ";
2262 message +=
"must first unlock the point by clicking the check box above labeled ";
2263 message +=
"\"Edit Lock Point\".";
2264 QMessageBox::warning(
m_parent,
"Point Locked", message);
2279 for (
int i=0; i<
m_editPoint->GetNumMeasures(); i++) {
2336 QString message =
"Unable to change Ignored on point. Set EditLock ";
2337 message +=
" to False.";
2338 QMessageBox::critical(
this,
"Error", message);
2363 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point" 2364 " before changing a measure.");
2379 emit measureChanged();
2411 emit measureChanged();
2433 QMessageBox::warning(
this,
"Point Locked",
"Point is Edit Locked. You must un-lock point" 2434 " before changing a measure.");
2448 emit measureChanged();
2481 emit measureChanged();
2497 if (curIndex < m_rightCombo->count() - 1) {
2546 QString message =
"Make sure the correct cube is opened.\n\n";
2548 QMessageBox::critical(
this,
"Error", message);
2595 QString message =
"Make sure the correct cube is opened.\n\n";
2597 QMessageBox::critical(
this,
"Error", message);
2650 QString s =
"Reference: ";
2660 s =
"Measure Type: ";
2696 QString s =
"Reference: ";
2707 s =
"Measure Type: ";
2729 if(e->type() != QEvent::Leave)
return false;
2751 int r = QMessageBox::warning(
this, tr(
"OK to continue?"),
2752 tr(
"The currently opened registration template has been modified.\n" 2754 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2757 if (r == QMessageBox::Yes)
2759 else if (r == QMessageBox::Cancel)
2777 QString filename = QFileDialog::getOpenFileName(
this,
2778 "Select a registration template",
".",
2779 "Registration template files (*.def *.pvl);;All files (*)");
2781 if (filename.isEmpty())
2797 QFile file(
FileName((QString) fn).expanded());
2798 if (!file.open(QIODevice::ReadOnly)) {
2799 QString msg =
"Failed to open template file \"" + fn +
"\"";
2800 QMessageBox::warning(
this,
"IO Error", msg);
2804 QTextStream stream(&file);
2809 sb->setValue(sb->minimum());
2846 QString filename = QFileDialog::getSaveFileName(
this,
2847 "Save registration template",
".",
2848 "Registration template files (*.def *.pvl);;All files (*)");
2850 if (filename.isEmpty())
2875 QMessageBox::warning(
this,
"Error", message);
2879 QString expandedFileName(
FileName((QString) fn).expanded());
2881 QFile file(expandedFileName);
2883 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2884 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you " 2886 QMessageBox::warning(
this,
"IO Error", msg);
2891 QTextStream stream(&file);
2922 registrationDialog.setWindowTitle(
"View or Edit Template File: " 2923 + templatePvl.fileName());
2924 registrationDialog.resize(550,360);
2925 registrationDialog.exec();
2929 QMessageBox::information(
this,
"Error", message);
2964 if(templateList->
type() ==
"registrations") {
2965 for(
int i = 0; i < templateList->size(); i++) {
2967 +
"/" +
FileName(templateList->at(i)->fileName()).name());
2981 QString expandedFileName = filename;
2982 if(!filename.startsWith(
"$base")){
2984 +
"/registrations/" + filename;
2999 if(fileName.startsWith(
"$base")) {
3003 int size = components.size();
3004 int index =
m_templateComboBox->findText(components[size - 2] +
"/" + components[size - 1]);
3028 s =
"Apriori Latitude: Null";
3031 s =
"Apriori Latitude: " +
3034 m_aprioriLatitude->setText(s);
3036 s =
"Apriori Longitude: Null";
3039 s =
"Apriori Longitude: " +
3042 m_aprioriLongitude->setText(s);
3044 s =
"Apriori Radius: Null";
3047 s =
"Apriori Radius: " +
3051 m_aprioriRadius->setText(s);
3099 QColor qc = Qt::red;
3101 p.setColor(QPalette::ButtonText,qc);
3121 QColor qc = Qt::red;
3123 p.setColor(QPalette::ButtonText,qc);
3147 (
m_editPoint->GetReferenceSN() == serialNumber)) {
3152 return m_editPoint->GetMeasure(serialNumber)->IsEditLocked();
3186 void ControlPointEditWidget::showHelp() {
3189 helpDialog->setWindowTitle(
"Match Tool Help");
3191 QVBoxLayout *mainLayout =
new QVBoxLayout;
3192 helpDialog->setLayout(mainLayout);
3194 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3195 mainLayout->addWidget(matchTitle);
3197 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line " 3198 "registration points between cubes. These " 3199 "points contain sample, line postions only, no latitude or " 3200 "longitude values are used or recorded.");
3201 matchSubtitle->setWordWrap(
true);
3202 mainLayout->addWidget(matchSubtitle);
3204 QTabWidget *tabArea =
new QTabWidget;
3205 tabArea->setDocumentMode(
true);
3206 mainLayout->addWidget(tabArea);
3209 QScrollArea *overviewTab =
new QScrollArea;
3210 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3211 overviewTab->setWidgetResizable(
true);
3213 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3214 overviewContainer->setLayout(overviewLayout);
3216 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3217 overviewLayout->addWidget(purposeTitle);
3219 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration " 3220 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The " 3221 "recorded registration points are sample and line pixel coordinates only. Therefore, this " 3222 "tool can be used on any images including ones that do not contain a camera model " 3223 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). " 3224 "This also means that the tool differs from the <i>qnet</i> control point network " 3225 "application in that no latitude or longitude values are ever used or recorded " 3226 "(regardless if the image has a camera model in Isis).</p>" 3227 "<p>The output control point network that this tool generates is primarily used 1) as " 3228 "input for an image-wide sample/line translation to register one image to another by " 3229 "'moving' pixel locations - refer to the documentation for applications such as " 3230 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded " 3231 "measurements in other spreadsheet or plotting packages to visualize magnitude " 3232 "and direction of varying translations of the images relative to one another.</p> " 3233 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool " 3234 "can be used to visually evaluate and edit the control point network created by " 3235 "<i>coreg</i>.</p> " 3236 "<p>The format of the output point network file is binary. This tool uses the Isis control " 3237 " network framework to create, co-register and save all control points and pixel " 3238 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to " 3239 "a readable PVL format." 3240 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> " 3241 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>" 3242 "<p>Control Points are drawn on the associated displayed cubes with the following colors: " 3243 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3244 purposeText->setWordWrap(
true);
3245 overviewLayout->addWidget(purposeText);
3247 overviewTab->setWidget(overviewContainer);
3250 QScrollArea *quickTab =
new QScrollArea;
3251 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3252 quickTab->setWidgetResizable(
true);
3254 QVBoxLayout *quickLayout =
new QVBoxLayout;
3255 quickContainer->setLayout(quickLayout);
3257 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3258 quickLayout->addWidget(quickTitle);
3260 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3261 quickLayout->addWidget(quickSubTitle);
3265 QLabel *quickPrep =
new QLabel(
"<p><ul>" 3266 "<li>Open the cubes with overlapping areas for choosing control points</li>" 3267 "<li>Choose the match tool <img src=\"" + toolIconDir +
3268 "/stock_draw-connector-with-arrows.png\" width=22 height=22> " 3269 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3270 quickPrep->setWordWrap(
true);
3271 quickLayout->addWidget(quickPrep);
3273 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top " 3274 "of the main window contains file action buttons and a help button:");
3275 morePrep->setWordWrap(
true);
3276 quickLayout->addWidget(morePrep);
3278 QLabel *fileButtons =
new QLabel(
"<p><ul>" 3279 "<li><img src=\"" + toolIconDir +
"/fileopen.png\" width=22 height=22> Open an existing " 3280 "control network <b>Note:</b> If you do not open an existing network, a new one will " 3282 "<li><img src=\"" + toolIconDir +
"/mActionFileSaveAs.png\" width=22 height=22> Save " 3283 "control network as ...</li>" 3284 "<li><img src=\"" + toolIconDir +
"/mActionFileSave.png\" width=22 height=22> Save " 3285 "control network to current file</li>" 3286 "<li><img src=\"" + toolIconDir +
"/help-contents.png\" width=22 height=22> Show Help " 3288 fileButtons->setWordWrap(
true);
3289 quickLayout->addWidget(fileButtons);
3291 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3292 quickLayout->addWidget(quickFunctionTitle);
3294 QLabel *quickFunction =
new QLabel(
3295 "The match tool window will be shown once " 3296 "you click in a cube viewport window using one of the following " 3297 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3298 quickFunction->setWordWrap(
true);
3299 quickLayout->addWidget(quickFunction);
3301 QLabel *quickDesc =
new QLabel(
"<p><ul>" 3302 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> " 3303 "All cubes in the control point must be displayed before loading the point</li>" 3304 "<li>Middle Click - Delete the control point closest to the click</li>" 3305 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3306 quickDesc->setWordWrap(
true);
3307 quickDesc->setOpenExternalLinks(
true);
3308 quickLayout->addWidget(quickDesc);
3310 quickTab->setWidget(quickContainer);
3313 QScrollArea *controlPointTab =
new QScrollArea;
3314 controlPointTab->setWidgetResizable(
true);
3315 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3317 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3318 controlPointContainer->setLayout(controlPointLayout);
3320 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3321 controlPointLayout->addWidget(controlPointTitle);
3323 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool " 3324 "is activated, the mouse buttons have the following function in the " 3325 "cube viewports of the main qview window:</h3>");
3326 mouseLabel->setWordWrap(
true);
3327 mouseLabel->setScaledContents(
true);
3328 controlPointLayout->addWidget(mouseLabel);
3330 QLabel *controlPointDesc =
new QLabel(
"<ul>" 3331 "<li>Left click - Edit the closest control point <b>Note:</b> " 3332 "All cubes in the control point must be displayed before loading the point</li>" 3333 "<li>Middle click - Delete the closest control point</li>" 3334 "<li>Right click - Create new control point at cursor location. This will bring up a new " 3335 "point dialog which allows you to enter a point id and will list all cube viewports, " 3336 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. " 3337 "When the desired cubes have been chosen, select the \"Done\" button which will load the " 3338 "control point into the control point editor window which will allow the control measure " 3339 "positions to be refined.</li>");
3340 controlPointDesc->setWordWrap(
true);
3341 controlPointLayout->addWidget(controlPointDesc);
3343 QLabel *controlPointEditing =
new QLabel(
3344 "<h4>Changing Control Measure Locations</h4>" 3345 "<p>Both the left and right control measure positions can be adjusted by:" 3347 "<li>Move the cursor location under the crosshair by clicking the left mouse " 3349 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>" 3350 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>" 3352 "<h4>Other Point Editor Functions</h4>" 3353 "<p>Along the right border of the window:</p>" 3355 "<li><strong>Link Zoom</strong> This will link the two small viewports together when " 3356 "zooming (ie. If this is checked, if the left view is zoomed, the right view will " 3357 "match the left view's zoom factor. " 3358 "<b>Note:</b> Zooming is controlled from the left view.</li>" 3359 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to " 3360 "its original orientation</li>" 3361 "<li><strong>Rotate:</strong> Rotate the right view using either the dial " 3362 "or entering degrees </li>" 3363 "<li><strong>Show control points:</strong> Draw crosshairs at all control " 3364 "point locations visible within the view</li>" 3365 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire " 3367 "<li><strong>Circle:</strong> Draw circle which may help center measure " 3368 "on a crater</li></ul" 3369 "<p>Below the left view:</p>" 3370 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the " 3371 "left view window using the \"Blink Start\" button <img src=\"" + toolIconDir +
3372 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3373 toolIconDir +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left " 3374 "and right views and the keyboard arrow keys may be used to move the both views while " 3376 "<li><strong>Register:</strong> Sub-pixel register the right view to " 3377 "the left view. A default registration template is used for setting parameters " 3378 "passed to the sub-pixel registration tool. The user may load in a predefined " 3379 "template or edit the current loaded template to influence successful " 3380 "co-registration results. For more information regarding the pattern matching " 3381 "functionlity or how to create a parameter template, refer to the Isis PatternMatch " 3382 "document and the <i>autoregtemplate</i> application.</li>" 3383 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, " 3384 "line positions under the crosshairs.</li>" 3385 "<li><strong>Save Point:</strong> Save the control point to the control network.</li>" 3387 controlPointEditing->setWordWrap(
true);
3388 controlPointLayout->addWidget(controlPointEditing);
3390 controlPointTab->setWidget(controlPointContainer);
3392 tabArea->addTab(overviewTab,
"&Overview");
3393 tabArea->addTab(quickTab,
"&Quick Start");
3394 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3396 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3398 buttonsLayout->addStretch();
3400 QPushButton *closeButton =
new QPushButton(
"&Close");
3401 closeButton->setIcon(QIcon(
FileName(
"$base/icons/guiStop.png").expanded()));
3402 closeButton->setDefault(
true);
3403 connect(closeButton, SIGNAL(clicked()),
3404 helpDialog, SLOT(close()));
3405 buttonsLayout->addWidget(closeButton);
3407 mainLayout->addLayout(buttonsLayout);
static QString templateRoot(QString projectRoot)
Appends the root directory name 'templates' to the project .
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.
Internalizes a list of shapes and allows for operations on the entire list.
Status SetAprioriSurfacePointSource(SurfacePointSource::Source source)
This updates the source of the surface point.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
double meters() const
Get the distance in meters.
double HotSample()
Returns the sample coordinate of the center pixel in the buffer for the interpolator.
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
double * DoubleBuffer() const
Returns the value of the shape buffer.
bool changeAllGroundSourceLocation()
Indicates whether all subsequent ground source files should be found in new source directory...
double Line() const
Returns the current line value of the camera model or projection.
const double Null
Value for an Isis Null pixel.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
double Interpolate(const double isamp, const double iline, const double buf[])
Performs an interpolation on the data according to the parameters set in the constructor.
File name manipulation and expansion.
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
Buffer for containing a two dimensional section of an image.
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name 'shapes' to the project .
QString fileName() const
Get the file name that this Template represents.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
PointType
These are the valid 'types' of point.
bool HasAprioriSurfacePointSourceFile() const
Checks to see if the surface point source file has been set.
Namespace for the standard library.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
QList< TemplateList * > regTemplates()
Return registration template FileNames.
int fileNameIndex(const QString &filename)
Return a list index given a filename.
Status SetChooserName(QString name)
Set the point's chooser name.
Widget to display Isis cubes for qt apps.
Registered to whole pixel (e.g.,pointreg)
Registered to sub-pixel (e.g., pointreg)
Control * activeControl()
Return the Active Control (control network)
Distance measurement, usually in meters.
QString importName() const
Get the name of the TemplateList this file was imported under.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
double degrees() const
Get the angle in units of Degrees.
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.
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Status SetAprioriSurfacePointSourceFile(QString sourceFile)
This updates the filename of where the apriori surface point came from.
bool changeControlNet()
Indicates whether the control network should be changed to reflect new ground source location...
double HotLine()
Returns the line coordinate of the center pixel in the buffer for the interpolator.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Hand Measured (e.g., qnet)
QString GetId() const
Return the Id of the control point.
Status SetCamera(Isis::Camera *camera)
Set pointer to camera associated with a measure.
int Samples()
Returns the number of samples needed by the interpolator.
Cube * cube()
Get the Cube * associated with this display property.
Contains multiple PvlContainers.
double Sample()
Returns the current sample number.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
QString fileName() const
Get the file name of the cube that this shape represents.
void remove(const QString &sn)
Remove the specified serial number from the list.
Container for cube-like labels.
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
QString GetChooserName() const
Return the chooser name.
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
int size() const
How many serial number / filename combos are in the list.
Status SetType(PointType newType)
Updates the control point's type.
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.
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
QString toString() const
Returns a string representation of this exception.
int Lines()
Returns the number of lines needed by the interpolator.
This represents a shape in a project-based GUI interface.
double Line()
Returns the current line number.
QString type() const
Get the type of template in this TemplateList.
static QString UserName()
Returns the user name.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
Namespace for ISIS/Bullet specific routines.
Project * project() const
Gets the Project for this directory.
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
void setFiles(QStringList pointFiles)
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
Obtain SPICE information for a spacecraft.
The distance is being specified in meters.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
double Sample() const
Returns the current line value of the camera model or projection.
PointType GetType() const
Serial Number list generator.
Distance GetLocalRadius() const
Return the radius of the surface point.
void radii(Distance r[3]) const
Returns the radii of the body in km.
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
QString fileName() const
Access the name of the control network file associated with this Control.
bool fileExists() const
Returns true if the file exists; false otherwise.
FileName externalCubeFileName() const
If this is an external cube label file, this will give you the cube dn file that this label reference...
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
Dialog used by ControlPointEditWidget to select a new location for ground source files.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
This is returned when the operation requires Edit Lock to be false but it is currently true...
IO Handler for Isis Cubes.