USGS

Isis 3.0 Object Programmers' Reference

Home

ControlPointGraphicsItem.cpp
1 #include "ControlPointGraphicsItem.h"
2 
3 #include <float.h>
4 #include <iostream>
5 
6 #include <QDebug>
7 #include <QEvent>
8 #include <QGraphicsScene>
9 #include <QGraphicsSceneContextMenuEvent>
10 #include <QMenu>
11 #include <QMessageBox>
12 
13 #include "Constants.h"
14 #include "ControlMeasure.h"
15 #include "ControlPoint.h"
16 #include "FileName.h"
17 #include "MosaicGraphicsView.h"
18 #include "MosaicSceneWidget.h"
19 #include "SerialNumberList.h"
20 #include "Statistics.h"
21 
22 using namespace std;
23 
24 namespace Isis {
29  ControlPointGraphicsItem::ControlPointGraphicsItem(QPointF center,
30  QPointF apriori, ControlPoint *cp, SerialNumberList *snList,
31  MosaicSceneWidget *boundingRectSrc, QGraphicsItem *parent) :
32  QGraphicsRectItem(parent) {
33  m_centerPoint = new QPointF(center);
34  m_mosaicScene = boundingRectSrc;
35  m_controlPoint = cp;
36  m_showArrow = false;
37  m_colorByMeasureCount = false;
39 
40  m_measureCount = -1;
42 
43  setZValue(DBL_MAX);
44 
45  m_origPoint = new QPointF(apriori);
46 
47  if(cp->IsIgnored())
48  setPen(QPen(Qt::red));
49  else if(cp->IsEditLocked())
50  setPen(QPen(Qt::magenta));
51  else if(cp->GetType() == ControlPoint::Fixed)
52  setPen(QPen(Qt::green));
53  else if(cp->GetType() == ControlPoint::Constrained)
54  setPen(QPen(Qt::darkGreen));
55  else // Free
56  setPen(QPen(Qt::blue));
57 
58  setBrush(Qt::NoBrush);
59 
60  setToolTip(makeToolTip(snList));
61 
62  setRect(calcRect());
63  setFiltersChildEvents(true);
64 // installEventFilter(this);
65  }
66 
67 
68  ControlPointGraphicsItem::~ControlPointGraphicsItem() {
69  if(m_centerPoint) {
70  delete m_centerPoint;
71  m_centerPoint = NULL;
72  }
73 
74  if(m_origPoint) {
75  delete m_origPoint;
76  m_origPoint = NULL;
77  }
78 
79  m_mosaicScene = NULL;
80  }
81 
82 
83  void ControlPointGraphicsItem::paint(QPainter *painter,
84  const QStyleOptionGraphicsItem *style, QWidget * widget) {
85  QRectF fullRect = calcRect();
86  QRectF crosshairRect = calcCrosshairRect();
87 
88  if(crosshairRect.isNull())
89  return;
90 
91  if(rect() != fullRect) {
92  setRect(fullRect);
93  }
94  else {
95  painter->setPen(pen());
96  painter->setBrush(brush());
97 
98  QPointF center = crosshairRect.center();
99 
100  QPointF centerLeft(crosshairRect.left(), center.y());
101  QPointF centerRight(crosshairRect.right(), center.y());
102  QPointF centerTop(center.x(), crosshairRect.top());
103  QPointF centerBottom(center.x(), crosshairRect.bottom());
104 
105  painter->drawLine(centerLeft, centerRight);
106  painter->drawLine(centerTop, centerBottom);
107 
108  if(!m_origPoint->isNull() && *m_origPoint != *m_centerPoint
109  && m_showArrow) {
110 
112  painter->setPen(Qt::black);
113  painter->setBrush(Qt::black);
114  }
115  else {
116  QColor zeroColor(Qt::black);
117  QColor fullColor(Qt::green);
118 
119  bool isColored = false;
120 
121  if (m_colorByMeasureCount) {
122  int fullColorMeasureCount = qMax(1, m_measureCount);
123  int measureCount = m_controlPoint->getMeasures(true).count();
124  isColored = (measureCount >= fullColorMeasureCount);
125  }
126  else {
127  fullColor = QColor(Qt::red);
128 
129  double fullColorErrorMag = 0.0;
130 
132  fullColorErrorMag = m_residualMagnitude;
133  }
134 
135  Statistics residualStats;
136  foreach (ControlMeasure *cm, m_controlPoint->getMeasures(true)) {
137  residualStats.AddData(cm->GetResidualMagnitude());
138  }
139 
140  if (residualStats.Average() != Null) {
141  double errorMag = residualStats.Maximum();
142  if (errorMag >= fullColorErrorMag) {
143  isColored = true;
144  }
145  }
146  }
147 
148  QColor finalColor = isColored? fullColor : zeroColor;
149 
150  painter->setPen(finalColor);
151  painter->setBrush(finalColor);
152  }
153 
154  painter->drawLine(*m_origPoint, *m_centerPoint);
155 
156  QPolygonF arrowHead = calcArrowHead();
157  painter->drawPolygon(arrowHead);
158  }
159  }
160  }
161 
162 
163  void ControlPointGraphicsItem::contextMenuEvent(
164  QGraphicsSceneContextMenuEvent * event) {
165  QMenu menu;
166 
167  QAction *title = menu.addAction(
168  m_controlPoint->GetId());
169  title->setEnabled(false);
170  menu.addSeparator();
171 
172  QAction *infoAction = menu.addAction("Show Point Info");
173 
174  QAction *selected = menu.exec(event->screenPos());
175 
176  if(selected == infoAction) {
177  QMessageBox::information(m_mosaicScene, "Control Point Information",
178  toolTip());
179  }
180  }
181 //
182 //
183 //void ControlPointGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
184 // qDebug()<<"ControlPointGraphicsItem::mouseReleaseEvent pointId = "<<QString::fromStdString(m_controlPoint->GetId());
185 //}
186 
187 
188  QRectF ControlPointGraphicsItem::calcRect() const {
189  QRectF pointRect(calcCrosshairRect());
190 
191  if(!m_origPoint->isNull() && pointRect.isValid()) {
192  // Make the rect contain the orig point
193  if(pointRect.left() > m_origPoint->x()) {
194  pointRect.setLeft(m_origPoint->x());
195  }
196  else if(pointRect.right() < m_origPoint->x()) {
197  pointRect.setRight(m_origPoint->x());
198  }
199 
200  if(pointRect.top() > m_origPoint->y()) {
201  pointRect.setTop(m_origPoint->y());
202  }
203  else if(pointRect.bottom() < m_origPoint->y()) {
204  pointRect.setBottom(m_origPoint->y());
205  }
206  }
207 
208  QPolygonF arrowHead = calcArrowHead();
209 
210  if(arrowHead.size() > 2) {
211  pointRect = pointRect.united(arrowHead.boundingRect());
212  }
213 
214  return pointRect;
215  }
216 
217 
218  QRectF ControlPointGraphicsItem::calcCrosshairRect() const {
219  QRectF pointRect;
220 
221  if(m_centerPoint && !m_centerPoint->isNull() && m_mosaicScene) {
222  static const int size = 12;
223  QPoint findSpotScreen =
224  m_mosaicScene->getView()->mapFromScene(*m_centerPoint);
225  QPoint findSpotTopLeftScreen =
226  findSpotScreen - QPoint(size / 2, size / 2);
227 
228  QRect pointRectScreen(findSpotTopLeftScreen, QSize(size, size));
229 
230  pointRect =
231  m_mosaicScene->getView()->mapToScene(pointRectScreen).boundingRect();
232  }
233 
234  return pointRect;
235  }
236 
237 
238  QPolygonF ControlPointGraphicsItem::calcArrowHead() const {
239  QPolygonF arrowHead;
240 
241  if(m_showArrow && !m_origPoint->isNull() &&
242  *m_origPoint != *m_centerPoint) {
243  QRectF crosshairRect = calcCrosshairRect();
244  double headSize = crosshairRect.width() * 4.0 / 5.0;
245 
246  double crosshairSize = headSize;
247 
248  // Draw arrow
249  QPointF lineVector = *m_centerPoint - *m_origPoint;
250  double lineVectorMag = sqrt(lineVector.x() * lineVector.x() +
251  lineVector.y() * lineVector.y());
252  double thetaPointOnLine = crosshairSize / (2 * (tanf(PI / 6) / 2) *
253  lineVectorMag);
254  QPointF pointOnLine = *m_centerPoint - thetaPointOnLine * lineVector;
255 
256  QPointF normalVector = QPointF(-lineVector.y(), lineVector.x());
257  double thetaNormal = crosshairSize / (2 * lineVectorMag);
258 
259  QPointF leftPoint = pointOnLine + thetaNormal * normalVector;
260  QPointF rightPoint = pointOnLine - thetaNormal * normalVector;
261 
262  arrowHead << leftPoint << crosshairRect.center() << rightPoint;
263  }
264 
265  return arrowHead;
266  }
267 
268 
269  QString ControlPointGraphicsItem::makeToolTip(SerialNumberList *snList) {
270  QString toolTip = "<div>Point ID: " +
271  m_controlPoint->GetId();
272  toolTip += "<br />Point Type: " +
273  m_controlPoint->GetPointTypeString();
274  toolTip += "<br />Number of Measures: ";
275  toolTip += toString(m_controlPoint->GetNumMeasures());
276  toolTip += "<br />Ignored: ";
277  toolTip += m_controlPoint->IsIgnored() ? "Yes" : "No";
278  toolTip += "<br />Edit Locked: ";
279  toolTip += m_controlPoint->IsEditLocked() ? "Yes" : "No";
280 
281  toolTip += "<br />";
282 
283  if(snList == NULL) {
284  toolTip += QStringList(m_controlPoint->getCubeSerialNumbers()).join("\n");
285  }
286  else {
287  QStringList serialNums(m_controlPoint->getCubeSerialNumbers());
288 
289  for(int snIndex = 0; snIndex < serialNums.size(); snIndex ++) {
290  QString serialNum = serialNums[snIndex];
291 
292  if(snIndex > 0)
293  toolTip += "<br />";
294 
295  if(snList->HasSerialNumber(serialNum)) {
296  toolTip +=
297  FileName(snList->FileName(serialNum)).name();
298  toolTip += " (" + serialNum + ")";
299  }
300  else {
301  toolTip += serialNum;
302  }
303 
304  double residMag = m_controlPoint->GetMeasure(serialNum)->GetResidualMagnitude();
305  if (residMag != Null) {
306  toolTip += " [residual: <font color='red'>" + toString(residMag) + "</font>]";
307  }
308  }
309  }
310 
311  toolTip += "</div>";
312 
313  return toolTip;
314  }
315 
316 
317 //bool MosaicSceneWidget::eventFilter(QObject *obj, QEvent *event) {
318 //
319 // switch(event->type()) {
320 // case QMouseEvent::GraphicsSceneMousePress: {
321 
322 
323 }
324