Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
FeatureNomenclatureTool.cpp
1 #include "IsisDebug.h"
2 #include "FeatureNomenclatureTool.h"
3 
4 #include <QAction>
5 #include <QApplication>
6 #include <QBitmap>
7 #include <QCheckBox>
8 #include <QClipboard>
9 #include <QComboBox>
10 #include <QDebug>
11 #include <QDesktopServices>
12 #include <QDialog>
13 #include <QHBoxLayout>
14 #include <QLabel>
15 #include <QMenu>
16 #include <QMessageBox>
17 #include <QProgressBar>
18 #include <QPushButton>
19 #include <QSettings>
20 #include <QPainter>
21 #include <QUrl>
22 
23 #include <geos/geom/Coordinate.h>
24 #include <geos/geom/CoordinateSequence.h>
25 #include <geos/geom/MultiPolygon.h>
26 
27 #include "Distance.h"
28 #include "FileName.h"
29 #include "ImagePolygon.h"
30 #include "Latitude.h"
31 #include "Longitude.h"
32 #include "MdiCubeViewport.h"
33 #include "NomenclatureToolConfigDialog.h"
34 #include "PolygonTools.h"
35 #include "Target.h"
36 #include "ToolPad.h"
37 
38 
39 namespace Isis {
40 
47  Tool(parent) {
48  m_foundNomenclature = NULL;
51  m_foundFeaturesCombo = NULL;
54  m_disclaimerBtn = NULL;
55  m_queryingProgress = NULL;
56  m_nomenclatureEnabled = false;
57  m_fontColor = NULL;
58 
62 
63  m_fontSize = 12;
64  m_fontColor = new QColor(237, 170, 171);
65  m_defaultEnabled = false;
66  m_disclaimedAlready = false;
67  m_showApprovedOnly = true;
69 
70  m_disclaimerText = "The nomenclature qview tool will label named features "
71  "in your opened cube files. This tool <strong>requires</strong> an "
72  "active internet connection, projection or camera information, and a "
73  "calculatable ground range to function. The larger the ground range ("
74  "covered area on a planet), the longer it will take to populate the "
75  "nomenclature for a particular cube.<br/><br/>"
76  "<font color='red'>**WARNING**</font> The accuracy of this tool is not "
77  "perfect, features <strong>can and will be mislabeled</strong> if you "
78  "have not properly controlled your images to the control network that "
79  "identifies the latitude/longitude values of a feature. Please use the "
80  "nomenclature website to verify a label is correct for a feature. "
81  "<br/><br/>See the IAU Gazetteer of Planetary Nomenclature website for "
82  "more information.<br/>"
83  "<a href='http://planetarynames.wr.usgs.gov/'>"
84  "http://planetarynames.wr.usgs.gov/</a>";
85 
86  connect(this, SIGNAL(toolActivated()),
87  this, SLOT(onToolActivated()));
88 
89  readSettings();
90 
92  }
93 
94 
99  delete m_foundNomenclature;
100  m_foundNomenclature = NULL;
101 
102  foreach (FeatureNomenclature *nomenclature, *m_nomenclatureSearchers) {
103  delete nomenclature;
104  }
105 
108  }
109 
110 
117  m_action = menu->addAction("Show Nomenclature");
118  m_action->setCheckable(true);
119  m_action->setChecked(m_nomenclatureEnabled);
120 
121  connect(m_action, SIGNAL(triggered(bool)),
122  m_findNomenclatureCheckBox, SLOT(setChecked(bool)));
123  }
124 
125 
133  QPainter *painter) {
136 
137  QFont fontToUse;
138  fontToUse.setPointSize(m_fontSize);
139  painter->setFont(fontToUse);
140  painter->setPen(QPen(*m_fontColor));
141  display.paint(painter, (m_extentType != None), m_extentType, m_showApprovedOnly);
142  }
143  }
144 
145 
152  return m_defaultEnabled;
153  }
154 
155 
162  return *m_fontColor;
163  }
164 
165 
172  return m_fontSize;
173  }
174 
175 
182  return m_showApprovedOnly;
183  }
184 
185 
192  return m_extentType;
193  }
194 
195 
201  void FeatureNomenclatureTool::setDefaultEnabled(bool defaultEnabled) {
204  writeSettings();
205  }
206  }
207 
208 
216  if (*m_fontColor != color) {
217  *m_fontColor = color;
218  writeSettings();
219 
220  foreach (MdiCubeViewport *vp, *cubeViewportList())
221  vp->viewport()->update();
222  }
223  }
224 
225 
232  void FeatureNomenclatureTool::setFontSize(int newFontSize) {
233  if (m_fontSize != newFontSize) {
234  m_fontSize = newFontSize;
235  writeSettings();
236 
238 
239  foreach (MdiCubeViewport *vp, *cubeViewportList())
240  vp->viewport()->update();
241  }
242  }
243 
244 
251  if (m_showApprovedOnly != approvedOnly) {
252  m_showApprovedOnly = approvedOnly;
253  writeSettings();
256 
257  foreach (MdiCubeViewport *vp, *cubeViewportList())
258  vp->viewport()->update();
259  }
260  }
261 
262 
270  if (m_extentType != show) {
271  m_extentType = show;
272  writeSettings();
273 
274  for (int i = 0; i < m_foundNomenclature->count(); i++) {
275  (*m_foundNomenclature)[i].applyExtentType(m_extentType);
276  }
277 
279 
280  foreach (MdiCubeViewport *vp, *cubeViewportList())
281  vp->viewport()->update();
282  }
283  }
284 
285 
292  return "&Options";
293  }
294 
295 
304  QStackedWidget *parent) {
305  QWidget *wrapperWidget = new QWidget;
306 
307  m_findNomenclatureCheckBox = new QCheckBox;
308  m_findNomenclatureCheckBox->setText("Name Features");
310  connect(m_findNomenclatureCheckBox, SIGNAL(stateChanged(int)),
311  this, SLOT(findNomenclatureStateChanged(int)));
312 
313  QLabel *foundFeaturesLabel = new QLabel("Found Features:");
315  m_foundFeaturesCombo->setSizeAdjustPolicy(
316  QComboBox::AdjustToContents);
317  m_foundFeaturesCombo->addItem("");
318 
319  m_nomenclatureCenterBtn = new QPushButton("Center on Feature");
320  m_nomenclatureCenterBtn->setEnabled(false);
321 
322  connect(m_nomenclatureCenterBtn, SIGNAL(clicked()),
323  this, SLOT(centerOnSelectedFeature()));
324 
325  m_nomenclatureOptionsBtn = new QPushButton("Tool Options");
326  connect(m_nomenclatureOptionsBtn, SIGNAL(clicked()),
327  this, SLOT(configure()));
328 
329  m_disclaimerBtn = new QPushButton("Disclaimer");
330  connect(m_disclaimerBtn, SIGNAL(clicked()),
331  this, SLOT(showDisclaimer()));
332 
333  connect(m_foundFeaturesCombo, SIGNAL(currentIndexChanged(int)),
334  this, SLOT(featureSelected()));
335 
337  m_queryingProgress->setObjectName("nomenclatureQueryProgress");
338  m_queryingProgress->setVisible(false);
339  m_queryingProgress->setRange(0, 0);
340 
341  QHBoxLayout *layout = new QHBoxLayout;
342  layout->setMargin(0);
343  layout->addWidget(m_findNomenclatureCheckBox);
344  layout->addWidget(foundFeaturesLabel);
345  layout->addWidget(m_foundFeaturesCombo);
346  layout->addWidget(m_nomenclatureCenterBtn);
347  layout->addWidget(m_nomenclatureOptionsBtn);
348  layout->addWidget(m_disclaimerBtn);
349  layout->addWidget(m_queryingProgress);
350  layout->addStretch(1);
351  wrapperWidget->setLayout(layout);
352  return wrapperWidget;
353  }
354 
355 
365  QAction *action = new QAction(toolpad);
366 
367  action->setIcon(QPixmap(toolIconDir() + "/nomenclature.png"));
368  action->setToolTip("Nomenclature (N)");
369  action->setShortcut(Qt::Key_N);
370  action->setObjectName("nomenclatureToolButton");
371 
372  QString text =
373  "<b>Function:</b> Display nomenclature on the visible images.\n"
374  "<p/><b>Hint:</b> While this tool is active, you can left and right "
375  "click on any of the named features for additional options."
376  "<p/><b>Shortcut:</b> N";
377  action->setWhatsThis(text);
378 
379  return action;
380  }
381 
382 
392  QPoint p, Qt::MouseButton s) {
393  if (m_nomenclatureEnabled &&
396  }
397  }
398 
399 
406  }
407 
408 
414  QVariant variant = m_foundFeaturesCombo->itemData(
415  m_foundFeaturesCombo->currentIndex());
416 
417  if (variant.toMap()["Viewport"].value<MdiCubeViewport *>() != NULL) {
418  MdiCubeViewport *vp =
419  variant.toMap()["Viewport"].value<MdiCubeViewport *>();
421  variant.toMap()["Feature"].value<FeatureNomenclature::Feature>();
422 
423  // We need to find the appropriate viewport also...
424  centerOnFeature(vp, feature);
425  }
426  }
427 
428 
433  NomenclatureToolConfigDialog *configDialog =
435  qobject_cast<QWidget *>(parent()));
436  configDialog->setAttribute(Qt::WA_DeleteOnClose);
437  configDialog->show();
438  }
439 
440 
448  QVariant variant = m_foundFeaturesCombo->itemData(
449  m_foundFeaturesCombo->currentIndex());
450 
451  bool featureSelected =
452  variant.toMap()["Viewport"].value<MdiCubeViewport *>() != NULL;
453 
454  m_nomenclatureCenterBtn->setEnabled(
456  }
457 
458 
464  FeatureNomenclature *searcher) {
465  MdiCubeViewport *viewport = m_nomenclatureSearchers->key(searcher);
466 
467  // The viewport could have gone away when we were still querying... handle
468  // that case.
469  bool vpValid = cubeViewportList()->contains(viewport);
470  if (vpValid)
471  featuresForViewportFound(viewport);
472 
473  if (m_nomenclatureEnabled) {
474  viewportDone(viewport);
475  }
476 
477  if (vpValid)
478  viewport->viewport()->update();
479  }
480 
481 
488  if (newState == Qt::Unchecked) {
489  m_nomenclatureEnabled = false;
491  }
492  else if (newState == Qt::Checked) {
493  m_nomenclatureEnabled = true;
495 
497  }
498 
499  foreach (MdiCubeViewport *vp, *cubeViewportList())
500  vp->viewport()->update();
501  }
502 
503 
511  if (m_nomenclatureEnabled) {
512 
513  for (int i = 0; i < m_foundNomenclature->count(); i++) {
514  (*m_foundNomenclature)[i].handleViewChanged(this);
515  }
516  }
517  }
518 
519 
525  if (!m_findNomenclatureCheckBox->isChecked())
526  m_findNomenclatureCheckBox->setChecked(true);
527  }
528 
529 
535  QMessageBox::warning(qobject_cast<QWidget *>(parent()),
536  "Nomenclature Disclaimer", m_disclaimerText);
537  m_disclaimedAlready = true;
538  writeSettings();
539  }
540 
541 
552  foreach (MdiCubeViewport *viewport, viewportsWithFoundNomenclature()) {
553  if (viewport == vp ||
554  (vp->isLinked() && viewport->isLinked())) {
555  viewportFeatureDisplay(viewport)->centerFeature(feature);
556  }
557  }
558  }
559 
560 
570  if (vp) {
572  if (m_nomenclatureSearchers->find(vp) != m_nomenclatureSearchers->end()) {
573  if ((*m_nomenclatureSearchers)[vp]->hasResult())
574  features.append((*m_nomenclatureSearchers)[vp]->features());
575  else
576  m_findNomenclatureCheckBox->setChecked(false);
577  }
578 
579  if (!viewportFeatureDisplay(vp)) {
580  m_foundNomenclature->append(ViewportFeatureDisplay(this, vp, features, m_extentType));
581  }
582 
583  features = viewportFeatureDisplay(vp)->features();
584 
585  QProgressDialog updatingFeaturesProgress(
586  tr("Projecting Features for [%1]").arg(vp->cube()->fileName().section('/',-1)),
587  QString(), 0, 100);
588 
589  updatingFeaturesProgress.setWindowModality(Qt::WindowModal);
590 
592 
593  for (int i = 0; i < features.count(); i++) {
594  feature = features[i];
595 
596  int progress = floor(100 * (double)i / (double)features.count());
597 
598  if (progress != updatingFeaturesProgress.value())
599  updatingFeaturesProgress.setValue(progress);
600 
601  if (updatingFeaturesProgress.wasCanceled()) {
602  m_nomenclatureSearchers->clear();
603  m_foundNomenclature->clear();
604  m_foundFeaturesCombo->clear();
605  m_findNomenclatureCheckBox->setChecked(false);
606  break;
607  }
608 
609  if ( !m_showApprovedOnly ||
611 
612  QString displayName = feature.cleanName() +
613  " (" + FileName(vp->cube()->fileName()).name() + ")";
614 
615  QString targetName = feature.target().toUpper();
616 
617  // never insert above the blank (at 0)
618  int insertPos = 1;
619 
620  bool foundInsertPos = m_foundFeaturesCombo->count() == 0;
621 
622  while (!foundInsertPos) {
623  if (insertPos >= m_foundFeaturesCombo->count()) {
624  foundInsertPos = true;
625  }
626  else {
627  QVariant insetPosData = m_foundFeaturesCombo->itemData(
628  insertPos);
629  QString insertPosTarget = insetPosData.toMap()["Target"].toString();
630 
631  if (targetName < insertPosTarget) {
632  foundInsertPos = true;
633  }
634  else if (targetName == insertPosTarget) {
635  if (!insetPosData.toMap()["Viewport"].isNull()) {
636  foundInsertPos = displayName.compare(
637  m_foundFeaturesCombo->itemText(insertPos),
638  Qt::CaseInsensitive) < 0;
639  }
640  }
641  }
642 
643  if (!foundInsertPos)
644  insertPos++;
645  }
646 
647  if (m_foundFeaturesCombo->itemData(insertPos - 1).toMap()[
648  "Target"].toString() != targetName) {
650  data["Target"] = targetName;
651 
652  QString controlNet = feature.controlNet();
653  if (controlNet != "")
654  controlNet = " (" + controlNet + ")";
655 
656  m_foundFeaturesCombo->insertItem(insertPos,
657  targetName + controlNet,
658  data);
659  QVariant font = m_foundFeaturesCombo->itemData(insertPos,
660  Qt::ForegroundRole);
661  m_foundFeaturesCombo->setItemData(insertPos, QColor(Qt::gray),
662  Qt::ForegroundRole);
663  insertPos++;
664 
665  m_foundFeaturesCombo->insertItem(insertPos,
666  "-----------",
667  data);
668  m_foundFeaturesCombo->setItemData(insertPos, QColor(Qt::gray),
669  Qt::ForegroundRole);
670  insertPos++;
671  }
672 
674  data["Feature"] = QVariant::fromValue<FeatureNomenclature::Feature>(
675  feature);
676  data["Viewport"] = qVariantFromValue(vp);
677  data["Target"] = qVariantFromValue(targetName);
678 
679  m_foundFeaturesCombo->insertItem(insertPos, displayName,
680  qVariantFromValue(data));
681  }
682  }
683  updatingFeaturesProgress.setValue( features.count() );
684  }
685  }
686 
687 
696  if (m_nomenclatureEnabled) {
697  // We're looking for viewports with nomenclature results that no longer
698  // exist with removedViewports.
699  QList<MdiCubeViewport *> removedViewports =
701 
702  foreach (MdiCubeViewport *vp, *cubeViewportList()) {
703  removedViewports.removeOne(vp);
704 
707 
708  if (!viewportFeaturesFound(vp) && finding.find(vp) == finding.end()) {
710  }
711  }
712 
713  bool removedAViewport = false;
714  foreach (MdiCubeViewport *vp, removedViewports) {
715  // A viewport disappeared; let's remove all references of it.
717  removedAViewport = true;
718  }
719 
720  if (removedAViewport) {
721  // Rebuild the combo box...
723  }
724  }
725  }
726 
727 
735  try {
736  // verify we can project before anything else
738 
739  if (!ugm)
740  throw IException();
741 
742  QString target;
743  if (vp->camera()) {
744  target = vp->camera()->target()->name();
745  }
746  else if (vp->projection()) {
747  PvlGroup mappingGrp = vp->projection()->Mapping();
748 
749  if (mappingGrp.hasKeyword("TargetName"))
750  target = mappingGrp["TargetName"][0];
751  }
752 
753  Latitude minLat;
754  Latitude maxLat;
755  Longitude minLon;
756  Longitude maxLon;
757  if (ugm->GroundRange(vp->cube(), minLat, maxLat, minLon, maxLon) &&
758  target != "") {
760  connect(searcher, SIGNAL(featuresIdentified(FeatureNomenclature *)),
761  this, SLOT(featuresIdentified(FeatureNomenclature *)));
762 
763  (*m_nomenclatureSearchers)[vp] = searcher;
765  (*m_nomenclatureSearchers)[vp]->queryFeatures(target.toUpper(),
766  minLat, minLon,
767  maxLat, maxLon);
768  }
769  else {
770  viewportDone(vp);
771  }
772  }
773  catch (IException &) {
774  viewportDone(vp);
775  }
776  }
777 
778 
784  if (m_foundFeaturesCombo) {
785  m_foundFeaturesCombo->clear();
786  m_foundFeaturesCombo->addItem("");
787 
790  }
791  }
792  }
793 
794 
802  for (int i = m_foundNomenclature->count() - 1; i >= 0; i--) {
803  if (m_foundNomenclature->at(i).sourceViewport() == vp)
804  m_foundNomenclature->removeAt(i);
805  }
806  }
807 
808 
816  QDialog *detailsDialog = new QDialog(qobject_cast<QWidget *>(parent()));
817  detailsDialog->setAttribute(Qt::WA_DeleteOnClose);
818 
819  QVBoxLayout *mainLayout = new QVBoxLayout;
820  detailsDialog->setLayout(mainLayout);
821 
822  mainLayout->addWidget(feature.toWidget());
823 
824  QWidget *buttonsAreaWrapper = new QWidget;
825 
826  QHBoxLayout *buttonsAreaLayout = new QHBoxLayout;
827  buttonsAreaWrapper->setLayout(buttonsAreaLayout);
828 
829  buttonsAreaLayout->addStretch();
830  QPushButton *okayBtn = new QPushButton("&Ok");
831  okayBtn->setIcon(QIcon::fromTheme("dialog-ok"));
832  connect(okayBtn, SIGNAL(clicked()),
833  detailsDialog, SLOT(accept()));
834  buttonsAreaLayout->addWidget(okayBtn);
835 
836  mainLayout->addWidget(buttonsAreaWrapper);
837 
838  detailsDialog->show();
839  }
840 
841 
849  QDesktopServices::openUrl(feature.referenceUrl());
850  }
851 
852 
859  bool isCurrentlyLoading = (m_nomenclatureSearchers->keys().count() > 0);
860 
861  if (isCurrentlyLoading) {
862  m_findNomenclatureCheckBox->setEnabled(false);
863  m_queryingProgress->setVisible(true);
864  }
865  else {
866  m_findNomenclatureCheckBox->setEnabled(true);
867  m_queryingProgress->setVisible(false);
869 
871  showDisclaimer();
872  }
873  }
874 
875  if (m_action) {
876  m_action->setChecked(m_nomenclatureEnabled);
877  }
878 
879  featureSelected();
880  }
881 
882 
893  if (m_nomenclatureSearchers->find(vp) != m_nomenclatureSearchers->end()) {
894  if ((*m_nomenclatureSearchers)[vp]) {
895  (*m_nomenclatureSearchers)[vp]->deleteLater();
896  }
897 
898  m_nomenclatureSearchers->remove(vp);
899  }
900 
901  if (viewportFeatureDisplay(vp) == NULL) {
902  m_foundNomenclature->append(
903  ViewportFeatureDisplay(this, vp,
905  }
906  else {
907  connect(vp, SIGNAL(screenPixelsChanged()),
908  this, SLOT(nomenclaturePositionsOutdated()));
909  }
910 
912  }
913 
914 
924  for (int i = 0; i < m_foundNomenclature->count(); i++) {
925  if (m_foundNomenclature->at(i).sourceViewport() == vp)
926  return &(*m_foundNomenclature)[i];
927  }
928 
929  return NULL;
930  }
931 
932 
942  const {
943  for (int i = 0; i < m_foundNomenclature->count(); i++) {
944  if (m_foundNomenclature->at(i).sourceViewport() == vp)
945  return &(*m_foundNomenclature)[i];
946  }
947 
948  return NULL;
949  }
950 
951 
961  const {
962  return (viewportFeatureDisplay(vp) != NULL);
963  }
964 
965 
975 
976  for (int i = 0; i < m_foundNomenclature->count(); i++) {
977  if (m_foundNomenclature->at(i).sourceViewport() != NULL)
978  result.append(m_foundNomenclature->at(i).sourceViewport());
979  }
980 
981  return result;
982  }
983 
984 
991  FileName config("$HOME/.Isis/qview/nomenclature.config");
992  QSettings settings(
993  config.expanded(), QSettings::NativeFormat);
994 
995  m_fontSize = settings.value("fontSize", m_fontSize).toInt();
996  *m_fontColor = settings.value("fontColor", *m_fontColor).value<QColor>();
998  settings.value("defaultEnabled", m_defaultEnabled).toBool();
1000  settings.value("disclaimerShown", m_disclaimedAlready).toBool();
1002  settings.value("showApprovedOnly", m_showApprovedOnly).toBool();
1003  m_extentType =
1004  VectorType(settings.value("vectorsShown", m_extentType).toInt());
1005  }
1006 
1007 
1013  FileName config("$HOME/.Isis/qview/nomenclature.config");
1014  QSettings settings(
1015  config.expanded(), QSettings::NativeFormat);
1016  settings.setValue("fontSize", m_fontSize);
1017  settings.setValue("fontColor", qVariantFromValue(*m_fontColor));
1018  settings.setValue("defaultEnabled", m_defaultEnabled);
1019  settings.setValue("disclaimerShown", m_disclaimedAlready);
1020  settings.setValue("showApprovedOnly", m_showApprovedOnly);
1021  settings.setValue("vectorsShown", m_extentType);
1022  }
1023 
1024 
1029  m_centerLine = Null;
1030  m_centerSample = Null;
1031  m_featureEdgeLineSamples = NULL;
1032  m_gmap = NULL;
1033 
1035  }
1036 
1037 
1049  m_centerLine = Null;
1050  m_centerSample = Null;
1051  m_featureEdgeLineSamples = NULL;
1052  m_gmap = NULL;
1053 
1054  m_featureEdgeLineSamples = new QList< QPair<double, double> >;
1055 
1056  m_feature = feature;
1057 
1058  if (vp) {
1059  m_gmap = vp->universalGroundMap();
1060  Latitude centerLat = m_feature.centerLatitude();
1061  Longitude centerLon = m_feature.centerLongitude();
1062  if (m_gmap && m_gmap->SetGround(centerLat, centerLon)) {
1063  m_centerSample = m_gmap->Sample();
1064  m_centerLine = m_gmap->Line();
1065 
1066  applyExtentType(vectorType);
1067  }
1068  }
1069  }
1070 
1071 
1078  const FeaturePosition &other) {
1079  m_centerLine = other.m_centerLine;
1080  m_centerSample = other.m_centerSample;
1081  m_featureEdgeLineSamples = NULL;
1082  m_gmap = NULL;
1083 
1084  m_featureEdgeLineSamples = new QList< QPair<double, double> >(
1085  *other.m_featureEdgeLineSamples);
1086 
1087  m_feature = other.m_feature;
1088 
1089  if (other.m_gmap)
1090  m_gmap = new UniversalGroundMap(*other.m_gmap);
1091  }
1092 
1093 
1098  m_centerLine = Null;
1099  m_centerSample = Null;
1100  m_gmap = NULL;
1101 
1102  delete m_featureEdgeLineSamples;
1103  m_featureEdgeLineSamples = NULL;
1104  }
1105 
1106 
1113  return (m_centerSample != Null && m_centerLine != Null);
1114  }
1115 
1116 
1123  const {
1124  return QPair<double, double>(m_centerSample, m_centerLine);
1125  }
1126 
1127 
1135  return *m_featureEdgeLineSamples;
1136  }
1137 
1138 
1146  return m_feature;
1147  }
1148 
1159 
1160  Latitude centerLat = m_feature.centerLatitude();
1161  Longitude centerLon = m_feature.centerLongitude();
1162 
1163  m_featureEdgeLineSamples->clear();
1164 
1166 
1167  // We're going to permute the edge lats/lons excluding the center, so
1168  // these lists are independent of each other.
1169  QList<Latitude> edgeLats;
1170  QList<Longitude> edgeLons;
1171 
1172  edgeLats.append(m_feature.northernLatitude());
1173  edgeLats.append(m_feature.centerLatitude());
1174  edgeLats.append(m_feature.southernLatitude());
1175 
1176  edgeLons.append(m_feature.easternLongitude());
1177  edgeLons.append(m_feature.centerLongitude());
1178  edgeLons.append(m_feature.westernLongitude());
1179 
1180  int edgeLatCount = edgeLats.count();
1181  int edgeLonCount = edgeLons.count();
1182 
1183  for (int latIndex = 0; latIndex < edgeLatCount; latIndex++) {
1184  for (int lonIndex = 0; lonIndex < edgeLonCount; lonIndex++) {
1185  Latitude &lat = edgeLats[latIndex];
1186  Longitude &lon = edgeLons[lonIndex];
1187 
1188  if (lat.isValid() && lon.isValid() &&
1189  (lat != centerLat || lon != centerLon) &&
1190  m_gmap->SetGround(lat, lon)) {
1191  m_featureEdgeLineSamples->append(
1192  QPair<double, double>(m_gmap->Sample(), m_gmap->Line()));
1193  }
1194  }
1195  }
1196  }
1197 
1198  else {
1199  QList< QPair<Latitude, Longitude> > edgeLatLons;
1200 
1202  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1203  m_feature.centerLongitude()));
1204  edgeLatLons.append(qMakePair(m_feature.centerLatitude(),
1205  m_feature.westernLongitude()));
1206  edgeLatLons.append(qMakePair(m_feature.centerLatitude(),
1207  m_feature.easternLongitude()));
1208  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1209  m_feature.centerLongitude()));
1210  }
1211 
1213  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1214  m_feature.easternLongitude()));
1215  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1216  m_feature.westernLongitude()));
1217  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1218  m_feature.westernLongitude()));
1219  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1220  m_feature.easternLongitude()));
1221  }
1222 
1223  int edgeLatLonCount = edgeLatLons.count();
1224 
1225  for (int edgeIndex = 0; edgeIndex < edgeLatLonCount; edgeIndex++) {
1226  Latitude &lat = edgeLatLons[edgeIndex].first;
1227  Longitude &lon = edgeLatLons[edgeIndex].second;
1228 
1229  if (lat.isValid() && lon.isValid() &&
1230  (lat != centerLat || lon != centerLon) &&
1231  m_gmap->SetGround(lat, lon)) {
1232  m_featureEdgeLineSamples->append(
1233  QPair<double, double>(m_gmap->Sample(), m_gmap->Line()));
1234  }
1235  }
1236  }
1237  }
1238 
1239 
1246  std::swap(m_centerLine, other.m_centerLine);
1247  std::swap(m_centerSample, other.m_centerSample);
1248  std::swap(m_featureEdgeLineSamples, other.m_featureEdgeLineSamples);
1249  std::swap(m_feature, other.m_feature);
1250  std::swap(m_gmap, other.m_gmap);
1251  }
1252 
1253 
1264  const FeaturePosition &rhs) {
1265  FeaturePosition copy(rhs);
1266  swap(copy);
1267  return *this;
1268  }
1269 
1270 
1278  return m_feature;
1279  }
1280 
1281 
1286  m_textRect = NULL;
1287  m_fullDisplayRect = NULL;
1288  m_edgePoints = NULL;
1289 
1290  m_textRect = new QRect;
1291  m_fullDisplayRect = new QRect;
1292  m_edgePoints = new QList<QPoint>;
1293  }
1294 
1295 
1307  QRect textRect, QRect fullDisplayRect, QList<QPoint> edgePoints) {
1308  m_textRect = NULL;
1309  m_fullDisplayRect = NULL;
1310  m_edgePoints = NULL;
1311 
1312  m_textRect = new QRect(textRect);
1313  m_fullDisplayRect = new QRect(fullDisplayRect);
1314  m_edgePoints = new QList<QPoint>(edgePoints);
1315  }
1316 
1317 
1323  const FeatureDisplayPosition &other) {
1324  m_textRect = NULL;
1325  m_fullDisplayRect = NULL;
1326  m_edgePoints = NULL;
1327 
1328  m_textRect = new QRect(*other.m_textRect);
1329  m_fullDisplayRect = new QRect(*other.m_fullDisplayRect);
1330  m_edgePoints = new QList<QPoint>(*other.m_edgePoints);
1331  }
1332 
1333 
1338  delete m_textRect;
1339  m_textRect = NULL;
1340 
1341  delete m_fullDisplayRect;
1342  m_fullDisplayRect = NULL;
1343 
1344  delete m_edgePoints;
1345  m_edgePoints = NULL;
1346  }
1347 
1348 
1356  return *m_textRect;
1357  }
1358 
1359 
1367  return *m_fullDisplayRect;
1368  }
1369 
1370 
1378  const {
1379  return *m_edgePoints;
1380  }
1381 
1382 
1390  FeatureDisplayPosition &other) {
1391  std::swap(m_textRect, other.m_textRect);
1392  std::swap(m_fullDisplayRect, other.m_fullDisplayRect);
1393  std::swap(m_edgePoints, other.m_edgePoints);
1394  }
1395 
1396 
1406  const FeatureDisplayPosition &rhs) {
1407  FeatureDisplayPosition copy(rhs);
1408  swap(copy);
1409  return *this;
1410  }
1411 
1412 
1417  m_sourceViewport = NULL;
1418  m_features = NULL;
1419  m_featureScreenAreas = NULL;
1420  m_viewportCubeRange = NULL;
1421 
1422  m_features = new QList<FeaturePosition>;
1423  m_featureScreenAreas = new QList<FeatureDisplayPosition>;
1424  m_viewportCubeRange = new QPair<QPointF, QPointF>;
1425  }
1426 
1427 
1437  FeatureNomenclatureTool *tool, MdiCubeViewport *sourceViewport,
1439  m_sourceViewport = sourceViewport;
1440  m_features = NULL;
1441  m_featureScreenAreas = NULL;
1442  m_viewportCubeRange = NULL;
1443 
1444  m_features = new QList<FeaturePosition>;
1445  m_featureScreenAreas = new QList<FeatureDisplayPosition>;
1446  m_viewportCubeRange = new QPair<QPointF, QPointF>;
1447 
1448  qSort(features.begin(), features.end(),
1450 
1451  for (int i = 0; i < features.count(); i++) {
1452  FeaturePosition display(sourceViewport, features[i], vectorType);
1453  if (display.isValid()) {
1454  m_features->append(display);
1455  }
1456  }
1457 
1458  handleViewChanged(tool);
1459  }
1460 
1461 
1468  const ViewportFeatureDisplay &other) {
1469  m_sourceViewport = other.m_sourceViewport;
1470  m_features = NULL;
1471  m_featureScreenAreas = NULL;
1472  m_viewportCubeRange = NULL;
1473 
1474  m_features = new QList<FeaturePosition>(*other.m_features);
1475  m_featureScreenAreas = new QList<FeatureDisplayPosition>(
1476  *other.m_featureScreenAreas);
1477  m_viewportCubeRange = new QPair<QPointF, QPointF>(
1478  *other.m_viewportCubeRange);
1479  }
1480 
1481 
1486  m_sourceViewport = NULL;
1487 
1488  delete m_features;
1489  m_features = NULL;
1490 
1491  delete m_featureScreenAreas;
1492  m_featureScreenAreas = NULL;
1493 
1494  delete m_viewportCubeRange;
1495  m_viewportCubeRange = NULL;
1496  }
1497 
1498 
1505  for (int i = 0; i < m_features->count(); i++) {
1506  (*m_features)[i].applyExtentType(vectorType);
1507  }
1508  }
1509 
1510 
1518  FeatureNomenclature::Feature feature) {
1519  QString displayName = feature.displayName();
1520 
1521  int foundIndex = -1;
1522  for (int i = 0; foundIndex == -1 && i < m_features->count(); i++) {
1523  if (displayName == m_features->at(i).feature().displayName()) {
1524  foundIndex = i;
1525  }
1526  }
1527 
1528  if (foundIndex != -1) {
1529  m_features->prepend(m_features->takeAt(foundIndex));
1530  m_featureScreenAreas->prepend(m_featureScreenAreas->takeAt(foundIndex));
1531 
1532  // The center() method creates artifacts/displays bad data in the viewport
1533  // ... the old 'cube' before centering stays around.
1534  m_sourceViewport->setScale(m_sourceViewport->scale(),
1535  m_features->first().center().first,
1536  m_features->first().center().second);
1537  m_sourceViewport->viewport()->update();
1538  }
1539  }
1540 
1541 
1551 
1552  for (int i = 0; i < m_features->count(); i++)
1553  featureList.append((*m_features)[i].feature());
1554 
1555  return featureList;
1556  }
1557 
1558 
1567 
1568  for (int i = 0; i < m_features->count(); i++)
1569  positionList.append((*m_features)[i]);
1570 
1571  return positionList;
1572  }
1573 
1574 
1580  MdiCubeViewport *
1582  return m_sourceViewport;
1583  }
1584 
1585 
1595  QPainter *painter, bool showVectors, VectorType vectorType, bool approvedOnly) const {
1596 
1597  if (viewportCubeRange() == *m_viewportCubeRange) {
1598 
1599  for (int i = 0; i < m_features->count() &&
1600  i < m_featureScreenAreas->count(); i++) {
1601 
1602  FeatureNomenclature::Feature feature = (*m_features)[i].feature();
1603  FeatureDisplayPosition pos = (*m_featureScreenAreas)[i];
1604  QRect textArea = pos.textArea();
1605  QRect fullArea = pos.displayArea();
1606 
1607  if (!fullArea.isNull() && fullArea != textArea && showVectors) {
1608  // For efficiency's sake
1609  QRect startRect = textArea.adjusted(-2, -2, 2, 2);
1610  QLineF topTextBorder(startRect.topLeft(), startRect.topRight());
1611  QLineF rightTextBorder(startRect.topRight(), startRect.bottomRight());
1612  QLineF bottomTextBorder(startRect.bottomLeft(),
1613  startRect.bottomRight());
1614  QLineF leftTextBorder(startRect.topLeft(), startRect.bottomLeft());
1615 
1616  QList<QLine> vectors;
1617 
1618  if (vectorType != Box) {
1619  foreach (QPoint point, pos.edgePoints()) {
1620  QLineF fullVector(textArea.center(), point);
1621  QPoint newVectorStart;
1622 
1623  QPointF intersectionPoint;
1624 
1625  if (point.y() < textArea.top()) {
1626  if (topTextBorder.intersect(fullVector, &intersectionPoint) ==
1627  QLineF::BoundedIntersection) {
1628  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1629  qRound(intersectionPoint.y()));
1630  }
1631  }
1632 
1633  if (point.x() > textArea.right()) {
1634  if (rightTextBorder.intersect(fullVector, &intersectionPoint) ==
1635  QLineF::BoundedIntersection) {
1636  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1637  qRound(intersectionPoint.y()));
1638  }
1639  }
1640 
1641  if (point.y() > textArea.bottom()) {
1642  if (bottomTextBorder.intersect(fullVector, &intersectionPoint) ==
1643  QLineF::BoundedIntersection) {
1644  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1645  qRound(intersectionPoint.y()));
1646  }
1647  }
1648 
1649  if (point.x() < textArea.left()) {
1650  if (leftTextBorder.intersect(fullVector, &intersectionPoint) ==
1651  QLineF::BoundedIntersection) {
1652  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1653  qRound(intersectionPoint.y()));
1654  }
1655  }
1656 
1657  if (!newVectorStart.isNull() &&
1658  QLineF(newVectorStart, point).length() > 10) {
1659  vectors.append(QLine(newVectorStart, point));
1660  }
1661  }
1662 
1663  foreach (QLine vector, vectors) {
1664  painter->drawLine(vector);
1665 
1666  //For 4 or 8 arrows
1667  Angle normalAngle(-1 * QLineF(vector).normalVector().angle(),
1668  Angle::Degrees);
1669 
1670  int magnitude = 10;
1671  double deltaX = magnitude * cos(normalAngle.radians());
1672  double deltaY = magnitude * sin(normalAngle.radians());
1673 
1674  QPoint normalStart(vector.x2() + deltaX, vector.y2() + deltaY);
1675  QPoint normalEnd(vector.x2() - deltaX, vector.y2() - deltaY);
1676  painter->drawLine(normalStart, normalEnd);
1677 
1678  Angle arrowheadAngle(30, Angle::Degrees);
1679  Angle vectorAngle(-1 * QLineF(vector).angle(), Angle::Degrees);
1680  Angle leftHead = vectorAngle - arrowheadAngle;
1681  Angle rightHead = vectorAngle + arrowheadAngle;
1682 
1683  int arrowheadMag = 10;
1684  deltaX = arrowheadMag * cos(leftHead.radians());
1685  deltaY = arrowheadMag * sin(leftHead.radians());
1686  painter->drawLine(
1687  vector.p2(), vector.p2() - QPoint(deltaX, deltaY));
1688 
1689  deltaX = arrowheadMag * cos(rightHead.radians());
1690  deltaY = arrowheadMag * sin(rightHead.radians());
1691  painter->drawLine(
1692  vector.p2(), vector.p2() - QPoint(deltaX, deltaY));
1693  }
1694  }
1695  else {
1696  // vector type == Box, draw the box
1697  if (pos.edgePoints().count() == 4) {
1698  QPolygon boundingPoly(pos.edgePoints().toVector());
1699  painter->drawPolygon(boundingPoly);
1700  }
1701  }
1702  }
1703 
1704  if (!textArea.isNull()) {
1705  QString featureName = feature.name();
1706  painter->drawText(textArea, featureName);
1707  }
1708  }
1709  }
1710  }
1711 
1712 
1722  FeatureNomenclatureTool *tool, QPoint p, Qt::MouseButton s) {
1723  for (int i = 0; i < m_featureScreenAreas->count(); i++) {
1724  QRect screenArea = m_featureScreenAreas->at(i).displayArea();
1725 
1726  if (screenArea.contains(p)) {
1727  FeatureNomenclature::Feature feature = m_features->at(i).feature();
1728  if (s == Qt::LeftButton) {
1729  tool->showFeatureDetails(feature);
1730  }
1731  else if (s == Qt::RightButton) {
1732  QMenu menu;
1733 
1734  QAction *title = menu.addAction(feature.displayName());
1735  title->setEnabled(false);
1736  menu.addSeparator();
1737 
1738  QAction *details = menu.addAction("Details...");
1739  QAction *website = menu.addAction("Website...");
1740  menu.addSeparator();
1741  QAction *center = menu.addAction("Center on Feature");
1742  QAction *copyUrl = menu.addAction("Copy Website URL");
1743 
1744  // This manual adjustment of the pos is a hack... probably due to our
1745  // cursors.
1746  QAction *selectedAction = menu.exec(
1747  m_sourceViewport->viewport()->mapToGlobal(p) +
1748  QPoint(0, 20), details);
1749 
1750  if (selectedAction == details) {
1751  tool->showFeatureDetails(feature);
1752  }
1753  else if (selectedAction == website) {
1754  tool->showFeatureWebsite(feature);
1755  }
1756  else if (selectedAction == center) {
1757  tool->centerOnFeature(m_sourceViewport, feature);
1758  }
1759  else if (selectedAction == copyUrl) {
1760  QApplication::clipboard()->setText(
1761  feature.referenceUrl().toString());
1762  }
1763  }
1764  }
1765  }
1766  }
1767 
1768 
1776  FeatureNomenclatureTool *tool) {
1777  m_featureScreenAreas->clear();
1778 
1779  QFont fontToUse;
1780  fontToUse.setPointSize(tool->fontSize());
1781  QFontMetrics fontMetrics(fontToUse);
1782 
1783  // Don't draw text that overlaps existing text.
1784  QList<QRect> rectsToAvoid;
1785 
1786  for (int i = 0; i < m_features->count(); i++) {
1787  FeatureNomenclature::Feature feature = (*m_features)[i].feature();
1788 
1789  m_featureScreenAreas->append(FeatureDisplayPosition());
1790 
1791  if ( !tool->m_showApprovedOnly ||
1792  (tool->m_showApprovedOnly && feature.status() == FeatureNomenclature::Approved) ) {
1793 
1794  double sample = (*m_features)[i].center().first;
1795  double line = (*m_features)[i].center().second;
1796 
1797  int viewportX;
1798  int viewportY;
1799  m_sourceViewport->cubeToViewport(sample, line,
1800  viewportX, viewportY);
1801 
1802  QString featureName = feature.name();
1803  QRect textDisplayArea(QPoint(viewportX, viewportY),
1804  QSize(fontMetrics.width(featureName) + 4,
1805  fontMetrics.height()));
1806  // Center the text on the viewportX,Y instead of starting it there...
1807  textDisplayArea.moveTopLeft(textDisplayArea.topLeft() -
1808  QPoint(textDisplayArea.width() / 2, textDisplayArea.height() / 2));
1809 
1810  bool canDisplay = false;
1811  if (textDisplayArea.left() < m_sourceViewport->width() &&
1812  textDisplayArea.right() > 0 &&
1813  textDisplayArea.top() < m_sourceViewport->height() &&
1814  textDisplayArea.bottom() > 0) {
1815  canDisplay = true;
1816  }
1817 
1818  QRect fullDisplayArea = textDisplayArea;
1819  QPair<double, double> edge;
1820  QList<QPoint> edgeScreenPoints;
1821 
1822  if (canDisplay && tool->vectorType() != None) {
1823  QList< QPair<double, double> > edges = (*m_features)[i].edges();
1824  foreach (edge, edges) {
1825  m_sourceViewport->cubeToViewport(edge.first, edge.second,
1826  viewportX, viewportY);
1827  edgeScreenPoints.append(QPoint(viewportX, viewportY));
1828  }
1829 
1830  if (tool->vectorType() != Box) {
1831  foreach (QPoint screenPoint, edgeScreenPoints) {
1832  fullDisplayArea = fullDisplayArea.united(
1833  QRect(screenPoint.x() - 3, screenPoint.y() - 3, 6, 6));
1834  }
1835  }
1836  else if (edges.count() == 4) {
1837 
1838  QPolygon boundingPoly(edgeScreenPoints.toVector());
1839 
1840  if (boundingPoly.intersected(textDisplayArea) == QPolygon(textDisplayArea, true)) {
1841  fullDisplayArea = boundingPoly.boundingRect();
1842  }
1843  }
1844  }
1845 
1846  if (canDisplay) {
1847  // If we intersect another feature, do not draw
1848  foreach (QRect rectToAvoid, rectsToAvoid) {
1849  if (canDisplay && fullDisplayArea.intersects(rectToAvoid)) {
1850  canDisplay = false;
1851  }
1852  }
1853  }
1854 
1855  if (canDisplay) {
1856  rectsToAvoid.append(fullDisplayArea);
1857  m_featureScreenAreas->last() = FeatureDisplayPosition(textDisplayArea, fullDisplayArea,
1858  edgeScreenPoints);
1859  }
1860  }
1861  *m_viewportCubeRange = viewportCubeRange();
1862  }
1863  }
1864 
1865 
1872  ViewportFeatureDisplay &other) {
1873  std::swap(m_sourceViewport, other.m_sourceViewport);
1874  std::swap(m_features, other.m_features);
1875  std::swap(m_featureScreenAreas, other.m_featureScreenAreas);
1876  std::swap(m_viewportCubeRange, other.m_viewportCubeRange);
1877  }
1878 
1879 
1889  const ViewportFeatureDisplay &rhs) {
1890  ViewportFeatureDisplay copy(rhs);
1891  swap(copy);
1892  return *this;
1893  }
1894 
1895 
1905  const {
1906  QPointF minValues;
1907  sourceViewport()->viewportToCube(1, 1, minValues.rx(), minValues.ry());
1908 
1909  QPointF maxValues;
1910  sourceViewport()->viewportToCube(sourceViewport()->viewport()->width(),
1911  sourceViewport()->viewport()->height(),
1912  maxValues.rx(), maxValues.ry());
1913 
1914  return QPair<QPointF, QPointF>(minValues, maxValues);
1915  }
1916 }
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::m_edgePoints
QList< QPoint > * m_edgePoints
The viewport screen pixel points which the edges are at.
Definition: FeatureNomenclatureTool.h:258
Isis::FeatureNomenclatureTool::fontColor
QColor fontColor() const
What is the font color to use?
Definition: FeatureNomenclatureTool.cpp:161
Isis::FeatureNomenclatureTool::VectorType
VectorType
Enumeration of extent vector typess.
Definition: FeatureNomenclatureTool.h:62
Isis::Angle::Degrees
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:56
Isis::FeatureNomenclature::Feature::status
IAUStatus status() const
Definition: FeatureNomenclature.cpp:740
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::handleViewChanged
void handleViewChanged(FeatureNomenclatureTool *tool)
The display options or area on the viewport has changed.
Definition: FeatureNomenclatureTool.cpp:1775
Isis::FeatureNomenclatureTool::showFeatureDetails
void showFeatureDetails(FeatureNomenclature::Feature)
Show a dialog with full feature details of a given feature.
Definition: FeatureNomenclatureTool.cpp:814
Isis::FeatureNomenclatureTool::FeaturePosition::m_centerSample
double m_centerSample
The cube sample position of the feature center, Null if !isValid()
Definition: FeatureNomenclatureTool.h:210
Isis::MdiCubeViewport
Cube display widget for certain Isis MDI applications.
Definition: MdiCubeViewport.h:39
QWidget
Isis::FeatureNomenclatureTool::updateTool
void updateTool()
Updates the state of the current tool.
Definition: FeatureNomenclatureTool.cpp:404
QProgressBar
Isis::FeatureNomenclature::Feature::referenceUrl
QUrl referenceUrl() const
Definition: FeatureNomenclature.cpp:722
Isis::Cube::fileName
virtual QString fileName() const
Returns the opened cube's filename.
Definition: Cube.cpp:1563
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::features
QList< FeatureNomenclature::Feature > features()
Get a list of features available on this viewport.
Definition: FeatureNomenclatureTool.cpp:1549
Isis::UniversalGroundMap
Universal Ground Map.
Definition: UniversalGroundMap.h:69
Isis::FeatureNomenclatureTool::removeFeatureDisplay
void removeFeatureDisplay(MdiCubeViewport *vp)
Remove knowledge of features on the given viewport.
Definition: FeatureNomenclatureTool.cpp:801
Isis::FeatureNomenclatureTool::centerOnSelectedFeature
void centerOnSelectedFeature()
Center the relevent viewport (and any viewports linked to it) on the feature selected in the feature ...
Definition: FeatureNomenclatureTool.cpp:413
QList
This is free and unencumbered software released into the public domain.
Definition: BoxcarCachingAlgorithm.h:13
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::FeatureNomenclatureTool::Arrows4
@ Arrows4
When using this vector (extent) type, 4 arrows will be drawn out from the text of the feature.
Definition: FeatureNomenclatureTool.h:83
Isis::Tool::cubeViewportList
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
Isis::FeatureNomenclature
Feature nomenclature database querier.
Definition: FeatureNomenclature.h:51
Isis::Tool::screenPixelsChanged
virtual void screenPixelsChanged()
This is called when actions change which pixels from the cube are displayed.
Definition: Tool.h:148
Isis::FeatureNomenclatureTool::m_showApprovedOnly
bool m_showApprovedOnly
Only show IAU approved features.
Definition: FeatureNomenclatureTool.h:380
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::m_viewportCubeRange
QPair< QPointF, QPointF > * m_viewportCubeRange
A check to make sure the cube viewport is in the correct state for painting.
Definition: FeatureNomenclatureTool.h:319
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FeatureNomenclatureTool::onToolActivated
void onToolActivated()
When this tool is activated (clicked on in the tool bar), turn ourselves on immediately.
Definition: FeatureNomenclatureTool.cpp:524
Isis::Tool
Base class for the Qisis tools.
Definition: Tool.h:67
Isis::FeatureNomenclatureTool::m_disclaimerBtn
QPointer< QPushButton > m_disclaimerBtn
This is the 'Disclaimer' button in this tool's tool bar.
Definition: FeatureNomenclatureTool.h:343
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::FeatureNomenclatureTool::menuName
QString menuName() const
This is the name of the menu that should be passed into "addTo()".
Definition: FeatureNomenclatureTool.cpp:291
Isis::FeatureNomenclatureTool::~FeatureNomenclatureTool
~FeatureNomenclatureTool()
Cleans up memory allocated by this tool.
Definition: FeatureNomenclatureTool.cpp:98
Isis::FeatureNomenclature::Feature::displayName
QString displayName() const
Definition: FeatureNomenclature.cpp:449
QMenu
Isis::FeatureNomenclatureTool::setFontColor
void setFontColor(QColor color)
Set the color to use for drawing on the viewport.
Definition: FeatureNomenclatureTool.cpp:215
Isis::FeatureNomenclatureTool::showApprovedOnly
bool showApprovedOnly() const
Show approved features only?
Definition: FeatureNomenclatureTool.cpp:181
Isis::Tool::toolIconDir
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:113
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::m_features
QList< FeaturePosition > * m_features
The features on the image in m_sourceViewport.
Definition: FeatureNomenclatureTool.h:311
Isis::FeatureNomenclatureTool::FeatureDisplayPosition
A named feature's position in a viewport.
Definition: FeatureNomenclatureTool.h:236
Isis::FeatureNomenclatureTool::findNomenclatureStateChanged
void findNomenclatureStateChanged(int)
The 'Name Features' check box has changed state.
Definition: FeatureNomenclatureTool.cpp:487
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::swap
void swap(FeatureDisplayPosition &other)
Swap member data with another instance of this class.
Definition: FeatureNomenclatureTool.cpp:1389
Isis::FeatureNomenclature::Feature::controlNet
QString controlNet() const
Definition: FeatureNomenclature.cpp:431
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::FeatureNomenclature::Feature::target
QString target() const
Definition: FeatureNomenclature.cpp:465
Isis::FeatureNomenclatureTool::defaultEnabled
bool defaultEnabled() const
Is this tool enabled by default? (i.e.
Definition: FeatureNomenclatureTool.cpp:151
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::operator=
ViewportFeatureDisplay & operator=(const ViewportFeatureDisplay &rhs)
Copy the data of rhs into *this.
Definition: FeatureNomenclatureTool.cpp:1888
Isis::FeatureNomenclatureTool::FeatureNomenclatureTool
FeatureNomenclatureTool(QWidget *parent)
This instantiates a FeatureNomenclatureTool.
Definition: FeatureNomenclatureTool.cpp:46
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::~FeatureDisplayPosition
~FeatureDisplayPosition()
Free the allocated memory.
Definition: FeatureNomenclatureTool.cpp:1337
Isis::FeatureNomenclatureTool::None
@ None
When using this vector (extent) type, no extents will be drawn.
Definition: FeatureNomenclatureTool.h:66
Isis::FeatureNomenclatureTool::m_foundNomenclature
QList< ViewportFeatureDisplay > * m_foundNomenclature
The nomenclature that has been identified, one for each viewport.
Definition: FeatureNomenclatureTool.h:351
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::m_fullDisplayRect
QRect * m_fullDisplayRect
The viewport screen pixel rect which the entire display will use.
Definition: FeatureNomenclatureTool.h:256
Isis::FeatureNomenclatureTool::addTo
void addTo(QMenu *menu)
Add the 'Show Nomenclature' option to the options menu.
Definition: FeatureNomenclatureTool.cpp:116
Isis::FeatureNomenclatureTool::setDefaultEnabled
void setDefaultEnabled(bool defaultEnabled)
Set whether this tool is enabled by default.
Definition: FeatureNomenclatureTool.cpp:201
Isis::CubeViewport::universalGroundMap
UniversalGroundMap * universalGroundMap() const
Definition: CubeViewport.h:353
Isis::FeatureNomenclature::Feature
A named feature on a target.
Definition: FeatureNomenclature.h:117
Isis::FeatureNomenclatureTool::Arrows8
@ Arrows8
When using this vector (extent) type, 8 arrows will be drawn out from the text of the feature.
Definition: FeatureNomenclatureTool.h:101
QComboBox
Isis::CubeViewport::camera
Camera * camera() const
Definition: CubeViewport.h:348
Isis::FeatureNomenclatureTool::setFontSize
void setFontSize(int newFontSize)
Set the font point size to use for drawing text on the viewport.
Definition: FeatureNomenclatureTool.cpp:232
Isis::FeatureNomenclatureTool::showFeatureWebsite
void showFeatureWebsite(FeatureNomenclature::Feature)
Show a web view pointed to the feature's web page.
Definition: FeatureNomenclatureTool.cpp:847
Isis::Longitude
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:40
Isis::Spice::target
virtual Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1368
Isis::FeatureNomenclatureTool::m_fontColor
QColor * m_fontColor
The color to use when drawing on the viewport.
Definition: FeatureNomenclatureTool.h:372
Isis::FeatureNomenclatureTool::FeaturePosition::center
QPair< double, double > center() const
Get the center sample/line position of the feature.
Definition: FeatureNomenclatureTool.cpp:1122
Isis::FeatureNomenclatureTool::FeaturePosition::m_centerLine
double m_centerLine
The cube line position of the feature center, Null if !isValid()
Definition: FeatureNomenclatureTool.h:208
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::FeatureDisplayPosition
FeatureDisplayPosition()
Instantiate a blank feature display position.
Definition: FeatureNomenclatureTool.cpp:1285
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::edgePoints
QList< QPoint > edgePoints() const
Get the edge screen pixel points in viewport screen coordinates that circle the feature.
Definition: FeatureNomenclatureTool.cpp:1377
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::operator=
FeatureDisplayPosition & operator=(const FeatureDisplayPosition &rhs)
Assign the state of rhs to this.This is exception-safe.
Definition: FeatureNomenclatureTool.cpp:1405
Isis::FeatureNomenclatureTool::setShowApprovedOnly
void setShowApprovedOnly(bool approvedOnly)
Set whether to show approved features and exclude unapproved features.
Definition: FeatureNomenclatureTool.cpp:250
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::paint
void paint(QPainter *painter, bool showVectors, VectorType vectorType, bool approvedOnly) const
Paint features onto the viewport.
Definition: FeatureNomenclatureTool.cpp:1594
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::featurePositions
QList< FeaturePosition > featurePositions()
Get the list of feature positions for a given display.
Definition: FeatureNomenclatureTool.cpp:1565
Isis::FeatureNomenclatureTool::FeaturePosition
A named feature's position in a cube.
Definition: FeatureNomenclatureTool.h:188
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::FeatureNomenclatureTool::FeaturePosition::applyExtentType
void applyExtentType(VectorType vectorType)
Applies the type of extents to the feature.
Definition: FeatureNomenclatureTool.cpp:1158
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::FeatureNomenclatureTool::FeaturePosition::m_gmap
UniversalGroundMap * m_gmap
The map used to determine the sample, line pair from a lat, lon pair.
Definition: FeatureNomenclatureTool.h:213
Isis::FeatureNomenclature::Approved
@ Approved
When this status is assigned to a feature, the displayed status will be "Adopted by the IAU" and the ...
Definition: FeatureNomenclature.h:67
Isis::FeatureNomenclatureTool::featuresForViewportFound
void featuresForViewportFound(MdiCubeViewport *vp)
Move the features from a searching state to a found state for the given viewport.
Definition: FeatureNomenclatureTool.cpp:569
Isis::FeatureNomenclatureTool::viewportFeaturesFound
bool viewportFeaturesFound(MdiCubeViewport *vp) const
Test if features have already been found for a given viewport.
Definition: FeatureNomenclatureTool.cpp:960
Isis::FeatureNomenclatureTool::toolStateChanged
void toolStateChanged()
This should be called any time this tool's enabled or searching state could have changed.
Definition: FeatureNomenclatureTool.cpp:858
Isis::FeatureNomenclature::featureDiameterGreaterThan
static bool featureDiameterGreaterThan(const FeatureNomenclature::Feature &lhs, const FeatureNomenclature::Feature &rhs)
Compare the diameter of two features.
Definition: FeatureNomenclature.cpp:193
Isis::FeatureNomenclatureTool::Box
@ Box
When using this vector (extent) type, 4 arrows will be drawn out from the text of the feature.
Definition: FeatureNomenclatureTool.h:110
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::m_sourceViewport
MdiCubeViewport * m_sourceViewport
The viewport this display is working with; we paint onto this viewport and react to events on this vi...
Definition: FeatureNomenclatureTool.h:309
Isis::FeatureNomenclatureTool::writeSettings
void writeSettings()
Write out this tool's preserved state between runs.
Definition: FeatureNomenclatureTool.cpp:1012
Isis::FeatureNomenclatureTool::m_nomenclatureOptionsBtn
QPointer< QPushButton > m_nomenclatureOptionsBtn
This is the 'Tool Options' button in this tool's tool bar.
Definition: FeatureNomenclatureTool.h:341
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::m_textRect
QRect * m_textRect
The viewport screen pixel rect which the text will consume.
Definition: FeatureNomenclatureTool.h:254
Isis::FeatureNomenclatureTool::FeaturePosition::m_feature
FeatureNomenclature::Feature m_feature
The feature for which we're encapsulating a viewport position.
Definition: FeatureNomenclatureTool.h:221
Isis::FeatureNomenclature::Feature::name
QString name() const
Definition: FeatureNomenclature.cpp:413
Isis::FeatureNomenclatureTool::m_nomenclatureSearchers
QMap< MdiCubeViewport *, FeatureNomenclature * > * m_nomenclatureSearchers
The nomenclature being queried currently, one for each viewport that has no found nomenclature.
Definition: FeatureNomenclatureTool.h:357
Isis::FeatureNomenclatureTool::FeaturePosition::~FeaturePosition
~FeaturePosition()
Cleans up allocated memory.
Definition: FeatureNomenclatureTool.cpp:1097
Isis::FeatureNomenclatureTool::m_nomenclatureEnabled
bool m_nomenclatureEnabled
Do we find and display nomenclature? This corresponds to the 'Name Features' check box and the 'Show ...
Definition: FeatureNomenclatureTool.h:364
Isis::FeatureNomenclatureTool::FeaturePosition::feature
FeatureNomenclature::Feature & feature()
Get the feature associated with this feature position.
Definition: FeatureNomenclatureTool.cpp:1145
Isis::NomenclatureToolConfigDialog
Configure user's settings for the nomenclature tool.
Definition: NomenclatureToolConfigDialog.h:28
Isis::FeatureNomenclatureTool::m_extentType
VectorType m_extentType
How we need to draw extents (if at all)
Definition: FeatureNomenclatureTool.h:378
Isis::FeatureNomenclatureTool
Display nomenclature on MDI Cube Viewports.
Definition: FeatureNomenclatureTool.h:56
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::~ViewportFeatureDisplay
~ViewportFeatureDisplay()
Cleans up memory allocated by this feature display.
Definition: FeatureNomenclatureTool.cpp:1485
Isis::MdiCubeViewport::isLinked
bool isLinked() const
Is the viewport linked with other viewports.
Definition: MdiCubeViewport.h:50
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::displayArea
QRect displayArea() const
Get the screen pixel rect in viewport screen coordinates that encapsulates the entire feature.
Definition: FeatureNomenclatureTool.cpp:1366
Isis::FeatureNomenclatureTool::fontSize
int fontSize() const
Retrieve the font size of the features in this tool.
Definition: FeatureNomenclatureTool.cpp:171
Isis::FeatureNomenclatureTool::m_nomenclatureCenterBtn
QPointer< QPushButton > m_nomenclatureCenterBtn
This is the 'Center' button in this tool's tool bar.
Definition: FeatureNomenclatureTool.h:339
Isis::FeatureNomenclatureTool::readSettings
void readSettings()
Read this tool's preserved state.
Definition: FeatureNomenclatureTool.cpp:990
Isis::FeatureNomenclatureTool::FeaturePosition::FeaturePosition
FeaturePosition()
Instiantiates a feature position with no data.
Definition: FeatureNomenclatureTool.cpp:1028
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::swap
void swap(ViewportFeatureDisplay &other)
Swap *this and other's member data in an exception-free way.
Definition: FeatureNomenclatureTool.cpp:1871
Isis::Angle
Defines an angle and provides unit conversions.
Definition: Angle.h:45
Isis::FeatureNomenclatureTool::nomenclaturePositionsOutdated
void nomenclaturePositionsOutdated()
Update the screen coordinates of the named features because the viewport has changed it's mappings.
Definition: FeatureNomenclatureTool.cpp:510
Isis::FeatureNomenclatureTool::m_findNomenclatureCheckBox
QPointer< QCheckBox > m_findNomenclatureCheckBox
This is the 'Name Features' check box when this tool is active.
Definition: FeatureNomenclatureTool.h:327
Isis::FeatureNomenclatureTool::featuresIdentified
void featuresIdentified(FeatureNomenclature *)
A feature nomenclature has finished querying...
Definition: FeatureNomenclatureTool.cpp:463
Isis::FeatureNomenclatureTool::FeaturePosition::isValid
bool isValid() const
Test if sample/line coordinates could be found for this feature.
Definition: FeatureNomenclatureTool.cpp:1112
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::FeatureNomenclatureTool::FeaturePosition::m_featureEdgeLineSamples
QList< QPair< double, double > > * m_featureEdgeLineSamples
The pair is cube sample, line (first and second) respectively.
Definition: FeatureNomenclatureTool.h:219
Isis::FeatureNomenclatureTool::FeaturePosition::swap
void swap(FeaturePosition &other)
Trade member data with other.
Definition: FeatureNomenclatureTool.cpp:1245
Isis::FeatureNomenclatureTool::vectorType
VectorType vectorType() const
Draw vectors to the extents of features?
Definition: FeatureNomenclatureTool.cpp:191
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::centerFeature
void centerFeature(FeatureNomenclature::Feature)
Center the viewport on this feature.
Definition: FeatureNomenclatureTool.cpp:1517
Isis::FeatureNomenclatureTool::createToolBarWidget
QWidget * createToolBarWidget(QStackedWidget *parent)
Creates the widget that goes on the tool bar when this tool is active.
Definition: FeatureNomenclatureTool.cpp:303
Isis::ToolPad
Definition: ToolPad.h:14
Isis::FeatureNomenclatureTool::viewportFeatureDisplay
ViewportFeatureDisplay * viewportFeatureDisplay(MdiCubeViewport *vp)
Map from viewport to feature display.
Definition: FeatureNomenclatureTool.cpp:923
Isis::FeatureNomenclatureTool::paintViewport
void paintViewport(MdiCubeViewport *vp, QPainter *painter)
Paint features on the given viewport.
Definition: FeatureNomenclatureTool.cpp:132
Isis::FeatureNomenclatureTool::FeaturePosition::edges
QList< QPair< double, double > > edges() const
Get the edge sample/line positions of the feature.
Definition: FeatureNomenclatureTool.cpp:1134
Isis::Angle::isValid
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
Definition: Angle.cpp:95
Isis::FeatureNomenclatureTool::showDisclaimer
void showDisclaimer()
Show the user our nomenclature disclaimer and make note that we have shown the disclaimer.
Definition: FeatureNomenclatureTool.cpp:534
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay
The feature display on a single viewport.
Definition: FeatureNomenclatureTool.h:275
Isis::FeatureNomenclatureTool::FeatureDisplayPosition::textArea
QRect textArea() const
Get the screen pixel rect in viewport screen coordinates that ought to be filled with the textual nam...
Definition: FeatureNomenclatureTool.cpp:1355
QPair< double, double >
Isis::FeatureNomenclatureTool::mouseButtonRelease
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
This handles a mouse release on one of the cube viewports when this tool is active.
Definition: FeatureNomenclatureTool.cpp:391
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::viewportCubeRange
QPair< QPointF, QPointF > viewportCubeRange() const
Get the min/max cube line/sample positions of the viewport.
Definition: FeatureNomenclatureTool.cpp:1904
Isis::FeatureNomenclatureTool::m_disclaimerText
QString m_disclaimerText
The (HTML) contents of the disclaimer to show the user.
Definition: FeatureNomenclatureTool.h:367
Isis::FeatureNomenclatureTool::configure
void configure()
Give a configuration dialog for the options available in this tool.
Definition: FeatureNomenclatureTool.cpp:432
Isis::FeatureNomenclatureTool::m_action
QPointer< QAction > m_action
This is the 'Show Nomenclature' toggleable action in the options menu.
Definition: FeatureNomenclatureTool.h:324
Isis::FeatureNomenclature::Feature::cleanName
QString cleanName() const
Definition: FeatureNomenclature.cpp:421
Isis::FeatureNomenclatureTool::m_defaultEnabled
bool m_defaultEnabled
Do we turn ourselves on immediately?
Definition: FeatureNomenclatureTool.h:374
Isis::FeatureNomenclatureTool::m_foundFeaturesCombo
QPointer< QComboBox > m_foundFeaturesCombo
This combo box lists all of the found features and their viewports.
Definition: FeatureNomenclatureTool.h:337
Isis::FeatureNomenclatureTool::rebuildFeaturesCombo
void rebuildFeaturesCombo()
Rebuild m_foundFeaturesCombo's data from scratch.
Definition: FeatureNomenclatureTool.cpp:783
Isis::FeatureNomenclatureTool::FeaturePosition::operator=
FeaturePosition & operator=(const FeaturePosition &rhs)
Assign rhs to this.
Definition: FeatureNomenclatureTool.cpp:1263
QMap
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:22
Isis::FeatureNomenclatureTool::toolPadAction
QAction * toolPadAction(ToolPad *pad)
Add this tool's action to the toolpad.
Definition: FeatureNomenclatureTool.cpp:364
Isis::FeatureNomenclatureTool::m_disclaimedAlready
bool m_disclaimedAlready
Have we ever shown the user our disclaimer?
Definition: FeatureNomenclatureTool.h:376
Isis::FeatureNomenclatureTool::findMissingNomenclature
void findMissingNomenclature()
Update this tool's nomenclature data based on this tool's enabled state and the current viewport list...
Definition: FeatureNomenclatureTool.cpp:695
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::handleMouseClicked
void handleMouseClicked(FeatureNomenclatureTool *tool, QPoint p, Qt::MouseButton s)
Handle a mouse click event on the viewport.
Definition: FeatureNomenclatureTool.cpp:1721
Isis::FeatureNomenclatureTool::m_fontSize
int m_fontSize
The font size to use when naming features.
Definition: FeatureNomenclatureTool.h:370
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::applyExtentType
void applyExtentType(VectorType vectorType)
Apply the extent type to all of the features for the source viewport.
Definition: FeatureNomenclatureTool.cpp:1504
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::ViewportFeatureDisplay
ViewportFeatureDisplay()
Create a blank feature display.
Definition: FeatureNomenclatureTool.cpp:1416
QDialog
Isis::FeatureNomenclature::Feature::toWidget
QWidget * toWidget() const
This converts the data in this feature to a widget.
Definition: FeatureNomenclature.cpp:259
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::sourceViewport
MdiCubeViewport * sourceViewport() const
Get the viewport associated with this feature display.
Definition: FeatureNomenclatureTool.cpp:1581
Isis::FeatureNomenclatureTool::centerOnFeature
void centerOnFeature(MdiCubeViewport *vp, FeatureNomenclature::Feature)
Center the given and any linked viewports (which contain the same feature) on the given feature.
Definition: FeatureNomenclatureTool.cpp:550
Isis::UniversalGroundMap::GroundRange
bool GroundRange(Cube *cube, Latitude &minLat, Latitude &maxLat, Longitude &minLon, Longitude &maxLon, bool allowEstimation=true)
Find the lat/lon range of the image.
Definition: UniversalGroundMap.cpp:320
Isis::FeatureNomenclatureTool::ViewportFeatureDisplay::m_featureScreenAreas
QList< FeatureDisplayPosition > * m_featureScreenAreas
The visible features on the image in m_sourceViewport.
Definition: FeatureNomenclatureTool.h:313
QAction
Isis::CubeViewport::cube
Cube * cube() const
Definition: CubeViewport.h:338
Isis::FeatureNomenclatureTool::featureSelected
void featureSelected()
This handles a feature being selected in the feature list combo box.
Definition: FeatureNomenclatureTool.cpp:447
Isis::FeatureNomenclatureTool::viewportDone
void viewportDone(MdiCubeViewport *vp)
Finalize the search results for the given viewport.
Definition: FeatureNomenclatureTool.cpp:892
Isis::FeatureNomenclatureTool::m_queryingProgress
QPointer< QProgressBar > m_queryingProgress
This is a busy indicator that is visible when queries are out to the nomenclature database.
Definition: FeatureNomenclatureTool.h:348
Isis::Tool::cubeViewport
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:197
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::FeatureNomenclatureTool::setVectorType
void setVectorType(VectorType show)
Set whether to draw vectors from the feature center to the feature extents on the viewport.
Definition: FeatureNomenclatureTool.cpp:269
Isis::FeatureNomenclatureTool::viewportsWithFoundNomenclature
QList< MdiCubeViewport * > viewportsWithFoundNomenclature()
Get a list of viewports with found nomenclature.
Definition: FeatureNomenclatureTool.cpp:973
Isis::Target::name
QString name() const
Return target name.
Definition: Target.cpp:516
Isis::CubeViewport::projection
Projection * projection() const
Definition: CubeViewport.h:343
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:16:26