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