1 #include "ControlPointGraphicsItem.h"
8 #include <QGraphicsScene>
9 #include <QGraphicsSceneContextMenuEvent>
11 #include <QMessageBox>
17 #include "MosaicGraphicsView.h"
18 #include "MosaicSceneWidget.h"
29 ControlPointGraphicsItem::ControlPointGraphicsItem(QPointF center,
33 m_centerPoint =
new QPointF(center);
34 m_mosaicScene = boundingRectSrc;
45 m_origPoint =
new QPointF(apriori);
48 if (cp->IsIgnored()) {
49 setPen(QPen(Qt::red, 0.0));
51 else if (cp->IsEditLocked()) {
52 setPen(QPen(Qt::magenta, 0.0));
55 setPen(QPen(Qt::green, 0.0));
58 setPen(QPen(Qt::darkGreen, 0.0));
61 setPen(QPen(Qt::blue, 0.0));
64 setBrush(Qt::NoBrush);
66 setToolTip(makeToolTip(snList));
70 setFlag(QGraphicsItem::ItemIsSelectable,
true);
71 setFlag(QGraphicsItem::ItemIsFocusable,
true);
78 ControlPointGraphicsItem::~ControlPointGraphicsItem() {
93 void ControlPointGraphicsItem::paint(QPainter *painter,
94 const QStyleOptionGraphicsItem *style,
QWidget * widget) {
95 QRectF fullRect = calcRect();
96 QRectF crosshairRect = calcCrosshairRect();
98 if (crosshairRect.isNull()) {
102 if (rect() != fullRect) {
106 painter->setPen(pen());
107 painter->setBrush(brush());
109 QPointF center = crosshairRect.center();
111 QPointF centerLeft(crosshairRect.left(), center.y());
112 QPointF centerRight(crosshairRect.right(), center.y());
113 QPointF centerTop(center.x(), crosshairRect.top());
114 QPointF centerBottom(center.x(), crosshairRect.bottom());
116 painter->drawLine(centerLeft, centerRight);
117 painter->drawLine(centerTop, centerBottom);
119 if (!m_origPoint->isNull() && *m_origPoint != *m_centerPoint
123 painter->setPen(Qt::black);
124 painter->setBrush(Qt::black);
127 QColor zeroColor(Qt::black);
128 QColor fullColor(Qt::green);
130 bool isColored =
false;
134 int measureCount = m_controlPoint->
getMeasures(
true).count();
135 isColored = (measureCount >= fullColorMeasureCount);
138 fullColor = QColor(Qt::red);
140 double fullColorErrorMag = 0.0;
146 Statistics residualStats;
147 foreach (ControlMeasure *cm, m_controlPoint->
getMeasures(
true)) {
148 residualStats.AddData(cm->GetResidualMagnitude());
151 if (residualStats.Average() !=
Null) {
152 double errorMag = residualStats.Maximum();
153 if (errorMag >= fullColorErrorMag) {
159 QColor finalColor = isColored? fullColor : zeroColor;
161 painter->setPen(finalColor);
162 painter->setBrush(finalColor);
165 painter->drawLine(*m_origPoint, *m_centerPoint);
167 QPolygonF arrowHead = calcArrowHead();
168 painter->drawPolygon(arrowHead);
174 ControlPoint *ControlPointGraphicsItem::controlPoint() {
175 return m_controlPoint;
178 void ControlPointGraphicsItem::setArrowVisible(
bool visible,
179 bool colorByMeasureCount,
181 bool colorByResidualMagnitude,
182 double residualMagnitude) {
183 m_showArrow = visible;
193 void ControlPointGraphicsItem::contextMenuEvent(
194 QGraphicsSceneContextMenuEvent * event) {
197 QAction *title = menu.addAction(
198 m_controlPoint->
GetId());
199 title->setEnabled(
false);
202 QAction *infoAction = menu.addAction(
"Show Point Info");
204 QAction *selected = menu.exec(event->screenPos());
206 if (selected == infoAction) {
207 QMessageBox::information(m_mosaicScene,
"Control Point Information",
213 QRectF ControlPointGraphicsItem::calcRect()
const {
214 QRectF pointRect(calcCrosshairRect());
216 if (!m_origPoint->isNull() && pointRect.isValid()) {
218 if (pointRect.left() > m_origPoint->x()) {
219 pointRect.setLeft(m_origPoint->x());
221 else if (pointRect.right() < m_origPoint->x()) {
222 pointRect.setRight(m_origPoint->x());
225 if (pointRect.top() > m_origPoint->y()) {
226 pointRect.setTop(m_origPoint->y());
228 else if (pointRect.bottom() < m_origPoint->y()) {
229 pointRect.setBottom(m_origPoint->y());
233 QPolygonF arrowHead = calcArrowHead();
235 if (arrowHead.size() > 2) {
236 pointRect = pointRect.united(arrowHead.boundingRect());
243 QRectF ControlPointGraphicsItem::calcCrosshairRect()
const {
246 if (m_centerPoint && !m_centerPoint->isNull() && m_mosaicScene) {
247 static const int size = 12;
248 QPoint findSpotScreen =
249 m_mosaicScene->getView()->mapFromScene(*m_centerPoint);
250 QPoint findSpotTopLeftScreen =
251 findSpotScreen - QPoint(size / 2, size / 2);
253 QRect pointRectScreen(findSpotTopLeftScreen, QSize(size, size));
256 m_mosaicScene->getView()->mapToScene(pointRectScreen).boundingRect();
263 QPolygonF ControlPointGraphicsItem::calcArrowHead()
const {
266 if (m_showArrow && !m_origPoint->isNull() &&
267 *m_origPoint != *m_centerPoint) {
268 QRectF crosshairRect = calcCrosshairRect();
269 double headSize = crosshairRect.width() * 4.0 / 5.0;
271 double crosshairSize = headSize;
274 QPointF lineVector = *m_centerPoint - *m_origPoint;
275 double lineVectorMag = sqrt(lineVector.x() * lineVector.x() +
276 lineVector.y() * lineVector.y());
277 double thetaPointOnLine = crosshairSize / (2 * (tanf(
PI / 6) / 2) *
279 QPointF pointOnLine = *m_centerPoint - thetaPointOnLine * lineVector;
281 QPointF normalVector = QPointF(-lineVector.y(), lineVector.x());
282 double thetaNormal = crosshairSize / (2 * lineVectorMag);
284 QPointF leftPoint = pointOnLine + thetaNormal * normalVector;
285 QPointF rightPoint = pointOnLine - thetaNormal * normalVector;
287 arrowHead << leftPoint << crosshairRect.center() << rightPoint;
294 QString ControlPointGraphicsItem::makeToolTip(SerialNumberList *snList) {
295 QString toolTip =
"<div>Point ID: " +
296 m_controlPoint->
GetId();
297 toolTip +=
"<br />Point Type: " +
299 toolTip +=
"<br />Number of Measures: ";
300 toolTip +=
toString(m_controlPoint->GetNumMeasures());
301 toolTip +=
"<br />Ignored: ";
302 toolTip += m_controlPoint->IsIgnored() ?
"Yes" :
"No";
303 toolTip +=
"<br />Edit Locked: ";
304 toolTip += m_controlPoint->IsEditLocked() ?
"Yes" :
"No";
308 if (snList == NULL) {
314 for(
int snIndex = 0; snIndex < serialNums.size(); snIndex ++) {
315 QString serialNum = serialNums[snIndex];
321 if (snList->hasSerialNumber(serialNum)) {
323 FileName(snList->fileName(serialNum)).name();
324 toolTip +=
" (" + serialNum +
")";
327 toolTip += serialNum;
331 if (residMag !=
Null) {
332 toolTip +=
" [residual: <font color='red'>" +
toString(residMag) +
"</font>]";
PointType GetType() const
const double Null
Value for an Isis Null pixel.
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
bool m_colorByMeasureCount
Are we coloring the movement arrow based on CP measure count.
double GetResidualMagnitude() const
Return Residual magnitude.
QString GetPointTypeString() const
Obtain a string representation of the PointType.
const double PI(3.14159265358979323846)
The mathematical constant PI.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
double m_residualMagnitude
Residual magnitude threshold for colored vs. black.
QString GetId() const
Return the Id of the control point.
bool IsSpecial(const double d)
Returns if the input pixel is special.
QList< ControlMeasure * > getMeasures(bool excludeIgnored=false) const
int m_measureCount
Measure count threshold for colored vs. black.
Serial Number list generator.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
QList< QString > getCubeSerialNumbers() const
bool m_colorByResidualMagnitude
Are we coloring the movement arrow based on max CM residual magnitude.