Isis 3.0 Programmer Reference
Back | Home
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 #if defined(__APPLE__)
21 #include <QtWebEngineWidgets/QWebEngineView>
22 #else
23 #include <QWebEngineView>
24 #endif
25 
26 #include <geos/geom/Coordinate.h>
27 #include <geos/geom/CoordinateSequence.h>
28 #include <geos/geom/MultiPolygon.h>
29 
30 #include "Distance.h"
31 #include "FileName.h"
32 #include "ImagePolygon.h"
33 #include "Latitude.h"
34 #include "Longitude.h"
35 #include "MdiCubeViewport.h"
36 #include "NomenclatureToolConfigDialog.h"
37 #include "PolygonTools.h"
38 #include "Target.h"
39 #include "ToolPad.h"
40 
41 
42 namespace Isis {
43 
50  Tool(parent) {
51  m_foundNomenclature = NULL;
54  m_foundFeaturesCombo = NULL;
57  m_disclaimerBtn = NULL;
58  m_queryingProgress = NULL;
59  m_nomenclatureEnabled = false;
60  m_fontColor = NULL;
61 
65 
66  m_fontSize = 12;
67  m_fontColor = new QColor(237, 170, 171);
68  m_defaultEnabled = false;
69  m_disclaimedAlready = false;
70  m_showApprovedOnly = true;
72 
73  m_disclaimerText = "The nomenclature qview tool will label named features "
74  "in your opened cube files. This tool <strong>requires</strong> an "
75  "active internet connection, projection or camera information, and a "
76  "calculatable ground range to function. The larger the ground range ("
77  "covered area on a planet), the longer it will take to populate the "
78  "nomenclature for a particular cube.<br/><br/>"
79  "<font color='red'>**WARNING**</font> The accuracy of this tool is not "
80  "perfect, features <strong>can and will be mislabeled</strong> if you "
81  "have not properly controlled your images to the control network that "
82  "identifies the latitude/longitude values of a feature. Please use the "
83  "nomenclature website to verify a label is correct for a feature. "
84  "<br/><br/>See the IAU Gazetteer of Planetary Nomenclature website for "
85  "more information.<br/>"
86  "<a href='http://planetarynames.wr.usgs.gov/'>"
87  "http://planetarynames.wr.usgs.gov/</a>";
88 
89  connect(this, SIGNAL(toolActivated()),
90  this, SLOT(onToolActivated()));
91 
92  readSettings();
93 
95  }
96 
97 
102  delete m_foundNomenclature;
103  m_foundNomenclature = NULL;
104 
105  foreach (FeatureNomenclature *nomenclature, *m_nomenclatureSearchers) {
106  delete nomenclature;
107  }
108 
111  }
112 
113 
119  void FeatureNomenclatureTool::addTo(QMenu *menu) {
120  m_action = menu->addAction("Show Nomenclature");
121  m_action->setCheckable(true);
122  m_action->setChecked(m_nomenclatureEnabled);
123 
124  connect(m_action, SIGNAL(triggered(bool)),
125  m_findNomenclatureCheckBox, SLOT(setChecked(bool)));
126  }
127 
128 
136  QPainter *painter) {
139 
140  QFont fontToUse;
141  fontToUse.setPointSize(m_fontSize);
142  painter->setFont(fontToUse);
143  painter->setPen(QPen(*m_fontColor));
144  display.paint(painter, (m_extentType != None), m_extentType, m_showApprovedOnly);
145  }
146  }
147 
148 
155  return m_defaultEnabled;
156  }
157 
158 
165  return *m_fontColor;
166  }
167 
168 
175  return m_fontSize;
176  }
177 
178 
185  return m_showApprovedOnly;
186  }
187 
188 
195  return m_extentType;
196  }
197 
198 
204  void FeatureNomenclatureTool::setDefaultEnabled(bool defaultEnabled) {
205  if (m_defaultEnabled != defaultEnabled) {
207  writeSettings();
208  }
209  }
210 
211 
219  if (*m_fontColor != color) {
220  *m_fontColor = color;
221  writeSettings();
222 
223  foreach (MdiCubeViewport *vp, *cubeViewportList())
224  vp->viewport()->update();
225  }
226  }
227 
228 
235  void FeatureNomenclatureTool::setFontSize(int newFontSize) {
236  if (m_fontSize != newFontSize) {
237  m_fontSize = newFontSize;
238  writeSettings();
239 
241 
242  foreach (MdiCubeViewport *vp, *cubeViewportList())
243  vp->viewport()->update();
244  }
245  }
246 
247 
254  if (m_showApprovedOnly != approvedOnly) {
255  m_showApprovedOnly = approvedOnly;
256  writeSettings();
259 
260  foreach (MdiCubeViewport *vp, *cubeViewportList())
261  vp->viewport()->update();
262  }
263  }
264 
265 
273  if (m_extentType != show) {
274  m_extentType = show;
275  writeSettings();
276 
277  for (int i = 0; i < m_foundNomenclature->count(); i++) {
278  (*m_foundNomenclature)[i].applyExtentType(m_extentType);
279  }
280 
282 
283  foreach (MdiCubeViewport *vp, *cubeViewportList())
284  vp->viewport()->update();
285  }
286  }
287 
288 
295  return "&Options";
296  }
297 
298 
307  QStackedWidget *parent) {
308  QWidget *wrapperWidget = new QWidget;
309 
310  m_findNomenclatureCheckBox = new QCheckBox;
311  m_findNomenclatureCheckBox->setText("Name Features");
313  connect(m_findNomenclatureCheckBox, SIGNAL(stateChanged(int)),
314  this, SLOT(findNomenclatureStateChanged(int)));
315 
316  QLabel *foundFeaturesLabel = new QLabel("Found Features:");
318  m_foundFeaturesCombo->setSizeAdjustPolicy(
319  QComboBox::AdjustToContents);
320  m_foundFeaturesCombo->addItem("");
321 
322  m_nomenclatureCenterBtn = new QPushButton("Center on Feature");
323  m_nomenclatureCenterBtn->setEnabled(false);
324 
325  connect(m_nomenclatureCenterBtn, SIGNAL(clicked()),
326  this, SLOT(centerOnSelectedFeature()));
327 
328  m_nomenclatureOptionsBtn = new QPushButton("Tool Options");
329  connect(m_nomenclatureOptionsBtn, SIGNAL(clicked()),
330  this, SLOT(configure()));
331 
332  m_disclaimerBtn = new QPushButton("Disclaimer");
333  connect(m_disclaimerBtn, SIGNAL(clicked()),
334  this, SLOT(showDisclaimer()));
335 
336  connect(m_foundFeaturesCombo, SIGNAL(currentIndexChanged(int)),
337  this, SLOT(featureSelected()));
338 
340  m_queryingProgress->setObjectName("nomenclatureQueryProgress");
341  m_queryingProgress->setVisible(false);
342  m_queryingProgress->setRange(0, 0);
343 
344  QHBoxLayout *layout = new QHBoxLayout;
345  layout->setMargin(0);
346  layout->addWidget(m_findNomenclatureCheckBox);
347  layout->addWidget(foundFeaturesLabel);
348  layout->addWidget(m_foundFeaturesCombo);
349  layout->addWidget(m_nomenclatureCenterBtn);
350  layout->addWidget(m_nomenclatureOptionsBtn);
351  layout->addWidget(m_disclaimerBtn);
352  layout->addWidget(m_queryingProgress);
353  layout->addStretch(1);
354  wrapperWidget->setLayout(layout);
355  return wrapperWidget;
356  }
357 
358 
368  QAction *action = new QAction(toolpad);
369 
370  action->setIcon(QPixmap(toolIconDir() + "/nomenclature.png"));
371  action->setToolTip("Nomenclature (N)");
372  action->setShortcut(Qt::Key_N);
373  action->setObjectName("nomenclatureToolButton");
374 
375  QString text =
376  "<b>Function:</b> Display nomenclature on the visible images.\n"
377  "<p/><b>Hint:</b> While this tool is active, you can left and right "
378  "click on any of the named features for additional options."
379  "<p/><b>Shortcut:</b> N";
380  action->setWhatsThis(text);
381 
382  return action;
383  }
384 
385 
395  QPoint p, Qt::MouseButton s) {
396  if (m_nomenclatureEnabled &&
399  }
400  }
401 
402 
409  }
410 
411 
417  QVariant variant = m_foundFeaturesCombo->itemData(
418  m_foundFeaturesCombo->currentIndex());
419 
420  if (variant.toMap()["Viewport"].value<MdiCubeViewport *>() != NULL) {
421  MdiCubeViewport *vp =
422  variant.toMap()["Viewport"].value<MdiCubeViewport *>();
424  variant.toMap()["Feature"].value<FeatureNomenclature::Feature>();
425 
426  // We need to find the appropriate viewport also...
427  centerOnFeature(vp, feature);
428  }
429  }
430 
431 
436  NomenclatureToolConfigDialog *configDialog =
438  qobject_cast<QWidget *>(parent()));
439  configDialog->setAttribute(Qt::WA_DeleteOnClose);
440  configDialog->show();
441  }
442 
443 
451  QVariant variant = m_foundFeaturesCombo->itemData(
452  m_foundFeaturesCombo->currentIndex());
453 
454  bool featureSelected =
455  variant.toMap()["Viewport"].value<MdiCubeViewport *>() != NULL;
456 
457  m_nomenclatureCenterBtn->setEnabled(
458  m_nomenclatureEnabled && featureSelected);
459  }
460 
461 
467  FeatureNomenclature *searcher) {
468  MdiCubeViewport *viewport = m_nomenclatureSearchers->key(searcher);
469 
470  // The viewport could have gone away when we were still querying... handle
471  // that case.
472  bool vpValid = cubeViewportList()->contains(viewport);
473  if (vpValid)
474  featuresForViewportFound(viewport);
475 
476  if (m_nomenclatureEnabled) {
477  viewportDone(viewport);
478  }
479 
480  if (vpValid)
481  viewport->viewport()->update();
482  }
483 
484 
491  if (newState == Qt::Unchecked) {
492  m_nomenclatureEnabled = false;
494  }
495  else if (newState == Qt::Checked) {
496  m_nomenclatureEnabled = true;
498 
500  }
501 
502  foreach (MdiCubeViewport *vp, *cubeViewportList())
503  vp->viewport()->update();
504  }
505 
506 
514  if (m_nomenclatureEnabled) {
515 
516  for (int i = 0; i < m_foundNomenclature->count(); i++) {
517  (*m_foundNomenclature)[i].handleViewChanged(this);
518  }
519  }
520  }
521 
522 
528  if (!m_findNomenclatureCheckBox->isChecked())
529  m_findNomenclatureCheckBox->setChecked(true);
530  }
531 
532 
538  QMessageBox::warning(qobject_cast<QWidget *>(parent()),
539  "Nomenclature Disclaimer", m_disclaimerText);
540  m_disclaimedAlready = true;
541  writeSettings();
542  }
543 
544 
555  foreach (MdiCubeViewport *viewport, viewportsWithFoundNomenclature()) {
556  if (viewport == vp ||
557  (vp->isLinked() && viewport->isLinked())) {
558  viewportFeatureDisplay(viewport)->centerFeature(feature);
559  }
560  }
561  }
562 
563 
573  if (vp) {
575  if (m_nomenclatureSearchers->find(vp) != m_nomenclatureSearchers->end()) {
576  if ((*m_nomenclatureSearchers)[vp]->hasResult())
577  features.append((*m_nomenclatureSearchers)[vp]->features());
578  else
579  m_findNomenclatureCheckBox->setChecked(false);
580  }
581 
582  if (!viewportFeatureDisplay(vp)) {
583  m_foundNomenclature->append(ViewportFeatureDisplay(this, vp, features, m_extentType));
584  }
585 
586  features = viewportFeatureDisplay(vp)->features();
587 
588  QProgressDialog updatingFeaturesProgress(
589  tr("Projecting Features for [%1]").arg(vp->cube()->fileName().section('/',-1)),
590  QString(), 0, 100);
591 
592  updatingFeaturesProgress.setWindowModality(Qt::WindowModal);
593 
595 
596  for (int i = 0; i < features.count(); i++) {
597  feature = features[i];
598 
599  int progress = floor(100 * (double)i / (double)features.count());
600 
601  if (progress != updatingFeaturesProgress.value())
602  updatingFeaturesProgress.setValue(progress);
603 
604  if (updatingFeaturesProgress.wasCanceled()) {
605  m_nomenclatureSearchers->clear();
606  m_foundNomenclature->clear();
607  m_foundFeaturesCombo->clear();
608  m_findNomenclatureCheckBox->setChecked(false);
609  break;
610  }
611 
612  if ( !m_showApprovedOnly ||
614 
615  QString displayName = feature.cleanName() +
616  " (" + FileName(vp->cube()->fileName()).name() + ")";
617 
618  QString targetName = feature.target().toUpper();
619 
620  // never insert above the blank (at 0)
621  int insertPos = 1;
622 
623  bool foundInsertPos = m_foundFeaturesCombo->count() == 0;
624 
625  while (!foundInsertPos) {
626  if (insertPos >= m_foundFeaturesCombo->count()) {
627  foundInsertPos = true;
628  }
629  else {
630  QVariant insetPosData = m_foundFeaturesCombo->itemData(
631  insertPos);
632  QString insertPosTarget = insetPosData.toMap()["Target"].toString();
633 
634  if (targetName < insertPosTarget) {
635  foundInsertPos = true;
636  }
637  else if (targetName == insertPosTarget) {
638  if (!insetPosData.toMap()["Viewport"].isNull()) {
639  foundInsertPos = displayName.compare(
640  m_foundFeaturesCombo->itemText(insertPos),
641  Qt::CaseInsensitive) < 0;
642  }
643  }
644  }
645 
646  if (!foundInsertPos)
647  insertPos++;
648  }
649 
650  if (m_foundFeaturesCombo->itemData(insertPos - 1).toMap()[
651  "Target"].toString() != targetName) {
653  data["Target"] = targetName;
654 
655  QString controlNet = feature.controlNet();
656  if (controlNet != "")
657  controlNet = " (" + controlNet + ")";
658 
659  m_foundFeaturesCombo->insertItem(insertPos,
660  targetName + controlNet,
661  data);
662  QVariant font = m_foundFeaturesCombo->itemData(insertPos,
663  Qt::ForegroundRole);
664  m_foundFeaturesCombo->setItemData(insertPos, QColor(Qt::gray),
665  Qt::ForegroundRole);
666  insertPos++;
667 
668  m_foundFeaturesCombo->insertItem(insertPos,
669  "-----------",
670  data);
671  m_foundFeaturesCombo->setItemData(insertPos, QColor(Qt::gray),
672  Qt::ForegroundRole);
673  insertPos++;
674  }
675 
677  data["Feature"] = QVariant::fromValue<FeatureNomenclature::Feature>(
678  feature);
679  data["Viewport"] = qVariantFromValue(vp);
680  data["Target"] = qVariantFromValue(targetName);
681 
682  m_foundFeaturesCombo->insertItem(insertPos, displayName,
683  qVariantFromValue(data));
684  }
685  }
686  updatingFeaturesProgress.setValue( features.count() );
687  }
688  }
689 
690 
699  if (m_nomenclatureEnabled) {
700  // We're looking for viewports with nomenclature results that no longer
701  // exist with removedViewports.
702  QList<MdiCubeViewport *> removedViewports =
704 
705  foreach (MdiCubeViewport *vp, *cubeViewportList()) {
706  removedViewports.removeOne(vp);
707 
710 
711  if (!viewportFeaturesFound(vp) && finding.find(vp) == finding.end()) {
713  }
714  }
715 
716  bool removedAViewport = false;
717  foreach (MdiCubeViewport *vp, removedViewports) {
718  // A viewport disappeared; let's remove all references of it.
720  removedAViewport = true;
721  }
722 
723  if (removedAViewport) {
724  // Rebuild the combo box...
726  }
727  }
728  }
729 
730 
738  try {
739  // verify we can project before anything else
741 
742  if (!ugm)
743  throw IException();
744 
745  QString target;
746  if (vp->camera()) {
747  target = vp->camera()->target()->name();
748  }
749  else if (vp->projection()) {
750  PvlGroup mappingGrp = vp->projection()->Mapping();
751 
752  if (mappingGrp.hasKeyword("TargetName"))
753  target = mappingGrp["TargetName"][0];
754  }
755 
756  Latitude minLat;
757  Latitude maxLat;
758  Longitude minLon;
759  Longitude maxLon;
760  if (ugm->GroundRange(vp->cube(), minLat, maxLat, minLon, maxLon) &&
761  target != "") {
763  connect(searcher, SIGNAL(featuresIdentified(FeatureNomenclature *)),
764  this, SLOT(featuresIdentified(FeatureNomenclature *)));
765 
766  (*m_nomenclatureSearchers)[vp] = searcher;
768  (*m_nomenclatureSearchers)[vp]->queryFeatures(target.toUpper(),
769  minLat, minLon,
770  maxLat, maxLon);
771  }
772  else {
773  viewportDone(vp);
774  }
775  }
776  catch (IException &) {
777  viewportDone(vp);
778  }
779  }
780 
781 
787  if (m_foundFeaturesCombo) {
788  m_foundFeaturesCombo->clear();
789  m_foundFeaturesCombo->addItem("");
790 
793  }
794  }
795  }
796 
797 
805  for (int i = m_foundNomenclature->count() - 1; i >= 0; i--) {
806  if (m_foundNomenclature->at(i).sourceViewport() == vp)
807  m_foundNomenclature->removeAt(i);
808  }
809  }
810 
811 
819  QDialog *detailsDialog = new QDialog(qobject_cast<QWidget *>(parent()));
820  detailsDialog->setAttribute(Qt::WA_DeleteOnClose);
821 
822  QVBoxLayout *mainLayout = new QVBoxLayout;
823  detailsDialog->setLayout(mainLayout);
824 
825  mainLayout->addWidget(feature.toWidget());
826 
827  QWidget *buttonsAreaWrapper = new QWidget;
828 
829  QHBoxLayout *buttonsAreaLayout = new QHBoxLayout;
830  buttonsAreaWrapper->setLayout(buttonsAreaLayout);
831 
832  buttonsAreaLayout->addStretch();
833  QPushButton *okayBtn = new QPushButton("&Ok");
834  okayBtn->setIcon(QIcon::fromTheme("dialog-ok"));
835  connect(okayBtn, SIGNAL(clicked()),
836  detailsDialog, SLOT(accept()));
837  buttonsAreaLayout->addWidget(okayBtn);
838 
839  mainLayout->addWidget(buttonsAreaWrapper);
840 
841  detailsDialog->show();
842  }
843 
844 
852  QDesktopServices::openUrl(feature.referenceUrl());
853  }
854 
855 
862  bool isCurrentlyLoading = (m_nomenclatureSearchers->keys().count() > 0);
863 
864  if (isCurrentlyLoading) {
865  m_findNomenclatureCheckBox->setEnabled(false);
866  m_queryingProgress->setVisible(true);
867  }
868  else {
869  m_findNomenclatureCheckBox->setEnabled(true);
870  m_queryingProgress->setVisible(false);
872 
874  showDisclaimer();
875  }
876  }
877 
878  if (m_action) {
879  m_action->setChecked(m_nomenclatureEnabled);
880  }
881 
882  featureSelected();
883  }
884 
885 
896  if (m_nomenclatureSearchers->find(vp) != m_nomenclatureSearchers->end()) {
897  if ((*m_nomenclatureSearchers)[vp]) {
898  (*m_nomenclatureSearchers)[vp]->deleteLater();
899  }
900 
901  m_nomenclatureSearchers->remove(vp);
902  }
903 
904  if (viewportFeatureDisplay(vp) == NULL) {
905  m_foundNomenclature->append(
906  ViewportFeatureDisplay(this, vp,
908  }
909  else {
910  connect(vp, SIGNAL(screenPixelsChanged()),
911  this, SLOT(nomenclaturePositionsOutdated()));
912  }
913 
915  }
916 
917 
927  for (int i = 0; i < m_foundNomenclature->count(); i++) {
928  if (m_foundNomenclature->at(i).sourceViewport() == vp)
929  return &(*m_foundNomenclature)[i];
930  }
931 
932  return NULL;
933  }
934 
935 
945  const {
946  for (int i = 0; i < m_foundNomenclature->count(); i++) {
947  if (m_foundNomenclature->at(i).sourceViewport() == vp)
948  return &(*m_foundNomenclature)[i];
949  }
950 
951  return NULL;
952  }
953 
954 
964  const {
965  return (viewportFeatureDisplay(vp) != NULL);
966  }
967 
968 
978 
979  for (int i = 0; i < m_foundNomenclature->count(); i++) {
980  if (m_foundNomenclature->at(i).sourceViewport() != NULL)
981  result.append(m_foundNomenclature->at(i).sourceViewport());
982  }
983 
984  return result;
985  }
986 
987 
994  FileName config("$HOME/.Isis/qview/nomenclature.config");
995  QSettings settings(
996  config.expanded(), QSettings::NativeFormat);
997 
998  m_fontSize = settings.value("fontSize", m_fontSize).toInt();
999  *m_fontColor = settings.value("fontColor", *m_fontColor).value<QColor>();
1001  settings.value("defaultEnabled", m_defaultEnabled).toBool();
1003  settings.value("disclaimerShown", m_disclaimedAlready).toBool();
1005  settings.value("showApprovedOnly", m_showApprovedOnly).toBool();
1006  m_extentType =
1007  VectorType(settings.value("vectorsShown", m_extentType).toInt());
1008  }
1009 
1010 
1016  FileName config("$HOME/.Isis/qview/nomenclature.config");
1017  QSettings settings(
1018  config.expanded(), QSettings::NativeFormat);
1019  settings.setValue("fontSize", m_fontSize);
1020  settings.setValue("fontColor", qVariantFromValue(*m_fontColor));
1021  settings.setValue("defaultEnabled", m_defaultEnabled);
1022  settings.setValue("disclaimerShown", m_disclaimedAlready);
1023  settings.setValue("showApprovedOnly", m_showApprovedOnly);
1024  settings.setValue("vectorsShown", m_extentType);
1025  }
1026 
1027 
1032  m_centerLine = Null;
1033  m_centerSample = Null;
1034  m_featureEdgeLineSamples = NULL;
1035  m_gmap = NULL;
1036 
1038  }
1039 
1040 
1052  m_centerLine = Null;
1053  m_centerSample = Null;
1054  m_featureEdgeLineSamples = NULL;
1055  m_gmap = NULL;
1056 
1057  m_featureEdgeLineSamples = new QList< QPair<double, double> >;
1058 
1059  m_feature = feature;
1060 
1061  if (vp) {
1062  m_gmap = vp->universalGroundMap();
1063  Latitude centerLat = m_feature.centerLatitude();
1064  Longitude centerLon = m_feature.centerLongitude();
1065  if (m_gmap && m_gmap->SetGround(centerLat, centerLon)) {
1066  m_centerSample = m_gmap->Sample();
1067  m_centerLine = m_gmap->Line();
1068 
1069  applyExtentType(vectorType);
1070  }
1071  }
1072  }
1073 
1074 
1081  const FeaturePosition &other) {
1082  m_centerLine = other.m_centerLine;
1083  m_centerSample = other.m_centerSample;
1084  m_featureEdgeLineSamples = NULL;
1085  m_gmap = NULL;
1086 
1087  m_featureEdgeLineSamples = new QList< QPair<double, double> >(
1088  *other.m_featureEdgeLineSamples);
1089 
1090  m_feature = other.m_feature;
1091 
1092  if (other.m_gmap)
1093  m_gmap = new UniversalGroundMap(*other.m_gmap);
1094  }
1095 
1096 
1101  m_centerLine = Null;
1102  m_centerSample = Null;
1103  m_gmap = NULL;
1104 
1105  delete m_featureEdgeLineSamples;
1106  m_featureEdgeLineSamples = NULL;
1107  }
1108 
1109 
1116  return (m_centerSample != Null && m_centerLine != Null);
1117  }
1118 
1119 
1126  const {
1127  return QPair<double, double>(m_centerSample, m_centerLine);
1128  }
1129 
1130 
1138  return *m_featureEdgeLineSamples;
1139  }
1140 
1141 
1149  return m_feature;
1150  }
1151 
1162 
1163  Latitude centerLat = m_feature.centerLatitude();
1164  Longitude centerLon = m_feature.centerLongitude();
1165 
1166  m_featureEdgeLineSamples->clear();
1167 
1168  if (vectorType == FeatureNomenclatureTool::Arrows8) {
1169 
1170  // We're going to permute the edge lats/lons excluding the center, so
1171  // these lists are independent of each other.
1172  QList<Latitude> edgeLats;
1173  QList<Longitude> edgeLons;
1174 
1175  edgeLats.append(m_feature.northernLatitude());
1176  edgeLats.append(m_feature.centerLatitude());
1177  edgeLats.append(m_feature.southernLatitude());
1178 
1179  edgeLons.append(m_feature.easternLongitude());
1180  edgeLons.append(m_feature.centerLongitude());
1181  edgeLons.append(m_feature.westernLongitude());
1182 
1183  int edgeLatCount = edgeLats.count();
1184  int edgeLonCount = edgeLons.count();
1185 
1186  for (int latIndex = 0; latIndex < edgeLatCount; latIndex++) {
1187  for (int lonIndex = 0; lonIndex < edgeLonCount; lonIndex++) {
1188  Latitude &lat = edgeLats[latIndex];
1189  Longitude &lon = edgeLons[lonIndex];
1190 
1191  if (lat.isValid() && lon.isValid() &&
1192  (lat != centerLat || lon != centerLon) &&
1193  m_gmap->SetGround(lat, lon)) {
1194  m_featureEdgeLineSamples->append(
1195  QPair<double, double>(m_gmap->Sample(), m_gmap->Line()));
1196  }
1197  }
1198  }
1199  }
1200 
1201  else {
1202  QList< QPair<Latitude, Longitude> > edgeLatLons;
1203 
1204  if (vectorType == FeatureNomenclatureTool::Arrows4) {
1205  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1206  m_feature.centerLongitude()));
1207  edgeLatLons.append(qMakePair(m_feature.centerLatitude(),
1208  m_feature.westernLongitude()));
1209  edgeLatLons.append(qMakePair(m_feature.centerLatitude(),
1210  m_feature.easternLongitude()));
1211  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1212  m_feature.centerLongitude()));
1213  }
1214 
1215  if (vectorType == FeatureNomenclatureTool::Box) {
1216  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1217  m_feature.easternLongitude()));
1218  edgeLatLons.append(qMakePair(m_feature.northernLatitude(),
1219  m_feature.westernLongitude()));
1220  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1221  m_feature.westernLongitude()));
1222  edgeLatLons.append(qMakePair(m_feature.southernLatitude(),
1223  m_feature.easternLongitude()));
1224  }
1225 
1226  int edgeLatLonCount = edgeLatLons.count();
1227 
1228  for (int edgeIndex = 0; edgeIndex < edgeLatLonCount; edgeIndex++) {
1229  Latitude &lat = edgeLatLons[edgeIndex].first;
1230  Longitude &lon = edgeLatLons[edgeIndex].second;
1231 
1232  if (lat.isValid() && lon.isValid() &&
1233  (lat != centerLat || lon != centerLon) &&
1234  m_gmap->SetGround(lat, lon)) {
1235  m_featureEdgeLineSamples->append(
1236  QPair<double, double>(m_gmap->Sample(), m_gmap->Line()));
1237  }
1238  }
1239  }
1240  }
1241 
1242 
1249  std::swap(m_centerLine, other.m_centerLine);
1250  std::swap(m_centerSample, other.m_centerSample);
1251  std::swap(m_featureEdgeLineSamples, other.m_featureEdgeLineSamples);
1252  std::swap(m_feature, other.m_feature);
1253  std::swap(m_gmap, other.m_gmap);
1254  }
1255 
1256 
1267  const FeaturePosition &rhs) {
1268  FeaturePosition copy(rhs);
1269  swap(copy);
1270  return *this;
1271  }
1272 
1273 
1281  return m_feature;
1282  }
1283 
1284 
1289  m_textRect = NULL;
1290  m_fullDisplayRect = NULL;
1291  m_edgePoints = NULL;
1292 
1293  m_textRect = new QRect;
1294  m_fullDisplayRect = new QRect;
1295  m_edgePoints = new QList<QPoint>;
1296  }
1297 
1298 
1310  QRect textRect, QRect fullDisplayRect, QList<QPoint> edgePoints) {
1311  m_textRect = NULL;
1312  m_fullDisplayRect = NULL;
1313  m_edgePoints = NULL;
1314 
1315  m_textRect = new QRect(textRect);
1316  m_fullDisplayRect = new QRect(fullDisplayRect);
1317  m_edgePoints = new QList<QPoint>(edgePoints);
1318  }
1319 
1320 
1326  const FeatureDisplayPosition &other) {
1327  m_textRect = NULL;
1328  m_fullDisplayRect = NULL;
1329  m_edgePoints = NULL;
1330 
1331  m_textRect = new QRect(*other.m_textRect);
1332  m_fullDisplayRect = new QRect(*other.m_fullDisplayRect);
1333  m_edgePoints = new QList<QPoint>(*other.m_edgePoints);
1334  }
1335 
1336 
1341  delete m_textRect;
1342  m_textRect = NULL;
1343 
1344  delete m_fullDisplayRect;
1345  m_fullDisplayRect = NULL;
1346 
1347  delete m_edgePoints;
1348  m_edgePoints = NULL;
1349  }
1350 
1351 
1359  return *m_textRect;
1360  }
1361 
1362 
1370  return *m_fullDisplayRect;
1371  }
1372 
1373 
1381  const {
1382  return *m_edgePoints;
1383  }
1384 
1385 
1393  FeatureDisplayPosition &other) {
1394  std::swap(m_textRect, other.m_textRect);
1395  std::swap(m_fullDisplayRect, other.m_fullDisplayRect);
1396  std::swap(m_edgePoints, other.m_edgePoints);
1397  }
1398 
1399 
1409  const FeatureDisplayPosition &rhs) {
1410  FeatureDisplayPosition copy(rhs);
1411  swap(copy);
1412  return *this;
1413  }
1414 
1415 
1420  m_sourceViewport = NULL;
1421  m_features = NULL;
1422  m_featureScreenAreas = NULL;
1423  m_viewportCubeRange = NULL;
1424 
1425  m_features = new QList<FeaturePosition>;
1426  m_featureScreenAreas = new QList<FeatureDisplayPosition>;
1427  m_viewportCubeRange = new QPair<QPointF, QPointF>;
1428  }
1429 
1430 
1440  FeatureNomenclatureTool *tool, MdiCubeViewport *sourceViewport,
1442  m_sourceViewport = sourceViewport;
1443  m_features = NULL;
1444  m_featureScreenAreas = NULL;
1445  m_viewportCubeRange = NULL;
1446 
1447  m_features = new QList<FeaturePosition>;
1448  m_featureScreenAreas = new QList<FeatureDisplayPosition>;
1449  m_viewportCubeRange = new QPair<QPointF, QPointF>;
1450 
1451  qSort(features.begin(), features.end(),
1453 
1454  for (int i = 0; i < features.count(); i++) {
1455  FeaturePosition display(sourceViewport, features[i], vectorType);
1456  if (display.isValid()) {
1457  m_features->append(display);
1458  }
1459  }
1460 
1461  handleViewChanged(tool);
1462  }
1463 
1464 
1471  const ViewportFeatureDisplay &other) {
1472  m_sourceViewport = other.m_sourceViewport;
1473  m_features = NULL;
1474  m_featureScreenAreas = NULL;
1475  m_viewportCubeRange = NULL;
1476 
1477  m_features = new QList<FeaturePosition>(*other.m_features);
1478  m_featureScreenAreas = new QList<FeatureDisplayPosition>(
1479  *other.m_featureScreenAreas);
1480  m_viewportCubeRange = new QPair<QPointF, QPointF>(
1481  *other.m_viewportCubeRange);
1482  }
1483 
1484 
1489  m_sourceViewport = NULL;
1490 
1491  delete m_features;
1492  m_features = NULL;
1493 
1494  delete m_featureScreenAreas;
1495  m_featureScreenAreas = NULL;
1496 
1497  delete m_viewportCubeRange;
1498  m_viewportCubeRange = NULL;
1499  }
1500 
1501 
1508  for (int i = 0; i < m_features->count(); i++) {
1509  (*m_features)[i].applyExtentType(vectorType);
1510  }
1511  }
1512 
1513 
1521  FeatureNomenclature::Feature feature) {
1522  QString displayName = feature.displayName();
1523 
1524  int foundIndex = -1;
1525  for (int i = 0; foundIndex == -1 && i < m_features->count(); i++) {
1526  if (displayName == m_features->at(i).feature().displayName()) {
1527  foundIndex = i;
1528  }
1529  }
1530 
1531  if (foundIndex != -1) {
1532  m_features->prepend(m_features->takeAt(foundIndex));
1533  m_featureScreenAreas->prepend(m_featureScreenAreas->takeAt(foundIndex));
1534 
1535  // The center() method creates artifacts/displays bad data in the viewport
1536  // ... the old 'cube' before centering stays around.
1537  m_sourceViewport->setScale(m_sourceViewport->scale(),
1538  m_features->first().center().first,
1539  m_features->first().center().second);
1540  m_sourceViewport->viewport()->update();
1541  }
1542  }
1543 
1544 
1554 
1555  for (int i = 0; i < m_features->count(); i++)
1556  featureList.append((*m_features)[i].feature());
1557 
1558  return featureList;
1559  }
1560 
1561 
1570 
1571  for (int i = 0; i < m_features->count(); i++)
1572  positionList.append((*m_features)[i]);
1573 
1574  return positionList;
1575  }
1576 
1577 
1583  MdiCubeViewport *
1585  return m_sourceViewport;
1586  }
1587 
1588 
1598  QPainter *painter, bool showVectors, VectorType vectorType, bool approvedOnly) const {
1599 
1600  if (viewportCubeRange() == *m_viewportCubeRange) {
1601 
1602  for (int i = 0; i < m_features->count() &&
1603  i < m_featureScreenAreas->count(); i++) {
1604 
1605  FeatureNomenclature::Feature feature = (*m_features)[i].feature();
1606  FeatureDisplayPosition pos = (*m_featureScreenAreas)[i];
1607  QRect textArea = pos.textArea();
1608  QRect fullArea = pos.displayArea();
1609 
1610  if (!fullArea.isNull() && fullArea != textArea && showVectors) {
1611  // For efficiency's sake
1612  QRect startRect = textArea.adjusted(-2, -2, 2, 2);
1613  QLineF topTextBorder(startRect.topLeft(), startRect.topRight());
1614  QLineF rightTextBorder(startRect.topRight(), startRect.bottomRight());
1615  QLineF bottomTextBorder(startRect.bottomLeft(),
1616  startRect.bottomRight());
1617  QLineF leftTextBorder(startRect.topLeft(), startRect.bottomLeft());
1618 
1619  QList<QLine> vectors;
1620 
1621  if (vectorType != Box) {
1622  foreach (QPoint point, pos.edgePoints()) {
1623  QLineF fullVector(textArea.center(), point);
1624  QPoint newVectorStart;
1625 
1626  QPointF intersectionPoint;
1627 
1628  if (point.y() < textArea.top()) {
1629  if (topTextBorder.intersect(fullVector, &intersectionPoint) ==
1630  QLineF::BoundedIntersection) {
1631  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1632  qRound(intersectionPoint.y()));
1633  }
1634  }
1635 
1636  if (point.x() > textArea.right()) {
1637  if (rightTextBorder.intersect(fullVector, &intersectionPoint) ==
1638  QLineF::BoundedIntersection) {
1639  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1640  qRound(intersectionPoint.y()));
1641  }
1642  }
1643 
1644  if (point.y() > textArea.bottom()) {
1645  if (bottomTextBorder.intersect(fullVector, &intersectionPoint) ==
1646  QLineF::BoundedIntersection) {
1647  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1648  qRound(intersectionPoint.y()));
1649  }
1650  }
1651 
1652  if (point.x() < textArea.left()) {
1653  if (leftTextBorder.intersect(fullVector, &intersectionPoint) ==
1654  QLineF::BoundedIntersection) {
1655  newVectorStart = QPoint(qRound(intersectionPoint.x()),
1656  qRound(intersectionPoint.y()));
1657  }
1658  }
1659 
1660  if (!newVectorStart.isNull() &&
1661  QLineF(newVectorStart, point).length() > 10) {
1662  vectors.append(QLine(newVectorStart, point));
1663  }
1664  }
1665 
1666  foreach (QLine vector, vectors) {
1667  painter->drawLine(vector);
1668 
1669  //For 4 or 8 arrows
1670  Angle normalAngle(-1 * QLineF(vector).normalVector().angle(),
1671  Angle::Degrees);
1672 
1673  int magnitude = 10;
1674  double deltaX = magnitude * cos(normalAngle.radians());
1675  double deltaY = magnitude * sin(normalAngle.radians());
1676 
1677  QPoint normalStart(vector.x2() + deltaX, vector.y2() + deltaY);
1678  QPoint normalEnd(vector.x2() - deltaX, vector.y2() - deltaY);
1679  painter->drawLine(normalStart, normalEnd);
1680 
1681  Angle arrowheadAngle(30, Angle::Degrees);
1682  Angle vectorAngle(-1 * QLineF(vector).angle(), Angle::Degrees);
1683  Angle leftHead = vectorAngle - arrowheadAngle;
1684  Angle rightHead = vectorAngle + arrowheadAngle;
1685 
1686  int arrowheadMag = 10;
1687  deltaX = arrowheadMag * cos(leftHead.radians());
1688  deltaY = arrowheadMag * sin(leftHead.radians());
1689  painter->drawLine(
1690  vector.p2(), vector.p2() - QPoint(deltaX, deltaY));
1691 
1692  deltaX = arrowheadMag * cos(rightHead.radians());
1693  deltaY = arrowheadMag * sin(rightHead.radians());
1694  painter->drawLine(
1695  vector.p2(), vector.p2() - QPoint(deltaX, deltaY));
1696  }
1697  }
1698  else {
1699  // vector type == Box, draw the box
1700  if (pos.edgePoints().count() == 4) {
1701  QPolygon boundingPoly(pos.edgePoints().toVector());
1702  painter->drawPolygon(boundingPoly);
1703  }
1704  }
1705  }
1706 
1707  if (!textArea.isNull()) {
1708  QString featureName = feature.name();
1709  painter->drawText(textArea, featureName);
1710  }
1711  }
1712  }
1713  }
1714 
1715 
1725  FeatureNomenclatureTool *tool, QPoint p, Qt::MouseButton s) {
1726  for (int i = 0; i < m_featureScreenAreas->count(); i++) {
1727  QRect screenArea = m_featureScreenAreas->at(i).displayArea();
1728 
1729  if (screenArea.contains(p)) {
1730  FeatureNomenclature::Feature feature = m_features->at(i).feature();
1731  if (s == Qt::LeftButton) {
1732  tool->showFeatureDetails(feature);
1733  }
1734  else if (s == Qt::RightButton) {
1735  QMenu menu;
1736 
1737  QAction *title = menu.addAction(feature.displayName());
1738  title->setEnabled(false);
1739  menu.addSeparator();
1740 
1741  QAction *details = menu.addAction("Details...");
1742  QAction *website = menu.addAction("Website...");
1743  menu.addSeparator();
1744  QAction *center = menu.addAction("Center on Feature");
1745  QAction *copyUrl = menu.addAction("Copy Website URL");
1746 
1747  // This manual adjustment of the pos is a hack... probably due to our
1748  // cursors.
1749  QAction *selectedAction = menu.exec(
1750  m_sourceViewport->viewport()->mapToGlobal(p) +
1751  QPoint(0, 20), details);
1752 
1753  if (selectedAction == details) {
1754  tool->showFeatureDetails(feature);
1755  }
1756  else if (selectedAction == website) {
1757  tool->showFeatureWebsite(feature);
1758  }
1759  else if (selectedAction == center) {
1760  tool->centerOnFeature(m_sourceViewport, feature);
1761  }
1762  else if (selectedAction == copyUrl) {
1763  QApplication::clipboard()->setText(
1764  feature.referenceUrl().toString());
1765  }
1766  }
1767  }
1768  }
1769  }
1770 
1771 
1779  FeatureNomenclatureTool *tool) {
1780  m_featureScreenAreas->clear();
1781 
1782  QFont fontToUse;
1783  fontToUse.setPointSize(tool->fontSize());
1784  QFontMetrics fontMetrics(fontToUse);
1785 
1786  // Don't draw text that overlaps existing text.
1787  QList<QRect> rectsToAvoid;
1788 
1789  for (int i = 0; i < m_features->count(); i++) {
1790  FeatureNomenclature::Feature feature = (*m_features)[i].feature();
1791 
1792  m_featureScreenAreas->append(FeatureDisplayPosition());
1793 
1794  if ( !tool->m_showApprovedOnly ||
1795  (tool->m_showApprovedOnly && feature.status() == FeatureNomenclature::Approved) ) {
1796 
1797  double sample = (*m_features)[i].center().first;
1798  double line = (*m_features)[i].center().second;
1799 
1800  int viewportX;
1801  int viewportY;
1802  m_sourceViewport->cubeToViewport(sample, line,
1803  viewportX, viewportY);
1804 
1805  QString featureName = feature.name();
1806  QRect textDisplayArea(QPoint(viewportX, viewportY),
1807  QSize(fontMetrics.width(featureName) + 4,
1808  fontMetrics.height()));
1809  // Center the text on the viewportX,Y instead of starting it there...
1810  textDisplayArea.moveTopLeft(textDisplayArea.topLeft() -
1811  QPoint(textDisplayArea.width() / 2, textDisplayArea.height() / 2));
1812 
1813  bool canDisplay = false;
1814  if (textDisplayArea.left() < m_sourceViewport->width() &&
1815  textDisplayArea.right() > 0 &&
1816  textDisplayArea.top() < m_sourceViewport->height() &&
1817  textDisplayArea.bottom() > 0) {
1818  canDisplay = true;
1819  }
1820 
1821  QRect fullDisplayArea = textDisplayArea;
1822  QPair<double, double> edge;
1823  QList<QPoint> edgeScreenPoints;
1824 
1825  if (canDisplay && tool->vectorType() != None) {
1826  QList< QPair<double, double> > edges = (*m_features)[i].edges();
1827  foreach (edge, edges) {
1828  m_sourceViewport->cubeToViewport(edge.first, edge.second,
1829  viewportX, viewportY);
1830  edgeScreenPoints.append(QPoint(viewportX, viewportY));
1831  }
1832 
1833  if (tool->vectorType() != Box) {
1834  foreach (QPoint screenPoint, edgeScreenPoints) {
1835  fullDisplayArea = fullDisplayArea.united(
1836  QRect(screenPoint.x() - 3, screenPoint.y() - 3, 6, 6));
1837  }
1838  }
1839  else if (edges.count() == 4) {
1840 
1841  QPolygon boundingPoly(edgeScreenPoints.toVector());
1842 
1843  if (boundingPoly.intersected(textDisplayArea) == QPolygon(textDisplayArea, true)) {
1844  fullDisplayArea = boundingPoly.boundingRect();
1845  }
1846  }
1847  }
1848 
1849  if (canDisplay) {
1850  // If we intersect another feature, do not draw
1851  foreach (QRect rectToAvoid, rectsToAvoid) {
1852  if (canDisplay && fullDisplayArea.intersects(rectToAvoid)) {
1853  canDisplay = false;
1854  }
1855  }
1856  }
1857 
1858  if (canDisplay) {
1859  rectsToAvoid.append(fullDisplayArea);
1860  m_featureScreenAreas->last() = FeatureDisplayPosition(textDisplayArea, fullDisplayArea,
1861  edgeScreenPoints);
1862  }
1863  }
1864  *m_viewportCubeRange = viewportCubeRange();
1865  }
1866  }
1867 
1868 
1875  ViewportFeatureDisplay &other) {
1876  std::swap(m_sourceViewport, other.m_sourceViewport);
1877  std::swap(m_features, other.m_features);
1878  std::swap(m_featureScreenAreas, other.m_featureScreenAreas);
1879  std::swap(m_viewportCubeRange, other.m_viewportCubeRange);
1880  }
1881 
1882 
1892  const ViewportFeatureDisplay &rhs) {
1893  ViewportFeatureDisplay copy(rhs);
1894  swap(copy);
1895  return *this;
1896  }
1897 
1898 
1908  const {
1909  QPointF minValues;
1910  sourceViewport()->viewportToCube(1, 1, minValues.rx(), minValues.ry());
1911 
1912  QPointF maxValues;
1913  sourceViewport()->viewportToCube(sourceViewport()->viewport()->width(),
1914  sourceViewport()->viewport()->height(),
1915  maxValues.rx(), maxValues.ry());
1916 
1917  return QPair<QPointF, QPointF>(minValues, maxValues);
1918  }
1919 }
void swap(FeaturePosition &other)
Trade member data with other.
Cube display widget for certain Isis MDI applications.
bool viewportFeaturesFound(MdiCubeViewport *vp) const
Test if features have already been found for a given viewport.
QPointer< QProgressBar > m_queryingProgress
This is a busy indicator that is visible when queries are out to the nomenclature database...
bool isValid() const
Test if sample/line coordinates could be found for this feature.
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
QRect textArea() const
Get the screen pixel rect in viewport screen coordinates that ought to be filled with the textual nam...
virtual void screenPixelsChanged()
This is called when actions change which pixels from the cube are displayed.
Definition: Tool.h:162
void viewportDone(MdiCubeViewport *vp)
Finalize the search results for the given viewport.
QList< MdiCubeViewport * > viewportsWithFoundNomenclature()
Get a list of viewports with found nomenclature.
void removeFeatureDisplay(MdiCubeViewport *vp)
Remove knowledge of features on the given viewport.
void showFeatureDetails(FeatureNomenclature::Feature)
Show a dialog with full feature details of a given feature.
UniversalGroundMap * universalGroundMap() const
Return the universal ground map associated with the cube (NULL implies none)
Definition: CubeViewport.h:243
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:109
void updateTool()
Updates the state of the current tool.
void applyExtentType(VectorType vectorType)
Apply the extent type to all of the features for the source viewport.
void centerOnSelectedFeature()
Center the relevent viewport (and any viewports linked to it) on the feature selected in the feature ...
File name manipulation and expansion.
Definition: FileName.h:111
void setFontColor(QColor color)
Set the color to use for drawing on the viewport.
Universal Ground Map.
double radians() const
Convert an angle to a double.
Definition: Angle.h:239
void onToolActivated()
When this tool is activated (clicked on in the tool bar), turn ourselves on immediately.
Feature nomenclature database querier.
bool m_showApprovedOnly
Only show IAU approved features.
void handleMouseClicked(FeatureNomenclatureTool *tool, QPoint p, Qt::MouseButton s)
Handle a mouse click event on the viewport.
QRect * m_textRect
The viewport screen pixel rect which the text will consume.
When using this vector (extent) type, 8 arrows will be drawn out from the text of the feature...
FeaturePosition()
Instiantiates a feature position with no data.
QWidget * toWidget() const
This converts the data in this feature to a widget.
When this status is assigned to a feature, the displayed status will be &quot;Adopted by the IAU&quot; and the ...
~FeatureNomenclatureTool()
Cleans up memory allocated by this tool.
QPointer< QPushButton > m_disclaimerBtn
This is the &#39;Disclaimer&#39; button in this tool&#39;s tool bar.
~ViewportFeatureDisplay()
Cleans up memory allocated by this feature display.
void findNomenclatureStateChanged(int)
The &#39;Name Features&#39; check box has changed state.
QList< ViewportFeatureDisplay > * m_foundNomenclature
The nomenclature that has been identified, one for each viewport.
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:59
double m_centerSample
The cube sample position of the feature center, Null if !isValid()
When using this vector (extent) type, no extents will be drawn.
Projection * projection() const
Return the projection associated with cube (NULL implies none)
Definition: CubeViewport.h:233
void setFontSize(int newFontSize)
Set the font point size to use for drawing text on the viewport.
void paint(QPainter *painter, bool showVectors, VectorType vectorType, bool approvedOnly) const
Paint features onto the viewport.
QColor fontColor() const
What is the font color to use?
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
FeatureNomenclatureTool(QWidget *parent)
This instantiates a FeatureNomenclatureTool.
QString menuName() const
This is the name of the menu that should be passed into &quot;addTo()&quot;.
void setDefaultEnabled(bool defaultEnabled)
Set whether this tool is enabled by default.
QColor * m_fontColor
The color to use when drawing on the viewport.
void addTo(QMenu *menu)
Add the &#39;Show Nomenclature&#39; option to the options menu.
double m_centerLine
The cube line position of the feature center, Null if !isValid()
void showFeatureWebsite(FeatureNomenclature::Feature)
Show a web view pointed to the feature&#39;s web page.
When using this vector (extent) type, 4 arrows will be drawn out from the text of the feature...
void swap(FeatureDisplayPosition &other)
Swap member data with another instance of this class.
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1277
void toolStateChanged()
This should be called any time this tool&#39;s enabled or searching state could have changed.
QString name() const
Return target name.
Definition: Target.cpp:483
QPair< double, double > center() const
Get the center sample/line position of the feature.
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:69
Cube * cube() const
Return the cube associated with viewport.
Definition: CubeViewport.h:228
int fontSize() const
Retrieve the font size of the features in this tool.
bool m_nomenclatureEnabled
Do we find and display nomenclature? This corresponds to the &#39;Name Features&#39; check box and the &#39;Show ...
A named feature&#39;s position in a cube.
void setShowApprovedOnly(bool approvedOnly)
Set whether to show approved features and exclude unapproved features.
VectorType m_extentType
How we need to draw extents (if at all)
QPointer< QPushButton > m_nomenclatureOptionsBtn
This is the &#39;Tool Options&#39; button in this tool&#39;s tool bar.
FeatureNomenclature::Feature & feature()
Get the feature associated with this feature position.
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
void featuresForViewportFound(MdiCubeViewport *vp)
Move the features from a searching state to a found state for the given viewport. ...
Camera * camera() const
Return the camera associated with the cube (NULL implies none)
Definition: CubeViewport.h:238
QList< FeatureDisplayPosition > * m_featureScreenAreas
The visible features on the image in m_sourceViewport.
FeatureNomenclature::Feature m_feature
The feature for which we&#39;re encapsulating a viewport position.
void writeSettings()
Write out this tool&#39;s preserved state between runs.
VectorType vectorType() const
Draw vectors to the extents of features?
bool isLinked() const
Is the viewport linked with other viewports.
QMap< MdiCubeViewport *, FeatureNomenclature * > * m_nomenclatureSearchers
The nomenclature being queried currently, one for each viewport that has no found nomenclature...
void nomenclaturePositionsOutdated()
Update the screen coordinates of the named features because the viewport has changed it&#39;s mappings...
void readSettings()
Read this tool&#39;s preserved state.
ViewportFeatureDisplay * viewportFeatureDisplay(MdiCubeViewport *vp)
Map from viewport to feature display.
QWidget * createToolBarWidget(QStackedWidget *parent)
Creates the widget that goes on the tool bar when this tool is active.
QList< QPoint > * m_edgePoints
The viewport screen pixel points which the edges are at.
ViewportFeatureDisplay & operator=(const ViewportFeatureDisplay &rhs)
Copy the data of rhs into *this.
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
QPair< QPointF, QPointF > viewportCubeRange() const
Get the min/max cube line/sample positions of the viewport.
QPointer< QPushButton > m_nomenclatureCenterBtn
This is the &#39;Center&#39; button in this tool&#39;s tool bar.
QRect displayArea() const
Get the screen pixel rect in viewport screen coordinates that encapsulates the entire feature...
bool defaultEnabled() const
Is this tool enabled by default? (i.e.
void configure()
Give a configuration dialog for the options available in this tool.
Defines an angle and provides unit conversions.
Definition: Angle.h:58
void featuresIdentified(FeatureNomenclature *)
A feature nomenclature has finished querying...
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Configure user&#39;s settings for the nomenclature tool.
bool m_defaultEnabled
Do we turn ourselves on immediately?
void paintViewport(MdiCubeViewport *vp, QPainter *painter)
Paint features on the given viewport.
QPointer< QComboBox > m_foundFeaturesCombo
This combo box lists all of the found features and their viewports.
UniversalGroundMap * m_gmap
The map used to determine the sample, line pair from a lat, lon pair.
QList< FeaturePosition > featurePositions()
Get the list of feature positions for a given display.
Display nomenclature on MDI Cube Viewports.
QList< QPoint > edgePoints() const
Get the edge screen pixel points in viewport screen coordinates that circle the feature.
void showDisclaimer()
Show the user our nomenclature disclaimer and make note that we have shown the disclaimer.
void handleViewChanged(FeatureNomenclatureTool *tool)
The display options or area on the viewport has changed.
bool showApprovedOnly() const
Show approved features only?
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
This handles a mouse release on one of the cube viewports when this tool is active.
MdiCubeViewport * sourceViewport() const
Get the viewport associated with this feature display.
QPointer< QCheckBox > m_findNomenclatureCheckBox
This is the &#39;Name Features&#39; check box when this tool is active.
void rebuildFeaturesCombo()
Rebuild m_foundFeaturesCombo&#39;s data from scratch.
Isis exception class.
Definition: IException.h:99
QRect * m_fullDisplayRect
The viewport screen pixel rect which the entire display will use.
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
QList< FeatureNomenclature::Feature > features()
Get a list of features available on this viewport.
QString m_disclaimerText
The (HTML) contents of the disclaimer to show the user.
When using this vector (extent) type, 4 arrows will be drawn out from the text of the feature...
Base class for the Qisis tools.
Definition: Tool.h:81
FeatureDisplayPosition & operator=(const FeatureDisplayPosition &rhs)
Assign the state of rhs to this.This is exception-safe.
void centerOnFeature(MdiCubeViewport *vp, FeatureNomenclature::Feature)
Center the given and any linked viewports (which contain the same feature) on the given feature...
static bool featureDiameterGreaterThan(const FeatureNomenclature::Feature &lhs, const FeatureNomenclature::Feature &rhs)
Compare the diameter of two features.
QPointer< QAction > m_action
This is the &#39;Show Nomenclature&#39; toggleable action in the options menu.
QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1160
bool m_disclaimedAlready
Have we ever shown the user our disclaimer?
FeaturePosition & operator=(const FeaturePosition &rhs)
Assign rhs to this.
int m_fontSize
The font size to use when naming features.
MdiCubeViewport * m_sourceViewport
The viewport this display is working with; we paint onto this viewport and react to events on this vi...
QPair< QPointF, QPointF > * m_viewportCubeRange
A check to make sure the cube viewport is in the correct state for painting.
void featureSelected()
This handles a feature being selected in the feature list combo box.
void findMissingNomenclature()
Update this tool&#39;s nomenclature data based on this tool&#39;s enabled state and the current viewport list...
FeatureDisplayPosition()
Instantiate a blank feature display position.
void applyExtentType(VectorType vectorType)
Applies the type of extents to the feature.
QList< QPair< double, double > > * m_featureEdgeLineSamples
The pair is cube sample, line (first and second) respectively.
QAction * toolPadAction(ToolPad *pad)
Add this tool&#39;s action to the toolpad.
void swap(ViewportFeatureDisplay &other)
Swap *this and other&#39;s member data in an exception-free way.
QList< QPair< double, double > > edges() const
Get the edge sample/line positions of the feature.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
A named feature&#39;s position in a viewport.
QList< FeaturePosition > * m_features
The features on the image in m_sourceViewport.
A named feature on a target.
void centerFeature(FeatureNomenclature::Feature)
Center the viewport on this feature.
bool GroundRange(Cube *cube, Latitude &minLat, Latitude &maxLat, Longitude &minLon, Longitude &maxLon, bool allowEstimation=true)
Find the lat/lon range of the image.
void setVectorType(VectorType show)
Set whether to draw vectors from the feature center to the feature extents on the viewport...
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
VectorType
Enumeration of extent vector typess.

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 ISIS Support Center
File Modified: 07/12/2023 23:18:03