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 }
void swap(FeaturePosition &other)
Trade member data with other.
Cube display widget for certain Isis MDI applications.
QPointer< QProgressBar > m_queryingProgress
This is a busy indicator that is visible when queries are out to the nomenclature database...
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.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
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.
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
Cube * cube() const
Definition: CubeViewport.h:348
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:116
void setFontColor(QColor color)
Set the color to use for drawing on the viewport.
void paint(QPainter *painter, bool showVectors, VectorType vectorType, bool approvedOnly) const
Paint features onto the viewport.
Universal Ground Map.
QPair< QPointF, QPointF > viewportCubeRange() const
Get the min/max cube line/sample positions of the viewport.
QString menuName() const
This is the name of the menu that should be passed into "addTo()".
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
void onToolActivated()
When this tool is activated (clicked on in the tool bar), turn ourselves on immediately.
double radians() const
Convert an angle to a double.
Definition: Angle.h:243
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.
MdiCubeViewport * sourceViewport() const
Get the viewport associated with this feature display.
When this status is assigned to a feature, the displayed status will be "Adopted by the IAU" and the ...
bool showApprovedOnly() const
Show approved features only?
~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:63
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.
void setFontSize(int newFontSize)
Set the font point size to use for drawing text on the viewport.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
FeatureNomenclatureTool(QWidget *parent)
This instantiates a FeatureNomenclatureTool.
bool defaultEnabled() const
Is this tool enabled by default? (i.e.
QPair< double, double > center() const
Get the center sample/line position of the feature.
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
void toolStateChanged()
This should be called any time this tool&#39;s enabled or searching state could have changed.
bool viewportFeaturesFound(MdiCubeViewport *vp) const
Test if features have already been found for a given viewport.
Camera * camera() const
Definition: CubeViewport.h:358
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:73
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.
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1290
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
UniversalGroundMap * universalGroundMap() const
Definition: CubeViewport.h:363
void featuresForViewportFound(MdiCubeViewport *vp)
Move the features from a searching state to a found state for the given viewport. ...
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.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
bool isValid() const
Test if sample/line coordinates could be found for this feature.
QMap< MdiCubeViewport *, FeatureNomenclature * > * m_nomenclatureSearchers
The nomenclature being queried currently, one for each viewport that has no found nomenclature...
bool isLinked() const
Is the viewport linked with other viewports.
QRect textArea() const
Get the screen pixel rect in viewport screen coordinates that ought to be filled with the textual nam...
QString name() const
Return target name.
Definition: Target.cpp:506
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.
VectorType vectorType() const
Draw vectors to the extents of features?
int fontSize() const
Retrieve the font size of the features in this tool.
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.
QPointer< QPushButton > m_nomenclatureCenterBtn
This is the &#39;Center&#39; button in this tool&#39;s tool bar.
void configure()
Give a configuration dialog for the options available in this tool.
Defines an angle and provides unit conversions.
Definition: Angle.h:62
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?
QWidget * toWidget() const
This converts the data in this feature to a widget.
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.
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.
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
This handles a mouse release on one of the cube viewports when this tool is active.
QPointer< QCheckBox > m_findNomenclatureCheckBox
This is the &#39;Name Features&#39; check box when this tool is active.
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
void rebuildFeaturesCombo()
Rebuild m_foundFeaturesCombo&#39;s data from scratch.
Isis exception class.
Definition: IException.h:107
QRect * m_fullDisplayRect
The viewport screen pixel rect which the entire display will use.
QList< FeatureNomenclature::Feature > features()
Get a list of features available on this viewport.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QString m_disclaimerText
The (HTML) contents of the disclaimer to show the user.
Projection * projection() const
Definition: CubeViewport.h:353
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...
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
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.
bool m_disclaimedAlready
Have we ever shown the user our disclaimer?
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
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.
QList< QPoint > edgePoints() const
Get the edge screen pixel points in viewport screen coordinates that circle the feature.
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.
QColor fontColor() const
What is the font color to use?
QRect displayArea() const
Get the screen pixel rect in viewport screen coordinates that encapsulates the entire feature...
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.
QList< QPair< double, double > > edges() const
Get the edge sample/line positions of the feature.
VectorType
Enumeration of extent vector typess.