USGS

Isis 3.0 Object Programmers' Reference

Home

MosaicControlNetTool.cpp

00001 #include "MosaicControlNetTool.h"
00002 
00003 #include <iostream>
00004 
00005 #include <QMenu>
00006 
00007 #include "ControlNet.h"
00008 #include "ControlNetGraphicsItem.h"
00009 #include "CubeDisplayProperties.h"
00010 #include "FileDialog.h"
00011 #include "IException.h"
00012 #include "IString.h"
00013 #include "MosaicControlNetToolMovementConfigDialog.h"
00014 #include "MosaicSceneWidget.h"
00015 #include "PvlObject.h"
00016 #include "SpecialPixel.h"
00017 
00018 namespace Isis {
00019 
00025   MosaicControlNetTool::MosaicControlNetTool(MosaicSceneWidget *scene) :
00026       MosaicTool(scene) {
00027     m_controlNet = NULL;
00028     m_controlNetGraphics = NULL;
00029     m_loadControlNetButton = NULL;
00030     m_displayControlNetButton = NULL;
00031     m_displayConnectivity = NULL;
00032     m_closeNetwork = NULL;
00033     m_controlNetFileLabel = NULL;
00034     m_randomizeColors = NULL;
00035 
00036     m_movementArrowColorSource = NoMovement;
00037     m_measureCount = 10;
00038     m_residualMagnitude = 5.0;
00039 
00040     // Create the action buttons
00041 
00042     m_displayControlNetButton = new QPushButton("Display");
00043     m_displayControlNetButton->setCheckable(true);
00044     m_displayControlNetButton->setEnabled(false);
00045     m_displayControlNetButton->setToolTip("Toggle the visibility of the "
00046         "control points and movement arrows in the network.");
00047     connect(m_displayControlNetButton, SIGNAL(clicked()), this, SLOT(displayControlNet()));
00048     connect(m_displayControlNetButton, SIGNAL(destroyed(QObject *)),
00049             this, SLOT(objectDestroyed(QObject *)));
00050 
00051     m_displayConnectivity = new QPushButton("Color Islands");
00052     m_displayConnectivity->setToolTip("Color cubes the same if the control "
00053         "network has a connection between them");
00054     connect(m_displayConnectivity, SIGNAL(clicked()), this, SLOT(displayConnectivity()));
00055     connect(m_displayConnectivity, SIGNAL(destroyed(QObject *)),
00056             this, SLOT(objectDestroyed(QObject *)));
00057     m_displayConnectivity->setEnabled(false);
00058 
00059     m_randomizeColors = new QPushButton("Color Images");
00060     m_randomizeColors->setToolTip("Color all cubes differently");
00061     connect(m_randomizeColors, SIGNAL(clicked()), this, SLOT(randomizeColors()));
00062     connect(m_randomizeColors, SIGNAL(destroyed(QObject *)),
00063             this, SLOT(objectDestroyed(QObject *)));
00064 
00065     m_configMovement = new QPushButton(tr("Configure Movement Display"));
00066     m_configMovement->setToolTip(tr("Show arrow from the apriori surface point to "
00067         "the adjusted surface point for each control point with this "
00068         "information"));
00069     connect(m_configMovement, SIGNAL(clicked()), this, SLOT(configMovement()));
00070     connect(m_configMovement, SIGNAL(destroyed(QObject *)),
00071             this, SLOT(objectDestroyed(QObject *)));
00072 
00073     m_closeNetwork = new QPushButton("Close Network");
00074     m_closeNetwork->setEnabled(false);
00075     m_closeNetwork->setVisible(false);
00076     m_closeNetwork->setToolTip("Close the currently open control network");
00077     connect(m_closeNetwork, SIGNAL(clicked()), this, SLOT(closeNetwork()));
00078     connect(m_closeNetwork, SIGNAL(destroyed(QObject *)),
00079             this, SLOT(objectDestroyed(QObject *)));
00080 
00081     m_loadControlNetButton = new QPushButton("Open Network");
00082     m_loadControlNetButton->setToolTip("Open and load a control network");
00083     connect(m_loadControlNetButton, SIGNAL(clicked()),
00084             this, SLOT(openControlNet()));
00085     connect(m_loadControlNetButton, SIGNAL(destroyed(QObject *)),
00086             this, SLOT(objectDestroyed(QObject *)));
00087 
00088     m_controlNetFileLabel = new QLabel;
00089     m_controlNetFileLabel->setToolTip("The filename of the currently open "
00090         "control network");
00091     connect(m_controlNetFileLabel, SIGNAL(destroyed(QObject *)),
00092             this, SLOT(objectDestroyed(QObject *)));
00093   }
00094 
00095 
00096   MosaicControlNetTool::~MosaicControlNetTool() {
00097     m_controlNetGraphics = NULL; // the scene cleans/cleaned this up
00098 
00099     delete m_loadControlNetButton;
00100     delete m_displayControlNetButton;
00101     delete m_displayConnectivity;
00102     delete m_configMovement;
00103     delete m_closeNetwork;
00104     delete m_controlNetFileLabel;
00105     delete m_randomizeColors;
00106 
00107     closeNetwork();
00108   }
00109 
00110 
00111   CubeDisplayProperties *MosaicControlNetTool::takeDisplay(
00112       QString sn, QList<CubeDisplayProperties *> &displays) {
00113     if (m_controlNet && m_controlNetGraphics) {
00114       QString filename = m_controlNetGraphics->snToFileName(sn);
00115 
00116       for(int i = 0; i < displays.size(); i++) {
00117         CubeDisplayProperties *display = displays[i];
00118 
00119         if (display->fileName() == filename) {
00120           return displays.takeAt(i);
00121         }
00122       }
00123     }
00124 
00125     return NULL;
00126   }
00127 
00128 
00129   PvlObject MosaicControlNetTool::toPvl() const {
00130     PvlObject obj(projectPvlObjectName());
00131 
00132     obj += PvlKeyword("FileName", m_controlNetFile);
00133     obj += PvlKeyword("Visible",
00134         Isis::toString((int)(m_controlNetGraphics && m_controlNetGraphics->isVisible())));
00135     obj += PvlKeyword("Movement", toString(m_movementArrowColorSource));
00136 
00137     if (maxMovementColorMeasureCount() != -1) {
00138       obj += PvlKeyword("MovementColorMaxMeasureCount", Isis::toString(m_measureCount));
00139     }
00140 
00141     if (maxMovementColorResidualMagnitude() != Null) {
00142       obj += PvlKeyword("MovementColorMaxResidualMagnitude",
00143                         Isis::toString(m_residualMagnitude));
00144     }
00145 
00146     return obj;
00147   }
00148 
00149 
00150   void MosaicControlNetTool::fromPvl(const PvlObject &obj) {
00151     m_controlNetFile = obj["FileName"][0];
00152     if (m_controlNetFile == "Null")
00153       m_controlNetFile = "";
00154 
00155     if (obj.HasKeyword("Movement")) {
00156       m_movementArrowColorSource = fromMovementColorSourceString(obj["Movement"]);
00157     }
00158 
00159     if (obj.HasKeyword("MovementColorMaxMeasureCount")) {
00160       m_measureCount = toInt(obj["MovementColorMaxMeasureCount"][0]);
00161     }
00162 
00163     if (obj.HasKeyword("MovementColorMaxResidualMagnitude")) {
00164       m_residualMagnitude = toDouble(obj["MovementColorMaxResidualMagnitude"][0]);
00165     }
00166 
00167     loadNetwork();
00168 
00169     if (m_controlNetGraphics && m_displayControlNetButton) {
00170       m_displayControlNetButton->setChecked( toBool(obj["Visible"][0]) );
00171       displayControlNet();
00172     }
00173   }
00174 
00175 
00176   QString MosaicControlNetTool::projectPvlObjectName() const {
00177     return "MosaicControlNetTool";
00178   }
00179 
00180 
00193   void MosaicControlNetTool::setMovementArrowColorSource(MovementColorSource colorSource,
00194       int maxMeasureCount, double maxResidualMagnitude) {
00195     m_movementArrowColorSource = colorSource;
00196     m_measureCount = maxMeasureCount;
00197     m_residualMagnitude = maxResidualMagnitude;
00198 
00199     if (m_controlNetGraphics) {
00200       m_controlNetGraphics->setArrowsVisible(m_movementArrowColorSource != NoMovement,
00201           m_movementArrowColorSource == MeasureCount, m_measureCount,
00202           m_movementArrowColorSource == ResidualMagnitude, m_residualMagnitude);
00203     }
00204   }
00205 
00206 
00210   MosaicControlNetTool::MovementColorSource MosaicControlNetTool::movementArrowColorSource() const {
00211     return m_movementArrowColorSource;
00212   }
00213 
00214 
00218   int MosaicControlNetTool::maxMovementColorMeasureCount() const {
00219     int result = -1;
00220 
00221     if (m_measureCount > 0)
00222       result = m_measureCount;
00223 
00224     return result;
00225   }
00226 
00227 
00232   double MosaicControlNetTool::maxMovementColorResidualMagnitude() const {
00233     double result = Null;
00234 
00235     if (!IsSpecial(m_residualMagnitude))
00236       result = m_residualMagnitude;
00237 
00238     return result;
00239   }
00240 
00241 
00245   QString MosaicControlNetTool::toString(MovementColorSource source) {
00246     QString result;
00247 
00248     switch (source) {
00249       case NoMovement:
00250         result = "No movement arrows";
00251         break;
00252 
00253       case NoColor:
00254         result = "Black movement arrows";
00255         break;
00256 
00257       case MeasureCount:
00258         result = "Movement arrows colored by measure count";
00259         break;
00260 
00261       case ResidualMagnitude:
00262         result = "Movement arrows colored by residual magnitude";
00263         break;
00264     }
00265 
00266     return result;
00267   }
00268 
00269 
00273   MosaicControlNetTool::MovementColorSource MosaicControlNetTool::fromMovementColorSourceString(
00274       QString string) {
00275     MovementColorSource result = NoMovement;
00276 
00277     for (int i = 0; i < NUM_MOVEMENT_COLOR_SOURCE_VALUES; i++) {
00278       if (string.toLower() == toString((MovementColorSource)i).toLower()) {
00279         result = (MovementColorSource)i;
00280       }
00281     }
00282 
00283     return result;
00284   }
00285 
00286 
00294   QAction *MosaicControlNetTool::getPrimaryAction() {
00295     QAction *action = new QAction(this);
00296     action->setIcon(getIcon("HILLBLU_molecola.png"));
00297     action->setToolTip("Control Net (c)");
00298     action->setShortcut(Qt::Key_C);
00299     QString text  =
00300       "<b>Function:</b>  Display and analyze a control network<br><br>"
00301       "This tool shows you all of the control points in your network for "
00302       "which a latitude/longitude can be calculated. The control points are "
00303       "shown as color-coded '+' marks. The control points have a right-click "
00304       "menu and information about them can be seen just by hovering over them."
00305       "<p><b>Shortcut:</b>  c</p> ";
00306     action->setWhatsThis(text);
00307     return action;
00308   }
00309 
00310 
00311   QWidget *MosaicControlNetTool::getToolBarWidget() {
00312     // Put the buttons in a horizontal orientation
00313     QHBoxLayout *actionLayout = new QHBoxLayout();
00314 
00315     if (m_displayControlNetButton)
00316       actionLayout->addWidget(m_displayControlNetButton);
00317 
00318     if (m_displayConnectivity)
00319       actionLayout->addWidget(m_displayConnectivity);
00320 
00321     if (m_randomizeColors)
00322       actionLayout->addWidget(m_randomizeColors);
00323 
00324     if (m_configMovement)
00325       actionLayout->addWidget(m_configMovement);
00326 
00327     if (m_closeNetwork)
00328       actionLayout->addWidget(m_closeNetwork);
00329 
00330     if (m_loadControlNetButton)
00331       actionLayout->addWidget(m_loadControlNetButton);
00332 
00333     if (m_controlNetFileLabel)
00334       actionLayout->addWidget(m_controlNetFileLabel);
00335 
00336     actionLayout->setMargin(0);
00337 
00338     QWidget *toolBarWidget = new QWidget;
00339     toolBarWidget->setLayout(actionLayout);
00340 
00341     return toolBarWidget;
00342   }
00343 
00344 
00348   void MosaicControlNetTool::configMovement() {
00349     MosaicControlNetToolMovementConfigDialog *configDialog =
00350         new MosaicControlNetToolMovementConfigDialog(this, qobject_cast<QWidget *>(parent()));
00351     configDialog->setAttribute(Qt::WA_DeleteOnClose);
00352     configDialog->show();
00353   }
00354 
00355 
00359   void MosaicControlNetTool::updateTool() {
00360     if (isActive() && m_controlNetFile == "") {
00361       openControlNet();
00362     }
00363   }
00364 
00365 
00370   void MosaicControlNetTool::displayConnectivity() {
00371     if (m_controlNet) {
00372       QList<CubeDisplayProperties *> displays = getWidget()->cubeDisplays();
00373 
00374       QList<QColor> colorsUsed;
00375 
00376       QList< QList<QString> > serialConns =
00377           m_controlNet->GetSerialConnections();
00378 
00379       QList<QString> island;
00380       foreach(island, serialConns) {
00381         QColor color;
00382 
00383         QString cubeSn;
00384         foreach(cubeSn, island) {
00385           CubeDisplayProperties *display = takeDisplay(cubeSn, displays);
00386 
00387           if (display) {
00388             while(!color.isValid()) {
00389               QColor displayColor = display->getValue(
00390                   CubeDisplayProperties::Color).value<QColor>();
00391 
00392               if (colorsUsed.indexOf(displayColor) == -1) {
00393                 colorsUsed.append(displayColor);
00394                 color = displayColor;
00395               }
00396               else {
00397                 QColor ranColor = CubeDisplayProperties::randomColor();
00398 
00399                 if (colorsUsed.indexOf(ranColor) == -1) {
00400                   colorsUsed.append(ranColor);
00401                   color = ranColor;
00402                 }
00403               }
00404             }
00405 
00406             display->setColor(color);
00407           }
00408         }
00409       }
00410     }
00411   }
00412 
00413 
00418   void MosaicControlNetTool::closeNetwork() {
00419     if (m_controlNetGraphics) {
00420       getWidget()->getScene()->removeItem(m_controlNetGraphics);
00421 
00422       delete m_controlNetGraphics;
00423     }
00424 
00425     if (m_controlNet) {
00426       delete m_controlNet;
00427       m_controlNet = NULL;
00428     }
00429 
00430     if (m_displayControlNetButton)
00431       m_displayControlNetButton->setChecked(false);
00432 
00433     if (m_displayControlNetButton)
00434       m_displayControlNetButton->setEnabled(false);
00435 
00436     if (m_displayConnectivity)
00437       m_displayConnectivity->setEnabled(false);
00438 
00439     if (m_closeNetwork) {
00440       m_closeNetwork->setEnabled(false);
00441       m_closeNetwork->setVisible(false);
00442     }
00443 
00444     if (m_loadControlNetButton) {
00445       m_loadControlNetButton->setEnabled(true);
00446       m_loadControlNetButton->setVisible(true);
00447     }
00448 
00449     if (m_controlNetFileLabel)
00450       m_controlNetFileLabel->setText("");
00451 
00452     m_controlNetFile = "";
00453   }
00454 
00455 
00459   void MosaicControlNetTool::objectDestroyed(QObject *obj) {
00460     if (obj == m_loadControlNetButton)
00461       m_loadControlNetButton = NULL;
00462     else if (obj == m_displayControlNetButton)
00463       m_displayControlNetButton = NULL;
00464     else if (obj == m_displayConnectivity)
00465       m_displayConnectivity = NULL;
00466     else if (obj == m_closeNetwork)
00467       m_closeNetwork = NULL;
00468     else if (obj == m_controlNetGraphics)
00469       m_controlNetGraphics = NULL;
00470     else if (obj == m_configMovement)
00471       m_configMovement = NULL;
00472     else if (obj == m_controlNetFileLabel)
00473       m_controlNetFileLabel = NULL;
00474     else if (obj == m_randomizeColors)
00475       m_randomizeColors = NULL;
00476   }
00477 
00478 
00483   void MosaicControlNetTool::openControlNet() {
00484 
00485     // Bring up a file dialog for user to select their cnet file.
00486     QString netFile = FileDialog::getOpenFileName(getWidget(),
00487                       "Select Control Net. File",
00488                       QDir::current().dirName() + "/",
00489                       "Control Networks (*.net);;All Files (*.*)");
00490 
00491     //--------------------------------------------------------------
00492     // if the file is not empty attempt to load in the control points
00493     // for each mosaic item
00494     //---------------------------------------------------------------
00495     if (!netFile.isEmpty()) {
00496       FileName controlNetFile(netFile);
00497       m_controlNetFile = controlNetFile.expanded();
00498       loadNetwork();
00499 
00500       if (m_displayControlNetButton)
00501         m_displayControlNetButton->setChecked(true);
00502     }
00503   }
00504 
00505 
00510   void MosaicControlNetTool::loadNetwork() {
00511     QString netFile = m_controlNetFile;
00512     closeNetwork();
00513     m_controlNetFile = netFile;
00514     m_controlNetFileLabel->setText( QFileInfo(netFile).fileName() );
00515 
00516     if (m_controlNetFile.size() > 0) {
00517       try {
00518         m_controlNet = new ControlNet(
00519             m_controlNetFile);
00520         m_controlNetGraphics = new ControlNetGraphicsItem(m_controlNet,
00521             getWidget());
00522 
00523         setMovementArrowColorSource(m_movementArrowColorSource,
00524                                     m_measureCount, m_residualMagnitude);
00525 
00526         connect(m_controlNetGraphics, SIGNAL(destroyed(QObject *)),
00527                 this, SLOT(objectDestroyed(QObject *)));
00528       }
00529       catch(IException &e) {
00530         QString message = "Invalid control network.\n";
00531         message += e.toString();
00532         QMessageBox::information(getWidget(), "Error", message);
00533         return;
00534       }
00535 
00536       if (m_displayControlNetButton)
00537         m_displayControlNetButton->setEnabled(true);
00538 
00539       if (m_displayConnectivity)
00540         m_displayConnectivity->setEnabled(true);
00541 
00542       if (m_closeNetwork) {
00543         m_closeNetwork->setEnabled(true);
00544         m_closeNetwork->setVisible(true);
00545       }
00546 
00547       if (m_loadControlNetButton) {
00548         m_loadControlNetButton->setEnabled(false);
00549         m_loadControlNetButton->setVisible(false);
00550       }
00551     }
00552   }
00553 
00554 
00555   void MosaicControlNetTool::randomizeColors() {
00556     foreach (CubeDisplayProperties * display, getWidget()->cubeDisplays()) {
00557       display->setColor(CubeDisplayProperties::randomColor());
00558     }
00559   }
00560 
00561 
00566   void MosaicControlNetTool::displayControlNet() {
00567     if (m_controlNetGraphics && m_displayControlNetButton)
00568       m_controlNetGraphics->setVisible(m_displayControlNetButton->isChecked());
00569   }
00570 }