Isis 3 Programmer Reference
ControlPointEdit.cpp
1 #include "ControlPointEdit.h"
2 
3 //TEST
4 #include <QDebug>
5 
6 #include <QApplication>
7 #include <QButtonGroup>
8 #include <QCheckBox>
9 #include <QColor>
10 #include <QDial>
11 #include <QDoubleSpinBox>
12 #include <QFileDialog>
13 #include <QGridLayout>
14 #include <QHBoxLayout>
15 #include <QLCDNumber>
16 #include <QMessageBox>
17 #include <QPalette>
18 #include <QPushButton>
19 #include <QRadioButton>
20 #include <QScrollBar>
21 #include <QSize>
22 #include <QString>
23 #include <QTimer>
24 #include <QToolButton>
25 
26 #include "Application.h"
27 #include "AutoReg.h"
28 #include "AutoRegFactory.h"
29 #include "ChipViewport.h"
30 #include "ControlMeasure.h"
31 #include "ControlMeasureLogData.h"
32 #include "FileName.h"
33 #include "IString.h"
34 #include "ProgramLauncher.h"
35 #include "Pvl.h"
36 #include "UniversalGroundMap.h"
37 
38 namespace Isis {
39 
40  const int VIEWSIZE = 301;
41 
57  bool allowLeftMouse, bool useGeometry) : QWidget(parent) {
58 
59  p_rotation = 0;
60  p_timerOn = false;
61  p_autoRegFact = NULL;
62  p_allowLeftMouse = allowLeftMouse;
63  p_useGeometry = useGeometry;
64 
65  // Initialize some pointers
66  p_leftCube = 0;
67  p_rightCube = 0;
68  p_leftGroundMap = 0;
69  p_rightGroundMap = 0;
70 
71  p_templateFileName = "$base/templates/autoreg/qnetReg.def";
72 
73  createPointEditor(parent);
74  if (cnet != NULL) emit newControlNetwork(cnet);
75  }
76 
77 
78  ControlPointEdit::~ControlPointEdit() {
79 
80  delete p_leftChip;
81  p_leftChip = NULL;
82  delete p_rightChip;
83  p_rightChip = NULL;
84  }
85 
86 
111  // Place everything in a grid
112  QGridLayout *gridLayout = new QGridLayout();
113  gridLayout->setSizeConstraint(QLayout::SetFixedSize);
114  // grid row
115  int row = 0;
116 
117  QString tempFileName = FileName("$base/icons").expanded();
118  QString toolIconDir = tempFileName;
119 
120  QSize isize(27, 27);
121  // Add zoom buttons
122  QToolButton *leftZoomIn = new QToolButton();
123  leftZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
124  leftZoomIn->setIconSize(isize);
125  leftZoomIn->setToolTip("Zoom In 2x");
126  leftZoomIn->setWhatsThis("Zoom In 2x on left measure.");
127 
128  QToolButton *leftZoomOut = new QToolButton();
129  leftZoomOut->setIcon(QPixmap(toolIconDir + "/viewmag-.png"));
130  leftZoomOut->setIconSize(isize);
131  leftZoomOut->setToolTip("Zoom Out 2x");
132  leftZoomOut->setWhatsThis("Zoom Out 2x on left measure.");
133 
134  QToolButton *leftZoom1 = new QToolButton();
135  leftZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
136  leftZoom1->setIconSize(isize);
137  leftZoom1->setToolTip("Zoom 1:1");
138  leftZoom1->setWhatsThis("Show left measure at full resolution.");
139 
140  QHBoxLayout *leftZoomPan = new QHBoxLayout;
141  leftZoomPan->addWidget(leftZoomIn);
142  leftZoomPan->addWidget(leftZoomOut);
143  leftZoomPan->addWidget(leftZoom1);
144 
145  // These buttons only used if allow mouse events in leftViewport
146  QToolButton *leftPanUp = 0;
147  QToolButton *leftPanDown = 0;
148  QToolButton *leftPanLeft = 0;
149  QToolButton *leftPanRight = 0;
150  if (p_allowLeftMouse) {
151  // Add arrows for panning
152  leftPanUp = new QToolButton(parent);
153  leftPanUp->setIcon(QIcon(FileName("$base/icons/up.png").
154  expanded()));
155  leftPanUp->setIconSize(isize);
156  leftPanUp->setToolTip("Move up 1 screen pixel");
157  leftPanUp->setStatusTip("Move up 1 screen pixel");
158  leftPanUp->setWhatsThis("Move the left measure up 1 screen pixel.");
159 
160  leftPanDown = new QToolButton(parent);
161  leftPanDown->setIcon(QIcon(FileName("$base/icons/down.png").
162  expanded()));
163  leftPanDown->setIconSize(isize);
164  leftPanDown->setToolTip("Move down 1 screen pixel");
165  leftPanDown->setStatusTip("Move down 1 screen pixel");
166  leftPanDown->setWhatsThis("Move the left measure down 1 screen pixel.");
167 
168  leftPanLeft = new QToolButton(parent);
169  leftPanLeft->setIcon(QIcon(FileName("$base/icons/back.png").
170  expanded()));
171  leftPanLeft->setIconSize(isize);
172  leftPanLeft->setToolTip("Move left 1 screen pixel");
173  leftPanLeft->setWhatsThis("Move the left measure to the left by 1 screen"
174  "pixel.");
175 
176  leftPanRight = new QToolButton(parent);
177  leftPanRight->setIcon(QIcon(FileName("$base/icons/forward.png").
178  expanded()));
179  leftPanRight->setIconSize(isize);
180  leftPanRight->setToolTip("Move right 1 screen pixel");
181  leftPanRight->setWhatsThis("Move the left measure to the right by 1"
182  "screen pixel.");
183 
184  leftZoomPan->addWidget(leftPanUp);
185  leftZoomPan->addWidget(leftPanDown);
186  leftZoomPan->addWidget(leftPanLeft);
187  leftZoomPan->addWidget(leftPanRight);
188  }
189 
190  leftZoomPan->addStretch();
191  gridLayout->addLayout(leftZoomPan, row, 0);
192 
193  p_rightZoomIn = new QToolButton();
194  p_rightZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
195  p_rightZoomIn->setIconSize(isize);
196  p_rightZoomIn->setToolTip("Zoom In 2x");
197  p_rightZoomIn->setWhatsThis("Zoom In 2x on right measure.");
198 
199  p_rightZoomOut = new QToolButton();
200  p_rightZoomOut->setIcon(QIcon(FileName("$base/icons/viewmag-.png").
201  expanded()));
202  p_rightZoomOut->setIconSize(isize);
203  p_rightZoomOut->setToolTip("Zoom Out 2x");
204  p_rightZoomOut->setWhatsThis("Zoom Out 2x on right measure.");
205 
206  p_rightZoom1 = new QToolButton();
207  p_rightZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
208  p_rightZoom1->setIconSize(isize);
209  p_rightZoom1->setToolTip("Zoom 1:1");
210  p_rightZoom1->setWhatsThis("Show right measure at full resolution.");
211 
212  QHBoxLayout *rightZoomPan = new QHBoxLayout;
213  rightZoomPan->addWidget(p_rightZoomIn);
214  rightZoomPan->addWidget(p_rightZoomOut);
215  rightZoomPan->addWidget(p_rightZoom1);
216 
217  // Add arrows for panning
218  QToolButton *rightPanUp = new QToolButton(parent);
219  rightPanUp->setIcon(QIcon(FileName("$base/icons/up.png").
220  expanded()));
221  rightPanUp->setIconSize(isize);
222  rightPanUp->setToolTip("Move up 1 screen pixel");
223  rightPanUp->setWhatsThis("Move the right measure up 1 screen pixel.");
224 
225  QToolButton *rightPanDown = new QToolButton(parent);
226  rightPanDown->setIcon(QIcon(FileName("$base/icons/down.png").
227  expanded()));
228  rightPanDown->setIconSize(isize);
229  rightPanDown->setToolTip("Move down 1 screen pixel");
230  rightPanUp->setWhatsThis("Move the right measure down 1 screen pixel.");
231 
232  QToolButton *rightPanLeft = new QToolButton(parent);
233  rightPanLeft->setIcon(QIcon(FileName("$base/icons/back.png").
234  expanded()));
235  rightPanLeft->setIconSize(isize);
236  rightPanLeft->setToolTip("Move left 1 screen pixel");
237  rightPanLeft->setWhatsThis("Move the right measure to the left by 1 screen"
238  "pixel.");
239 
240  QToolButton *rightPanRight = new QToolButton(parent);
241  rightPanRight->setIcon(QIcon(FileName("$base/icons/forward.png").
242  expanded()));
243  rightPanRight->setIconSize(isize);
244  rightPanRight->setToolTip("Move right 1 screen pixel");
245  rightPanRight->setWhatsThis("Move the right measure to the right by 1"
246  "screen pixel.");
247 
248  rightZoomPan->addWidget(rightPanUp);
249  rightZoomPan->addWidget(rightPanDown);
250  rightZoomPan->addWidget(rightPanLeft);
251  rightZoomPan->addWidget(rightPanRight);
252  rightZoomPan->addStretch();
253 
254  gridLayout->addLayout(rightZoomPan, row++, 1);
255 
256  // Add zoom factor label and stretch locking checkbox
257  p_leftZoomFactor = new QLabel();
258  QCheckBox *leftLockStretch = new QCheckBox("lock stretch");
259  // there are two "lock stretch" checkboxes (left and right)
260  // use same whats this text for both
261  QString whatsThisTextForStretchLocking = "If checked then a new stretch "
262  "will NOT be calculated for each pan or zoom change. Note that stretch"
263  " changes made using the stretch tool will ALWAYS take effect, "
264  "regardless of the state of this checkbox.";
265  leftLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
266  QHBoxLayout *leftzflsLayout = new QHBoxLayout;
267  leftzflsLayout->addWidget(p_leftZoomFactor);
268  leftzflsLayout->addWidget(leftLockStretch);
269  gridLayout->addLayout(leftzflsLayout, row, 0);
270 
271  p_rightZoomFactor = new QLabel();
272  QCheckBox *rightLockStretch = new QCheckBox("lock stretch");
273  rightLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
274  QHBoxLayout *rightzflsLayout = new QHBoxLayout;
275  rightzflsLayout->addWidget(p_rightZoomFactor);
276  rightzflsLayout->addWidget(rightLockStretch);
277  gridLayout->addLayout(rightzflsLayout, row++, 1);
278 
279 
280  p_leftView = new ChipViewport(VIEWSIZE, VIEWSIZE, this);
281  // Do not want to accept mouse/keyboard events
282  if (!p_allowLeftMouse) p_leftView->setDisabled(true);
283 
284  gridLayout->addWidget(p_leftView, row, 0);
285 
286  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
287  p_leftView, SLOT(setControlNet(ControlNet *)));
288 
289  connect(this,
290  SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
291  p_leftView,
292  SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
293 
294  connect(leftLockStretch, SIGNAL(stateChanged(int)),
295  p_leftView,
296  SLOT(changeStretchLock(int)));
297  leftLockStretch->setChecked(false);
298 
299 
300  // Connect left zoom buttons to ChipViewport's zoom slots
301  connect(leftZoomIn, SIGNAL(clicked()), p_leftView, SLOT(zoomIn()));
302  connect(leftZoomOut, SIGNAL(clicked()), p_leftView, SLOT(zoomOut()));
303  connect(leftZoom1, SIGNAL(clicked()), p_leftView, SLOT(zoom1()));
304 
305  // If zoom on left, need to re-geom right
306  connect(leftZoomIn, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
307  connect(leftZoomOut, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
308  connect(leftZoom1, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
309 
310  // Connect the ChipViewport tackPointChanged signal to
311  // the update sample/line label
312  connect(p_leftView, SIGNAL(tackPointChanged(double)),
313  this, SLOT(updateLeftPositionLabel(double)));
314 
315  // we want to allow this connection so that if a changed point is saved
316  // and the same image is showing in both viewports, the left will refresh.
317  connect(this, SIGNAL(updateLeftView(double, double)),
318  p_leftView, SLOT(refreshView(double, double)));
319 
320  connect (p_leftView, SIGNAL(userMovedTackPoint()),
321  this, SLOT(colorizeSaveButton()));
322 
323  if (p_allowLeftMouse) {
324  // Connect pan buttons to ChipViewport
325  connect(leftPanUp, SIGNAL(clicked()), p_leftView, SLOT(panUp()));
326  connect(leftPanDown, SIGNAL(clicked()), p_leftView, SLOT(panDown()));
327  connect(leftPanLeft, SIGNAL(clicked()), p_leftView, SLOT(panLeft()));
328  connect(leftPanRight, SIGNAL(clicked()), p_leftView, SLOT(panRight()));
329 
330  connect(leftPanUp, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
331  connect(leftPanDown, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
332  connect(leftPanLeft, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
333  connect(leftPanRight, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
334  }
335 
336  p_rightView = new ChipViewport(VIEWSIZE, VIEWSIZE, this);
337  gridLayout->addWidget(p_rightView, row, 1);
338 
339  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
340  p_rightView, SLOT(setControlNet(ControlNet *)));
341  connect(this,
342  SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
343  p_rightView,
344  SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
345  connect(rightLockStretch, SIGNAL(stateChanged(int)),
346  p_rightView,
347  SLOT(changeStretchLock(int)));
348  rightLockStretch->setChecked(false);
349 
350  // Connect the ChipViewport tackPointChanged signal to
351  // the update sample/line label
352  connect(p_rightView, SIGNAL(tackPointChanged(double)),
353  this, SLOT(updateRightPositionLabel(double)));
354  connect(this, SIGNAL(updateRightView(double, double)),
355  p_rightView, SLOT(refreshView(double, double)));
356 
357  connect (p_rightView, SIGNAL(userMovedTackPoint()),
358  this, SLOT(colorizeSaveButton()));
359 
360  connect(p_rightZoomIn, SIGNAL(clicked()), p_rightView, SLOT(zoomIn()));
361  connect(p_rightZoomOut, SIGNAL(clicked()), p_rightView, SLOT(zoomOut()));
362  connect(p_rightZoom1, SIGNAL(clicked()), p_rightView, SLOT(zoom1()));
363 
364  // Connect pan buttons to ChipViewport
365  connect(rightPanUp, SIGNAL(clicked()), p_rightView, SLOT(panUp()));
366  connect(rightPanDown, SIGNAL(clicked()), p_rightView, SLOT(panDown()));
367  connect(rightPanLeft, SIGNAL(clicked()), p_rightView, SLOT(panLeft()));
368  connect(rightPanRight, SIGNAL(clicked()), p_rightView, SLOT(panRight()));
369 
370  connect(rightPanUp, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
371  connect(rightPanDown, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
372  connect(rightPanLeft, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
373  connect(rightPanRight, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
374 
375  // Create chips for left and right
376  p_leftChip = new Chip(VIEWSIZE, VIEWSIZE);
377  p_rightChip = new Chip(VIEWSIZE, VIEWSIZE);
378 
379  QButtonGroup *bgroup = new QButtonGroup();
380  p_nogeom = new QRadioButton();
381  p_nogeom->setChecked(true);
382  connect(p_nogeom, SIGNAL(clicked()), this, SLOT(setNoGeom()));
383 
384  QCheckBox *linkZoom = NULL;
385  if (p_useGeometry) {
386  p_nogeom->setText("No geom/rotate");
387  p_nogeom->setToolTip("Reset right measure to it's native geometry.");
388  p_nogeom->setWhatsThis("Reset right measure to it's native geometry. "
389  "If measure was rotated, set rotation back to 0. "
390  "If measure was geomed to match the left measure, "
391  "reset the geometry back to it's native state.");
392  p_geom = new QRadioButton("Geom");
393  p_geom->setToolTip("Geom right measure to match geometry of left measure.");
394  p_geom->setWhatsThis("Using an affine transform, geom the right measure to match the "
395  "geometry of the left measure.");
396  bgroup->addButton(p_geom);
397  connect(p_geom, SIGNAL(clicked()), this, SLOT(setGeom()));
398  }
399  else {
400  linkZoom = new QCheckBox("Link Zoom");
401  linkZoom->setToolTip("Link zooming between the left and right views.");
402  linkZoom->setWhatsThis("When zooming in the left view, the right view will "
403  "be set to the same zoom factor as the left view.");
404  connect(linkZoom, SIGNAL(toggled(bool)), this, SLOT(setZoomLink(bool)));
405 
406  p_nogeom->setText("No rotate");
407  p_nogeom->setToolTip("Reset right measure to it's native geometry.");
408  p_nogeom->setWhatsThis("Reset right measure to it's native geometry. "
409  "If measure was rotated, set rotation back to 0.");
410  }
411  bgroup->addButton(p_nogeom);
412 
413  QRadioButton *rotate = new QRadioButton("Rotate");
414  bgroup->addButton(rotate);
415  // TODO: ?? Don't think we need this connection
416  connect(rotate, SIGNAL(clicked()), this, SLOT(setRotate()));
417 
418  // Set some defaults
419  p_geomIt = false;
420  p_rotation = 0;
421  p_linkZoom = false;
422 
423  p_dial = new QDial();
424  p_dial->setRange(0, 360);
425  p_dial->setWrapping(false);
426  p_dial->setNotchesVisible(true);
427  p_dial->setNotchTarget(5.);
428  p_dial->setEnabled(false);
429  p_dial->setToolTip("Rotate right measure");
430  p_dial->setWhatsThis("Rotate the right measure by degrees.");
431 
432  p_dialNumber = new QLCDNumber();
433  p_dialNumber->setEnabled(false);
434  p_dialNumber->setToolTip("Rotate right measure");
435  p_dialNumber->setWhatsThis("Rotate the right measure by given number"
436  " of degrees.");
437  connect(p_dial, SIGNAL(valueChanged(int)), p_dialNumber, SLOT(display(int)));
438  connect(p_dial, SIGNAL(valueChanged(int)), p_rightView, SLOT(rotateChip(int)));
439 
440  QCheckBox *showPoints = new QCheckBox("Show control points");
441  showPoints->setToolTip("Draw control point crosshairs");
442  showPoints->setWhatsThis("This will toggle whether crosshairs are drawn"
443  " for the control points located within the measure''s"
444  " view. For areas of dense measurements, turning this"
445  " off will allow easier viewing of features.");
446  connect(showPoints, SIGNAL(toggled(bool)), p_leftView, SLOT(setPoints(bool)));
447  connect(showPoints, SIGNAL(toggled(bool)), p_rightView, SLOT(setPoints(bool)));
448  showPoints->setChecked(true);
449 
450  QCheckBox *cross = new QCheckBox("Show crosshair");
451  connect(cross, SIGNAL(toggled(bool)), p_leftView, SLOT(setCross(bool)));
452  connect(cross, SIGNAL(toggled(bool)), p_rightView, SLOT(setCross(bool)));
453  cross->setChecked(true);
454  cross->setToolTip("Show the red crosshair across measure view");
455  cross->setWhatsThis("This will toggle whether the crosshair across the"
456  " measure view will be shown");
457 
458  QCheckBox *circle = new QCheckBox("Circle");
459  circle->setChecked(false);
460  circle->setToolTip("Draw circle");
461  circle->setWhatsThis("Draw circle on measure view. This can aid in"
462  " centering a crater under the crosshair.");
463  connect(circle, SIGNAL(toggled(bool)), this, SLOT(setCircle(bool)));
464 
465  p_slider = new QScrollBar(Qt::Horizontal);
466  p_slider->setRange(1, 100);
467  p_slider->setSingleStep(1);
468  connect(p_slider, SIGNAL(valueChanged(int)), p_leftView, SLOT(setCircleSize(int)));
469  connect(p_slider, SIGNAL(valueChanged(int)), p_rightView, SLOT(setCircleSize(int)));
470  p_slider->setValue(20);
471  p_slider->setDisabled(true);
472  p_slider->hide();
473  p_slider->setToolTip("Adjust circle size");
474  p_slider->setWhatsThis("This allows the cirle size to be adjusted.");
475 
476  QVBoxLayout *vlayout = new QVBoxLayout();
477  if (!p_useGeometry) {
478  vlayout->addWidget(linkZoom);
479  }
480  vlayout->addWidget(p_nogeom);
481  if (p_useGeometry) {
482  vlayout->addWidget(p_geom);
483  }
484  vlayout->addWidget(rotate);
485  vlayout->addWidget(p_dial);
486  vlayout->addWidget(p_dialNumber);
487  vlayout->addWidget(showPoints);
488  vlayout->addWidget(cross);
489  vlayout->addWidget(circle);
490  vlayout->addWidget(p_slider);
491  gridLayout->addLayout(vlayout, row++, 2);
492 
493  // Show sample / line for measure of chips shown
494  p_leftSampLinePosition = new QLabel();
495  p_leftSampLinePosition->setToolTip("Sample/Line under the crosshair");
496  gridLayout->addWidget(p_leftSampLinePosition, row, 0);
497  p_rightSampLinePosition = new QLabel();
498  p_rightSampLinePosition->setToolTip("Sample/Line under the crosshair");
499  gridLayout->addWidget(p_rightSampLinePosition, row++, 1);
500 
501  if (p_useGeometry) {
502  // Show lat / lon for measure of chips shown
503  p_leftLatLonPosition = new QLabel();
504  p_leftLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
505  gridLayout->addWidget(p_leftLatLonPosition, row, 0);
506  p_rightLatLonPosition = new QLabel();
507  p_rightLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
508  gridLayout->addWidget(p_rightLatLonPosition, row++, 1);
509  }
510 
511 
512  // Add auto registration extension
513  p_autoRegExtension = new QWidget;
514  p_oldPosition = new QLabel;
515  p_oldPosition->setToolTip("Measure Sample/Line before sub-pixel "
516  "registration");
517  p_oldPosition->setWhatsThis("Original Sample/Line of the right measure "
518  "before the sub-pixel registration. If you select the \"Undo\" "
519  "button, the measure will revert back to this Sample/Line.");
520  p_goodFit = new QLabel;
521  p_goodFit->setToolTip("Goodness of Fit result from sub-pixel registration.");
522  p_goodFit->setWhatsThis("Resulting Goodness of Fit from sub-pixel "
523  "registration.");
524  QVBoxLayout *autoRegLayout = new QVBoxLayout;
525  autoRegLayout->setMargin(0);
526  autoRegLayout->addWidget(p_oldPosition);
527  autoRegLayout->addWidget(p_goodFit);
528  p_autoRegExtension->setLayout(autoRegLayout);
529  p_autoRegShown = false;
530  p_autoRegAttempted = false;
531  gridLayout->addWidget(p_autoRegExtension, row++, 1);
532 
533 
534  QHBoxLayout *leftLayout = new QHBoxLayout();
535  QToolButton *stop = new QToolButton();
536  stop->setIcon(QPixmap(toolIconDir + "/blinkStop.png"));
537  stop->setIconSize(QSize(22, 22));
538  stop->setToolTip("Blink Stop");
539  QString text = "<b>Function:</b> Stop automatic timed blinking";
540  stop->setWhatsThis(text);
541  connect(stop, SIGNAL(released()), this, SLOT(blinkStop()));
542 
543  QToolButton *start = new QToolButton();
544  start->setIcon(QPixmap(toolIconDir + "/blinkStart.png"));
545  start->setIconSize(QSize(22, 22));
546  start->setToolTip("Blink Start");
547  text = "<b>Function:</b> Start automatic timed blinking. Cycles \
548  through linked viewports at variable rate";
549  start->setWhatsThis(text);
550  connect(start, SIGNAL(released()), this, SLOT(blinkStart()));
551 
552  p_blinkTimeBox = new QDoubleSpinBox();
553  p_blinkTimeBox->setMinimum(0.1);
554  p_blinkTimeBox->setMaximum(5.0);
555  p_blinkTimeBox->setDecimals(1);
556  p_blinkTimeBox->setSingleStep(0.1);
557  p_blinkTimeBox->setValue(0.5);
558  p_blinkTimeBox->setToolTip("Blink Time Delay");
559  text = "<b>Function:</b> Change automatic blink rate between " +
560  QString::number(p_blinkTimeBox->minimum()) + " and " +
561  QString::number(p_blinkTimeBox->maximum()) + " seconds";
562  p_blinkTimeBox->setWhatsThis(text);
563  connect(p_blinkTimeBox, SIGNAL(valueChanged(double)),
564  this, SLOT(changeBlinkTime(double)));
565 
566  leftLayout->addWidget(stop);
567  leftLayout->addWidget(start);
568  leftLayout->addWidget(p_blinkTimeBox);
569 
570  if (p_useGeometry) {
571  QPushButton *find = new QPushButton("Find");
572  find->setShortcut(Qt::Key_F);
573  find->setToolTip("Move right measure to same Latitude/Longitude as left. "
574  "<strong>Shortcut: F</strong>");
575  find->setWhatsThis("Find the Latitude/Longitude under the crosshair in the "
576  "left measure and move the right measure to the same "
577  "latitude/longitude.");
578  leftLayout->addWidget(find);
579  connect(find, SIGNAL(clicked()), this, SLOT(findPoint()));
580  }
581 
582  leftLayout->addStretch();
583  gridLayout->addLayout(leftLayout, row, 0);
584 
585  QHBoxLayout *rightLayout = new QHBoxLayout();
586  p_autoReg = new QPushButton("Register");
587  p_autoReg->setShortcut(Qt::Key_R);
588  p_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
589  "<strong>Shortcut: R</strong>");
590  p_autoReg->setWhatsThis("Sub-pixel register the right measure to the left "
591  "and move the result under the crosshair. After "
592  "viewing the results, the option exists to move the "
593  "measure back to the original position by selecting "
594  "<strong>\"Undo Registration\"</strong>.");
595  if (p_allowLeftMouse) {
596  p_saveMeasure = new QPushButton("Save Measures");
597  p_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
598  "point (control point currently being edited). "
599  "<strong>Shortcut: M</strong>. "
600  " <strong>Note: The edit control point "
601  "will not be saved to the network until you select "
602  "<strong>\"Save Point\"</strong>");
603  }
604  else {
605  p_saveMeasure = new QPushButton("Save Measure");
606  p_saveMeasure->setToolTip("Save the right measure to the edit control "
607  "point (control point currently being edited). "
608  "<strong>Shortcut: M</strong>. "
609  " <strong>Note: The edit control point "
610  "will not be saved to the network until you select "
611  "<strong>\"Save Point\"</strong>");
612  }
613  p_saveMeasure->setShortcut(Qt::Key_M);
614  p_saveDefaultPalette = p_saveMeasure->palette();
615 
616  rightLayout->addWidget(p_autoReg);
617  rightLayout->addWidget(p_saveMeasure);
618  rightLayout->addStretch();
619  gridLayout->addLayout(rightLayout, row, 1);
620 
621  connect(p_autoReg, SIGNAL(clicked()), this, SLOT(registerPoint()));
622  connect(p_saveMeasure, SIGNAL(clicked()), this, SLOT(saveMeasure()));
623 
624  setLayout(gridLayout);
625 
626  //p_pointEditor->setCentralWidget(cw);
627  p_autoRegExtension->hide();
628 
629  //p_pointEditor->setVisible(true);
630  //p_pointEditor->raise();
631  }
632 
633 
656  Cube *leftCube, QString pointId) {
657 
658  // Make sure registration is turned off
659  if (p_autoRegShown) {
660  // Undo Registration
661  p_autoRegShown = false;
662  p_autoRegExtension->hide();
663  p_autoReg->setText("Register");
664  p_autoReg->setToolTip("Sub-pixel register the right measure to the left."
665  "<strong>Shortcut: R</strong>");
666  p_autoReg->setShortcut(Qt::Key_R);
667  }
668 
669  p_leftMeasure = leftMeasure;
670 
671  if (p_useGeometry) {
672  // get new ground map
673  if ( p_leftGroundMap != 0 ) delete p_leftGroundMap;
674  p_leftGroundMap = new UniversalGroundMap(*leftCube);
675  }
676  p_leftCube = leftCube;
677 
678  p_leftChip->TackCube(p_leftMeasure->GetSample(), p_leftMeasure->GetLine());
679  p_leftChip->Load(*p_leftCube);
680 
681  // Dump into left chipViewport
682  p_leftView->setChip(p_leftChip, p_leftCube);
683 
684  // Only update right if not loading a new point. If it's a new point, right measure
685  // hasn't been loaded yet.
686  if (pointId == p_pointId && p_geomIt) updateRightGeom();
687  p_pointId = pointId;
688  }
689 
690 
717  Cube *rightCube, QString pointId) {
718 
719  // Make sure registration is turned off
720  if (p_autoRegShown) {
721  // Undo Registration
722  p_autoRegShown = false;
723  p_autoRegExtension->hide();
724  p_autoReg->setText("Register");
725  p_autoReg->setShortcut(Qt::Key_R);
726  }
727  p_autoRegAttempted = false;
728 
729  p_rightMeasure = rightMeasure;
730  p_pointId = pointId;
731 
732  if (p_useGeometry) {
733  // get new ground map
734  if ( p_rightGroundMap != 0 ) delete p_rightGroundMap;
735  p_rightGroundMap = new UniversalGroundMap(*rightCube);
736  }
737  p_rightCube = rightCube;
738 
739  p_rightChip->TackCube(p_rightMeasure->GetSample(),
740  p_rightMeasure->GetLine());
741  if (p_geomIt == false) {
742  p_rightChip->Load(*p_rightCube);
743  }
744  else {
745  try {
746  p_rightChip->Load(*p_rightCube, *p_leftChip, *p_leftCube);
747 
748  }
749  catch (IException &e) {
750  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
751  QString message = fullError.toString();
752  QMessageBox::information((QWidget *)parent(), "Error", message);
753  p_rightChip->Load(*p_rightCube);
754  p_geomIt = false;
755  p_nogeom->setChecked(true);
756  p_geom->setChecked(false);
757  }
758  }
759 
760  // Dump into right chipViewport
761  p_rightView->setChip(p_rightChip, p_rightCube);
762 
763  updateRightGeom();
764  //p_rightView->geomChip(p_leftChip,p_leftCube);
765 
766  // New right measure, make sure Save Measure Button text is default
767  p_saveMeasure->setPalette(p_saveDefaultPalette);
768 
769  }
770 
771 
785  QString pos = "Sample: " + QString::number(p_leftView->tackSample()) +
786  " Line: " + QString::number(p_leftView->tackLine());
787  p_leftSampLinePosition->setText(pos);
788 
789  if (p_useGeometry) {
790  // Get lat/lon from point in left
791  p_leftGroundMap->SetImage(p_leftView->tackSample(), p_leftView->tackLine());
792  double lat = p_leftGroundMap->UniversalLatitude();
793  double lon = p_leftGroundMap->UniversalLongitude();
794 
795  pos = "Latitude: " + QString::number(lat) +
796  " Longitude: " + QString::number(lon);
797  p_leftLatLonPosition->setText(pos);
798  }
799 
800  // Print zoom scale factor
801  pos = "Zoom Factor: " + QString::number(zoomFactor);
802  p_leftZoomFactor->setText(pos);
803 
804  // If zooms are linked, make right match left
805  if (p_linkZoom) {
806  p_rightView->zoom(p_leftView->zoomFactor());
807  }
808 
809  }
810 
811 
820 
821  // If registration Info is on, turn off
822  if (p_autoRegShown) {
823  // Undo Registration
824  p_autoRegShown = false;
825  p_autoRegExtension->hide();
826  p_autoReg->setText("Register");
827  p_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
828  "<strong>Shortcut: R</strong>");
829  p_autoReg->setShortcut(Qt::Key_R);
830  }
831 
832  QString pos = "Sample: " + QString::number(p_rightView->tackSample()) +
833  " Line: " + QString::number(p_rightView->tackLine());
834  p_rightSampLinePosition->setText(pos);
835 
836  if (p_useGeometry) {
837  // Get lat/lon from point in right
838  p_rightGroundMap->SetImage(p_rightView->tackSample(), p_rightView->tackLine());
839  double lat = p_rightGroundMap->UniversalLatitude();
840  double lon = p_rightGroundMap->UniversalLongitude();
841 
842  pos = "Latitude: " + QString::number(lat) +
843  " Longitude: " + QString::number(lon);
844  p_rightLatLonPosition->setText(pos);
845  }
846 
847  // Print zoom scale factor
848  pos = "Zoom Factor: " + QString::number(zoomFactor);
849  p_rightZoomFactor->setText(pos);
850 
851  }
852 
853 
860 
861  QColor qc = Qt::red;
862  QPalette p = p_saveMeasure->palette();
863  p.setColor(QPalette::ButtonText,qc);
864  p_saveMeasure->setPalette(p);
865 
866  }
867 
868 
879 
880  // Get lat/lon from point in left
881  p_leftGroundMap->SetImage(p_leftView->tackSample(), p_leftView->tackLine());
882  double lat = p_leftGroundMap->UniversalLatitude();
883  double lon = p_leftGroundMap->UniversalLongitude();
884 
885  // Reload right chipViewport with this new tack point.
886  if ( p_rightGroundMap->SetUniversalGround(lat, lon) ) {
887  emit updateRightView(p_rightGroundMap->Sample(), p_rightGroundMap->Line());
888 
889  // If moving from saved measure, turn save button to red
890  if (p_rightGroundMap->Sample() != p_rightMeasure->GetSample() ||
891  p_rightGroundMap->Line() != p_rightMeasure->GetLine())
893  }
894  else {
895  QString message = "Latitude: " + QString::number(lat) + " Longitude: " +
896  QString::number(lon) + " is not on the right image. Right measure " +
897  "was not moved.";
898  QMessageBox::warning((QWidget *)parent(),"Warning",message);
899  }
900 
901  }
902 
903 
934 
935  // if the auto registration factory has not been initialized, do it here
936  if (p_autoRegFact == NULL) {
937  try {
938  Pvl pvl(p_templateFileName);
939  p_autoRegFact = AutoRegFactory::Create(pvl);
940  }
941  catch (IException &e) {
942  p_autoRegFact = NULL;
943  IException fullError(e, IException::Io,
944  "Cannot create AutoRegFactory. As a result, "
945  "sub-pixel registration will not work.",
946  _FILEINFO_);
947  QString message = fullError.toString();
948  QMessageBox::information((QWidget *)parent(), "Error", message);
949  return;
950  }
951  }
952 
953  if (p_autoRegShown) {
954  // Undo Registration
955  p_autoRegShown = false;
956  p_autoRegExtension->hide();
957  p_autoReg->setText("Register");
958  p_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
959  "<strong>Shortcut: R</strong>");
960  p_autoReg->setShortcut(Qt::Key_R);
961 
962  // Reload chip with original measure
963  emit updateRightView(p_rightMeasure->GetSample(),
964  p_rightMeasure->GetLine());
965  // Since un-doing registration, make sure save button not red
966  p_saveMeasure->setPalette(p_saveDefaultPalette);
967  return;
968  }
969  p_autoRegAttempted = true;
970 
971  try {
972  p_autoRegFact->PatternChip()->TackCube(p_leftMeasure->GetSample(),
973  p_leftMeasure->GetLine());
974  p_autoRegFact->PatternChip()->Load(*p_leftCube);
975  p_autoRegFact->SearchChip()->TackCube(p_rightMeasure->GetSample(),
976  p_rightMeasure->GetLine());
977  if (p_useGeometry) {
978  p_autoRegFact->SearchChip()->Load(*p_rightCube,
979  *(p_autoRegFact->PatternChip()), *p_leftCube);
980  }
981  else {
982  p_autoRegFact->SearchChip()->Load(*p_rightCube);
983  }
984  }
985  catch (IException &e) {
986  QString msg = "Cannot register this point, unable to Load chips.\n";
987  msg += e.toString();
988  QMessageBox::information((QWidget *)parent(), "Error", msg);
989  return;
990  }
991 
992  try {
993  AutoReg::RegisterStatus status = p_autoRegFact->Register();
994  if (!p_autoRegFact->Success()) {
995  QString msg = "Cannot sub-pixel register this point.\n";
997  msg += "\n\nNot enough valid data in Pattern Chip.\n";
998  msg += " PatternValidPercent = ";
999  msg += QString::number(p_autoRegFact->PatternValidPercent()) + "%";
1000  }
1001  else if (status == AutoReg::FitChipNoData) {
1002  msg += "\n\nNo valid data in Fit Chip.";
1003  }
1004  else if (status == AutoReg::FitChipToleranceNotMet) {
1005  msg += "\n\nGoodness of Fit Tolerance not met.\n";
1006  msg += "\nGoodnessOfFit = " + QString::number(p_autoRegFact->GoodnessOfFit());
1007  msg += "\nGoodnessOfFitTolerance = ";
1008  msg += QString::number(p_autoRegFact->Tolerance());
1009  }
1010  else if (status == AutoReg::SurfaceModelNotEnoughValidData) {
1011  msg += "\n\nNot enough valid points in the fit chip window for sub-pixel ";
1012  msg += "accuracy. Probably too close to edge.\n";
1013  }
1014  else if (status == AutoReg::SurfaceModelSolutionInvalid) {
1015  msg += "\n\nCould not model surface for sub-pixel accuracy.\n";
1016  }
1017  else if (status == AutoReg::SurfaceModelDistanceInvalid) {
1018  double sampDist, lineDist;
1019  p_autoRegFact->Distance(sampDist, lineDist);
1020  msg += "\n\nSub pixel algorithm moves registration more than tolerance.\n";
1021  msg += "\nSampleMovement = " + QString::number(sampDist) +
1022  " LineMovement = " + QString::number(lineDist);
1023  msg += "\nDistanceTolerance = " +
1024  QString::number(p_autoRegFact->DistanceTolerance());
1025  }
1026  else if (status == AutoReg::PatternZScoreNotMet) {
1027  double score1, score2;
1028  p_autoRegFact->ZScores(score1, score2);
1029  msg += "\n\nPattern data max or min does not pass z-score test.\n";
1030  msg += "\nMinimumZScore = " + QString::number(p_autoRegFact->MinimumZScore());
1031  msg += "\nCalculatedZscores = " + QString::number(score1) + ", " + QString::number(score2);
1032  }
1033  else if (status == AutoReg::AdaptiveAlgorithmFailed) {
1034  msg += "\n\nError occured in Adaptive algorithm.";
1035  }
1036  else {
1037  msg += "\n\nUnknown registration error.";
1038  }
1039 
1040  QMessageBox::information((QWidget *)parent(), "Error", msg);
1041  return;
1042  }
1043  }
1044  catch (IException &e) {
1045  QString msg = "Cannot register this point.\n";
1046  msg += e.toString();
1047  QMessageBox::information((QWidget *)parent(), "Error", msg);
1048  return;
1049  }
1050 
1051  // Load chip with new registered point
1052  emit updateRightView(p_autoRegFact->CubeSample(), p_autoRegFact->CubeLine());
1053  // If registered pt different from measure, colorize the save button
1054  if (p_autoRegFact->CubeSample() != p_rightMeasure->GetSample() ||
1055  p_autoRegFact->CubeLine() != p_rightMeasure->GetLine()) {
1057  }
1058 
1059  QString oldPos = "Original Sample: " +
1060  QString::number(p_rightMeasure->GetSample()) + " Original Line: " +
1061  QString::number(p_rightMeasure->GetLine());
1062  p_oldPosition->setText(oldPos);
1063 
1064  QString goodFit = "Goodness of Fit: " +
1065  QString::number(p_autoRegFact->GoodnessOfFit());
1066  p_goodFit->setText(goodFit);
1067 
1068  p_autoRegExtension->show();
1069  p_autoRegShown = true;
1070  p_autoReg->setText("Undo Registration");
1071  p_autoReg->setToolTip("Undo sub-pixel registration. "
1072  "<strong>Shortcut: U</strong>");
1073  p_autoReg->setShortcut(Qt::Key_U);
1074  }
1075 
1076 
1112 
1113  if (p_rightMeasure != NULL) {
1114 
1115  if (p_rightMeasure->IsEditLocked()) {
1116  QString message = "The right measure is locked. You must first unlock the measure by ";
1117  message += "clicking the check box above labeled \"Edit Lock Measure\".";
1118  QMessageBox::warning((QWidget *)parent(),"Warning",message);
1119  return;
1120  }
1121 
1122  if (p_autoRegShown) {
1123  try {
1124  // Save autoreg parameters to the right measure log entry
1125  // Eccentricity may be invalid, check before writing.
1126  p_rightMeasure->SetLogData(ControlMeasureLogData(
1128  p_autoRegFact->GoodnessOfFit()));
1129  double minZScore, maxZScore;
1130  p_autoRegFact->ZScores(minZScore,maxZScore);
1131  p_rightMeasure->SetLogData(ControlMeasureLogData(
1133  minZScore));
1134  p_rightMeasure->SetLogData(ControlMeasureLogData(
1136  maxZScore));
1137  }
1138  // need to handle exception that SetLogData throws if our data is invalid -
1139  // unhandled exceptions thrown in Qt signal and slot connections produce undefined behavior
1140  catch (IException &e) {
1141  QString message = e.toString();
1142  QMessageBox::critical((QWidget *)parent(), "Error", message);
1143  return;
1144  }
1145 
1146  // Reset AprioriSample/Line to the current coordinate, before the
1147  // coordinate is updated with the registered coordinate.
1148  p_rightMeasure->SetAprioriSample(p_rightMeasure->GetSample());
1149  p_rightMeasure->SetAprioriLine(p_rightMeasure->GetLine());
1150 
1151  p_rightMeasure->SetChooserName("Application qnet");
1153 
1154  p_autoRegShown = false;
1155  p_autoRegExtension->hide();
1156  p_autoReg->setText("Register");
1157  p_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
1158  "<strong>Shortcut: R</strong>");
1159  p_autoReg->setShortcut(Qt::Key_R);
1160  }
1161  else {
1162  p_rightMeasure->SetChooserName(Application::UserName());
1163  p_rightMeasure->SetType(ControlMeasure::Manual);
1164  p_rightMeasure->DeleteLogData(
1166  p_rightMeasure->DeleteLogData(
1168  p_rightMeasure->DeleteLogData(
1170  }
1171 
1172  // Get cube position at right chipViewport crosshair
1173  p_rightMeasure->SetCoordinate(p_rightView->tackSample(),
1174  p_rightView->tackLine());
1175  p_rightMeasure->SetDateTime();
1176 
1177  }
1178 
1179  if (p_allowLeftMouse) {
1180  if (p_leftMeasure != NULL) {
1181  if (p_leftMeasure->IsEditLocked()) {
1182  QString message = "The left measure is locked. You must first unlock the measure by ";
1183  message += "clicking the check box above labeled \"Edit Lock Measure\".";
1184  QMessageBox::warning((QWidget *)parent(),"Warning",message);
1185  return;
1186  }
1187 
1188  p_leftMeasure->SetCoordinate(p_leftView->tackSample(), p_leftView->tackLine());
1189  p_leftMeasure->SetDateTime();
1190  p_leftMeasure->SetChooserName(Application::UserName());
1191  p_leftMeasure->SetType(ControlMeasure::Manual);
1192  }
1193  }
1194 
1195  // If the right chip is the same as the left chip, copy right into left and
1196  // re-load the left.
1197  if (p_rightMeasure->GetCubeSerialNumber() ==
1198  p_leftMeasure->GetCubeSerialNumber()) {
1199 
1200  *p_leftMeasure = *p_rightMeasure;
1201  setLeftMeasure(p_leftMeasure,p_leftCube,p_pointId);
1202  }
1203 
1204  // Change Save Measure button text back to default palette
1205  p_saveMeasure->setPalette(p_saveDefaultPalette);
1206 
1207  // Redraw measures on viewports
1208  emit measureSaved();
1209  }
1210 
1211 
1220 
1221  if (p_geomIt) {
1222  try {
1223  p_rightView->geomChip(p_leftChip, p_leftCube);
1224 
1225  }
1226  catch (IException &e) {
1227  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1228  QString message = fullError.toString();
1229  QMessageBox::information((QWidget *)parent(), "Error", message);
1230  p_geomIt = false;
1231  p_nogeom->setChecked(true);
1232  p_geom->setChecked(false);
1233  }
1234  }
1235  }
1236 
1237 
1239 // * Slot to update the right ChipViewport for zoom
1240 // * operations
1241 // *
1242 // * @author 2012-07-26 Tracie Sucharski
1243 // *
1244 // * @internal
1245 // */
1246 //void ControlPointEdit::updateRightZoom() {
1247 //
1248 // if (p_linkZoom) {
1249 // try {
1250 // p_rightView->geomChip(p_leftChip, p_leftCube);
1251 //
1252 // }
1253 // catch (IException &e) {
1254 // IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1255 // QString message = fullError.toString();
1256 // QMessageBox::information((QWidget *)parent(), "Error", message);
1257 // p_geomIt = false;
1258 // p_nogeom->setChecked(true);
1259 // p_geom->setChecked(false);
1260 // }
1261 // }
1262 //}
1263 
1264 
1271  QApplication::setOverrideCursor(Qt::WaitCursor);
1272 
1273  // Text needs to be reset because it was changed to
1274  // indicate why it's greyed out
1275  QString text = "Zoom in 2X";
1276  p_rightZoomIn->setEnabled(true);
1277  p_rightZoomIn->setWhatsThis(text);
1278  p_rightZoomIn->setToolTip("Zoom In");
1279  text = "Zoom out 2X";
1280  p_rightZoomOut->setEnabled(true);
1281  p_rightZoomOut->setWhatsThis(text);
1282  p_rightZoomOut->setToolTip("Zoom Out");
1283  text = "Zoom 1:1";
1284  p_rightZoom1->setEnabled(true);
1285  p_rightZoom1->setWhatsThis(text);
1286  p_rightZoom1->setToolTip("Zoom 1:1");
1287 
1288  p_geomIt = false;
1289  p_rightView->nogeomChip();
1290 
1291  QApplication::restoreOverrideCursor();
1292 
1293  p_dial->setEnabled(true);
1294  p_dialNumber->setEnabled(true);
1295  p_dial->setNotchesVisible(true);
1296 
1297  }
1298 
1299 
1309 
1310  if (p_geomIt == true) return;
1311 
1312  QApplication::setOverrideCursor(Qt::WaitCursor);
1313 
1314  // Grey right view zoom buttons
1315  QString text = "Zoom functions disabled when Geom is set";
1316  p_rightZoomIn->setEnabled(false);
1317  p_rightZoomIn->setWhatsThis(text);
1318  p_rightZoomIn->setToolTip(text);
1319  p_rightZoomOut->setEnabled(false);
1320  p_rightZoomOut->setWhatsThis(text);
1321  p_rightZoomOut->setToolTip(text);
1322  p_rightZoom1->setEnabled(false);
1323  p_rightZoom1->setWhatsThis(text);
1324  p_rightZoom1->setToolTip(text);
1325 
1326 
1327  // Reset dial to 0 before disabling
1328  p_dial->setValue(0);
1329  p_dial->setEnabled(false);
1330  p_dialNumber->setEnabled(false);
1331 
1332  p_geomIt = true;
1333 
1334  try {
1335  p_rightView->geomChip(p_leftChip, p_leftCube);
1336  }
1337  catch (IException &e) {
1338  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1339  QString message = fullError.toString();
1340  QMessageBox::information((QWidget *)parent(), "Error", message);
1341  p_geomIt = false;
1342  p_nogeom->setChecked(true);
1343  p_geom->setChecked(false);
1344  }
1345 
1346  QApplication::restoreOverrideCursor();
1347  }
1348 
1349 
1356 
1357  QApplication::setOverrideCursor(Qt::WaitCursor);
1358 
1359  QString text = "Zoom in 2X";
1360  p_rightZoomIn->setEnabled(true);
1361  p_rightZoomIn->setWhatsThis(text);
1362  p_rightZoomIn->setToolTip("Zoom In");
1363  text = "Zoom out 2X";
1364  p_rightZoomOut->setEnabled(true);
1365  p_rightZoomOut->setWhatsThis(text);
1366  p_rightZoomOut->setToolTip("Zoom Out");
1367  text = "Zoom 1:1";
1368  p_rightZoom1->setEnabled(true);
1369  p_rightZoom1->setWhatsThis(text);
1370  p_rightZoom1->setToolTip("Zoom 1:1");
1371 
1372  // Reset dial to 0 before disabling
1373  p_dial->setValue(0);
1374  p_dial->setEnabled(false);
1375  p_dialNumber->setEnabled(false);
1376 
1377  p_geomIt = false;
1378  p_rightView->nogeomChip();
1379 
1380  QApplication::restoreOverrideCursor();
1381  }
1382 
1383 
1391  void ControlPointEdit::setCircle(bool checked) {
1392 
1393  if (checked == p_circle) return;
1394 
1395  p_circle = checked;
1396  if (p_circle) {
1397  // Turn on slider bar
1398  p_slider->setDisabled(false);
1399  p_slider->show();
1400  p_slider->setValue(20);
1401  p_leftView->setCircle(true);
1402  p_rightView->setCircle(true);
1403  }
1404  else {
1405  p_slider->setDisabled(true);
1406  p_slider->hide();
1407  p_leftView->setCircle(false);
1408  p_rightView->setCircle(false);
1409  }
1410 
1411  }
1412 
1413 
1421  void ControlPointEdit::setZoomLink(bool checked) {
1422 
1423  if (checked == p_linkZoom) return;
1424 
1425  p_linkZoom = checked;
1426  if (p_linkZoom) {
1427  p_rightView->zoom(p_leftView->zoomFactor());
1428  }
1429  }
1430 
1431 
1434  if (p_timerOn) return;
1435 
1436  // Set up blink list
1437  p_blinkList.push_back(p_leftView);
1438  p_blinkList.push_back(p_rightView);
1439  p_blinkIndex = 0;
1440 
1441  p_timerOn = true;
1442  int msec = (int)(p_blinkTimeBox->value() * 1000.0);
1443  p_timer = new QTimer(this);
1444  connect(p_timer, SIGNAL(timeout()), this, SLOT(updateBlink()));
1445  p_timer->start(msec);
1446  }
1447 
1448 
1451  p_timer->stop();
1452  p_timerOn = false;
1453  p_blinkList.clear();
1454 
1455  // Reload left chipViewport with original chip
1456  p_leftView->repaint();
1457 
1458  }
1459 
1460 
1467  void ControlPointEdit::changeBlinkTime(double interval) {
1468  if (p_timerOn) p_timer->setInterval((int)(interval * 1000.));
1469  }
1470 
1471 
1474 
1475  p_blinkIndex = !p_blinkIndex;
1476  p_leftView->loadView(*(p_blinkList)[p_blinkIndex]);
1477  }
1478 
1479 
1499 
1500  AutoReg *reg = NULL;
1501  // save original template filename
1502  QString temp = p_templateFileName;
1503  try {
1504  // set template filename to user chosen pvl file
1505  p_templateFileName = fn;
1506 
1507  // Create PVL object with this file
1508  Pvl pvl(fn);
1509 
1510  // try to register file
1511  reg = AutoRegFactory::Create(pvl);
1512  if (p_autoRegFact != NULL)
1513  delete p_autoRegFact;
1514  p_autoRegFact = reg;
1515 
1516  p_templateFileName = fn;
1517 
1518  // undo registration if a point is already registered
1519  // this prevents the user from saving a measure with invalid data
1520  if (p_autoRegShown)
1521  registerPoint();
1522 
1523  return true;
1524  }
1525  catch (IException &e) {
1526  // set templateFileName back to its original value
1527  p_templateFileName = temp;
1528  IException fullError(e, IException::Io,
1529  "Cannot create AutoRegFactory for " +
1530  fn +
1531  ". As a result, current template file will remain set to " +
1532  p_templateFileName, _FILEINFO_);
1533  QString message = fullError.toString();
1534  QMessageBox::information((QWidget *)parent(), "Error", message);
1535  return false;
1536  }
1537  }
1538 
1539 
1546  void ControlPointEdit::allowLeftMouse(bool allowMouse) {
1547  p_allowLeftMouse = allowMouse;
1548 
1549  if (p_allowLeftMouse) {
1550  p_saveMeasure = new QPushButton("Save Measures");
1551  p_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
1552  "point (control point currently being edited). "
1553  " <strong>Note: The edit control point "
1554  "will not be saved to the network until you select "
1555  "<strong>\"Save Point\"</strong>");
1556  }
1557  else {
1558  p_saveMeasure = new QPushButton("Save Measure");
1559  p_saveMeasure->setToolTip("Save the right measure to the edit control "
1560  "point (control point currently being edited). "
1561  " <strong>Note: The edit control point "
1562  "will not be saved to the network until you select "
1563  "<strong>\"Save Point\"</strong>");
1564  }
1565  }
1566 
1567 
1568  void ControlPointEdit::refreshChips() {
1569  p_leftView->update();
1570  p_rightView->update();
1571  }
1572 
1573 
1583 
1584  // if (!p_autoRegShown) {
1585  if (!p_autoRegAttempted) {
1586  QString message = "Point must be Registered before chips can be saved.";
1587  QMessageBox::warning((QWidget *)parent(), "Warning", message);
1588  return;
1589  }
1590 
1591  // Save chips - pattern, search and fit
1592  QString baseFile = p_pointId.replace(" ", "_") + "_" +
1593  toString((int)(p_leftMeasure ->GetSample())) + "_" +
1594  toString((int)(p_leftMeasure ->GetLine())) + "_" +
1595  toString((int)(p_rightMeasure->GetSample())) + "_" +
1596  toString((int)(p_rightMeasure->GetLine())) + "_";
1597  QString fname = baseFile + "Search.cub";
1598  QString command = "$ISISROOT/bin/qview \'" + fname + "\'";
1599  p_autoRegFact->RegistrationSearchChip()->Write(fname);
1600  fname = baseFile + "Pattern.cub";
1601  command += " \'" + fname + "\'";
1602  p_autoRegFact->RegistrationPatternChip()->Write(fname);
1603  fname = baseFile + "Fit.cub";
1604  command += " \'" + fname + "\' &";
1605  p_autoRegFact->FitChip()->Write(fname);
1607  }
1608 }
Status SetType(MeasureType type)
Set how the coordinate was obtained.
void allowLeftMouse(bool allowMouse)
Set the option that allows mouse movements in the left ChipViewport.
Error occured in Adaptive algorithm.
Definition: AutoReg.h:205
double MinimumZScore() const
Return minimumPatternZScore.
Definition: AutoReg.h:366
void zoom(double zoomFactor)
Zoom by a specified factor.
double Line() const
Returns the current line value of the camera model or projection.
void findPoint()
Find point from left ChipViewport in the right ChipViewport.
File name manipulation and expansion.
Definition: FileName.h:116
Universal Ground Map.
A small chip of data used for pattern matching.
Definition: Chip.h:102
void setNoGeom()
Slot to turn off geom.
Chip * RegistrationSearchChip()
Return pointer to search chip used in registration.
Definition: AutoReg.h:243
Not enough valid data in pattern chip.
Definition: AutoReg.h:198
void updateRightPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of right measure.
Not enough points to fit a surface model for sub-pixel accuracy.
Definition: AutoReg.h:201
Chip * RegistrationPatternChip()
Return pointer to pattern chip used in registration.
Definition: AutoReg.h:233
Surface model moves registration more than one pixel.
Definition: AutoReg.h:203
Statistical and similar ControlMeasure associated information.
void registerPoint()
Sub-pixel register point in right chipViewport with point in left.
double DistanceTolerance() const
Return distance tolerance.
Definition: AutoReg.h:316
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
void updateLeftPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of left measure.
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
Definition: AutoReg.cpp:600
Chip * SearchChip()
Return pointer to search chip.
Definition: AutoReg.h:223
void saveChips()
Slot to save registration chips to files and fire off qview.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
Registered to sub-pixel (e.g., pointreg)
double GoodnessOfFit() const
Return the goodness of fit of the match algorithm.
Definition: AutoReg.h:339
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
double tackLine()
Returns tack line.
void colorizeSaveButton()
Turn "Save Measure" button text to red.
double tackSample()
Return the position of cube under cross hair.
Control measures store z-scores in pairs.
double CubeSample() const
Return the search chip cube sample that best matched.
Definition: AutoReg.h:356
void ZScores(double &score1, double &score2) const
Return the ZScores of the pattern chip.
Definition: AutoReg.h:376
void setRightMeasure(ControlMeasure *rightMeasure, Cube *rightCube, QString pointId)
Set the measure displayed in the right ChipViewport.
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
ControlPointEdit(ControlNet *cnet, QWidget *parent=0, bool allowLeftMouse=false, bool useGeometry=true)
Constructs a ControlPointEdit widget.
a control network
Definition: ControlNet.h:271
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename...
Hand Measured (e.g., qnet)
double Tolerance() const
Return match algorithm tolerance.
Definition: AutoReg.h:306
Pixel value mapper.
Definition: Stretch.h:72
Chip * PatternChip()
Return pointer to pattern chip.
Definition: AutoReg.h:218
void Write(const QString &filename)
Writes the contents of the Chip to a cube.
Definition: Chip.cpp:1007
void setGeom()
Turn geom on.
void changeBlinkTime(double interval)
Set blink rate.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
void blinkStart()
Slot to start blink function.
void SetLogData(ControlMeasureLogData)
This adds or updates the log data information associated with data&#39;s type.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
void saveMeasure()
Save control measure under the crosshair in right ChipViewport.
void updateBlink()
Slot to cause the blink to happen coinciding with the timer.
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
double CubeLine() const
Return the search chip cube line that best matched.
Definition: AutoReg.h:361
double PatternValidPercent() const
Return pattern chip valid percent. The default value is.
Definition: AutoReg.h:296
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
void geomChip(Chip *matchChip, Cube *matchChipCube)
Slot to geom chip (apply geometry transformation)
double zoomFactor()
Return the zoom factor.
bool Success() const
Return whether the match algorithm succeeded or not.
Definition: AutoReg.h:334
Fit chip did not have any valid data.
Definition: AutoReg.h:199
Container for cube-like labels.
Definition: Pvl.h:135
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 updateRightGeom()
Slot to update the geomed right ChipViewport for zoom operations.
Auto Registration class.
Definition: AutoReg.h:183
void blinkStop()
Slot to stop blink function.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
static AutoReg * Create(Pvl &pvl)
Create an AutoReg object using a PVL specification.
GoodnessOfFit is pointreg information for reference measures.
Goodness of fit tolerance not satisfied.
Definition: AutoReg.h:200
void createPointEditor(QWidget *parent)
Design the PointEdit widget.
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
Viewport for Isis Chips.
Definition: ChipViewport.h:85
void setRotate()
Slot to update the right ChipViewport for zoom operations.
RegisterStatus
Enumeration of the Register() method&#39;s return status.
Definition: AutoReg.h:195
void Distance(double &sampDistance, double &lineDistance)
Return the distance point moved.
Definition: AutoReg.h:326
void setChip(Chip *chip, Cube *chipCube)
Set chip.
static QString UserName()
Returns the user name.
Isis exception class.
Definition: IException.h:107
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
a control measurement
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
Chip * FitChip()
Return pointer to fit chip.
Definition: AutoReg.h:228
void DeleteLogData(long dataType)
This deletes log data of the specified type.
Status SetDateTime()
Date Time - Creation Time.
Could not model surface for sub-pixel accuracy.
Definition: AutoReg.h:202
Pattern data max or min does not pass the z-score test.
Definition: AutoReg.h:204
double Sample() const
Returns the current line value of the camera model or projection.
void setCircle(bool checked)
Slot to change state of circle.
const int VIEWSIZE
Constant representing the length and width of the chip viewports.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
void setZoomLink(bool)
Turn linking of zoom on or off.
void loadView(ChipViewport &newView)
Load with another ChipViewport, used for blinking.
void setCircle(bool)
Turn circle widgets on/off.
void nogeomChip()
Slot to un-geom chip (revert geometry transformation)
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
void setLeftMeasure(ControlMeasure *leftMeasure, Cube *leftCube, QString pointId)
Set the measure displayed in the left ChipViewport.
IO Handler for Isis Cubes.
Definition: Cube.h:170