Isis 3 Programmer Reference
MatrixSceneWidget.cpp
1#include "MatrixSceneWidget.h"
2
3#include <float.h>
4#include <sstream>
5
6#include <QGraphicsRectItem>
7#include <QGraphicsSceneMouseEvent>
8#include <QList>
9#include <QMap>
10#include <QPen>
11#include <QtCore>
12#include <QtWidgets>
13#include <QtXml>
14#include <QTransform>
15
16#include "CorrelationMatrix.h"
17#include "Directory.h"
18#include "Distance.h"
19#include "FileName.h"
20#include "GraphicsView.h"
21#include "IException.h"
22#include "IString.h"
23#include "MatrixGraphicsScene.h"
24#include "MatrixGraphicsView.h"
25#include "MatrixOptions.h"
26#include "ProgressBar.h"
27#include "Project.h"
28#include "PvlObject.h"
29#include "Pvl.h"
30#include "SparseBlockMatrix.h"
31#include "TextFile.h"
32#include "Target.h"
33#include "ToolPad.h"
34
35#include <boost/numeric/ublas/fwd.hpp>
36#include <boost/numeric/ublas/io.hpp>
37#include <boost/numeric/ublas/matrix_sparse.hpp>
38#include <boost/numeric/ublas/matrix_proxy.hpp>
39
40using namespace boost::numeric::ublas;
41namespace Isis {
52 bool showTools,
53 bool internalizeToolBarsAndProgress,
54 Directory *directory,
55 QWidget *parent) : QWidget(parent) {
57
59 m_graphicsScene->installEventFilter(this);
60
63 m_graphicsView->setInteractive(true);
64
65// try {
66// m_matrixOptions = new MatrixOptions(
67// m_directory->project()->lastNotUndoneWorkOrder()->correlationMatrix(), this);
68// connect(m_matrixOptions, SIGNAL( optionsUpdated() ),
69// this, SLOT( redrawElements() ) );
70// }
71// catch (IException &e) {
72// throw IException(e, IException::Unknown, "bad workorder", _FILEINFO_);
73// }
74
75 // Draw Initial Matrix
76// try {
77// drawElements( m_directory->project()->lastNotUndoneWorkOrder()->correlationMatrix() );
78// drawGrid( m_directory->project()->lastNotUndoneWorkOrder()->correlationMatrix() );
79// }
80// catch (IException &e) {
81// throw IException(e, IException::Unknown, "bad workorder", _FILEINFO_);
82// }
83
84 m_graphicsView->setResizeAnchor(QGraphicsView::AnchorViewCenter);
85
86 m_quickMapAction = NULL;
87
88 m_outlineRect = NULL;
89
91 m_progress->setVisible(false);
92
93 QGridLayout * sceneLayout = new QGridLayout;
94 sceneLayout->setContentsMargins(0, 0, 0, 0);
95 setLayout(sceneLayout);
96
97 // If we are making our own layout, we can create our own status area.
98 if (!status && internalizeToolBarsAndProgress)
99 status = new QStatusBar;
100
101 if (showTools) {
102
103 if (internalizeToolBarsAndProgress) {
104
105 sceneLayout->addWidget(m_graphicsView, 1, 1, 1, 1);
106
107 QHBoxLayout *horizontalStatusLayout = new QHBoxLayout;
108 horizontalStatusLayout->addWidget(m_progress);
109 horizontalStatusLayout->addStretch();
110 horizontalStatusLayout->addWidget(status);
111
112 sceneLayout->addLayout(horizontalStatusLayout, 2, 0, 1, 2);
113 }
114 else {
115 sceneLayout->addWidget(m_graphicsView, 0, 0, 1, 1);
116 }
117
118 setWhatsThis("This is the matrix scene. You can interact with the "
119 "matrix elements shown here. ");
120
121 getView()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
122 getView()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
123
124 getView()->enableResizeZooming(false);
125
126 connect( getView()->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
127 this, SLOT( sendVisibleRectChanged() ) );
128 connect( getView()->verticalScrollBar() , SIGNAL( valueChanged(int) ),
129 this, SLOT( sendVisibleRectChanged() ) );
130 connect( getView()->horizontalScrollBar(), SIGNAL( rangeChanged(int, int) ),
131 this, SLOT( sendVisibleRectChanged() ) );
132 connect( getView()->verticalScrollBar() , SIGNAL( rangeChanged(int, int) ),
133 this, SLOT( sendVisibleRectChanged() ) );
134 }
135 else {
136 sceneLayout->addWidget(m_graphicsView, 0, 0, 1, 1);
137
138 getView()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
139 getView()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
140
141 setWhatsThis("This is the matrix world view. The matrix will be "
142 "shown here, but you cannot zoom in.");
143 }
144// draw elements
145 }
146
147
152 m_outlineRect = NULL; // The scene will clean this up
153 }
154
155
164
165
174
175
183 bool MatrixSceneWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
184 bool handled = false;
185
186 QList<QGraphicsItem *> selectedGraphicsItems = getScene()->selectedItems();
187 // qDebug() << "number of selected items:" << selectedGraphicsItems.count();
188// QList<MatrixSceneItem *> selectedMatrixElementItems;
189// QList<MatrixElement*> selectedMatrixElements;
190//
191// foreach (QGraphicsItem *graphicsItem, selectedGraphicsItems) {
192// MatrixSceneItem *sceneMatrixElementItem = dynamic_cast<MatrixSceneItem *>(graphicsItem);
193//
194// if (!sceneMatrixElementItem) {
195// sceneMatrixElementItem = dynamic_cast<MatrixSceneItem *>( graphicsItem->parentItem() );
196// }
197//
198// if ( sceneMatrixElementItem && sceneMatrixElementItem->element() ) {
199// selectedMatrixElementItems.append(sceneMatrixElementItem);
200// selectedMatrixElements.append( sceneMatrixElementItem->element() );
201// }
202// }
203//
204// if ( selectedMatrixElementItems.count() ) {
205// QMenu menu;
206//
207// QAction *title = menu.addAction( tr("%L1 Selected MatrixElements").arg( selectedMatrixElements.count() ) );
208// title->setEnabled(false);
209// menu.addSeparator();
210//
211// Project *project = m_directory ? m_directory->project() : NULL;
212//
213// QList<QAction *> displayActs = selectedMatrixElements.supportedActions(project);
214//
215// if (m_directory) {
216// displayActs.append(NULL);
217// displayActs.append( m_directory->supportedActions( new QList<MatrixElement*>(selectedMatrixElements) ) );
218// }
219//
220// QAction *displayAct;
221// foreach(displayAct, displayActs) {
222// if (displayAct == NULL) {
223// menu.addSeparator();
224// }
225// else {
226// menu.addAction(displayAct);
227// }
228// }
229//
230// handled = true;
231// menu.exec( event->screenPos() );
232// }
233
234 return handled;
235 }
236
237
246
247
254 QRectF boundingRect;
255
256 if (m_outlineRect)
257 boundingRect = boundingRect.united( m_outlineRect->boundingRect() );
258
259 return boundingRect;
260 }
261
262
271
272
279 QList<QAction *> viewActs;
280
281// foreach(MatrixTool *tool, *m_tools) {
282// QList<QAction *> toolViewActs = tool->getViewActions();
283// viewActs.append(toolViewActs);
284// }
285
286 return viewActs;
287 }
288
289
297 QList<QAction *> results;
298
299 return results;
300 }
301
302
307// void MatrixSceneWidget::refit() {
308// QRectF sceneRect = m_graphicsScene->itemsBoundingRect();
309//
310// if ( sceneRect.isEmpty() )
311// return;
312//
313// // double xPadding = sceneRect.width() * 0.10;
314// // double yPadding = sceneRect.height() * 0.10;
315// //
316// // sceneRect.adjust(-xPadding, -yPadding, xPadding, yPadding);
317// getView()->fitInView(sceneRect, Qt::KeepAspectRatio);
318// }
319
320
325 QPointF topLeft = getView()->mapToScene(0, 0);
326 QPointF bottomRight =
327 getView()->mapToScene( (int)getView()->width(), (int)getView()->height() );
328
329 QRectF visibleRect(topLeft, bottomRight);
330 emit visibleRectChanged(visibleRect);
331 }
332
333
351 bool MatrixSceneWidget::eventFilter(QObject *obj, QEvent *event) {
352 bool stopProcessingEvent = true;
353
354 switch( event->type() ) {
355 case QMouseEvent::GraphicsSceneMousePress: {
356 if (m_graphicsScene->itemAt( ( (QGraphicsSceneMouseEvent *)event )->scenePos(),
357 QTransform() ) ) {
358 emit elementClicked(m_graphicsScene->itemAt(
359 ( (QGraphicsSceneMouseEvent *)event )->scenePos(),
360 QTransform() )->toolTip() );
361 }
362 stopProcessingEvent = false;
363 break;
364 }
365
366 case QMouseEvent::GraphicsSceneMouseDoubleClick:
367 emit mouseDoubleClick(
368 ((QGraphicsSceneMouseEvent *)event)->scenePos());
369 m_graphicsView->fitInView(m_graphicsScene->itemsBoundingRect(), Qt::KeepAspectRatio);
370 stopProcessingEvent = false;
371 break;
372
373 default:
374 stopProcessingEvent = false;
375 break;
376 }
377
378 return stopProcessingEvent;
379 }
380
381
388
389
390// /**
391// * Refit scene and items when the widget size changes.
392// */
393// void MatrixSceneWidget::fitInView() {
394// }
395
396
407 int elementSize = 10;
408 int startX = 20;
409 int x = 20;
410 int startY = 20;
411 int y = 20;
412 int yOffset = 0;
413 QList<QGraphicsRectItem *> squares;
414 QGraphicsRectItem *rectangle;
415 QList<int> paramList;
416
417 // This will change depending on the values of the elements
418 QBrush fillBrush(Qt::blue);
419 QPen outlinePen(Qt::black);
420 outlinePen.setWidth(0);
421
422 // Image and parameters of column
423 QMapIterator<QString, QStringList> colIterator( *corrMatrix.imagesAndParameters() );
424 // Image and parameters of row
425 QMapIterator<QString, QStringList> rowIterator( *corrMatrix.imagesAndParameters() );
426
427 foreach ( SparseBlockColumnMatrix blockColumn, *( corrMatrix.visibleBlocks() ) ) {
428 QMapIterator<int, matrix<double>*> block(blockColumn);
429 bool lastBlock = true;
430 block.toBack(); // moves iterator to AFTER the last item
431 colIterator.next();
432 rowIterator = colIterator;
433
434 do {
435 block.previous(); // go to last item
436 rowIterator.previous();
437 for (int row = 0; row < (int)block.value()->size1(); row++) {
438 for (int column = 0; column < (int)block.value()->size2(); column++) {
439
440 // The values of this matrix should always be between 1 and -1.
441 QColor fillColor;
442 if ( !m_matrixOptions->colorScheme() ) {
443 double red = 0;
444 double green = 0;
445 double lowerColorValue = fabs( ( *block.value() )(row, column) ) * 255.0;
446 if (fabs( ( *block.value() )(row, column) ) < .5) {
447 red = lowerColorValue * 2;
448 green = 255;
449 }
450 else {
451 green = 255 - ( (lowerColorValue - 127.5) * 2 );
452 red = 255;
453 }
454 fillColor = QColor(red, green, 0);
455 }
456
457 bool draw = true;
458 // Deal with diagonal.
459 if (lastBlock) {
460 if (column < row) {
461 draw = false;
462 }
463 else if (column == row) {
464 outlinePen.setColor(Qt::black);
465 fillBrush.setColor(Qt::blue); // This will always be a single color
466 }
467 else {
468 outlinePen.setColor(Qt::black);
469 if ( m_matrixOptions->colorScheme() ) {
470 if ( fabs( ( *block.value() )(row, column) ) >=
472 fillBrush.setColor( m_matrixOptions->badCorrelationColor() );
473 }
474 else {
475 fillBrush.setColor( m_matrixOptions->goodCorrelationColor() );
476 }
477 }
478 else {
479 fillBrush.setColor(fillColor);
480 }
481 }
482 }
483 else {
484 outlinePen.setColor(Qt::black);
485 if ( m_matrixOptions->colorScheme() ) {
486 if ( fabs( ( *block.value() )(row, column) ) >=
488 fillBrush.setColor( m_matrixOptions->badCorrelationColor() );
489 }
490 else {
491 fillBrush.setColor( m_matrixOptions->goodCorrelationColor() );
492 }
493 }
494 else {
495 fillBrush.setColor(fillColor);
496 }
497 }
498
499 // Should rectangle be a matrix element?
500 if (draw) {
501 rectangle = m_graphicsScene->addRect(x, y, // Start Position
502 elementSize, elementSize, // Rectangle Size
503 outlinePen, fillBrush); // outline/fill options
504 QString img1 = "Image 1 : " + colIterator.key() + "\n";
505 QString param1 = "Parameter 1: " + colIterator.value().at(column) + "\n";
506 QString img2 = "Image 2 : " + rowIterator.key() + "\n";
507 QString param2 = "Parameter 2: " + rowIterator.value().at(row);
508 QString toolTip = "Correlation : "
509 + QString::number( ( *block.value() )(row, column) )
510 + "\n" + img1 + param1 + img2 + param2;
511 rectangle->setToolTip(toolTip);
512 }
513 x += elementSize;
514 }
515 x = startX;
516 y += elementSize;
517 }
518 x = startX;
519 // jump up by the number of rows in the previous block
520 if ( block.hasPrevious() ) {
521 yOffset += block.peekPrevious().value()->size1() * elementSize;
522 }
523 y = startY - yOffset;
524 lastBlock = false;
525 } while ( block.hasPrevious() );
526
527 startX += block.value()->size2() * elementSize;
528 startY += block.value()->size1() * elementSize;
529 x = startX;
530 y = startY;
531 yOffset = 0;
532 }
533 }
534
535
542 int startVX = 20;
543 int startVY = 20;
544 int startHX = 20;
545 int startHY = 20;
546
547 int elementSize = 10;
548
549 QList<int> segments;
550 int segmentLength = 0;
551
552 QMapIterator<QString, QStringList> it( *corrMatrix.imagesAndParameters() );
553 // get list of segment lengths1
554 while ( it.hasNext() ) {
555 it.next();
556 int numOfParams = it.value().count();
557 segmentLength += numOfParams * elementSize;
558 segments.append(segmentLength);
559 }
560
561 segments.removeLast();
562
563 QList<QGraphicsLineItem> lines;
564
565 QPen pen;
566 pen.setColor(Qt::black);
567 pen.setWidth(1);
568
569 // Top of matrix, at this point segmentLength is the length of the longest side
570 QGraphicsLineItem *hLine;
571 hLine = new QGraphicsLineItem(startHX, startHY,
572 startHX + segmentLength, startHY);
573 hLine->setPen(pen);
574 m_graphicsScene->addItem(hLine);
575
576 // Right most side of matrix (edge)
577 QGraphicsLineItem *vLine;
578 vLine = new QGraphicsLineItem(startVX + segmentLength, startVY,
579 startVX + segmentLength, startVY + segmentLength);
580 vLine->setPen(pen);
581 m_graphicsScene->addItem(vLine);
582
583 int edge = startVX + segmentLength;
584 int currentLength = segmentLength;
585 int currentVX = startVX;
586
587 //draw the rest of the grid
588 foreach (int segment, segments) {
589 currentVX = startVX + segment;
590 currentLength = segmentLength - segment;
591
592 vLine = new QGraphicsLineItem(currentVX, startVY,
593 currentVX, startVY + segment);
594
595 hLine = new QGraphicsLineItem(edge - currentLength, startHY + segment,
596 edge, startHY + segment);
597
598 vLine->setPen(pen);
599 hLine->setPen(pen);
600 m_graphicsScene->addItem(vLine);
601 m_graphicsScene->addItem(hLine);
602 }
603 }
604
605
610 drawElements( *m_matrixOptions->parentMatrix() );
611 }
612
613
619// void MatrixSceneWidget::repaintItems(bool colorScheme) {
620// if (colorScheme) {
621// // dont actually use this. just redo the colors?
622// drawElements( m_directory->project()->correlationMatrix() );
623// }
624// else {
625// foreach ( MatrixElement element, m_graphicsScene->items() ) {
626// if ( element.correlation() >= m_options->tolerance() ) {
627// element.setColor( m_options->badCorrelationColor() );
628// }
629// else {
630// element.setColor( m_options->goodCorrelationColor() );
631// }
632// }
633// }
634// }
635
636
643 m_matrixOptions = new MatrixOptions(corrMat, this);
644 connect(m_matrixOptions, SIGNAL( optionsUpdated() ),
645 this, SLOT( redrawElements() ) );
646 }
647}
This is a container for the correlation matrix that comes from a bundle adjust.
A graphics scene with improved user-interaction for use with the MatrixSceneWidget.
A graphics view that resizes in a more friendly way.
This class holds the matrix color and focus information.
QColor badCorrelationColor()
The color selected for the correlation values that are above the given threshold.
QColor goodCorrelationColor()
The color selected for the correlation values that are below the given threshold.
double colorTolerance()
Threshold for what is considered a bad correlation.
bool colorScheme()
Use the green-red gradient if false.
MatrixSceneWidget(QStatusBar *status, bool showTools, bool internalizeToolBarsAndProgress, Directory *directory, QWidget *parent=0)
Constructor, creates a matrix scene widget.
void sendVisibleRectChanged()
This method refits the items in the graphics view.
MatrixGraphicsView * m_graphicsView
The graphics view that displays the scene.
void setUpOptions(CorrelationMatrix corrMat)
Change item colors when options are changed.
bool contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
This is called by MatrixGraphicsScene::contextMenuEvent.
Directory * directory() const
Accessor for the directory.
MatrixGraphicsView * getView() const
Accessor for the QGraphicsView.
MatrixOptions * m_matrixOptions
Options for the correlation matrix.
void redrawItems()
Redraws all the items in the view.
void drawGrid(CorrelationMatrix corrMatrix)
Draw the lines that will show the columns and blocks for each image.
ProgressBar * m_progress
Progress bar.
void mouseDoubleClick(QPointF)
Emitted when handling a mouse double-click.
QList< QAction * > getViewActions()
Accessor for the view actions.
Directory * m_directory
The directory of the project.
QGraphicsScene * getScene() const
Accessor for the QGraphicsScene.
QProgressBar * getProgress()
Accessor for the widget's progress bar.
QAction * m_quickMapAction
??? (always NULL)
QList< QAction * > supportedActions(CorrelationMatrix *matrix)
Get a list of applicable actions for the elements in this scene.
void redrawElements()
Redraw matrix when the focus is changed.
virtual ~MatrixSceneWidget()
Default Destructor.
void visibleRectChanged(QRectF)
Emitted when the visible rectangle is changed.
virtual bool eventFilter(QObject *obj, QEvent *ev)
Pick the relevant actions given the type of event that occured in the scene.
QGraphicsScene * m_graphicsScene
The graphics scene holds the scene items.
QGraphicsRectItem * m_outlineRect
Rectangle outlining the area where the images go.
void drawElements(CorrelationMatrix corrMatrix)
Draw elements.
void elementClicked(QString)
Emitted when an element of the widget is clicked.
QRectF elementsBoundingRect() const
Returns the bounding rectangle for the images.
SparseBlockColumnMatrix.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16