1 #include "MosaicControlNetTool.h" 
    5 #include <QGraphicsScene> 
    7 #include <QInputDialog> 
   11 #include <QMessageBox> 
   12 #include <QPushButton> 
   14 #include "ChipViewportsWidget.h" 
   16 #include "ControlList.h" 
   18 #include "ControlNetGraphicsItem.h" 
   21 #include "ControlPointEditWidget.h" 
   23 #include "FileDialog.h" 
   31 #include "MosaicControlNetToolMovementConfigDialog.h" 
   32 #include "MosaicSceneItem.h" 
   33 #include "MosaicSceneWidget.h" 
   34 #include "MosaicGraphicsView.h" 
   51     m_controlNetGraphics = NULL;
 
   52     m_loadControlNetButton = NULL;
 
   53     m_displayControlNetButton = NULL;
 
   54     m_displayConnectivity = NULL;
 
   55     m_closeNetwork = NULL;
 
   56     m_controlNetFileLabel = NULL;
 
   58     m_randomizeColors = NULL;
 
   66     m_displayControlNetButton = 
new QPushButton(
"Display");
 
   67     m_displayControlNetButton->setCheckable(
true);
 
   68     m_displayControlNetButton->setEnabled(
false);
 
   69     m_displayControlNetButton->setToolTip(
"Toggle the visibility of the " 
   70         "control points and movement arrows in the network.");
 
   71     connect(m_displayControlNetButton, SIGNAL(clicked()), 
this, SLOT(
displayControlNet()));
 
   72     connect(m_displayControlNetButton, SIGNAL(destroyed(
QObject *)),
 
   75     m_displayConnectivity = 
new QPushButton(
"Color Islands");
 
   76     m_displayConnectivity->setToolTip(
"Color cubes the same if the control " 
   77         "network has a connection between them");
 
   79     connect(m_displayConnectivity, SIGNAL(destroyed(
QObject *)),
 
   81     m_displayConnectivity->setEnabled(
false);
 
   83     m_randomizeColors = 
new QPushButton(
"Color Images");
 
   84     m_randomizeColors->setToolTip(
"Color all cubes differently");
 
   85     connect(m_randomizeColors, SIGNAL(clicked()), 
this, SLOT(randomizeColors()));
 
   86     connect(m_randomizeColors, SIGNAL(destroyed(
QObject *)),
 
   89     m_configMovement = 
new QPushButton(tr(
"Configure Movement Display"));
 
   90     m_configMovement->setToolTip(tr(
"Show arrow from the apriori surface point to " 
   91         "the adjusted surface point for each control point with this " 
   93     connect(m_configMovement, SIGNAL(clicked()), 
this, SLOT(
configMovement()));
 
   94     connect(m_configMovement, SIGNAL(destroyed(
QObject *)),
 
   97     m_closeNetwork = 
new QPushButton(
"Close Network");
 
   98     m_closeNetwork->setEnabled(
false);
 
   99     m_closeNetwork->setVisible(
false);
 
  100     m_closeNetwork->setToolTip(
"Close the currently open control network");
 
  101     connect(m_closeNetwork, SIGNAL(clicked()), 
this, SLOT(
closeNetwork()));
 
  102     connect(m_closeNetwork, SIGNAL(destroyed(
QObject *)),
 
  105     m_loadControlNetButton = 
new QPushButton(
"Open Network");
 
  106     m_loadControlNetButton->setToolTip(
"Open and load a control network");
 
  107     connect(m_loadControlNetButton, SIGNAL(clicked()),
 
  109     connect(m_loadControlNetButton, SIGNAL(destroyed(
QObject *)),
 
  112     m_controlNetFileLabel = 
new QLabel;
 
  113     m_controlNetFileLabel->setToolTip(
"The filename of the currently open " 
  115     connect(m_controlNetFileLabel, SIGNAL(destroyed(
QObject *)),
 
  118     connect(
this, SIGNAL(controlPointSelected(
ControlPoint *)),
 
  119             getWidget(), SIGNAL(controlPointSelected(
ControlPoint *)));
 
  123   MosaicControlNetTool::~MosaicControlNetTool() {
 
  124     m_controlNetGraphics = NULL; 
 
  126     delete m_loadControlNetButton;
 
  127     delete m_displayControlNetButton;
 
  128     delete m_displayConnectivity;
 
  129     delete m_configMovement;
 
  130     delete m_closeNetwork;
 
  131     delete m_controlNetFileLabel;
 
  132     delete m_randomizeColors;
 
  138   Image *MosaicControlNetTool::takeImage(
 
  139       QString sn, ImageList &images) {
 
  140     if (m_controlNet && m_controlNetGraphics) {
 
  141       QString filename = m_controlNetGraphics->snToFileName(sn);
 
  143       for(
int i = 0; i < images.size(); i++) {
 
  144         Image *image = images[i];
 
  146         if (image->fileName() == filename) {
 
  147           return images.takeAt(i);
 
  156   PvlObject MosaicControlNetTool::toPvl()
 const {
 
  157     PvlObject obj(projectPvlObjectName());
 
  159     obj += PvlKeyword(
"FileName", m_controlNetFile);
 
  160     obj += PvlKeyword(
"Visible",
 
  161         Isis::toString((
int)(m_controlNetGraphics && m_controlNetGraphics->isVisible())));
 
  169       obj += PvlKeyword(
"MovementColorMaxResidualMagnitude",
 
  177   void MosaicControlNetTool::fromPvl(
const PvlObject &obj) {
 
  178     m_controlNetFile = obj[
"FileName"][0];
 
  179     if (m_controlNetFile == 
"Null")
 
  180       m_controlNetFile = 
"";
 
  182     if (obj.hasKeyword(
"Movement")) {
 
  186     if (obj.hasKeyword(
"MovementColorMaxMeasureCount")) {
 
  190     if (obj.hasKeyword(
"MovementColorMaxResidualMagnitude")) {
 
  196     if (m_controlNetGraphics && m_displayControlNetButton) {
 
  197       m_displayControlNetButton->setChecked( 
toBool(obj[
"Visible"][0]) );
 
  203   QString MosaicControlNetTool::projectPvlObjectName()
 const {
 
  204     return "MosaicControlNetTool";
 
  221       int maxMeasureCount, 
double maxResidualMagnitude) {
 
  226     if (m_controlNetGraphics) {
 
  260     double result = 
Null;
 
  277         result = 
"No movement arrows";
 
  281         result = 
"Black movement arrows";
 
  285         result = 
"Movement arrows colored by measure count";
 
  289         result = 
"Movement arrows colored by residual magnitude";
 
  323     action->setIcon(
getIcon(
"HILLBLU_molecola.png"));
 
  324     action->setToolTip(
"Control Net (c)");
 
  325     action->setShortcut(Qt::Key_C);
 
  327       "<b>Function:</b>  Display and analyze a control network<br><br>" 
  328       "This tool shows you all of the control points in your network for " 
  329       "which a latitude/longitude can be calculated. The control points are " 
  330       "shown as color-coded '+' marks. The control points have a right-click " 
  331       "menu and information about them can be seen just by hovering over them." 
  332       "<p><b>Shortcut:</b>  c</p> ";
 
  333     action->setWhatsThis(text);
 
  340     QHBoxLayout *actionLayout = 
new QHBoxLayout();
 
  342     if (m_displayControlNetButton)
 
  343       actionLayout->addWidget(m_displayControlNetButton);
 
  345     if (m_displayConnectivity)
 
  346       actionLayout->addWidget(m_displayConnectivity);
 
  348     if (m_randomizeColors)
 
  349       actionLayout->addWidget(m_randomizeColors);
 
  351     if (m_configMovement)
 
  352       actionLayout->addWidget(m_configMovement);
 
  355       actionLayout->addWidget(m_closeNetwork);
 
  357     if (m_loadControlNetButton)
 
  358       actionLayout->addWidget(m_loadControlNetButton);
 
  360     if (m_controlNetFileLabel)
 
  361       actionLayout->addWidget(m_controlNetFileLabel);
 
  363     actionLayout->setMargin(0);
 
  366     toolBarWidget->setLayout(actionLayout);
 
  368     return toolBarWidget;
 
  378     configDialog->setAttribute(Qt::WA_DeleteOnClose);
 
  379     configDialog->show();
 
  388       getWidget()->setCubesSelectable(
true);
 
  389       getWidget()->getView()->setContextMenuPolicy(Qt::NoContextMenu);
 
  390       getWidget()->enableRubberBand(
false);
 
  393       getWidget()->setCubesSelectable(
true);
 
  394       getWidget()->getView()->setContextMenuPolicy(Qt::DefaultContextMenu);
 
  395       getWidget()->enableRubberBand(
false);
 
  397     if (
isActive() && m_controlNetFile == 
"") {
 
  408     if (m_controlNetGraphics && m_displayControlNetButton)
 
  409       m_controlNetGraphics->setVisible( m_displayControlNetButton->isChecked() );
 
  419       ImageList images = getWidget()->images();
 
  427       foreach(island, serialConns) {
 
  431         foreach(cubeSn, island) {
 
  432           Image *image = takeImage(cubeSn, images);
 
  435             while(!color.isValid()) {
 
  439               if (colorsUsed.indexOf(displayColor) == -1) {
 
  440                 colorsUsed.append(displayColor);
 
  441                 color = displayColor;
 
  446                 if (colorsUsed.indexOf(ranColor) == -1) {
 
  447                   colorsUsed.append(ranColor);
 
  461   void MosaicControlNetTool::displayChangedControlPoint(QString changedControlPoint) {
 
  462     m_controlNetGraphics->clearControlPointGraphicsItem(changedControlPoint);
 
  467   void MosaicControlNetTool::displayNewControlPoint(QString newControlPoint) {
 
  476   void MosaicControlNetTool::displayUponControlPointDeletion() {
 
  477     m_controlNetGraphics->clearControlPointGraphicsItem( QString(
"Point ID") );
 
  487     if (m_controlNetGraphics) {
 
  488       getWidget()->getScene()->removeItem(m_controlNetGraphics);
 
  489       delete m_controlNetGraphics;
 
  492     if (m_controlNet && !getWidget()->directory()) {
 
  497     if (m_displayControlNetButton)
 
  498       m_displayControlNetButton->setChecked(
false);
 
  500     if (m_displayControlNetButton)
 
  501       m_displayControlNetButton->setEnabled(
false);
 
  503     if (m_displayConnectivity)
 
  504       m_displayConnectivity->setEnabled(
false);
 
  506     if (m_closeNetwork) {
 
  507       m_closeNetwork->setEnabled(
false);
 
  508       m_closeNetwork->setVisible(
false);
 
  511     if (m_loadControlNetButton) {
 
  512       m_loadControlNetButton->setEnabled(
true);
 
  513       m_loadControlNetButton->setVisible(
true);
 
  516     if (m_controlNetFileLabel)
 
  517       m_controlNetFileLabel->setText(
"");
 
  519     m_controlNetFile = 
"";
 
  527     if (obj == m_loadControlNetButton)
 
  528       m_loadControlNetButton = NULL;
 
  529     else if (obj == m_displayControlNetButton)
 
  530       m_displayControlNetButton = NULL;
 
  531     else if (obj == m_displayConnectivity)
 
  532       m_displayConnectivity = NULL;
 
  533     else if (obj == m_closeNetwork)
 
  534       m_closeNetwork = NULL;
 
  535     else if (obj == m_controlNetGraphics)
 
  536       m_controlNetGraphics = NULL;
 
  537     else if (obj == m_configMovement)
 
  538       m_configMovement = NULL;
 
  539     else if (obj == m_controlNetFileLabel)
 
  540       m_controlNetFileLabel = NULL;
 
  541     else if (obj == m_randomizeColors)
 
  542       m_randomizeColors = NULL;
 
  551     if (!getWidget()->directory()) {
 
  553       QString netFile = FileDialog::getOpenFileName(getWidget(),
 
  554                         "Select Control Net. File",
 
  555                         QDir::current().dirName() + 
"/",
 
  556                         "Control Networks (*.net);;All Files (*.*)");
 
  562       if (!netFile.isEmpty()) {
 
  564         m_controlNetFile = controlNetFile.expanded();
 
  569         if (activeControl == NULL) {
 
  571           QString message = 
"No active control network chosen.  Choose active control network on " 
  573           QMessageBox::critical(getWidget(), 
"Error", message);
 
  577         m_controlNetFile = activeControl->
fileName(); 
 
  580     if (!m_controlNetFile.isEmpty()) {
 
  582       if (m_displayControlNetButton) m_displayControlNetButton->setChecked(
true);
 
  592     QString netFile = m_controlNetFile;
 
  594     m_controlNetFile = netFile;
 
  595     m_controlNetFileLabel->setText( QFileInfo(netFile).fileName() );
 
  597     if (m_controlNetFile.size() > 0) {
 
  599         if (!getWidget()->directory()) {
 
  600           m_controlNet = 
new ControlNet(m_controlNetFile);
 
  608         connect(m_controlNetGraphics, SIGNAL(destroyed(
QObject *)),
 
  623         QString message = 
"Invalid control network.\n";
 
  625         QMessageBox::information(getWidget(), 
"Error", message);
 
  629       if (m_displayControlNetButton)
 
  630         m_displayControlNetButton->setEnabled(
true);
 
  632       if (m_displayConnectivity)
 
  633         m_displayConnectivity->setEnabled(
true);
 
  635       if (m_closeNetwork) {
 
  636         m_closeNetwork->setEnabled(
true);
 
  637         m_closeNetwork->setVisible(
true);
 
  640       if (m_loadControlNetButton) {
 
  641         m_loadControlNetButton->setEnabled(
false);
 
  642         m_loadControlNetButton->setVisible(
false);
 
  648   void MosaicControlNetTool::randomizeColors() {
 
  649     foreach (
Image *image, getWidget()->images()) {
 
  656   void MosaicControlNetTool::mouseButtonRelease(QPointF point, Qt::MouseButton mouseButton) {
 
  658     if (!
isActive() || !m_controlNet) 
return;
 
  661     if (!getWidget()->directory()) 
return;
 
  663     ControlPoint *cp = NULL;
 
  666     if (mouseButton == Qt::LeftButton) {
 
  669       cp = m_controlNetGraphics->findClosestControlPoint();
 
  676       emit modifyControlPoint(cp);
 
  681     else if (mouseButton == Qt::MidButton) {
 
  684       cp = m_controlNetGraphics->findClosestControlPoint();
 
  687         QString message = 
"No points exist for deleting. Create points " 
  688                           "using the right mouse button.";
 
  689         QMessageBox::warning(getWidget(), 
"Warning", message);
 
  693       emit deleteControlPoint(cp);
 
  698     else if (mouseButton == Qt::RightButton) {
 
  703       ImageList imagesAtMousePosition;
 
  705       foreach (
QGraphicsItem *graphicsItem, itemsAtMousePosition) {
 
  706         MosaicSceneItem *sceneImageItem = 
dynamic_cast<MosaicSceneItem *
>(graphicsItem);
 
  708         if (!sceneImageItem) {
 
  709           sceneImageItem = 
dynamic_cast<MosaicSceneItem *
>(graphicsItem->parentItem());
 
  712         if (sceneImageItem && sceneImageItem->image()) {
 
  713           imagesAtMousePosition.append(sceneImageItem->image());
 
  717       if (imagesAtMousePosition.count()) {
 
  719         Projection *proj = getWidget()->getProjection();
 
  723           TProjection *tproj = (TProjection *) proj;
 
  724           if (tproj && getWidget()->getView()->sceneRect().contains(point)) {
 
  725             if ( tproj->SetCoordinate( point.x(), -1 * point.y() ) ) {
 
  730               emit createControlPoint(lat.degrees(), lon.degrees());
 
QVariant getValue(int property) const 
Get a property's associated data. 
 
This represents an ISIS control net in a project-based GUI interface. 
 
Internalizes a list of images and allows for operations on the entire list. 
 
const double Null
Value for an Isis Null pixel. 
 
File name manipulation and expansion. 
 
void setArrowsVisible(bool visible, bool colorByMeasureCount, int measureCount, bool colorByJigsawError, double residualMagnitude)
Enable/disable and configure movement arrows for all CP displays in the network. 
 
int toInt(const QString &string)
Global function to convert from a string to an integer. 
 
QString toString(bool boolToConvert)
Global function to convert a boolean to a string. 
 
double toDouble(const QString &string)
Global function to convert from a string to a double. 
 
Control * activeControl()
Return the Active Control (control network) 
 
Project * project() const 
Gets the Project for this directory. 
 
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
 
Control Network Display on Mosaic Scene. 
 
bool IsSpecial(const double d)
Returns if the input pixel is special. 
 
This represents a cube in a project-based GUI interface. 
 
void setColor(QColor newColor)
Change the color associated with this cube. 
 
QList< QList< QString > > GetSerialConnections() const 
This method searches through all the cube serial numbers in the network. 
 
ImageDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this image. 
 
QString fileName() const 
Access the name of the control network file associated with this Control. 
 
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control. 
 
Unless noted otherwise, the portions of Isis written by the USGS are public domain. 
 
bool toBool(const QString &string)
Global function to convert from a string to a boolean. 
 
QString toString() const 
Returns a string representation of this exception. 
 
The color of the cube, default randomized (QColor) 
 
void buildChildren()
Call this to re-calculate where control points ought to lie. 
 
ProjectionType
This enum defines the subclasses of Projection supported in Isis. 
 
static QColor randomColor()
Creates and returns a random color for the intial color of the footprint polygon. ...
 
Unless noted otherwise, the portions of Isis written by the USGS are public domain. 
 
These projections are used to map triaxial and irregular-shaped bodies.