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