Isis 3 Programmer Reference
ControlNetTool.cpp
1 #include "ControlNetTool.h"
2 
3 #include <sstream>
4 #include <vector>
5 #include <iomanip>
6 
7 #include <QBrush>
8 #include <QDebug>
9 #include <QList>
10 #include <QMessageBox>
11 #include <QPainter>
12 #include <QPen>
13 #include <QPoint>
14 #include <QString>
15 
16 #include "Application.h"
17 #include "ControlList.h"
18 #include "ControlMeasure.h"
19 #include "ControlNet.h"
20 #include "ControlPoint.h"
21 #include "ControlPointEditView.h"
22 #include "ControlPointEditWidget.h"
23 #include "CubeDnView.h"
24 #include "Directory.h"
25 #include "IException.h"
26 #include "MdiCubeViewport.h"
27 #include "Project.h"
28 #include "SerialNumber.h"
29 #include "Shape.h"
30 #include "ShapeList.h"
31 #include "ToolPad.h"
32 #include "UniversalGroundMap.h"
33 #include "ViewportMainWindow.h"
34 #include "Workspace.h"
35 
36 using namespace std;
37 
38 namespace Isis {
50  ControlNetTool::ControlNetTool (Directory *directory, QWidget *parent) : Tool(parent) {
51 
52  m_directory = directory;
53  m_view = qobject_cast<CubeDnView *>(parent);
54  }
55 
56 
57  ControlNetTool::~ControlNetTool () {
58  }
59 
60 
76  QAction *action = new QAction(this);
77  action->setIcon(QPixmap(toolIconDir()+"/HILLBLU_molecola.png"));
78  action->setToolTip("Control Point Editor (T)");
79  action->setStatusTip("If tool disabled, make sure you have a control net in your project and "
80  "it is set to the active control.");
81  action->setShortcut(Qt::Key_T);
82 
83  //The object name is being set and used as a key to search with for this action in
84  //other classes (ie. CubeDnView)
85  action->setObjectName("ControlNetTool");
86 
87  QList<ControlList *> cnets = m_directory->project()->controls();
88 
89  //Check to see if there are any control nets within the project.
90  //If not, then this action should be disabled.
91  if (cnets.isEmpty()) {
92  action->setDisabled(true);
93  }
94 
95  return action;
96  }
97 
98 
106  m_controlNet = cnet;
107  // Cannot use Tool::cubeViewportList() because it does not properly return a NULL if viewports
108  // don't exist.
109  if (workspace() && workspace()->cubeViewportList()) {
111  }
112  }
113 
114 
115  void ControlNetTool::loadNetwork() {
116 
117  setControlNet(m_directory->project()->activeControl()->controlNet());
118  }
119 
120 
131  void ControlNetTool::mouseButtonRelease(QPoint p, Qt::MouseButton s) {
132  MdiCubeViewport *cvp = cubeViewport();
133  if (m_controlNet == NULL || cvp == NULL) return;
134 
135  // Determine if the cvp is a Shape
136  // Get all ShapeLists from Project
137  bool isGroundSource = m_view->viewportContainsShape(cvp);
138 
139  double samp,line;
140  cvp->viewportToCube(p.x(),p.y(),samp,line);
141  QString sn = SerialNumber::Compose(cvp->cube()->fileName());
142 
143  if (s == Qt::LeftButton) {
144 
145  if (isGroundSource) {
146  QString message = "Cannot select point for editing on ground source. Select ";
147  message += "point using un-projected images or the Cnet Editor View (choose \"View Network\" ";
148  message += "from the context menu for control nets on the project tree).";
149  QMessageBox::critical(m_ControlNetTool, "Error", message);
150  return;
151  }
152 
153  // Find closest control point in network
154  // since we are in a connected slot, we need to handle exceptions thrown by FindClosest
155  try {
156  ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
157  emit modifyControlPoint(point, sn);
158  }
159  catch (IException &ie) {
160  QString message = "No points exist for editing. Create points using the right mouse";
161  message += " button.";
162  QMessageBox::warning(m_ControlNetTool, "Warning", message);
163  return;
164  }
165  }
166 
167  else if (s == Qt::MidButton) {
168 
169  if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
170  QString message = "No points exist for deleting. Create points ";
171  message += "using the right mouse button.";
172  QMessageBox::warning(m_ControlNetTool, "Warning", message);
173  return;
174  }
175 
176  if (isGroundSource) {
177  QString message = "Cannot select point for deleting on ground source. Select ";
178  message += "point using un-projected images or the Cnet Editor View (choose \"View Network\" ";
179  message += "from the context menu for control nets on the project tree).";
180  QMessageBox::critical(m_ControlNetTool, "Error", message);
181  return;
182  }
183 
184  // Find closest control point in network
185  ControlPoint *point = NULL;
186  try {
187  point = m_controlNet->FindClosest(sn, samp, line);
188 
189  if (point == NULL) {
190  QString message = "No points exist for deleting. Create points ";
191  message += "using the right mouse button.";
192  QMessageBox::warning(m_ControlNetTool, "Warning", message);
193  return;
194  }
195  }
196  catch (IException &e) {
197  QString message = "Cannot find point on this image for deleting.";
198  QMessageBox::critical(m_ControlNetTool, "Error", message);
199  return;
200  }
201 
202  emit deleteControlPoint(point);
203  }
204  else if (s == Qt::RightButton) {
205 
206  UniversalGroundMap *gmap = cvp->universalGroundMap();
207  if (!gmap->SetImage(samp,line)) {
208  QString message = "Invalid latitude or longitude at this point. ";
209  QMessageBox::critical(NULL, "Error", message);
210  return;
211  }
212  double lat = gmap->UniversalLatitude();
213  double lon = gmap->UniversalLongitude();
214  emit createControlPoint(lat, lon, cvp->cube(), isGroundSource);
215  }
216  }
217 
218 
225  void ControlNetTool::paintViewport(MdiCubeViewport *vp, QPainter *painter) {
226 
227  if (m_controlNet) {
228  drawAllMeasurements(vp, painter);
229  }
230  }
231 
232 
241 
242  // Take care of drawing things on all viewPorts.
243  // Calling update will cause the Tool class to call all registered tools
244  // if point has been deleted, this will remove it from the main window
245  if (cubeViewportList()) {
246  MdiCubeViewport *vp;
247  for (int i=0; i<(int)cubeViewportList()->size(); i++) {
248  vp = (*(cubeViewportList()))[i];
249  vp->viewport()->update();
250  }
251  }
252  }
253 
254 
282 
283  // Without a controlnetwork there are no points, or if new net, no points
284  if (m_controlNet == 0 || m_controlNet->GetNumPoints() == 0) return;
285 
286  // Don't show the measurments on cubes not in the serial number list
287  // TODO: Should we show them anyway
288  // TODO: Should we add the SN to the viewPort
289  QString serialNumber = SerialNumber::Compose(*vp->cube(), true);
290 
291  // Get list of shapes in the ipce project and see if the serial number for viewport passed in
292  // matches any of the project shapes. If there's a match, draw any ground points.
293  QList<ShapeList *> projectShapes = m_directory->project()->shapes();
294  foreach (ShapeList *shapeList, projectShapes) {
295  foreach (Shape *shape, *shapeList) {
296  QString shapeSn = shape->serialNumber();
297  if (serialNumber == shapeSn) {
298  // Get cube, then ground map so that location can be calculated
299  UniversalGroundMap *gmap = new UniversalGroundMap(*(shape->cube()));
300  drawGroundMeasures(vp, painter, gmap);
301  delete gmap;
302  gmap = NULL;
303  return;
304  }
305  }
306  }
307 
308 
309  if (!m_controlNet->GetCubeSerials().contains(
310  serialNumber)) return;
311 
312  QList<ControlMeasure *> measures =
313  m_controlNet->GetMeasuresInCube(serialNumber);
314  // loop through all measures contained in this cube
315  for (int i = 0; i < measures.count(); i++) {
316  ControlMeasure *m = measures[i];
317  // Find the measurments on the viewport
318  double samp = m->GetSample();
319  double line = m->GetLine();
320  int x, y;
321  vp->cubeToViewport(samp, line, x, y);
322  // if the point is ignored,
323  if (m->Parent()->IsIgnored()) {
324  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
325  }
326  // point is not ignored, but measure matching this image is ignored,
327  else if (m->IsIgnored()) {
328  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
329  }
330  // Neither point nor measure is not ignored and the measure is fixed,
331  else if (m->Parent()->GetType() != ControlPoint::Free) {
332  painter->setPen(Qt::magenta);// set point marker magenta
333  }
334  else {
335  painter->setPen(Qt::green); // set all other point markers green
336  }
337  // draw points
338  painter->drawLine(x - 5, y, x + 5, y);
339  painter->drawLine(x, y - 5, x, y + 5);
340  }
341  // if ControlNetTool is open, the editPointId will contain the ControlPoint Id of the current edit
342  // point.
343  ControlPoint *currentEditPoint = NULL;
344  if (m_directory->controlPointEditView()) {
345  currentEditPoint = m_directory->controlPointEditView()->controlPointEditWidget()->editPoint();
346  }
347  if (currentEditPoint && m_controlNet->ContainsPoint(currentEditPoint->GetId())) {
348  // Selected point is in the image,
349  if (currentEditPoint->HasSerialNumber(serialNumber)) {
350  // find the measurement
351  double samp = (*currentEditPoint)[serialNumber]->GetSample();
352  double line = (*currentEditPoint)[serialNumber]->GetLine();
353  int x, y;
354  vp->cubeToViewport(samp, line, x, y);
355 
356  QPainterPath path;
357  // Draw circle, then crosshair inside circle
358  path.addEllipse(QPointF(x,y), 5., 5.);
359  path.moveTo(x, y-5);
360  path.lineTo(x, y+5);
361  path.moveTo(x-5, y);
362  path.lineTo(x+5, y);
363 
364 // QBrush brush(Qt::red);
365  QPen pen(QPen(Qt::red, 0.0));
366  // draw the selected point in each image last so it's on top of the rest of the points
367  painter->setPen(pen);
368  painter->drawPath(path);
369  }
370  }
371  }
372 
373 
383  UniversalGroundMap *groundMap) {
384 
385 
386  // if ControlPointEditView is open, the editPointId will contain the ControlPoint Id of the
387  // current edit point. Save so that when drawing point, it can be drawn to indicate current
388  // edit point.
389  ControlPoint *currentEditPoint = NULL;
390  if (m_directory->controlPointEditView()) {
391  currentEditPoint = m_directory->controlPointEditView()->controlPointEditWidget()->editPoint();
392  }
393 
394 
395  // loop through control network looking for fixed and constrained points
396  for (int i = 0; i < m_controlNet->GetNumPoints(); i++) {
397  ControlPoint &p = *((*m_controlNet)[i]);
398  if (p.GetType() == ControlPoint::Free) continue;
399  if (!p.HasAprioriCoordinates()) continue;
400 
401  // Find the sample, line location on the ground image
402  if (groundMap->SetGround(p.GetAprioriSurfacePoint().GetLatitude(),
403  p.GetAprioriSurfacePoint().GetLongitude())) {
404  double samp = groundMap->Sample();
405  double line = groundMap->Line();
406  int x, y;
407  vp->cubeToViewport(samp, line, x, y);
408 
409  // if the point is ignored,
410  if (p.IsIgnored()) {
411  painter->setPen(QColor(255, 255, 0)); // set point marker yellow
412  // draw points
413  painter->drawLine(x - 5, y, x + 5, y);
414  painter->drawLine(x, y - 5, x, y + 5);
415  }
416  // If this point is the current edit point in ControlPointEditView
417  else if (currentEditPoint != NULL && p.GetId() == currentEditPoint->GetId()) {
418  // Draw circle, then crosshair inside circle
419  QPainterPath path;
420  path.addEllipse(QPointF(x,y), 5., 5.);
421  path.moveTo(x, y-5);
422  path.lineTo(x, y+5);
423  path.moveTo(x-5, y);
424  path.lineTo(x+5, y);
425  // set point marker red
426  QBrush brush(Qt::red);
427  // set point marker bold - line width 2
428  QPen pen(brush, 2);
429  painter->setPen(pen);
430  painter->drawPath(path);
431  }
432  // Only Constrained or Fixed pts. If Free, we've already skipped.
433  else {
434  painter->setPen(Qt::magenta);// set point marker magenta
435  // draw points
436  painter->drawLine(x - 5, y, x + 5, y);
437  painter->drawLine(x, y - 5, x, y + 5);
438  }
439  }
440  }
441  }
442 }
Cube display widget for certain Isis MDI applications.
Internalizes a list of shapes and allows for operations on the entire list.
Definition: ShapeList.h:33
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
double Line() const
Returns the current line value of the camera model or projection.
Cube * cube() const
Definition: CubeViewport.h:348
ControlPointEditWidget * controlPointEditWidget()
Returns the ControlPointEditWidget.
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
Handle mouse events on CubeViewport.
Universal Ground Map.
$Date$ $Revision$
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
Namespace for the standard library.
ControlPointEditView * controlPointEditView()
Gets the ControlPointEditWidget associated with the Directory.
Definition: Directory.cpp:1453
void cubeToViewport(double sample, double line, int &x, int &y) const
Turns a cube into a viewport.
Control * activeControl()
Return the Active Control (control network)
Definition: Project.cpp:1903
QAction * toolPadAction(ToolPad *pad)
Adds the ControlNet tool action to the tool pad.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
A Free point is a Control Point that identifies common measurements between two or more cubes...
Definition: ControlPoint.h:399
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
a control network
Definition: ControlNet.h:271
QString GetId() const
Return the Id of the control point.
bool SetGround(Latitude lat, Longitude lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
Cube * cube()
Get the Cube * associated with this display property.
Definition: Shape.cpp:325
UniversalGroundMap * universalGroundMap() const
Definition: CubeViewport.h:363
QString serialNumber()
Get the serial number.
Definition: Shape.cpp:386
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
A single control point.
Definition: ControlPoint.h:369
void setControlNet(ControlNet *controlNet)
Set the active control net to be used for editing.
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Definition: Control.cpp:142
void drawGroundMeasures(MdiCubeViewport *vp, QPainter *painter, UniversalGroundMap *groundMap)
Draw all Fixed or Constrained points on the ground source viewport.
QList< ControlList * > controls()
Return controls in project.
Definition: Project.cpp:2038
void paintViewport(MdiCubeViewport *cvp, QPainter *painter)
This will draw the control measures on the given cube viewport.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
This represents a shape in a project-based GUI interface.
Definition: Shape.h:78
View that displays cubes in a QView-like way.
Definition: CubeDnView.h:111
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
void drawAllMeasurements(MdiCubeViewport *vp, QPainter *painter)
Draw all measurments located on the image in this viewPort.
void paintAllViewports()
This method will repaint the Control Points in each viewport.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Project * project() const
Gets the Project for this directory.
Definition: Directory.cpp:1325
Base class for the Qisis tools.
Definition: Tool.h:81
a control measurement
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
double Sample() const
Returns the current line value of the camera model or projection.
PointType GetType() const
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
$Date$ $Revision$