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