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
37using namespace std;
38
39namespace Isis {
40
47 Tool(parent) {
54 m_disclaimerBtn = NULL;
55 m_queryingProgress = NULL;
57 m_fontColor = NULL;
58
59 m_foundNomenclature = new QList<ViewportFeatureDisplay>;
61 new QMap< MdiCubeViewport *, FeatureNomenclature *>;
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
90
92 }
93
94
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
154
155
162 return *m_fontColor;
163 }
164
165
172 return m_fontSize;
173 }
174
175
184
185
194
195
207
208
216 if (*m_fontColor != color) {
217 *m_fontColor = color;
219
220 foreach (MdiCubeViewport *vp, *cubeViewportList())
221 vp->viewport()->update();
222 }
223 }
224
225
233 if (m_fontSize != newFontSize) {
234 m_fontSize = newFontSize;
236
238
239 foreach (MdiCubeViewport *vp, *cubeViewportList())
240 vp->viewport()->update();
241 }
242 }
243
244
251 if (m_showApprovedOnly != approvedOnly) {
252 m_showApprovedOnly = approvedOnly;
256
257 foreach (MdiCubeViewport *vp, *cubeViewportList())
258 vp->viewport()->update();
259 }
260 }
261
262
270 if (m_extentType != show) {
271 m_extentType = show;
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) {
396 }
397 }
398
399
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
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) {
495
497 }
498
499 foreach (MdiCubeViewport *vp, *cubeViewportList())
500 vp->viewport()->update();
501 }
502
503
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;
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) {
571 QList<FeatureNomenclature::Feature> features;
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()) {
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) {
649 QMap<QString, QVariant> data;
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
673 QMap<QString, QVariant> data;
674 data["Feature"] = QVariant::fromValue<FeatureNomenclature::Feature>(
675 feature);
676 data["Viewport"] = QVariant::fromValue(vp);
677 data["Target"] = QVariant::fromValue(targetName);
678
679 m_foundFeaturesCombo->insertItem(insertPos, displayName,
680 QVariant::fromValue(data));
681 }
682 }
683 updatingFeaturesProgress.setValue( features.count() );
684 }
685 }
686
687
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
737 UniversalGroundMap *ugm = vp->universalGroundMap();
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 *)),
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
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
872 }
873 }
874
875 if (m_action) {
876 m_action->setChecked(m_nomenclatureEnabled);
877 }
878
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,
904 QList<FeatureNomenclature::Feature>(), m_extentType));
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
972 QList<MdiCubeViewport *>
974 QList<MdiCubeViewport *> result;
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", QVariant::fromValue(*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
1032 m_gmap = NULL;
1033
1034 m_featureEdgeLineSamples = new QList< QPair<double, double> >;
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
1133 QList< QPair<double, double> >
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,
1438 QList<FeatureNomenclature::Feature> features, VectorType vectorType) {
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 sort(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
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
1548 QList<FeatureNomenclature::Feature>
1550 QList<FeatureNomenclature::Feature> featureList;
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
1564 QList<FeatureNomenclatureTool::FeaturePosition>
1566 QList<FeatureNomenclatureTool::FeaturePosition> positionList;
1567
1568 for (int i = 0; i < m_features->count(); i++)
1569 positionList.append((*m_features)[i]);
1570
1571 return positionList;
1572 }
1573
1574
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.intersects(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.intersects(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.intersects(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.intersects(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(),
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
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.horizontalAdvance(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
1903 QPair<QPointF, QPointF>
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}
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.
Namespace for the standard library.