Isis 3 Programmer Reference
ControlMeasureEditWidget.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "ControlMeasureEditWidget.h"
10
11#include <QApplication>
12#include <QButtonGroup>
13#include <QCheckBox>
14#include <QColor>
15#include <QDial>
16#include <QDoubleSpinBox>
17#include <QFileDialog>
18#include <QGridLayout>
19#include <QHBoxLayout>
20#include <QLCDNumber>
21#include <QListWidget>
22#include <QMessageBox>
23#include <QPalette>
24#include <QPushButton>
25#include <QRadioButton>
26#include <QScrollBar>
27#include <QSize>
28#include <QString>
29#include <QTimer>
30#include <QToolButton>
31
32#include "Application.h"
33#include "AutoReg.h"
34#include "AutoRegFactory.h"
35#include "ChipViewport.h"
36#include "ControlMeasure.h"
37#include "ControlMeasureLogData.h"
38#include "ControlPoint.h"
39#include "FileName.h"
40#include "IString.h"
41#include "ProgramLauncher.h"
42#include "Pvl.h"
43#include "SerialNumberList.h"
44#include "UniversalGroundMap.h"
45
46namespace Isis {
47
49 const int VIEWSIZE = 301;
50
65 bool allowLeftMouse,
66 bool useGeometry) : QWidget(parent) {
67
68 m_rotation = 0;
69 m_timerOn = false;
70 m_timerOnRight = false;
71 m_autoRegFact = NULL;
73 m_useGeometry = useGeometry;
74
75 // Initialize some pointers
76 m_leftCube = 0;
77 m_rightCube = 0;
80
81 m_templateFileName = "$ISISROOT/appdata/templates/autoreg/qnetReg.def";
82
83 createMeasureEditor(parent);
84 }
85
86
97
98
122 // Place everything in a grid
123 QGridLayout *gridLayout = new QGridLayout();
124 gridLayout->setSizeConstraint(QLayout::SetFixedSize);
125 // grid row
126 int row = 0;
127
128 QString tempFileName = FileName("$ISISROOT/appdata/images/icons").expanded();
129 QString toolIconDir = tempFileName;
130
131 QSize isize(27, 27);
132 // Add zoom buttons
133 QToolButton *leftZoomIn = new QToolButton();
134 leftZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
135 leftZoomIn->setIconSize(isize);
136 leftZoomIn->setToolTip("Zoom In 2x");
137 leftZoomIn->setWhatsThis("Zoom In 2x on left measure.");
138
139 QToolButton *leftZoomOut = new QToolButton();
140 leftZoomOut->setIcon(QPixmap(toolIconDir + "/viewmag-.png"));
141 leftZoomOut->setIconSize(isize);
142 leftZoomOut->setToolTip("Zoom Out 2x");
143 leftZoomOut->setWhatsThis("Zoom Out 2x on left measure.");
144
145 QToolButton *leftZoom1 = new QToolButton();
146 leftZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
147 leftZoom1->setIconSize(isize);
148 leftZoom1->setToolTip("Zoom 1:1");
149 leftZoom1->setWhatsThis("Show left measure at full resolution.");
150
151 QHBoxLayout *leftZoomPan = new QHBoxLayout;
152 leftZoomPan->addWidget(leftZoomIn);
153 leftZoomPan->addWidget(leftZoomOut);
154 leftZoomPan->addWidget(leftZoom1);
155
156 // These buttons only used if allow mouse events in leftViewport
157 QToolButton *leftPanUp = 0;
158 QToolButton *leftPanDown = 0;
159 QToolButton *leftPanLeft = 0;
160 QToolButton *leftPanRight = 0;
161 if ( m_allowLeftMouse ) {
162 // Add arrows for panning
163 leftPanUp = new QToolButton(parent);
164 leftPanUp->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/up.png").
165 expanded()));
166 leftPanUp->setIconSize(isize);
167 leftPanUp->setToolTip("Move up 1 screen pixel");
168 leftPanUp->setStatusTip("Move up 1 screen pixel");
169 leftPanUp->setWhatsThis("Move the left measure up 1 screen pixel.");
170
171 leftPanDown = new QToolButton(parent);
172 leftPanDown->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/down.png").
173 expanded()));
174 leftPanDown->setIconSize(isize);
175 leftPanDown->setToolTip("Move down 1 screen pixel");
176 leftPanDown->setStatusTip("Move down 1 screen pixel");
177 leftPanDown->setWhatsThis("Move the left measure down 1 screen pixel.");
178
179 leftPanLeft = new QToolButton(parent);
180 leftPanLeft->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/back.png").
181 expanded()));
182 leftPanLeft->setIconSize(isize);
183 leftPanLeft->setToolTip("Move left 1 screen pixel");
184 leftPanLeft->setWhatsThis("Move the left measure to the left by 1 screen"
185 "pixel.");
186
187 leftPanRight = new QToolButton(parent);
188 leftPanRight->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/forward.png").
189 expanded()));
190 leftPanRight->setIconSize(isize);
191 leftPanRight->setToolTip("Move right 1 screen pixel");
192 leftPanRight->setWhatsThis("Move the left measure to the right by 1"
193 "screen pixel.");
194
195 leftZoomPan->addWidget(leftPanUp);
196 leftZoomPan->addWidget(leftPanDown);
197 leftZoomPan->addWidget(leftPanLeft);
198 leftZoomPan->addWidget(leftPanRight);
199 }
200
201 leftZoomPan->addStretch();
202 gridLayout->addLayout(leftZoomPan, row, 0);
203
204 m_rightZoomIn = new QToolButton();
205 m_rightZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
206 m_rightZoomIn->setIconSize(isize);
207 m_rightZoomIn->setToolTip("Zoom In 2x");
208 m_rightZoomIn->setWhatsThis("Zoom In 2x on right measure.");
209
210 m_rightZoomOut = new QToolButton();
211 m_rightZoomOut->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/viewmag-.png").
212 expanded()));
213 m_rightZoomOut->setIconSize(isize);
214 m_rightZoomOut->setToolTip("Zoom Out 2x");
215 m_rightZoomOut->setWhatsThis("Zoom Out 2x on right measure.");
216
217 m_rightZoom1 = new QToolButton();
218 m_rightZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
219 m_rightZoom1->setIconSize(isize);
220 m_rightZoom1->setToolTip("Zoom 1:1");
221 m_rightZoom1->setWhatsThis("Show right measure at full resolution.");
222
223 QHBoxLayout *rightZoomPan = new QHBoxLayout;
224 rightZoomPan->addWidget(m_rightZoomIn);
225 rightZoomPan->addWidget(m_rightZoomOut);
226 rightZoomPan->addWidget(m_rightZoom1);
227
228 // Add arrows for panning
229 QToolButton *rightPanUp = new QToolButton(parent);
230 rightPanUp->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/up.png").
231 expanded()));
232 rightPanUp->setIconSize(isize);
233 rightPanUp->setToolTip("Move up 1 screen pixel");
234 rightPanUp->setWhatsThis("Move the right measure up 1 screen pixel.");
235
236 QToolButton *rightPanDown = new QToolButton(parent);
237 rightPanDown->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/down.png").
238 expanded()));
239 rightPanDown->setIconSize(isize);
240 rightPanDown->setToolTip("Move down 1 screen pixel");
241 rightPanUp->setWhatsThis("Move the right measure down 1 screen pixel.");
242
243 QToolButton *rightPanLeft = new QToolButton(parent);
244 rightPanLeft->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/back.png").
245 expanded()));
246 rightPanLeft->setIconSize(isize);
247 rightPanLeft->setToolTip("Move left 1 screen pixel");
248 rightPanLeft->setWhatsThis("Move the right measure to the left by 1 screen"
249 "pixel.");
250
251 QToolButton *rightPanRight = new QToolButton(parent);
252 rightPanRight->setIcon(QIcon(FileName("$ISISROOT/appdata/images/icons/forward.png").
253 expanded()));
254 rightPanRight->setIconSize(isize);
255 rightPanRight->setToolTip("Move right 1 screen pixel");
256 rightPanRight->setWhatsThis("Move the right measure to the right by 1"
257 "screen pixel.");
258
259 rightZoomPan->addWidget(rightPanUp);
260 rightZoomPan->addWidget(rightPanDown);
261 rightZoomPan->addWidget(rightPanLeft);
262 rightZoomPan->addWidget(rightPanRight);
263 rightZoomPan->addStretch();
264
265 gridLayout->addLayout(rightZoomPan, row++, 1);
266
267 // Add zoom factor label and stretch locking checkbox
268 m_leftZoomFactor = new QLabel();
269 QCheckBox *leftLockStretch = new QCheckBox("lock stretch");
270 // there are two "lock stretch" checkboxes (left and right)
271 // use same whats this text for both
272 QString whatsThisTextForStretchLocking = "If checked then a new stretch "
273 "will NOT be calculated for each pan or zoom change. Note that stretch"
274 " changes made using the stretch tool will ALWAYS take effect, "
275 "regardless of the state of this checkbox.";
276 leftLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
277 QHBoxLayout *leftzflsLayout = new QHBoxLayout;
278 leftzflsLayout->addWidget(m_leftZoomFactor);
279 leftzflsLayout->addWidget(leftLockStretch);
280 gridLayout->addLayout(leftzflsLayout, row, 0);
281
282 m_rightZoomFactor = new QLabel();
283 QCheckBox *rightLockStretch = new QCheckBox("lock stretch");
284 rightLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
285 QHBoxLayout *rightzflsLayout = new QHBoxLayout;
286 rightzflsLayout->addWidget(m_rightZoomFactor);
287 rightzflsLayout->addWidget(rightLockStretch);
288 gridLayout->addLayout(rightzflsLayout, row++, 1);
289
290
292 // Do not want to accept mouse/keyboard events
293 if ( !m_allowLeftMouse ) m_leftView->setDisabled(true);
294
295 gridLayout->addWidget(m_leftView, row, 0);
296
297 connect(this, SIGNAL(newControlNetwork(ControlNet *)),
298 m_leftView, SLOT(setControlNet(ControlNet *)));
299
300 connect(this,
301 SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
303 SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
304
305 connect(leftLockStretch, SIGNAL(stateChanged(int)),
307 SLOT(changeStretchLock(int)));
308 leftLockStretch->setChecked(false);
309
310
311 // Connect left zoom buttons to ChipViewport's zoom slots
312 connect(leftZoomIn, SIGNAL(clicked()), m_leftView, SLOT(zoomIn()));
313 connect(leftZoomOut, SIGNAL(clicked()), m_leftView, SLOT(zoomOut()));
314 connect(leftZoom1, SIGNAL(clicked()), m_leftView, SLOT(zoom1()));
315
316 // If zoom on left, need to re-geom right
317 connect(leftZoomIn, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
318 connect(leftZoomOut, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
319 connect(leftZoom1, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
320
321 // Connect the ChipViewport tackPointChanged signal to
322 // the update sample/line label
323 connect(m_leftView, SIGNAL(tackPointChanged(double)),
324 this, SLOT(updateLeftPositionLabel(double)));
325
326 // we want to allow this connection so that if a changed point is saved
327 // and the same image is showing in both viewports, the left will refresh.
328 connect(this, SIGNAL(updateLeftView(double, double)),
329 m_leftView, SLOT(refreshView(double, double)));
330
331 connect (m_leftView, SIGNAL(userMovedTackPoint()),
332 this, SLOT(colorizeSaveButton()));
333
334 if ( m_allowLeftMouse ) {
335 // Connect pan buttons to ChipViewport
336 connect(leftPanUp, SIGNAL(clicked()), m_leftView, SLOT(panUp()));
337 connect(leftPanDown, SIGNAL(clicked()), m_leftView, SLOT(panDown()));
338 connect(leftPanLeft, SIGNAL(clicked()), m_leftView, SLOT(panLeft()));
339 connect(leftPanRight, SIGNAL(clicked()), m_leftView, SLOT(panRight()));
340
341 connect(leftPanUp, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
342 connect(leftPanDown, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
343 connect(leftPanLeft, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
344 connect(leftPanRight, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
345 }
346
348 gridLayout->addWidget(m_rightView, row, 1);
349
350 connect(this, SIGNAL(newControlNetwork(ControlNet *)),
351 m_rightView, SLOT(setControlNet(ControlNet *)));
352 connect(this, SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
353 m_rightView, SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
354 connect(rightLockStretch, SIGNAL(stateChanged(int)),
355 m_rightView, SLOT(changeStretchLock(int)));
356 rightLockStretch->setChecked(false);
357
358 // Connect the ChipViewport tackPointChanged signal to
359 // the update sample/line label
360 connect(m_rightView, SIGNAL(tackPointChanged(double)),
361 this, SLOT(updateRightPositionLabel(double)));
362 connect(this, SIGNAL(updateRightView(double, double)),
363 m_rightView, SLOT(refreshView(double, double)));
364
365 connect (m_rightView, SIGNAL(userMovedTackPoint()),
366 this, SLOT(colorizeSaveButton()));
367
368 connect(m_rightZoomIn, SIGNAL(clicked()), m_rightView, SLOT(zoomIn()));
369 connect(m_rightZoomOut, SIGNAL(clicked()), m_rightView, SLOT(zoomOut()));
370 connect(m_rightZoom1, SIGNAL(clicked()), m_rightView, SLOT(zoom1()));
371
372 // Connect pan buttons to ChipViewport
373 connect(rightPanUp, SIGNAL(clicked()), m_rightView, SLOT(panUp()));
374 connect(rightPanDown, SIGNAL(clicked()), m_rightView, SLOT(panDown()));
375 connect(rightPanLeft, SIGNAL(clicked()), m_rightView, SLOT(panLeft()));
376 connect(rightPanRight, SIGNAL(clicked()), m_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
386
387 QButtonGroup *bgroup = new QButtonGroup();
388 m_nogeom = new QRadioButton();
389 m_nogeom->setChecked(true);
390 connect(m_nogeom, SIGNAL(clicked()), this, SLOT(setNoGeom()));
391
392 QCheckBox *linkZoom = NULL;
393 if (m_useGeometry) {
394 m_nogeom->setText("No geom/rotate");
395 m_nogeom->setToolTip("Reset right measure to it's native geometry.");
396 m_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 m_geom = new QRadioButton("Geom");
401 m_geom->setToolTip("Geom right measure to match geometry of left measure.");
402 m_geom->setWhatsThis("Using an affine transform, geom the right measure to match the "
403 "geometry of the left measure.");
404 bgroup->addButton(m_geom);
405 connect(m_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 m_nogeom->setText("No rotate");
415 m_nogeom->setToolTip("Reset right measure to it's native geometry.");
416 m_nogeom->setWhatsThis("Reset right measure to it's native geometry. "
417 "If measure was rotated, set rotation back to 0.");
418 }
419 bgroup->addButton(m_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 m_geomIt = false;
428 m_rotation = 0;
429 m_linkZoom = false;
430
431 m_dial = new QDial();
432 m_dial->setRange(0, 360);
433 m_dial->setWrapping(false);
434 m_dial->setNotchesVisible(true);
435 m_dial->setNotchTarget(5.);
436 m_dial->setEnabled(false);
437 m_dial->setToolTip("Rotate right measure");
438 m_dial->setWhatsThis("Rotate the right measure by degrees.");
439
440 m_dialNumber = new QLCDNumber();
441 m_dialNumber->setEnabled(false);
442 m_dialNumber->setToolTip("Rotate right measure");
443 m_dialNumber->setWhatsThis("Rotate the right measure by given number"
444 " of degrees.");
445 connect(m_dial, SIGNAL(valueChanged(int)), m_dialNumber, SLOT(display(int)));
446 connect(m_dial, SIGNAL(valueChanged(int)), m_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)), m_leftView, SLOT(setPoints(bool)));
455 connect(showPoints, SIGNAL(toggled(bool)), m_rightView, SLOT(setPoints(bool)));
456 showPoints->setChecked(true);
457
458 QCheckBox *cross = new QCheckBox("Show crosshair");
459 connect(cross, SIGNAL(toggled(bool)), m_leftView, SLOT(setCross(bool)));
460 connect(cross, SIGNAL(toggled(bool)), m_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 m_slider = new QScrollBar(Qt::Horizontal);
474 m_slider->setRange(1, 100);
475 m_slider->setSingleStep(1);
476 connect(m_slider, SIGNAL(valueChanged(int)), m_leftView, SLOT(setCircleSize(int)));
477 connect(m_slider, SIGNAL(valueChanged(int)), m_rightView, SLOT(setCircleSize(int)));
478 m_slider->setValue(20);
479 m_slider->setDisabled(true);
480 m_slider->hide();
481 m_slider->setToolTip("Adjust circle size");
482 m_slider->setWhatsThis("This allows the cirle size to be adjusted.");
483
484 QVBoxLayout *vlayout = new QVBoxLayout();
485 if (!m_useGeometry) {
486 vlayout->addWidget(linkZoom);
487 }
488 vlayout->addWidget(m_nogeom);
489 if (m_useGeometry) {
490 vlayout->addWidget(m_geom);
491 }
492 vlayout->addWidget(rotate);
493 vlayout->addWidget(m_dial);
494 vlayout->addWidget(m_dialNumber);
495 vlayout->addWidget(showPoints);
496 vlayout->addWidget(cross);
497 vlayout->addWidget(circle);
498 vlayout->addWidget(m_slider);
499 gridLayout->addLayout(vlayout, row++, 2);
500
501 // Show sample / line for measure of chips shown
502 m_leftSampLinePosition = new QLabel();
503 m_leftSampLinePosition->setToolTip("Sample/Line under the crosshair");
504 gridLayout->addWidget(m_leftSampLinePosition, row, 0);
505 m_rightSampLinePosition = new QLabel();
506 m_rightSampLinePosition->setToolTip("Sample/Line under the crosshair");
507 gridLayout->addWidget(m_rightSampLinePosition, row++, 1);
508
509 if (m_useGeometry) {
510 // Show lat / lon for measure of chips shown
511 m_leftLatLonPosition = new QLabel();
512 m_leftLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
513 gridLayout->addWidget(m_leftLatLonPosition, row, 0);
514 m_rightLatLonPosition = new QLabel();
515 m_rightLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
516 gridLayout->addWidget(m_rightLatLonPosition, row++, 1);
517 }
518
519 // Add auto registration extension
521 m_oldPosition = new QLabel;
522 m_oldPosition->setToolTip("Measure Sample/Line before sub-pixel "
523 "registration");
524 m_oldPosition->setWhatsThis("Original Sample/Line of the right measure "
525 "before the sub-pixel registration. If you select the \"Undo\" "
526 "button, the measure will revert back to this Sample/Line.");
527 m_goodFit = new QLabel;
528 m_goodFit->setToolTip("Goodness of Fit result from sub-pixel registration.");
529 m_goodFit->setWhatsThis("Resulting Goodness of Fit from sub-pixel "
530 "registration.");
531 QVBoxLayout *autoRegLayout = new QVBoxLayout;
532 autoRegLayout->setMargin(0);
533 autoRegLayout->addWidget(m_oldPosition);
534 autoRegLayout->addWidget(m_goodFit);
535 m_autoRegExtension->setLayout(autoRegLayout);
536 m_autoRegShown = false;
537 m_autoRegAttempted = false;
538 gridLayout->addWidget(m_autoRegExtension, row++, 1);
539
540
541 QHBoxLayout *leftLayout = new QHBoxLayout();
542 QToolButton *stop = new QToolButton();
543 stop->setIcon(QPixmap(toolIconDir + "/blinkStop.png"));
544 stop->setIconSize(QSize(22, 22));
545 stop->setToolTip("Blink Stop");
546 QString text = "<b>Function:</b> Stop automatic timed blinking";
547 stop->setWhatsThis(text);
548 connect(stop, SIGNAL(released()), this, SLOT(blinkStop()));
549
550 QToolButton *start = new QToolButton();
551 start->setIcon(QPixmap(toolIconDir + "/blinkStart.png"));
552 start->setIconSize(QSize(22, 22));
553 start->setToolTip("Blink Start");
554 text = "<b>Function:</b> Start automatic timed blinking. Cycles \
555 through linked viewports at variable rate";
556 start->setWhatsThis(text);
557 connect(start, SIGNAL(released()), this, SLOT(blinkStart()));
558
559 m_blinkTimeBox = new QDoubleSpinBox();
560 m_blinkTimeBox->setMinimum(0.1);
561 m_blinkTimeBox->setMaximum(5.0);
562 m_blinkTimeBox->setDecimals(1);
563 m_blinkTimeBox->setSingleStep(0.1);
564 m_blinkTimeBox->setValue(0.5);
565 m_blinkTimeBox->setToolTip("Blink Time Delay");
566 text = "<b>Function:</b> Change automatic blink rate between " +
567 QString::number(m_blinkTimeBox->minimum()) + " and " +
568 QString::number(m_blinkTimeBox->maximum()) + " seconds";
569 m_blinkTimeBox->setWhatsThis(text);
570 connect(m_blinkTimeBox, SIGNAL(valueChanged(double)),
571 this, SLOT(changeBlinkTime(double)));
572
573 leftLayout->addWidget(stop);
574 leftLayout->addWidget(start);
575 leftLayout->addWidget(m_blinkTimeBox);
576
577 if (m_useGeometry) {
578 QPushButton *find = new QPushButton("Find");
579 find->setShortcut(Qt::Key_F);
580 find->setToolTip("Move right measure to same Latitude/Longitude as left. "
581 "<strong>Shortcut: F</strong>");
582 find->setWhatsThis("Find the Latitude/Longitude under the crosshair in the "
583 "left measure and move the right measure to the same "
584 "latitude/longitude.");
585 leftLayout->addWidget(find);
586 connect(find, SIGNAL(clicked()), this, SLOT(findPoint()));
587 }
588
589 leftLayout->addStretch();
590 gridLayout->addLayout(leftLayout, row, 0);
591
592 QHBoxLayout *rightLayout = new QHBoxLayout();
593 m_autoReg = new QPushButton("Register");
594 m_autoReg->setShortcut(Qt::Key_R);
595 m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
596 "<strong>Shortcut: R</strong>");
597 m_autoReg->setWhatsThis("Sub-pixel register the right measure to the left "
598 "and move the result under the crosshair. After "
599 "viewing the results, the option exists to move the "
600 "measure back to the original position by selecting "
601 "<strong>\"Undo Registration\"</strong>.");
602 if (m_allowLeftMouse) {
603 m_saveMeasure = new QPushButton("Save Measures");
604 m_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
605 "point (control point currently being edited). "
606 "<strong>Shortcut: M</strong>. "
607 " <strong>Note: The edit control point "
608 "will not be saved to the network until you select "
609 "<strong>\"Save Point\"</strong>");
610 }
611 else {
612 m_saveMeasure = new QPushButton("Save Measure");
613 m_saveMeasure->setToolTip("Save the right measure to the edit control "
614 "point (control point currently being edited). "
615 "<strong>Shortcut: M</strong>. "
616 " <strong>Note: The edit control point "
617 "will not be saved to the network until you select "
618 "<strong>\"Save Point\"</strong>");
619 }
620 m_saveMeasure->setShortcut(Qt::Key_M);
622
623 // Blink extension allows all measures in the current control point to be blinked and gives
624 // user ability to select which measures and the order for blinking
626
627 QPushButton *blinkButton = new QPushButton("Advanced Blink");
628 blinkButton->setCheckable(true);
629 connect(blinkButton, &QAbstractButton::toggled, m_blinkExtension, &QWidget::setVisible);
630 connect(blinkButton, SIGNAL(clicked()), this, SLOT(showBlinkExtension()));
631
632 QHBoxLayout *rightBlinkLayout = new QHBoxLayout();
633 QToolButton *stopRight = new QToolButton();
634 stopRight->setIcon(QPixmap(toolIconDir + "/blinkStop.png"));
635 stopRight->setIconSize(QSize(22, 22));
636 stopRight->setToolTip("Blink Stop");
637 text = "<b>Function:</b> Stop automatic timed blinking";
638 stopRight->setWhatsThis(text);
639 connect(stopRight, SIGNAL(released()), this, SLOT(blinkStopRight()));
640
641 QToolButton *startRight = new QToolButton();
642 startRight->setIcon(QPixmap(toolIconDir + "/blinkStart.png"));
643 startRight->setIconSize(QSize(22, 22));
644 startRight->setToolTip("Blink Start");
645 text = "<b>Function:</b> Start automatic timed blinking. Cycles \
646 through linked viewports at variable rate";
647 startRight->setWhatsThis(text);
648 connect(startRight, SIGNAL(released()), this, SLOT(blinkStartRight()));
649
650 m_blinkTimeBoxRight = new QDoubleSpinBox();
651 m_blinkTimeBoxRight->setMinimum(0.1);
652 m_blinkTimeBoxRight->setMaximum(5.0);
653 m_blinkTimeBoxRight->setDecimals(1);
654 m_blinkTimeBoxRight->setSingleStep(0.1);
655 m_blinkTimeBoxRight->setValue(0.5);
656 m_blinkTimeBoxRight->setToolTip("Blink Time Delay");
657 text = "<b>Function:</b> Change automatic blink rate between " +
658 QString::number(m_blinkTimeBox->minimum()) + " and " +
659 QString::number(m_blinkTimeBox->maximum()) + " seconds";
660 m_blinkTimeBoxRight->setWhatsThis(text);
661 connect(m_blinkTimeBoxRight, SIGNAL(valueChanged(double)),
662 this, SLOT(changeBlinkTimeRight(double)));
663
664 rightBlinkLayout->addWidget(stopRight);
665 rightBlinkLayout->addWidget(startRight);
666 rightBlinkLayout->addWidget(m_blinkTimeBoxRight);
667
668 m_blinkListWidget = new QListWidget(m_blinkExtension);
669 m_blinkListWidget->setMinimumHeight(100);
670 m_blinkListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
671 m_blinkListWidget->setDragEnabled(true);
672 m_blinkListWidget->setAcceptDrops(true);
673 m_blinkListWidget->setDropIndicatorShown(true);
674 m_blinkListWidget->setDragDropMode(QAbstractItemView::InternalMove);
675// connect(m_blinkListWidget, SIGNAL(itemActivated(QListWidgetItem *)),
676// this, SLOT(toggleBlink(QListWidgetItem *)));
677// connect(m_blinkListWidget, SIGNAL(currentRowChanged(int)),
678// this, SLOT(updateWindow()));
679
680 rightBlinkLayout->addWidget(m_blinkListWidget);
681
682 m_blinkExtension->setLayout(rightBlinkLayout);
683
684
685
686
687
688
689 rightLayout->addWidget(m_autoReg);
690 rightLayout->addWidget(m_saveMeasure);
691 rightLayout->addWidget(blinkButton);
692 rightLayout->addStretch();
693 gridLayout->addLayout(rightLayout, row++, 1);
694 gridLayout->addWidget(m_blinkExtension, row, 1);
695 connect(m_autoReg, SIGNAL(clicked()), this, SLOT(registerPoint()));
696 connect(m_saveMeasure, SIGNAL(clicked()), this, SLOT(saveMeasure()));
697
698 setLayout(gridLayout);
699
700 //m_pointEditor->setCentralWidget(cw);
701 m_autoRegExtension->hide();
702 m_blinkExtension->hide();
703
704 //m_pointEditor->setVisible(true);
705 //m_pointEditor->raise();
706 }
707
708
732 Cube *leftCube, QString pointId) {
733
734 // Make sure registration is turned off
735 if ( m_autoRegShown ) {
736 // Undo Registration
737 m_autoRegShown = false;
738 m_autoRegExtension->hide();
739 m_autoReg->setText("Register");
740 m_autoReg->setToolTip("Sub-pixel register the right measure to the left."
741 "<strong>Shortcut: R</strong>");
742 m_autoReg->setShortcut(Qt::Key_R);
743 }
744
745 m_leftMeasure = leftMeasure;
746
747 if (m_useGeometry) {
748 // get new ground map
749 if ( m_leftGroundMap != 0 ) delete m_leftGroundMap;
750 m_leftGroundMap = new UniversalGroundMap(*leftCube);
751 }
752 m_leftCube = leftCube;
753
754 m_leftChip->TackCube(m_leftMeasure->GetSample(), m_leftMeasure->GetLine());
756
757 // Dump into left chipViewport
759
760 // Only update right if not loading a new point. If it's a new point, right measure
761 // hasn't been loaded yet.
762 if (pointId == m_pointId && m_geomIt) updateRightGeom();
763 m_pointId = pointId;
764 }
765
766
774 void ControlMeasureEditWidget::setLeftPosition(double sample, double line) {
775
776 m_leftChip->TackCube(sample, line);
777 emit updateLeftView(sample, line);
778 }
779
780
788 void ControlMeasureEditWidget::setRightPosition(double sample, double line) {
789
790 m_rightChip->TackCube(sample, line);
791 emit updateRightView(sample, line);
792 }
793
794
822 Cube *rightCube, QString pointId) {
823
824 // Make sure registration is turned off
825 if ( m_autoRegShown ) {
826 // Undo Registration
827 m_autoRegShown = false;
828 m_autoRegExtension->hide();
829 m_autoReg->setText("Register");
830 m_autoReg->setShortcut(Qt::Key_R);
831 m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
832 "<strong>Shortcut: R</strong>");
833 }
834 m_autoRegAttempted = false;
835
836 m_rightMeasure = rightMeasure;
837 m_pointId = pointId;
838
839 if (m_useGeometry) {
840 // get new ground map
841 if ( m_rightGroundMap != 0 ) delete m_rightGroundMap;
842 m_rightGroundMap = new UniversalGroundMap(*rightCube);
843 }
844 m_rightCube = rightCube;
845
846 m_rightChip->TackCube(m_rightMeasure->GetSample(),
847 m_rightMeasure->GetLine());
848 if ( m_geomIt == false ) {
850 }
851 else {
852 try {
854
855 }
856 catch (IException &e) {
857 IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
858 QString message = fullError.toString();
859 QMessageBox::information((QWidget *)parent(), "Error", message);
861 m_geomIt = false;
862 m_nogeom->setChecked(true);
863 m_geom->setChecked(false);
864 }
865 }
866
867 // Dump into left chipViewport
869
871
872 // New right measure, make sure Save Measure Button text is default
874 }
875
876
891 QString pos = "Sample: " + QString::number(m_leftView->tackSample()) +
892 " Line: " + QString::number(m_leftView->tackLine());
893 m_leftSampLinePosition->setText(pos);
894
895 if (m_useGeometry) {
896 // Get lat/lon from point in left
898 double lat = m_leftGroundMap->UniversalLatitude();
899 double lon = m_leftGroundMap->UniversalLongitude();
900
901 pos = "Latitude: " + QString::number(lat) +
902 " Longitude: " + QString::number(lon);
903 m_leftLatLonPosition->setText(pos);
904 }
905
906 // Print zoom scale factor
907 pos = "Zoom Factor: " + QString::number(zoomFactor);
908 m_leftZoomFactor->setText(pos);
909
910 // If zooms are linked, make right match left
911 if (m_linkZoom) {
913 }
914 }
915
916
928
929 // If registration Info is on, turn off
930 if (m_autoRegShown) {
931 // Undo Registration
932 m_autoRegShown = false;
933 m_autoRegExtension->hide();
934 m_autoReg->setText("Register");
935 m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
936 "<strong>Shortcut: R</strong>");
937 m_autoReg->setShortcut(Qt::Key_R);
938 }
939
940 QString pos = "Sample: " + QString::number(m_rightView->tackSample()) +
941 " Line: " + QString::number(m_rightView->tackLine());
942 m_rightSampLinePosition->setText(pos);
943
944 if (m_useGeometry) {
945 // Get lat/lon from point in right
947 double lat = m_rightGroundMap->UniversalLatitude();
948 double lon = m_rightGroundMap->UniversalLongitude();
949
950 pos = "Latitude: " + QString::number(lat) +
951 " Longitude: " + QString::number(lon);
952 m_rightLatLonPosition->setText(pos);
953 }
954
955 // Print zoom scale factor
956 pos = "Zoom Factor: " + QString::number(zoomFactor);
957 m_rightZoomFactor->setText(pos);
958
959 }
960
961
968
969 QColor qc = Qt::red;
970 QPalette p = m_saveMeasure->palette();
971 p.setColor(QPalette::ButtonText,qc);
972 m_saveMeasure->setPalette(p);
973
974 }
975
976
987
988 // Get lat/lon from point in left
990 double lat = m_leftGroundMap->UniversalLatitude();
991 double lon = m_leftGroundMap->UniversalLongitude();
992
993 // Reload right chipViewport with this new tack point.
994 if ( m_rightGroundMap->SetUniversalGround(lat, lon) ) {
995 emit updateRightView(m_rightGroundMap->Sample(), m_rightGroundMap->Line());
996
997 // If moving from saved measure, turn save button to red
998 if (m_rightGroundMap->Sample() != m_rightMeasure->GetSample() ||
999 m_rightGroundMap->Line() != m_rightMeasure->GetLine())
1001 }
1002 else {
1003 QString message = "Latitude: " + QString::number(lat) + " Longitude: " +
1004 QString::number(lon) + " is not on the right image. Right measure " +
1005 "was not moved.";
1006 QMessageBox::warning((QWidget *)parent(),"Warning",message);
1007 }
1008
1009 }
1010
1011
1042
1043 // if the auto registration factory has not been initialized, do it here
1044 if (m_autoRegFact == NULL) {
1045 try {
1048 }
1049 catch (IException &e) {
1050 m_autoRegFact = NULL;
1051 IException fullError(e, IException::Io,
1052 "Cannot create AutoRegFactory. As a result, "
1053 "sub-pixel registration will not work.",
1054 _FILEINFO_);
1055 QString message = fullError.toString();
1056 QMessageBox::information((QWidget *)parent(), "Error", message);
1057 return;
1058 }
1059 }
1060
1061 if ( m_autoRegShown ) {
1062 // Undo Registration
1063 m_autoRegShown = false;
1064 m_autoRegExtension->hide();
1065 m_autoReg->setText("Register");
1066 m_autoReg->setShortcut(Qt::Key_R);
1067 m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
1068 "<strong>Shortcut: R</strong>");
1069
1070 // Reload chip with original measure
1071 emit updateRightView(m_rightMeasure->GetSample(),
1072 m_rightMeasure->GetLine());
1073 // Since un-doing registration, make sure save button not red
1075 return;
1076
1077 }
1078 m_autoRegAttempted = true;
1079
1080 try {
1082 m_leftMeasure->GetSample(), m_leftMeasure->GetLine());
1085 m_rightMeasure->GetSample(),
1086 m_rightMeasure->GetLine());
1087 if (m_useGeometry) {
1090 }
1091 else {
1093 }
1094 }
1095 catch (IException &e) {
1096 QString msg = "Cannot register this point, unable to Load chips.\n";
1097 msg += e.toString();
1098 QMessageBox::information((QWidget *)parent(), "Error", msg);
1099 return;
1100 }
1101
1102 try {
1104 if ( !m_autoRegFact->Success() ) {
1105 QString msg = "Cannot sub-pixel register this point.\n";
1107 msg += "\n\nNot enough valid data in Pattern Chip.\n";
1108 msg += " PatternValidPercent = ";
1109 msg += QString::number(m_autoRegFact->PatternValidPercent()) + "%";
1110 }
1111 else if ( status == AutoReg::FitChipNoData ) {
1112 msg += "\n\nNo valid data in Fit Chip.";
1113 }
1114 else if ( status == AutoReg::FitChipToleranceNotMet ) {
1115 msg += "\n\nGoodness of Fit Tolerance not met.\n";
1116 msg += "\nGoodnessOfFit = " + QString::number(m_autoRegFact->GoodnessOfFit());
1117 msg += "\nGoodnessOfFitTolerance = ";
1118 msg += QString::number(m_autoRegFact->Tolerance());
1119 }
1120 else if ( status == AutoReg::SurfaceModelNotEnoughValidData ) {
1121 msg += "\n\nNot enough valid points in the fit chip window for sub-pixel ";
1122 msg += "accuracy. Probably too close to edge.\n";
1123 }
1124 else if ( status == AutoReg::SurfaceModelSolutionInvalid ) {
1125 msg += "\n\nCould not model surface for sub-pixel accuracy.\n";
1126 }
1127 else if ( status == AutoReg::SurfaceModelDistanceInvalid ) {
1128 double sampDist, lineDist;
1129 m_autoRegFact->Distance(sampDist, lineDist);
1130 msg += "\n\nSub pixel algorithm moves registration more than tolerance.\n";
1131 msg += "\nSampleMovement = " + QString::number(sampDist) +
1132 " LineMovement = " + QString::number(lineDist);
1133 msg += "\nDistanceTolerance = " +
1134 QString::number(m_autoRegFact->DistanceTolerance());
1135 }
1136 else if ( status == AutoReg::PatternZScoreNotMet ) {
1137 double score1, score2;
1138 m_autoRegFact->ZScores(score1, score2);
1139 msg += "\n\nPattern data max or min does not pass z-score test.\n";
1140 msg += "\nMinimumZScore = " + QString::number(m_autoRegFact->MinimumZScore());
1141 msg += "\nCalculatedZscores = " + QString::number(score1) + ", " + QString::number(score2);
1142 }
1143 else if ( status == AutoReg::AdaptiveAlgorithmFailed ) {
1144 msg += "\n\nError occured in Adaptive algorithm.";
1145 }
1146 else {
1147 msg += "\n\nUnknown registration error.";
1148 }
1149
1150 QMessageBox::information((QWidget *)parent(), "Error", msg);
1151 return;
1152 }
1153 }
1154 catch (IException &e) {
1155 QString msg = "Cannot register this point.\n";
1156 msg += e.toString();
1157 QMessageBox::information((QWidget *)parent(), "Error", msg);
1158 return;
1159 }
1160
1161
1162
1163 // Load chip with new registered point
1164 emit updateRightView(m_autoRegFact->CubeSample(), m_autoRegFact->CubeLine());
1165 // If registered pt different from measure, colorize the save button
1166 if (m_autoRegFact->CubeSample() != m_rightMeasure->GetSample() ||
1167 m_autoRegFact->CubeLine() != m_rightMeasure->GetLine()) {
1169 }
1170
1171 QString oldPos = "Original Sample: " +
1172 QString::number(m_rightMeasure->GetSample()) + " Original Line: " +
1173 QString::number(m_rightMeasure->GetLine());
1174 m_oldPosition->setText(oldPos);
1175
1176 QString goodFit = "Goodness of Fit: " +
1177 QString::number(m_autoRegFact->GoodnessOfFit());
1178 m_goodFit->setText(goodFit);
1179
1180 m_autoRegExtension->show();
1181 m_autoRegShown = true;
1182 m_autoReg->setText("Undo Registration");
1183 m_autoReg->setToolTip("Undo sub-pixel registration. "
1184 "<strong>Shortcut: U</strong>");
1185 m_autoReg->setShortcut(Qt::Key_U);
1186 }
1187
1188
1227
1228 if ( m_rightMeasure != NULL ) {
1229
1231 QString message = "The right measure is locked. You must first unlock the measure by ";
1232 message += "clicking the check box above labeled \"Edit Lock Measure\".";
1233 QMessageBox::warning((QWidget *)parent(),"Warning",message);
1234 return;
1235 }
1236
1237 if ( m_autoRegShown ) {
1238 try {
1239 // Save autoreg parameters to the right measure log entry
1240 // Eccentricity may be invalid, check before writing.
1244 double minZScore, maxZScore;
1245 m_autoRegFact->ZScores(minZScore,maxZScore);
1248 minZScore));
1251 maxZScore));
1252 }
1253 // need to handle exception that SetLogData throws if our data is invalid -
1254 // unhandled exceptions thrown in Qt signal and slot connections produce undefined behavior
1255 catch (IException &e) {
1256 QString message = e.toString();
1257 QMessageBox::critical((QWidget *)parent(), "Error", message);
1258 return;
1259 }
1260
1261 // Reset AprioriSample/Line to the current coordinate, before the
1262 // coordinate is updated with the registered coordinate.
1263 m_rightMeasure->SetAprioriSample(m_rightMeasure->GetSample());
1264 m_rightMeasure->SetAprioriLine(m_rightMeasure->GetLine());
1265
1266 m_rightMeasure->SetChooserName("Application qnet");
1268
1269 m_autoRegShown = false;
1270 m_autoRegExtension->hide();
1271 m_autoReg->setText("Register");
1272 m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
1273 "<strong>Shortcut: R</strong>");
1274 m_autoReg->setShortcut(Qt::Key_R);
1275 }
1276 else {
1285 }
1286
1287 // Get cube position at right chipViewport crosshair
1291
1292 }
1293
1294 if ( m_allowLeftMouse ) {
1295 if ( m_leftMeasure != NULL ) {
1296 if (m_leftMeasure->IsEditLocked()) {
1297 QString message = "The left measure is locked. You must first unlock the measure by ";
1298 message += "clicking the check box above labeled \"Edit Lock Measure\".";
1299 QMessageBox::warning((QWidget *)parent(),"Warning",message);
1300 return;
1301 }
1302
1307 }
1308 }
1309
1310 // If the right chip is the same as the left chip, copy right into left and
1311 // re-load the left.
1314
1317 }
1318
1319 // Change Save Measure button text back to default palette
1321
1322 // Redraw measures on viewports
1323 emit measureSaved();
1324 }
1325
1326
1336
1337 if ( m_geomIt ) {
1338 try {
1340
1341 }
1342 catch (IException &e) {
1343 IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1344 QString message = fullError.toString();
1345 QMessageBox::information((QWidget *)parent(), "Error", message);
1346 m_geomIt = false;
1347 m_nogeom->setChecked(true);
1348 m_geom->setChecked(false);
1349 }
1350 }
1351 }
1352
1353
1354
1356// * Slot to update the right ChipViewport for zoom
1357// * operations
1358// *
1359// * @author 2012-07-26 Tracie Sucharski
1360// *
1361// * @internal
1362// */
1363//void ControlMeasureEditWidget::updateRightZoom() {
1364//
1365// if ( m_linkZoom ) {
1366// try {
1367// m_rightView->geomChip(m_leftChip, m_leftCube);
1368//
1369// }
1370// catch (IException &e) {
1371// IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1372// QString message = fullError.toString();
1373// QMessageBox::information((QWidget *)parent(), "Error", message);
1374// m_geomIt = false;
1375// m_nogeom->setChecked(true);
1376// m_geom->setChecked(false);
1377// }
1378// }
1379//}
1380
1381
1389 QApplication::setOverrideCursor(Qt::WaitCursor);
1390
1391 // Text needs to be reset because it was changed to
1392 // indicate why it's greyed out
1393 QString text = "Zoom in 2X";
1394 m_rightZoomIn->setEnabled(true);
1395 m_rightZoomIn->setWhatsThis(text);
1396 m_rightZoomIn->setToolTip("Zoom In");
1397 text = "Zoom out 2X";
1398 m_rightZoomOut->setEnabled(true);
1399 m_rightZoomOut->setWhatsThis(text);
1400 m_rightZoomOut->setToolTip("Zoom Out");
1401 text = "Zoom 1:1";
1402 m_rightZoom1->setEnabled(true);
1403 m_rightZoom1->setWhatsThis(text);
1404 m_rightZoom1->setToolTip("Zoom 1:1");
1405
1406 m_geomIt = false;
1408
1409 QApplication::restoreOverrideCursor();
1410
1411 m_dial->setEnabled(true);
1412 m_dialNumber->setEnabled(true);
1413 m_dial->setNotchesVisible(true);
1414
1415 }
1416
1417
1428
1429 if ( m_geomIt == true ) return;
1430
1431 QApplication::setOverrideCursor(Qt::WaitCursor);
1432
1433 // Grey right view zoom buttons
1434 QString text = "Zoom functions disabled when Geom is set";
1435 m_rightZoomIn->setEnabled(false);
1436 m_rightZoomIn->setWhatsThis(text);
1437 m_rightZoomIn->setToolTip(text);
1438 m_rightZoomOut->setEnabled(false);
1439 m_rightZoomOut->setWhatsThis(text);
1440 m_rightZoomOut->setToolTip(text);
1441 m_rightZoom1->setEnabled(false);
1442 m_rightZoom1->setWhatsThis(text);
1443 m_rightZoom1->setToolTip(text);
1444
1445
1446 // Reset dial to 0 before disabling
1447 m_dial->setValue(0);
1448 m_dial->setEnabled(false);
1449 m_dialNumber->setEnabled(false);
1450
1451 m_geomIt = true;
1452
1453 try {
1455
1456 }
1457 catch (IException &e) {
1458 IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1459 QString message = fullError.toString();
1460 QMessageBox::information((QWidget *)parent(), "Error", message);
1461 m_geomIt = false;
1462 m_nogeom->setChecked(true);
1463 m_geom->setChecked(false);
1464 }
1465
1466 QApplication::restoreOverrideCursor();
1467 }
1468
1469
1477
1478 QApplication::setOverrideCursor(Qt::WaitCursor);
1479
1480 QString text = "Zoom in 2X";
1481 m_rightZoomIn->setEnabled(true);
1482 m_rightZoomIn->setWhatsThis(text);
1483 m_rightZoomIn->setToolTip("Zoom In");
1484 text = "Zoom out 2X";
1485 m_rightZoomOut->setEnabled(true);
1486 m_rightZoomOut->setWhatsThis(text);
1487 m_rightZoomOut->setToolTip("Zoom Out");
1488 text = "Zoom 1:1";
1489 m_rightZoom1->setEnabled(true);
1490 m_rightZoom1->setWhatsThis(text);
1491 m_rightZoom1->setToolTip("Zoom 1:1");
1492
1493 // Reset dial to 0 before disabling
1494 m_dial->setValue(0);
1495 m_dial->setEnabled(false);
1496 m_dialNumber->setEnabled(false);
1497
1498 m_geomIt = false;
1500
1501 QApplication::restoreOverrideCursor();
1502 }
1503
1504
1513
1514 if ( checked == m_circle ) return;
1515
1516 m_circle = checked;
1517 if ( m_circle ) {
1518 // Turn on slider bar
1519 m_slider->setDisabled(false);
1520 m_slider->show();
1521 m_slider->setValue(20);
1522 m_leftView->setCircle(true);
1523 m_rightView->setCircle(true);
1524 }
1525 else {
1526 m_slider->setDisabled(true);
1527 m_slider->hide();
1528 m_leftView->setCircle(false);
1529 m_rightView->setCircle(false);
1530 }
1531 }
1532
1533
1542
1543 if ( checked == m_linkZoom ) return;
1544
1545 m_linkZoom = checked;
1546 if ( m_linkZoom ) {
1548 }
1549 }
1550
1551
1556 if ( m_timerOn ) return;
1557
1558 // Set up blink list
1559 m_blinkList.push_back(m_leftView);
1560 m_blinkList.push_back(m_rightView);
1561 m_blinkIndex = 0;
1562
1563 m_timerOn = true;
1564 int msec = (int)(m_blinkTimeBox->value() * 1000.0);
1565 m_timer = new QTimer(this);
1566 connect(m_timer, SIGNAL(timeout()), this, SLOT(updateBlink()));
1567 m_timer->start(msec);
1568 }
1569
1570
1575 m_timer->stop();
1576 m_timerOn = false;
1577 m_blinkList.clear();
1578
1579 // Reload left chipViewport with original chip
1580 m_leftView->repaint();
1581
1582 }
1583
1584
1592 if ( m_timerOn ) m_timer->setInterval((int)(interval * 1000.));
1593 }
1594
1595
1604
1605
1625
1626 AutoReg *reg = NULL;
1627 // save original template filename
1628 QString temp = m_templateFileName;
1629 try {
1630 // set template filename to user chosen pvl file
1631 m_templateFileName = fn;
1632
1633 // Create PVL object with this file
1634 Pvl pvl(fn);
1635
1636 // try to register file
1637 reg = AutoRegFactory::Create(pvl);
1638 if ( m_autoRegFact != NULL )
1639 delete m_autoRegFact;
1640 m_autoRegFact = reg;
1641
1642 m_templateFileName = fn;
1643 return true;
1644 }
1645 catch (IException &e) {
1646 // set templateFileName back to its original value
1647 m_templateFileName = temp;
1648 IException fullError(e, IException::Io,
1649 "Cannot create AutoRegFactory for " +
1650 fn +
1651 ". As a result, current template file will remain set to " +
1652 m_templateFileName, _FILEINFO_);
1653 QString message = fullError.toString();
1654 QMessageBox::information((QWidget *)parent(), "Error", message);
1655 emit setTemplateFailed(m_templateFileName);
1656 return false;
1657 }
1658 }
1659
1660
1669 m_allowLeftMouse = allowMouse;
1670
1671 if (m_allowLeftMouse) {
1672 m_saveMeasure = new QPushButton("Save Measures");
1673 m_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
1674 "point (control point currently being edited). "
1675 " <strong>Note: The edit control point "
1676 "will not be saved to the network until you select "
1677 "<strong>\"Save Point\"</strong>");
1678 }
1679 else {
1680 m_saveMeasure = new QPushButton("Save Measure");
1681 m_saveMeasure->setToolTip("Save the right measure to the edit control "
1682 "point (control point currently being edited). "
1683 " <strong>Note: The edit control point "
1684 "will not be saved to the network until you select "
1685 "<strong>\"Save Point\"</strong>");
1686 }
1687 }
1688
1689
1690 void ControlMeasureEditWidget::refreshChips() {
1691 m_leftView->update();
1692 m_rightView->update();
1693 }
1694
1695
1706
1707// if (!m_autoRegShown) {
1708 if ( !m_autoRegAttempted ) {
1709 QString message = "Point must be Registered before chips can be saved.";
1710 QMessageBox::warning((QWidget *)parent(), "Warning", message);
1711 return;
1712 }
1713
1714 // Save chips - pattern, search and fit
1715 QString baseFile = m_pointId.replace(" ", "_") + "_" +
1716 toString((int)(m_leftMeasure ->GetSample())) + "_" +
1717 toString((int)(m_leftMeasure ->GetLine())) + "_" +
1718 toString((int)(m_rightMeasure->GetSample())) + "_" +
1719 toString((int)(m_rightMeasure->GetLine())) + "_";
1720 QString fname = baseFile + "Search.cub";
1721 QString command = "$ISISROOT/bin/qview \'" + fname + "\'";
1723 fname = baseFile + "Pattern.cub";
1724 command += " \'" + fname + "\'";
1726 fname = baseFile + "Fit.cub";
1727 command += " \'" + fname + "\' &";
1728 m_autoRegFact->FitChip()->Write(fname);
1730 }
1731
1732
1741
1742 m_editPoint = editPoint;
1743 m_serialNumberList = snList;
1744
1745
1746 m_blinkListWidget->clear();
1747 }
1748
1749
1750 void ControlMeasureEditWidget::showBlinkExtension() {
1751 m_blinkListWidget->clear();
1752 // Get all measure filenames for ListWidget
1753 for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1754 ControlMeasure &m = *(*m_editPoint)[i];
1755 QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
1756 // TODO Ipce TLS Look at QnetNavTool for how selectedItems is used so don't need map
1757 // between full cubename and base name.
1758// QString tempFileName = FileName(file).name();
1759 m_blinkListWidget->addItem(file);
1760
1761
1762
1763// if (m_editPoint->IsReferenceExplicit() &&
1764// (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
1765// m_blinkListWidget->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1766// }
1767 }
1768 }
1769
1770
1773
1774 if ( m_timerOnRight ) return;
1775
1776 // Set up blink list. Create ChipViewport for each cube active in the ListWidget, using the
1777 // correct zoom and geom selections
1778 QList<QListWidgetItem *> selected = m_blinkListWidget->selectedItems();
1779 if (selected.size() < 1) {
1780 QMessageBox::information((QWidget *)parent(), "Error", "No files selected for blinking.");
1781 return;
1782 }
1783
1784 // Find measure for each selected file, create cube, chip and chipViewport
1785 for (int i=0; i<selected.size(); i++) {
1786 QString file = selected.at(i)->text();
1787 QString serial = m_serialNumberList->serialNumber(file);
1788 Cube *blinkCube = new Cube(selected.at(i)->text());
1789 Chip *blinkChip = new Chip(VIEWSIZE, VIEWSIZE);
1790 ControlMeasure *blinkMeasure = m_editPoint->GetMeasure(serial);
1791 blinkChip->TackCube(blinkMeasure->GetSample(), blinkMeasure->GetLine());
1792 blinkChip->Load(*blinkCube);
1793 ChipViewport *blinkViewport = new ChipViewport(VIEWSIZE, VIEWSIZE, this);
1794 blinkViewport->setChip(blinkChip, blinkCube);
1795 if (m_geomIt) {
1796 blinkViewport->geomChip(m_leftChip, m_leftCube);
1797 }
1798 else {
1799 blinkViewport->zoom(m_leftView->zoomFactor());
1800 }
1801 m_blinkChipViewportListRight.append(blinkViewport);
1802 }
1803
1805
1806 m_timerOnRight = true;
1807 int msec = (int)(m_blinkTimeBoxRight->value() * 1000.0);
1808 m_timerRight = new QTimer(this);
1809 connect(m_timerRight, SIGNAL(timeout()), this, SLOT(updateBlinkRight()));
1810 m_timerRight->start(msec);
1811 }
1812
1813
1816
1817 m_timerRight->stop();
1818 m_timerOnRight = false;
1820 // Reload left chipViewport with original chip
1821 m_rightView->repaint();
1822 }
1823
1824
1832 if ( m_timerOnRight ) m_timerRight->setInterval((int)(interval * 1000.));
1833 }
1834
1835
1845}
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.
QPushButton * m_autoReg
Button to auto-register the measure.
QLCDNumber * m_dialNumber
The current amount of rotation (in degrees)
QTimer * m_timer
Timer on the blinking.
ControlPoint * m_editPoint
The control point currently being edited.
void saveChips()
Slot to save registration chips to files and fire off qview.
QToolButton * m_rightZoomIn
Button for zooming in right chip viewport.
QLabel * m_rightLatLonPosition
Label for right chip viewport's current lat/lon.
void setRightPosition(double sample, double line)
Set the tack position of the measure in the right ChipViewport.
QList< ChipViewport * > m_blinkChipViewportListRight
List of viewports to blink through.
QLabel * m_leftLatLonPosition
Label for left chip viewport's current lat/lon.
void updateLeftPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of left measure.
ChipViewport * m_rightView
Right ChipViewport.
QLabel * m_rightSampLinePosition
Label for right chip viewport's current sample/line.
UniversalGroundMap * m_leftGroundMap
UniversalGroundMap for left cube.
void setCircle(bool)
Turn circle widgets on/off.
void setZoomLink(bool)
Turn linking of zoom on or off.
void setLeftMeasure(ControlMeasure *leftMeasure, Cube *leftCube, QString pointId)
Set the measure displayed in the left ChipViewport.
QLabel * m_leftZoomFactor
Label for left chip viewport's zoom factor.
SerialNumberList * m_serialNumberList
The serial numbers for each measure of m_editpoint.
int m_rotation
Amount to rotate right chip viewport TODO Is this used??
void colorizeSaveButton()
Turn "Save Measure" button text to red.
bool m_autoRegAttempted
Whether or not auto-registration has been attempted.
void findPoint()
Find point from left ChipViewport in the right ChipViewport.
ChipViewport * m_leftView
Left ChipViewport.
QPushButton * m_saveMeasure
Button to save the current measure.
void allowLeftMouse(bool allowMouse)
Set the option that allows mouse movements in the left ChipViewport.
void blinkStop()
Slot to stop blink function.
QTimer * m_timerRight
Timer for tracking image blink time.
QList< ChipViewport * > m_blinkList
List of chip viewports to blink.
bool m_linkZoom
Link zoom factors between chip viewports.
bool m_autoRegShown
Whether or not the auto-reg extension is shown.
void blinkStartRight()
Slot to start blink function for advanced blink functionality.
QDoubleSpinBox * m_blinkTimeBox
The current blink step (in seconds)
void updateBlinkRight()
Slot to cause the blink to happen coinciding with the timer.
void setPoint(ControlPoint *editPoint, SerialNumberList *snList)
Set the Control Point for this widget.
void updateRightPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of right measure.
Cube * m_rightCube
Right chip viewport's Cube.
QString m_pointId
Associated control point id of the right measure.
void createMeasureEditor(QWidget *parent)
Design the MeasureEdit widget.
bool m_geomIt
Apply geometry to the right chip viewport.
QString m_templateFileName
Registration template filename.
void updateBlink()
Slot to cause the blink to happen coinciding with the timer.
QRadioButton * m_nogeom
Radio button to remove geometry/rotation for right chip viewport.
void changeBlinkTime(double interval)
Set blink rate.
bool m_timerOn
Indicates if the blink timer is on.
bool m_circle
Whether or not to draw circle in center of the right chip viewport.
unsigned char m_blinkIndexRight
Index of image being blinked.
ControlMeasureEditWidget(QWidget *parent=0, bool allowLeftMouse=false, bool useGeometry=true)
Constructs a ControlMeasureEditWidget widget.
QPalette m_saveDefaultPalette
Default color palette for the Save button.
QDoubleSpinBox * m_blinkTimeBoxRight
Input for time between image blinks.
ControlMeasure * m_rightMeasure
Right ControlMeasure.
QLabel * m_oldPosition
The old sample and line before registering.
AutoReg * m_autoRegFact
Created AutoReg.
QWidget * m_autoRegExtension
Widget that shows after registering a measure.
void blinkStart()
Slot to start blink function.
QWidget * m_blinkExtension
Widget for selecting images and timing to blink through them.
QToolButton * m_rightZoom1
Button for 1:1 zoom on right chip viewport.
void updateRightGeom()
Slot to update the geomed right ChipViewport for zoom operations.
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename.
void registerPoint()
Sub-pixel register point in right chipViewport with point in left.
void blinkStopRight()
Slot to stop blink function.
QToolButton * m_rightZoomOut
Button for zooming out right chip viewport.
QLabel * m_leftSampLinePosition
Label for left chip viewport's current sample/line.
bool m_timerOnRight
Timer is on for right viewport.
void changeBlinkTimeRight(double interval)
Set blink rate.
void saveMeasure()
Save control measure under the crosshair in right ChipViewport.
bool m_useGeometry
Whether or not to allow geometry/rotation on right chip viewport.
UniversalGroundMap * m_rightGroundMap
UniversalGroundMap for right cube.
QRadioButton * m_geom
Radio button to apply geometry/rotation to right chip viewport.
ControlMeasure * m_leftMeasure
Left ControlMeasure.
unsigned char m_blinkIndex
Index of the chip to load in the left chip viewport.
void setLeftPosition(double sample, double line)
Set the tack position of the measure in the left ChipViewport.
void setRightMeasure(ControlMeasure *rightMeasure, Cube *rightCube, QString pointId)
Set the measure displayed in the right ChipViewport.
QScrollBar * m_slider
Slider that controls the size of the center circle.
QLabel * m_rightZoomFactor
Label for right chip viewport's zoom factor.
QListWidget * m_blinkListWidget
List of images being blinked through.
QLabel * m_goodFit
The goodness of fit value after registering.
bool m_allowLeftMouse
Whether or not to allow mouse events on left chip viewport.
Cube * m_leftCube
Left chip viewport's Cube.
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
A single control point.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
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
Serial Number list generator.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
QString fileName(const QString &sn)
Return a filename given a serial number.
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.