1#include "MosaicSceneItem.h"
9#include <QGraphicsItem>
10#include <QGraphicsSceneContextMenuEvent>
15#include <QStyleOptionGraphicsItem>
16#include <QTreeWidgetItem>
19#include "DisplayProperties.h"
20#include "FileDialog.h"
24#include "ImagePolygon.h"
26#include "LineManager.h"
27#include "MosaicGraphicsView.h"
28#include "MosaicSceneWidget.h"
29#include "PolygonTools.h"
31#include "SerialNumber.h"
32#include "Statistics.h"
35#include "TProjection.h"
37using namespace geos::geom;
48 if (parent->getProjection() == NULL) {
49 std::string msg =
"Parent does not have projection in MosaicWidget";
50 throw IException(IException::User, msg, _FILEINFO_);
55 connect(m_image, SIGNAL(destroyed(
QObject *)),
56 this, SLOT(lostCubeDisplay()));
57 connect(m_image, SIGNAL(destroyed(
QObject *)),
58 this, SLOT(deleteLater()));
62 m_cubeDnStretch = NULL;
64 m_showingLabel =
false;
65 m_ignoreCubeDisplayChanged =
false;
73 setToolTip(m_image->displayProperties()->displayName());
75 setAcceptHoverEvents(
true);
87 if(parent->userHasTools()) {
105 scene()->removeItem(
this);
107 while(m_polygons->size()) {
108 delete m_polygons->takeAt(0);
113 QRectF MosaicSceneItem::boundingRect()
const {
116 QGraphicsPolygonItem *polygon;
117 foreach(polygon, *m_polygons) {
118 boundingRect = boundingRect.united(polygon->boundingRect());
121 foreach(polyChild, polygon->childItems()) {
122 if(polyChild->isVisible()) {
123 boundingRect = boundingRect.united(
124 mapFromItem(polyChild, polyChild->boundingRect()).boundingRect());
141 const QStyleOptionGraphicsItem *option,
QWidget *widget) {
149 if (!childItems().count()) {
150 foreach (QGraphicsPolygonItem *polyItem, *m_polygons) {
151 polyItem->paint(painter, option, widget);
160 void MosaicSceneItem::setupFootprint() {
166 tr(
"Cannot display footprints of images which have no footprints. "
174 catch(IException &e) {
175 m_image->deleteLater();
177 IString msg =
"Could not project the footprint from cube [" +
178 m_image->displayProperties()->displayName() +
"]";
190 prepareGeometryChange();
196 while(m_polygons->size()) {
197 QGraphicsPolygonItem *polyItem = m_polygons->at(0);
199 if (polyItem->scene()) {
200 polyItem->scene()->removeItem(polyItem);
202 m_polygons->removeAll(polyItem);
224 bool useFullChildrenHierarchy = (mp->getNumGeometries() > 1) || m_showingLabel;
226 for (
unsigned int i = 0; i < mp->getNumGeometries(); i++) {
227 const Geometry *geom = mp->getGeometryN(i);
228 CoordinateSequence *pts;
230 pts = geom->getCoordinates().release();
238 for (
unsigned int j = 0; j < pts->getSize(); j++) {
242 double x = proj->
XCoord();
243 double y = -1 * (proj->
YCoord());
245 polyPoints.push_back(QPointF(x, y));
249 setFlag(QGraphicsItem::ItemIsSelectable,
true);
250 setFlag(QGraphicsItem::ItemIsFocusable,
true);
252 QGraphicsPolygonItem *polyItem = NULL;
254 if (useFullChildrenHierarchy) {
255 polyItem =
new QGraphicsPolygonItem(
this);
258 polyItem =
new QGraphicsPolygonItem;
261 polyItem->setPolygon(QPolygonF(polyPoints));
263 if (m_showingLabel) {
264 QGraphicsSimpleTextItem *label = NULL;
266 label =
new QGraphicsSimpleTextItem(polyItem);
269 label->setText(m_image->displayProperties()->displayName());
270 label->setFlag(QGraphicsItem::ItemIsMovable);
271 label->setFont(QFont(
"Helvetica", 10));
272 label->setPos(polyItem->polygon().boundingRect().center());
273 label->setFlag(QGraphicsItem::ItemIgnoresTransformations,
true);
275 QRectF boundingRect = polyItem->boundingRect();
276 if(boundingRect.width() < boundingRect.height())
277 label->setRotation(90.0);
280 m_polygons->append(polyItem);
299 double pixelValue = 0;
302 Brick gryBrick(1, 1, 1, m_image->cube()->pixelType());
304 m_image->cube()->read(gryBrick);
306 pixelValue = gryBrick[0];
307 if (pixelValue ==
Null) {
310 if (pixelValue < 0) pixelValue = 0;
311 if (pixelValue > 255) pixelValue = 255;
324 const QStyleOptionGraphicsItem *option) {
326 QApplication::setOverrideCursor(Qt::WaitCursor);
329 QGraphicsPolygonItem *polygon;
330 foreach(polygon, *m_polygons) {
331 QPolygonF polyBounding = polygon->polygon();
332 QRectF sceneRect = polyBounding.boundingRect();
333 QPolygon screenPoly = m_scene->getView()->mapFromScene(sceneRect);
334 QRect visibleBox = screenPoly.boundingRect();
336 int bbWidth = (int)visibleBox.width();
337 int bbHeight = (int)visibleBox.height();
339 int bbLeft = visibleBox.left();
340 int bbTop = visibleBox.top();
341 int bbRight = visibleBox.right();
342 int bbBottom = visibleBox.bottom();
344 QImage image(bbWidth, bbHeight, QImage::Format_ARGB32);
346 for (
int y = bbTop; y <= bbBottom; y++) {
347 QRgb *lineData = (QRgb *)image.scanLine(y - bbTop);
349 for (
int x = bbLeft; x <= bbRight; x++) {
350 lineData[x - bbLeft] = qRgba(0, 0, 0, 0);
354 QPointF scenePos = m_scene->getView()->mapToScene(
357 if(polygon->polygon().containsPoint(scenePos, Qt::OddEvenFill)) {
360 m_scene->getProjection()->SetCoordinate(scenePos.x(),
363 double lat = ((
TProjection *)(m_scene->getProjection()))->UniversalLatitude();
364 double lon = ((
TProjection *)(m_scene->getProjection()))->UniversalLongitude();
371 if(groundMap->SetUniversalGround(lat, lon)) {
374 if(groundMap->Camera() && groundMap->Camera()->InCube()) {
375 double samp = groundMap->Camera()->Sample();
376 double line = groundMap->Camera()->Line();
382 double samp = groundMap->Projection()->WorldX();
383 double line = groundMap->Projection()->WorldY();
390 int stretched = (int)stretch->
Map(dn);
392 lineData[x - bbLeft] = qRgba(stretched, stretched,
402 painter->drawImage(polygon->boundingRect(), image);
409 QApplication::restoreOverrideCursor();
413 QColor MosaicSceneItem::color()
const {
424 if (!m_ignoreCubeDisplayChanged) {
425 bool wasBlocking = m_scene->blockSelectionChange(
true);
427 m_scene->blockSelectionChange(wasBlocking);
429 if (m_showingLabel !=
455 switch (event->type()) {
456 case QEvent::GraphicsSceneContextMenu:
457 scenePos = ((QGraphicsSceneContextMenuEvent *)event)->scenePos();
459 case QEvent::GraphicsSceneHoverEnter:
460 case QEvent::GraphicsSceneHoverMove:
461 case QEvent::GraphicsSceneHoverLeave:
462 scenePos = ((QGraphicsSceneHoverEvent *)event)->scenePos();
464 case QEvent::GraphicsSceneMouseMove:
465 case QEvent::GraphicsSceneMousePress:
466 case QEvent::GraphicsSceneMouseRelease:
467 case QEvent::GraphicsSceneMouseDoubleClick:
468 scenePos = ((QGraphicsSceneMouseEvent *)event)->scenePos();
474 bool ourEvent =
true;
475 if(!scenePos.isNull()) {
480 return QGraphicsObject::sceneEvent(event);
498 QGraphicsPolygonItem * polygon;
499 foreach(polygon, *m_polygons) {
500 if(polygon->contains(p)) {
517 QGraphicsPolygonItem * polygon;
519 m_ignoreCubeDisplayChanged =
true;
525 selected = isSelected();
528 foreach(polygon, *m_polygons) {
529 selected = selected || (polygon->scene() && polygon->isSelected());
532 m_image->displayProperties()->setSelected(selected);
535 if(selected != isSelected()) {
536 bool wasBlocking = m_scene->blockSelectionChange(
true);
537 setSelected(selected);
538 m_scene->blockSelectionChange(wasBlocking);
541 foreach(polygon, *m_polygons) {
542 if(polygon->isSelected() != selected) {
543 polygon->setSelected(selected);
547 m_ignoreCubeDisplayChanged =
false;
557 QGraphicsSceneContextMenuEvent *event) {
562 QAction *title = menu.addAction(m_image->displayProperties()->displayName());
563 title->setEnabled(
false);
569 Directory *directory = m_scene->directory();
575 displayActs.append(NULL);
580 foreach(displayAct, displayActs) {
581 if (displayAct == NULL) {
585 menu.addAction(displayAct);
590 QAction *removeAction = menu.addAction(
"Close Cube");
592 if (QApplication::applicationName() ==
"qmos") {
593 connect(removeAction, SIGNAL(triggered()),
594 m_image, SLOT(deleteLater()));
597 connect(removeAction, SIGNAL(triggered()), SLOT(
onCloseCube()));
600 menu.exec(event->screenPos());
606 void MosaicSceneItem::lostCubeDisplay() {
615 emit mosaicCubeClosed(m_image);
625 if (childItems().count()) {
626 setFlag(QGraphicsItem::ItemIsSelectable,
false);
629 setFlag(QGraphicsItem::ItemIsSelectable, m_scene->cubesSelectable());
635 foreach(QAbstractGraphicsShapeItem *polygon, *m_polygons) {
638 polygon->setBrush(color());
641 polygon->setBrush(Qt::NoBrush);
645 QColor opaqueColor(color());
646 opaqueColor.setAlpha(255);
649 QPen pen(opaqueColor);
650 pen.setCosmetic(
true);
651 polygon->setPen(pen);
654 polygon->setPen(Qt::NoPen);
657 polygon->setFlag(QGraphicsItem::ItemIsSelectable,
658 m_scene->cubesSelectable());
662 polyChild->setVisible(
665 polyChild->setFlag(QGraphicsItem::ItemIsSelectable,
666 m_scene->cubesSelectable());
670 if(polyChild->type() == 9) {
671 QGraphicsSimpleTextItem * text =
672 (QGraphicsSimpleTextItem *)polyChild;
673 text->setBrush(opaqueColor);
679 emit changed(regionsChanged);
692 if (m_cubeDnStretch != NULL || !m_image)
return m_cubeDnStretch;
702 m_image->cube()->read(mgr);
705 for(
int i = 0; i < skip; i++)
709 m_cubeDnStretch =
new Stretch();
710 m_cubeDnStretch->AddPair(stats.
BestMinimum(), 0.0);
711 m_cubeDnStretch->AddPair(stats.
BestMaximum(), 255.0);
713 m_cubeDnStretch->SetNull(0.0);
714 m_cubeDnStretch->SetLis(0.0);
715 m_cubeDnStretch->SetLrs(0.0);
716 m_cubeDnStretch->SetHis(255.0);
717 m_cubeDnStretch->SetHrs(255.0);
718 m_cubeDnStretch->SetMinimum(0.0);
719 m_cubeDnStretch->SetMaximum(255.0);
721 return m_cubeDnStretch;
Buffer for containing a three dimensional section of an image.
void SetBasePosition(const int start_sample, const int start_line, const int start_band)
This method is used to set the base position of the shape buffer.
int size() const
Returns the total number of pixels in the shape buffer.
double * DoubleBuffer() const
Returns the value of the shape buffer.
bool begin()
Moves the shape buffer to the first position.
QList< QAction * > supportedActions(DataType data)
Returns a list of supported actions for a WorkOrder.
Project * project() const
Gets the Project for this directory.
QVariant getValue(int property) const
Get a property's associated data.
QString displayName() const
Returns the display name.
void addSupport(int property)
Call this with every property you support, otherwise they will not communicate properly between widge...
@ Unknown
A type of error that cannot be classified as any of the other error types.
void print() const
Prints a string representation of this exception to stderr.
This is the GUI communication mechanism for cubes.
Property
This is a list of properties and actions that are possible.
@ ShowLabel
True if the cube should show its display name (bool)
@ ShowFill
True if the cube should show a fill area if possible (bool)
@ ShowDNs
True if the cube should show DN values if possible (bool)
@ Selected
The selection state of this cube (bool)
@ Zooming
Data ignored. Tells if the cube supports the zoomFit action.
@ Color
The color of the cube, default randomized (QColor)
@ ZOrdering
Data ignored. Tells if the cube supports the "move*" actions.
@ ShowOutline
True if the cube should be outlined (bool)
This represents a cube in a project-based GUI interface.
geos::geom::MultiPolygon * footprint()
Get the footprint of this image (if available).
ImageDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this image.
Internalizes a list of images and allows for operations on the entire list.
void append(Image *const &value)
Appends an image to the image list.
QList< QAction * > supportedActions(Project *project=NULL)
Gets a list of pre-connected actions that have to do with display.
Buffer manager, for moving through a cube in lines.
void updateChildren()
This applies the displayProperties and selectability.
geos::geom::MultiPolygon * m_180mp
This item's multipolygon in the -180/180 longitude domain.
~MosaicSceneItem()
Mosaic Item destructor.
geos::geom::MultiPolygon * m_mp
This item's multipolygon in the 0/360 longitude domain.
void cubeDisplayChanged()
Someone changed something in the cube display properties, re-read the whole thing.
Stretch * getStretch()
This gets a Stretch object that will work for the cubeDisplay converting from DN to screen pixel.
void drawImage(QPainter *painter, const QStyleOptionGraphicsItem *option)
This method reads in and draws the image associated with this item.
void updateSelection(bool)
Update the selected state.
virtual bool sceneEvent(QEvent *event)
This filters out events that happen within our polygons.
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
The user right clicked on us (or otherwise requested a context menu).
MosaicSceneItem(Image *image, MosaicSceneWidget *parent)
MosaicSceneItem constructor.
void reproject()
Called anytime the user reprojects the cube.
double getPixelValue(int sample, int line)
Returns the pixel value at the given sample/line.
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Re-paints the item.
void onCloseCube()
Emits a signal when Close Cube is selected from the context menu.
bool contains(const QPointF &) const
Test if we contain the point.
The main project for ipce.
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround,...
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround,...
This class is used to accumulate statistics on double arrays.
double BestMinimum(const double percent=99.5) const
This method returns the better of the absolute minimum or the Chebyshev minimum.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
double BestMaximum(const double percent=99.5) const
This method returns the better of the absolute maximum or the Chebyshev maximum.
double Map(const double value) const
Maps an input value to an output value based on the stretch pairs and/or special pixel mappings.
Base class for Map TProjections.
virtual bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType,...
bool Has180Domain() const
This indicates if the longitude domain is -180 to 180 (as opposed to 0 to 360).
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
const double Null
Value for an Isis Null pixel.
bool IsSpecial(const double d)
Returns if the input pixel is special.