Isis 3 Programmer Reference
ChipViewport.cpp
1 #include "IsisDebug.h"
2 
3 #include "ChipViewport.h"
4 
5 #include <iostream>
6 
7 #include <QMessageBox>
8 #include <QPainter>
9 
10 #include "ControlMeasure.h"
11 #include "ControlNet.h"
12 #include "ControlPoint.h"
13 #include "Cube.h"
14 #include "CubeViewport.h"
15 #include "SerialNumber.h"
16 #include "Stretch.h"
17 
18 namespace Isis {
19 
27  ChipViewport::ChipViewport(int width, int height, QWidget *parent) : QWidget(parent) {
28 
29  setFixedSize(width, height);
30  setBackgroundRole(QPalette::Dark);
31 // setFocusPolicy(Qt::StrongFocus);
32 
33  m_width = width;
34  m_height = height;
35  m_zoomFactor = 1.0;
36  m_rotation = 0;
37  m_geomIt = false;
38  m_tempView = NULL;
39  m_cross = true;
40  m_circle = false;
41  m_chip = NULL;
42  m_chipCube = NULL;
43  m_matchChip = NULL;
44  m_matchChipCube = NULL;
45  m_image = NULL;
46  m_image = new QImage(512, 512, QImage::Format_RGB32);
47  m_image->fill(Qt::black);
48  m_controlNet = NULL;
49  m_stretchLocked = false;
50  m_stretch = NULL;
51 
52  m_stretch = new Stretch;
53  }
54 
55 
60  if (m_stretch) {
61  delete m_stretch;
62  m_stretch = NULL;
63  }
64  }
65 
66 
77  bool ChipViewport::cubeToViewport(double samp, double line,
78  int &x, int &y) {
79 
80  m_chip->SetCubePosition(samp, line);
81  x = ((int) m_chip->ChipSample()) - 1;
82  y = ((int) m_chip->ChipLine()) - 1;
83 
84  return m_chip->IsInsideChip(samp, line);
85  }
86 
87 
102  void ChipViewport::setChip(Chip *chip, Cube *chipCube) {
103  // Is the chip usable?
104  if (chip == NULL || chipCube == NULL) {
106  "Can not view NULL chip pointer",
107  _FILEINFO_);
108  }
109 
110  m_zoomFactor = 1.0;
111  m_rotation = 0;
112 
113  m_chip = chip;
114  m_chipCube = chipCube;
115  if (m_image != NULL)
116  delete m_image;
117  m_image = new QImage(chip->Samples(), chip->Lines(), QImage::Format_RGB32);
118 
119  autoStretch();
121  }
122 
123 
129  paintImage();
130  update();
131  }
132 
133 
141 
142  ASSERT(cvp != NULL);
143 
144  if (!cvp || !m_chipCube)
145  return;
146 
147  // only stretch if the CubeViewport is opened to the same cube as we are,
148  // otherwise the signal was meant for a different ChipViewport!
149  if (cvp->cube()->fileName() == m_chipCube->fileName()) {
150 
151  // if user right clicked in the CubeViewport then we get a SIGNAL with a
152  // NULL Stretch. This is used to signify that we need to restretch on our
153  // own (go back to global).
154  if (!newStretch) {
156  paintImage();
157  update();
158  }
159  else {
160  *m_stretch = *newStretch;
161  m_gray.stretch = *newStretch;
162  paintImage();
163  update();
164  }
165  }
166  }
167 
168 
174  void ChipViewport::changeStretchLock(int newStatus) {
175  if (newStatus == 0)
176  m_stretchLocked = false;
177  else
178  m_stretchLocked = true;
179  }
180 
181 
189  void ChipViewport::computeStretch(Stretch &stretch, bool force) {
190  if (m_stretchLocked && !force) {
191  stretch = *m_stretch;
192  }
193  else {
194  Statistics stats;
195  for (int line = 1; line < m_chip->Lines(); line++) {
196  for (int samp = 1; samp < m_chip->Samples(); samp++) {
197  double value = m_chip->GetValue(samp, line);
198  stats.AddData(&value, 1);
199  }
200  }
201 
202  Histogram hist(stats.BestMinimum(), stats.BestMaximum());
203  for (int line = 1; line <= m_chip->Lines(); line++) {
204  for (int samp = 1; samp <= m_chip->Samples(); samp++) {
205  double value = m_chip->GetValue(samp, line);
206  hist.AddData(&value, 1);
207  }
208  }
209 
210  stretch.ClearPairs();
211  if (hist.Percent(0.5) != hist.Percent(99.5)) {
212  stretch.AddPair(hist.Percent(0.5), 0.0);
213  stretch.AddPair(hist.Percent(99.5), 255.0);
214  }
215  else {
216  stretch.AddPair(-DBL_MAX, 0.0);
217  stretch.AddPair(DBL_MAX, 255.0);
218  }
219 
220  *m_stretch = stretch;
221  }
222  }
223 
224 
229  //TODO ??? Need something similar to CubeViewport clipping, so that
230  // at edge of image, fill viewport w/ black
231  for (int y = 0; y < m_chip->Lines(); y++) {
232  QRgb *rgb = (QRgb *) m_image->scanLine(y);
233  int r, g, b;
234  for (int x = 0; x < m_chip->Samples(); x++) {
235  r = g = b = (int) m_gray.stretch.Map(m_chip->GetValue(x + 1, y + 1));
236  rgb[x] = qRgb(r, g, b);
237  }
238  }
239  repaint();
240 
241  }
242 
243 
256  void ChipViewport::paintEvent(QPaintEvent *e) {
257 
258  QPainter painter(this);
259 
260  if (m_tempView != NULL) {
261  painter.drawImage(0, 0, *(m_tempView->m_image));
262  }
263  else {
264  painter.drawImage(0, 0, *m_image);
265  }
266 
267  if (m_cross == true) {
268  painter.setPen(Qt::red);
269  painter.drawLine(0, (m_height - 1) / 2, m_width - 1, (m_height - 1) / 2);
270  painter.drawLine((m_width - 1) / 2, 0, (m_width - 1) / 2, m_height - 1);
271  }
272 
273  if (m_circle == true) {
274  painter.setPen(Qt::red);
275  painter.drawEllipse((m_height - 1) / 2 - m_circleSize / 2,
276  (m_width - 1) / 2 - m_circleSize / 2,
278  }
279 
280  QString serialNumber = m_chipCube? SerialNumber::Compose(*m_chipCube) : QString();
281  if (m_controlNet && !serialNumber.isEmpty()
282  && m_controlNet->GetCubeSerials().contains(serialNumber)) {
283  // draw measure locations if we have a control network
284  // If the serial number is Unknown, we probably have a ground source
285  // file or level 2 which means it does not exist in the network
286  //TODO Is there a better way to handle this?
287  if (m_showPoints && serialNumber.compare("Unknown") &&
288  m_controlNet->GetNumPoints() != 0) {
289  QList<ControlMeasure *> measures =
290  m_controlNet->GetMeasuresInCube(serialNumber);
291  // loop through all points in the control net
292  for (int i = 0; i < measures.count(); i++) {
293  ControlMeasure *m = measures[i];
294  // Find the measurments on the viewport
295  double samp = m->GetSample();
296  double line = m->GetLine();
297  int x, y;
298 
299  cubeToViewport(samp, line, x, y);
300  // Determine pen color
301  // if the point or measure is ignored set to yellow
302  if (m->Parent()->IsIgnored() ||
303  (!m->Parent()->IsIgnored() && m->IsIgnored())) {
304  painter.setPen(QColor(255, 255, 0)); // set point marker yellow
305  }
306  // check for ground measure
307  else if (m->Parent()->GetType() == ControlPoint::Fixed) {
308  painter.setPen(Qt::magenta);// set point marker magenta
309  }
310  else {
311  painter.setPen(Qt::green); // set all other point markers green
312  }
313 
314  // draw points which are not under cross
315  if (x != (m_width - 1) / 2 || y != (m_height - 1) / 2) {
316  painter.drawLine(x - 5, y, x + 5, y);
317  painter.drawLine(x, y - 5, x, y + 5);
318  }
319  }
320  }
321  }
322 
323  m_tempView = NULL;
324  //painter.end();
325 
326  }
327 
328 
335  m_tempView = &newView;
336  update();
337  }
338 
339 
347  return m_chip->CubeSample();
348  }
349 
350 
358  return m_chip->CubeLine();
359  }
360 
361 
366  int x, y;
367  x = m_chip->TackSample();
368  y = m_chip->TackLine() - 1;
369  // Reload with new cube position
370  m_chip->SetChipPosition((double)x, (double)y);
372  }
373 
374 
379  int x, y;
380  x = m_chip->TackSample();
381  y = m_chip->TackLine() + 1;
382  // Reload with new cube position
383  m_chip->SetChipPosition((double)x, (double)y);
385  }
386 
387 
392  int x, y;
393  x = m_chip->TackSample() - 1;
394  y = m_chip->TackLine();
395  // Reload with new cube position
396  m_chip->SetChipPosition((double)x, (double)y);
398  }
399 
400 
405  int x, y;
406  x = m_chip->TackSample() + 1;
407  y = m_chip->TackLine();
408  // Reload with new cube position
409  m_chip->SetChipPosition((double)x, (double)y);
411  }
412 
413 
418  m_zoomFactor /= 2.0;
419  reloadChip();
420  }
421 
422 
427  m_zoomFactor *= 2.0;
428  reloadChip();
429  }
430 
431 
436  m_zoomFactor = 1.0;
437  reloadChip();
438  }
439 
440 
446  void ChipViewport::zoom(double zoomFactor) {
448  reloadChip();
449  }
450 
451 
458  return m_zoomFactor;
459  }
460 
461 
468  void ChipViewport::refreshView(double tackSample, double tackLine) {
470  }
471 
472 
478  void ChipViewport::enterEvent(QEvent *e) {
479  setFocus();
480  }
481 
482 
488  void ChipViewport::keyPressEvent(QKeyEvent *e) {
489 
490  int x, y;
491  x = m_chip->TackSample();
492  y = m_chip->TackLine();
493  if (e->key() == Qt::Key_Up) {
494  y--;
495  }
496  else if (e->key() == Qt::Key_Down) {
497  y++;
498  }
499  else if (e->key() == Qt::Key_Left) {
500  x--;
501  }
502  else if (e->key() == Qt::Key_Right) {
503  x++;
504  }
505  else {
506  QWidget::keyPressEvent(e);
507  return;
508  }
509 
510  // Reload with new cube position
511  m_chip->SetChipPosition((double)x, (double)y);
513  emit userMovedTackPoint();
514  }
515 
516 
526  void ChipViewport::mousePressEvent(QMouseEvent *event) {
527 
528  QPoint p = event->pos();
529  if (event->button() == Qt::LeftButton) {
530  // Reload with new cube position
531  m_chip->SetChipPosition((double)p.x(), (double)p.y());
533  emit userMovedTackPoint();
534  // This was added when the scrolled area was added to the QnetTool.
535  // For some reason when clicking in the ChipViewport, focus would be
536  // lost and the arrow keys would no longer work.
537  //TODO Is this the correct way to fix this, why is it happening?
538  setFocus();
539  }
540  }
541 
542 
548  void ChipViewport::setPoints(bool checked) {
549 
550  if (checked == m_showPoints)
551  return;
552 
553  m_showPoints = checked;
554  repaint();
555 
556  }
557 
558 
564  void ChipViewport::setCross(bool checked) {
565 
566  if (checked == m_cross)
567  return;
568 
569  m_cross = checked;
570  repaint();
571 
572  }
573 
574 
580  void ChipViewport::setCircle(bool checked) {
581 
582  if (checked == m_circle)
583  return;
584 
585  m_circle = checked;
586  repaint();
587  }
588 
589 
596 
597  m_circleSize = size;
598  repaint();
599 
600  }
601 
602 
613  void ChipViewport::geomChip(Chip *matchChip, Cube *matchChipCube) {
614 
615  m_geomIt = true;
616  m_matchChip = matchChip;
617  m_matchChipCube = matchChipCube;
618  try {
619  m_chip->Load(*m_chipCube, *matchChip, *matchChipCube);
620 // m_chip->ReLoad(*matchChip,m_zoomFactor);
621  }
622  catch (IException &e) {
623  QString msg = "Cannot geom chip.\n";
624  msg += e.toString();
625  QMessageBox::information((QWidget *)parent(), "Error", msg);
626  return;
627  }
628 
629  //TODO ??? Can these be added to paintEvent method ???
630  autoStretch();
631  }
632 
633 
642 
643  m_geomIt = false;
644  try {
646  }
647  catch (IException &e) {
648  QString msg = "Cannot load no geom chip.\n";
649  msg += e.toString();
650  QMessageBox::information((QWidget *)parent(), "Error", msg);
651  return;
652  }
653 
654  //TODO ??? Can these be added to paintEvent method ???
655  autoStretch();
656  }
657 
658 
669  void ChipViewport::rotateChip(int rotation) {
670 
671  m_rotation = -rotation;
672  try {
673  m_chip->Load(*m_chipCube, -rotation, m_zoomFactor);
674  }
675  catch (IException &e) {
676  QString msg = "Cannot load rotated chip.\n";
677  msg += e.toString();
678  QMessageBox::information((QWidget *)parent(), "Error", msg);
679  return;
680  }
681 
682  //TODO ??? Can these be added to paintEvent method ???
683  autoStretch();
684  }
685 
686 
699  void ChipViewport::reloadChip(double tackSample, double tackLine) {
700 
701  // Is the chip usable?
702  if (m_chip == NULL) {
704  "Can not view NULL chip pointer",
705  _FILEINFO_);
706  }
707 
708  if (tackSample != 0. && tackLine != 0.)
710  if (m_geomIt) {
711  if (m_matchChip == NULL) {
712  throw IException(IException::User, "Invalid match chip", _FILEINFO_);
713  }
714  try {
716  }
717  catch (IException &e) {
718  QString msg = "Cannot reload chip.\n";
719  msg += e.toString();
720  QMessageBox::information((QWidget *)parent(), "Error", msg);
721  return;
722  }
723 // m_chip->ReLoad(*m_matchChip,m_zoomFactor);
724  }
725  else {
726  try {
728  }
729  catch (IException &e) {
730  QString msg = "Cannot reload chip.\n";
731  msg += e.toString();
732  QMessageBox::information((QWidget *)parent(), "Error", msg);
733  return;
734  }
735  }
736 
737 
738  //TODO ??? Can these be added to paintEvent method ???
739  autoStretch();
740 
741  // emit signal indicating tack point changed so that the TieTool
742  // can update the sample/line label.
744  }
745 }
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
Definition: Chip.cpp:665
void zoom(double zoomFactor)
Zoom by a specified factor.
void enterEvent(QEvent *e)
If mouse enters, make sure key events are processed w/o clicking.
void SetCubePosition(const double sample, const double line)
Compute the position of the chip given a cube coordinate.
Definition: Chip.cpp:682
void panUp()
Pan up.
Cube * cube() const
Definition: CubeViewport.h:348
double m_zoomFactor
Zoom Factor.
Definition: ChipViewport.h:232
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
Definition: ControlPoint.h:386
int m_circleSize
Circle size.
Definition: ChipViewport.h:240
void setCircleSize(int size)
Set the size of the circle.
double Map(const double value) const
Maps an input value to an output value based on the stretch pairs and/or special pixel mappings...
Definition: Stretch.cpp:84
A small chip of data used for pattern matching.
Definition: Chip.h:102
BandInfo m_gray
Info for the gray bands.
Definition: ChipViewport.h:221
Cube * m_chipCube
The chip&#39;s cube.
Definition: ChipViewport.h:223
double BestMaximum(const double percent=99.5) const
This method returns the better of the absolute maximum or the Chebyshev maximum.
Definition: Statistics.cpp:634
void zoomOut()
Zoom out.
Stretch stretch
Stretch for the band BandInfo constructor.
Definition: ChipViewport.h:209
bool IsInsideChip(double sample, double line)
Definition: Chip.cpp:184
void paintImage()
Paints the chip viewport after the chip has been updated.
bool m_stretchLocked
Whether or not to lock the stretch when transforming.
Definition: ChipViewport.h:253
void setCross(bool checked)
Slot to change state of crosshair.
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition: Chip.cpp:204
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
double tackLine()
Returns tack line.
void computeStretch(Stretch &stretch, bool force=false)
Compute automatic stretch for a portion of the cube.
double tackSample()
Return the position of cube under cross hair.
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
void rotateChip(int rotation)
Slot to rotate chip.
void keyPressEvent(QKeyEvent *e)
Process arrow keystrokes on cube.
int GetNumPoints() const
Return the number of control points in the network.
This class is used to accumulate statistics on double arrays.
Definition: Statistics.h:107
QImage * m_image
The image.
Definition: ChipViewport.h:235
void AddPair(const double input, const double output)
Adds a stretch pair to the list of pairs.
Definition: Stretch.cpp:63
double BestMinimum(const double percent=99.5) const
This method returns the better of the absolute minimum or the Chebyshev minimum.
Definition: Statistics.cpp:611
bool m_showPoints
Draw control points.
Definition: ChipViewport.h:237
int Lines() const
Definition: Chip.h:122
ChipViewport * m_tempView
Temporary viewport.
Definition: ChipViewport.h:242
virtual ~ChipViewport()
Destructor.
Container of a cube histogram.
Definition: Histogram.h:86
Pixel value mapper.
Definition: Stretch.h:72
int m_height
Chip height.
Definition: ChipViewport.h:226
bool m_geomIt
geomIt?
Definition: ChipViewport.h:228
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
double CubeLine() const
Definition: Chip.h:226
void refreshView(double tackSample, double tackLine)
Slot to refresh viewport when the tack point has changed.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
double CubeSample() const
Definition: Chip.h:219
void reloadChip(double tackSample=0., double tackLine=0.)
Reloads the chip at the given tack point on the cube.
QList< QString > GetCubeSerials() const
Use this method to get a complete list of all the cube serial numbers in the network.
void geomChip(Chip *matchChip, Cube *matchChipCube)
Slot to geom chip (apply geometry transformation)
ChipViewport(int width, int height, QWidget *parent=0)
Construct an empty viewport.
void paintEvent(QPaintEvent *e)
Repaint the viewport.
int TackSample() const
This method returns a chip&#39;s fixed tack sample; the middle of the chip.
Definition: Chip.h:192
Cube * m_matchChipCube
The matching chip&#39;s cube.
Definition: ChipViewport.h:230
double zoomFactor()
Return the zoom factor.
double ChipLine() const
Definition: Chip.h:242
void autoStretch()
Apply automatic stretch using data from entire chip.
bool m_circle
Draw circle.
Definition: ChipViewport.h:239
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Definition: Chip.cpp:225
void zoom1()
Zoom by a factor of one.
void mousePressEvent(QMouseEvent *event)
Process mouse events.
Stretch * m_stretch
Current stretch on the chip viewport.
Definition: ChipViewport.h:254
void changeStretchLock(int)
Locks or unlocks the stretch on the chip viewport during transformations (zoom, pan, etc.)
void panLeft()
Pan left.
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
void ClearPairs()
Clears the stretch pairs.
Definition: Stretch.h:184
Viewport for Isis Chips.
Definition: ChipViewport.h:85
int Samples() const
Definition: Chip.h:115
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
QList< ControlMeasure *> GetMeasuresInCube(QString serialNumber)
Get all the measures pertaining to a given cube serial number.
void setChip(Chip *chip, Cube *chipCube)
Set chip.
void tackPointChanged(double)
< Signal sent when tack point changes
void panRight()
Pan right.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
a control measurement
void zoomIn()
Zoom in.
double ChipSample() const
Definition: Chip.h:235
double GetValue(int sample, int line)
Loads a Chip with a value.
Definition: Chip.h:161
int m_rotation
Rotation.
Definition: ChipViewport.h:233
bool m_cross
Draw crosshair.
Definition: ChipViewport.h:238
void panDown()
Pan down.
void setPoints(bool checked)
Slot to set whether control points are drawn.
void setCircle(bool checked)
Slot to change state of circle.
PointType GetType() const
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Definition: Statistics.cpp:154
Chip * chip() const
Return chip.
Definition: ChipViewport.h:102
Chip * m_chip
The chip.
Definition: ChipViewport.h:222
void loadView(ChipViewport &newView)
Load with another ChipViewport, used for blinking.
int m_width
Chip width.
Definition: ChipViewport.h:225
void stretchFromCubeViewport(Stretch *, CubeViewport *)
Applies a new stretch to the specified cube viewport.
void nogeomChip()
Slot to un-geom chip (revert geometry transformation)
bool cubeToViewport(double samp, double line, int &x, int &y)
Get viewport x and y from cube sample and line.
int TackLine() const
This method returns a chip&#39;s fixed tack line; the middle of the chip.
Definition: Chip.h:203
Chip * m_matchChip
The matching chip.
Definition: ChipViewport.h:229
IO Handler for Isis Cubes.
Definition: Cube.h:170