Isis 3 Programmer Reference
AdvancedTrackTool.cpp
1 #include "AdvancedTrackTool.h"
2 
3 #include <QAction>
4 #include <QApplication>
5 #include <QLabel>
6 #include <QListIterator>
7 #include <QMenu>
8 #include <QMenuBar>
9 #include <QMessageBox>
10 #include <QPushButton>
11 #include <QScrollArea>
12 #include <QSize>
13 #include <QTableWidget>
14 #include <QTableWidgetItem>
15 #include <QToolBar>
16 #include <QVBoxLayout>
17 
18 #include "Angle.h"
19 #include "Camera.h"
20 #include "CameraDistortionMap.h"
21 #include "CameraFocalPlaneMap.h"
22 #include "Distance.h"
23 #include "iTime.h"
24 #include "Longitude.h"
25 #include "MdiCubeViewport.h"
26 #include "Projection.h"
27 #include "RingPlaneProjection.h"
28 #include "SerialNumber.h"
29 #include "SpecialPixel.h"
30 #include "TableMainWindow.h"
31 #include "Target.h"
32 #include "TProjection.h"
33 #include "TrackingTable.h"
34 
35 namespace Isis {
36 
37  // For mosaic tracking
38 #define FLOAT_MIN -16777215
39 
46  p_tableWin = new TableMainWindow("Advanced Tracking", parent);
48  connect(p_tableWin, SIGNAL(fileLoaded()), this, SLOT(updateID()));
49 
50  p_action = new QAction(parent);
51  p_action->setText("Tracking ...");
52  p_action->setIcon(QPixmap(toolIconDir() + "/goto.png"));
53  p_action->setShortcut(Qt::CTRL + Qt::Key_T);
54  p_action->setWhatsThis("<b>Function: </b> Opens the Advanced Tracking Tool \
55  window. This window will track sample/line positions,\
56  lat/lon positions, and many other pieces of \
57  information. All of the data in the window can be \
58  saved to a text file. <p><b>Shortcut: </b> Ctrl+T</p>");
59  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(showTable()));
60  activate(true);
61  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(raise()));
62  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(syncColumns()));
63  p_tableWin->installEventFilter(this);
64 
65  // Adds each item of checkBoxItems to the table.
66  // If a tool tip is specified, we cannot skip parameters, so -1 and
67  // Qt::Horizontal are specified.
68  QList< QList<QString> >::iterator iter;
69  for (iter = checkBoxItems.begin(); iter != checkBoxItems.end(); ++iter) {
70  QList<QString> currentList = *iter;
71  QString header = currentList[0];
72  QString menuText = currentList[2];
73  QString toolTip = currentList[3];
74  bool onByDefault;
75  if (currentList[1] == QString("true")) {
76  onByDefault = true;
77  }
78  else {
79  onByDefault = false;
80  }
81 
82  if (toolTip != QString("")) {
83  p_tableWin->addToTable(onByDefault, header, menuText,
84  -1, Qt::Horizontal, toolTip);
85  }
86  else {
87  p_tableWin->addToTable(onByDefault, header, menuText);
88  }
89  }
90 
91  //This variable will keep track of how many times
92  // the user has issued the 'record' command.
93  p_id = 0;
94 
95  // Setup 10 blank rows in the table
96  for(int r = 0; r < 10; r++) {
97  p_tableWin->table()->insertRow(r);
98  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
99  QTableWidgetItem *item = new QTableWidgetItem("");
100  p_tableWin->table()->setItem(r, c, item);
101  }
102  }
103 
104  // Create the action for recording points
105  QAction *recordAction = new QAction(parent);
106  recordAction->setShortcut(Qt::Key_R);
107  parent->addAction(recordAction);
108  connect(recordAction, SIGNAL(triggered()), this, SLOT(record()));
109  p_tableWin->setStatusMessage("To record press the R key"
110  " --- Double click on a cell to enable crtl+c (copy) and"
111  " ctrl+v (paste).");
112 
113  // Add a help menu to the menu bar
114  QMenuBar *menuBar = p_tableWin->menuBar();
115  QMenu *helpMenu = menuBar->addMenu("&Help");
116  QAction *help = new QAction(p_tableWin);
117  help->setText("&Tool Help");
118  help->setShortcut(Qt::CTRL + Qt::Key_H);
119  connect(help, SIGNAL(triggered()), this, SLOT(helpDialog()));
120  helpMenu->addAction(help);
121  p_tableWin->setMenuBar(menuBar);
122  installEventFilter(p_tableWin);
123 
124  m_showHelpOnStart = true;
125  readSettings();
126  }
127 
137  if(e->type() == QEvent::Show) {
138  activate(true);
139  if (m_showHelpOnStart) {
140  helpDialog();
141  m_showHelpOnStart = false;
142  writeSettings();
143  }
144  }
145  else if(e->type() == QEvent::Hide) {
146  activate(false);
147  }
148  return Tool::eventFilter(o, e);
149  }
150 
151 
158  menu->addAction(p_action);
159  }
160 
168  perm->addAction(p_action);
169  }
170 
178  updateRow(p);
179  }
180 
187 
188  if(cubeViewport()->isLinked()) {
189  for(int i = 0; i < p_numRows; i++) {
191  }
192  }
193  else {
195  }
196 
197  }
198 
205  MdiCubeViewport *cvp = cubeViewport();
206  if(cvp == NULL) {
208  return;
209  }
210 
211  if(!cubeViewport()->isLinked()) {
212  updateRow(cvp, p, p_tableWin->currentRow());
213  p_numRows = 1;
214  }
215  else {
216  p_numRows = 0;
217  for(int i = 0; i < (int)cubeViewportList()->size(); i++) {
218  MdiCubeViewport *d = (*(cubeViewportList()))[i];
219  if(d->isLinked()) {
221  p_numRows++;
222  }
223  }
224  }
225  }
226 
227 
236  int AdvancedTrackTool::getIndex(QString keyword) {
237  int index = 0;
238  QList< QList<QString> >::iterator iter;
239  for (iter = checkBoxItems.begin(); iter != checkBoxItems.end(); ++iter) {
240  QList<QString> currentList = *iter;
241  QList<QString> splitHeader = currentList[0].split(":");
242  QList<QString>::iterator headerIter;
243  for (headerIter = splitHeader.begin(); headerIter != splitHeader.end(); ++headerIter) {
244  QString header = *headerIter;
245  if (header.toLower() == keyword.toLower()) {
246  return index;
247  }
248  index++;
249  }
250  }
251  IString msg = "Header [" + keyword + "] not found; make sure spelling is correct";
252  throw IException(IException::Io, msg, _FILEINFO_);
253  }
254 
262  void AdvancedTrackTool::updateRow(MdiCubeViewport *cvp, QPoint p, int row) {
263  // Get the sample line position to report
264  double sample, line;
265  cvp->viewportToCube(p.x(), p.y(), sample, line);
266  int isample = int (sample + 0.5);
267  int iline = int (line + 0.5);
268 
269  /*if there are linked cvp's then we want to highlight (select)
270  the row of the active cvp.*/
271  if(cvp->isLinked()) {
272 
273  if(cvp == cubeViewport()) {
274  p_tableWin->table()->selectRow(row);
275  }
276 
277  }
278 
279 
280  // Do we need more rows?
281  if(row + 1 > p_tableWin->table()->rowCount()) {
282  p_tableWin->table()->insertRow(row);
283  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
284  QTableWidgetItem *item = new QTableWidgetItem("");
285  p_tableWin->table()->setItem(row, c, item);
286  if(c == 0) p_tableWin->table()->scrollToItem(item);
287  }
288  }
289 
290  // Blank out the row to remove stuff left over from previous cvps
291  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
292  p_tableWin->table()->item(row, c)->setText("");
293  }
294 
295  // Don't write anything if we are outside the cube
296  if(sample < 0.5) return;
297  if(line < 0.5) return;
298  if(sample > cvp->cubeSamples() + 0.5) return;
299  if(line > cvp->cubeLines() + 0.5) return;
300 
301  // Write cols 0-2 (id, sample, line)
302  p_tableWin->table()->item(row, getIndex("ID"))->setText(QString::number(p_id));
303  p_tableWin->table()->item(row, getIndex("Sample"))->setText(QString::number(sample));
304  p_tableWin->table()->item(row, getIndex("Line"))->setText(QString::number(line));
305 
306  // Write col 3 (band)
307  if (cvp->isGray()) {
308  p_tableWin->table()->item(row, getIndex("Band"))->setText(QString::number(cvp->grayBand()));
309  }
310  else {
311  p_tableWin->table()->item(row, getIndex("Band"))->setText(QString::number(cvp->redBand()));
312  }
313 
314  // Write out the path, filename, and serial number
315  FileName fname = FileName(cvp->cube()->fileName()).expanded();
316  QString fnamePath = fname.path();
317  QString fnameName = fname.name();
318  p_tableWin->table()->item(row, getIndex("Path"))->setText(fnamePath);
319  p_tableWin->table()->item(row, getIndex("FileName"))->setText(fnameName);
320  if (!cvp->cube()->hasGroup("Tracking") && !cvp->cube()->hasTable("InputImages")){
321  p_tableWin->table()->item(row, getIndex("Serial Number"))->setText(SerialNumber::Compose(*cvp->cube()));
322  }
323 
324  // If we are outside of the image then we are done
325  if((sample < 0.5) || (line < 0.5) ||
326  (sample > cvp->cubeSamples() + 0.5) ||
327  (line > cvp->cubeLines() + 0.5)) {
328  return;
329  }
330 
331  // Otherwise write out col 4 (Pixel value)
332  if(cvp->isGray()) {
333  QString grayPixel = PixelToString(cvp->grayPixel(isample, iline));
334  QString p = grayPixel;
335  p_tableWin->table()->item(row, getIndex("Pixel"))->setText(p);
336  }
337  else {
338  QString redPixel = PixelToString(cvp->redPixel(isample, iline));
339  QString p = redPixel;
340  p_tableWin->table()->item(row, getIndex("Pixel"))->setText(p);
341  }
342 
343  // Do we have a camera model?
344  if(cvp->camera() != NULL) {
345  if(cvp->camera()->SetImage(sample, line)) {
346  // Write columns ocentric lat/lon, and radius, only if set image succeeds
347  double lat = cvp->camera()->UniversalLatitude();
348  double lon = cvp->camera()->UniversalLongitude();
349 
350  double radius = cvp->camera()->LocalRadius().meters();
351  p_tableWin->table()->item(row, getIndex("Planetocentric Latitude"))->
352  setText(QString::number(lat, 'f', 15));
353  p_tableWin->table()->item(row, getIndex("360 Positive East Longitude"))->
354  setText(QString::number(lon, 'f', 15));
355  p_tableWin->table()->item(row, getIndex("Local Radius"))->
356  setText(QString::number(radius, 'f', 15));
357 
358  /* 180 Positive East Lon. */
359  p_tableWin->table()->item(row, getIndex("180 Positive East Longitude"))->
360  setText(QString::number(TProjection::To180Domain(lon), 'f', 15));
361 
362  // Write out the planetographic and positive west values, only if set image succeeds
363  lon = -lon;
364  while(lon < 0.0) lon += 360.0;
365  Distance radii[3];
366  cvp->camera()->radii(radii);
367  lat = TProjection::ToPlanetographic(lat, radii[0].meters(), radii[2].meters());
368  p_tableWin->table()->item(row, getIndex("Planetographic Latitude"))->
369  setText(QString::number(lat, 'f', 15));
370  p_tableWin->table()->item(row, getIndex("360 Positive West Longitude"))->
371  setText(QString::number(lon, 'f', 15));
372 
373  /*180 Positive West Lon. */
374  p_tableWin->table()->item(row, getIndex("180 Positive West Longitude"))->setText(
375  QString::number(TProjection::To180Domain(lon), 'f', 15));
376 
377  // Next write out columns, the x/y/z position of the lat/lon, only if set image succeeds
378  double pos[3];
379  cvp->camera()->Coordinate(pos);
380  p_tableWin->table()->item(row, getIndex("Point X"))->setText(QString::number(pos[0]));
381  p_tableWin->table()->item(row, getIndex("Point Y"))->setText(QString::number(pos[1]));
382  p_tableWin->table()->item(row, getIndex("Point Z"))->setText(QString::number(pos[2]));
383 
384  // Write out columns resolution, only if set image succeeds
385  double res = cvp->camera()->PixelResolution();
386  if (res != -1.0) {
387  p_tableWin->table()->item(row, getIndex("Resolution"))->setText(QString::number(res));
388  }
389  else {
390  p_tableWin->table()->item(row, getIndex("Resolution"))->setText("");
391  }
392 
393  // Write out columns, oblique pixel resolution, only if set image succeeds
394  double obliquePRes = cvp->camera()->ObliquePixelResolution();
395  if (obliquePRes != Isis::Null) {
396  p_tableWin->table()->item(row, getIndex("Oblique Pixel Resolution"))->
397  setText(QString::number(obliquePRes));
398  }
399  else {
400  p_tableWin->table()->item(row, getIndex("Oblique Pixel Resolution"))->setText("");
401  }
402 
403  // Write out columns photometric angle values, only if set image succeeds
404  double phase = cvp->camera()->PhaseAngle();
405  p_tableWin->table()->item(row, getIndex("Phase"))->setText(QString::number(phase));
406  double incidence = cvp->camera()->IncidenceAngle();
407  p_tableWin->table()->item(row, getIndex("Incidence"))->setText(QString::number(incidence));
408  double emission = cvp->camera()->EmissionAngle();
409  p_tableWin->table()->item(row, getIndex("Emission"))->setText(QString::number(emission));
410 
411  // Write out columns local incidence and emission, only if set image
412  // succeeds. This might fail if there are holes in the DEM.
413  // Calculates the angles local to the slope for the DEMs, compare against
414  // the incidence and emission angles calculated for the sphere
415  Angle phaseAngle, incidenceAngle, emissionAngle;
416  bool bSuccess = false;
417  cvp->camera()->LocalPhotometricAngles(phaseAngle, incidenceAngle, emissionAngle, bSuccess);
418  if(bSuccess) {
419  p_tableWin->table()->item(row, getIndex("LocalIncidence"))->
420  setText(QString::number(incidenceAngle.degrees()));
421  p_tableWin->table()->item(row, getIndex("LocalEmission"))->
422  setText(QString::number(emissionAngle.degrees()));
423  }
424  else {
425  p_tableWin->table()->item(row, getIndex("LocalIncidence"))->setText("");
426  p_tableWin->table()->item(row, getIndex("LocalEmission"))->setText("");
427  }
428 
429  // If set image succeeds, write out columns north azimuth, sun azimuth, solar longitude
430  // north azimuth is meaningless for ring plane projections
431  double northAzi = cvp->camera()->NorthAzimuth();
432  if (cvp->camera()->target()->shape()->name() != "Plane"
433  && Isis::IsValidPixel(northAzi)) {
434  p_tableWin->table()->item(row, getIndex("North Azimuth"))->
435  setText(QString::number(northAzi));
436  }
437  else { // north azimuth is meaningless for ring plane projections
438  p_tableWin->table()->item(row, getIndex("North Azimuth"))->setText("");
439  }
440 
441  double sunAzi = cvp->camera()->SunAzimuth();
442  if (Isis::IsValidPixel(sunAzi)) {
443  p_tableWin->table()->item(row, getIndex("Sun Azimuth"))->
444  setText(QString::number(sunAzi));
445  }
446  else { // sun azimuth is null
447  p_tableWin->table()->item(row, getIndex("Sun Azimuth"))->setText("");
448  }
449 
450  double spacecraftAzi = cvp->camera()->SpacecraftAzimuth();
451  if (Isis::IsValidPixel(spacecraftAzi)) {
452  p_tableWin->table()->item(row, getIndex("Spacecraft Azimuth"))->
453  setText(QString::number(spacecraftAzi));
454  }
455  else { // spacecraft azimuth is null
456  p_tableWin->table()->item(row, getIndex("Spacecraft Azimuth"))->setText("");
457  }
458 
459  // Write out columns solar lon, slant distance, local solar time
460  double solarLon = cvp->camera()->solarLongitude().degrees();
461  p_tableWin->table()->item(row, getIndex("Solar Longitude"))->
462  setText(QString::number(solarLon));
463  double slantDistance = cvp->camera()->SlantDistance();
464  p_tableWin->table()->item(row, getIndex("Slant Distance"))->
465  setText(QString::number(slantDistance));
466  double lst = cvp->camera()->LocalSolarTime();
467  p_tableWin->table()->item(row, getIndex("Local Solar Time"))->
468  setText(QString::number(lst));
469  } // end if set image succeeds
470 
471  // Always write out the x/y/z of the undistorted focal plane
472  CameraDistortionMap *distortedMap = cvp->camera()->DistortionMap();
473  double undistortedFocalPlaneX = distortedMap->UndistortedFocalPlaneX();
474  p_tableWin->table()->item(row, getIndex("Undistorted Focal X"))->
475  setText(QString::number(undistortedFocalPlaneX));
476  double undistortedFocalPlaneY = distortedMap->UndistortedFocalPlaneY();
477  p_tableWin->table()->item(row, getIndex("Undistorted Focal Y"))->
478  setText(QString::number(undistortedFocalPlaneY));
479  double undistortedFocalPlaneZ = distortedMap->UndistortedFocalPlaneZ();
480  p_tableWin->table()->item(row, getIndex("Undistorted Focal Z"))->
481  setText(QString::number(undistortedFocalPlaneZ));
482 
483  // Always write out the x/y of the distorted focal plane
484  CameraFocalPlaneMap *focalPlaneMap = cvp->camera()->FocalPlaneMap();
485  double distortedFocalPlaneX = focalPlaneMap->FocalPlaneX();
486  p_tableWin->table()->item(row, getIndex("Focal Plane X"))->
487  setText(QString::number(distortedFocalPlaneX));
488  double distortedFocalPlaneY = focalPlaneMap->FocalPlaneY();
489  p_tableWin->table()->item(row, getIndex("Focal Plane Y"))->
490  setText(QString::number(distortedFocalPlaneY));
491 
492  // Always write out columns ra/dec, regardless of whether set image succeeds
493  double ra = cvp->camera()->RightAscension();
494  p_tableWin->table()->item(row, getIndex("Right Ascension"))->setText(QString::number(ra));
495  double dec = cvp->camera()->Declination();
496  p_tableWin->table()->item(row, getIndex("Declination"))->setText(QString::number(dec));
497 
498  // Always write out columns et and utc, regardless of whether set image succeeds
499  iTime time(cvp->camera()->time());
500  p_tableWin->table()->item(row, getIndex("Ephemeris Time"))->
501  setText(QString::number(time.Et(), 'f', 15));
502  QString time_utc = time.UTC();
503  p_tableWin->table()->item(row, getIndex("UTC"))->setText(time_utc);
504 
505  // Always out columns spacecraft position, regardless of whether set image succeeds
506  double pos[3];
507  cvp->camera()->instrumentPosition(pos);
508  p_tableWin->table()->item(row, getIndex("Spacecraft X"))->setText(QString::number(pos[0]));
509  p_tableWin->table()->item(row, getIndex("Spacecraft Y"))->setText(QString::number(pos[1]));
510  p_tableWin->table()->item(row, getIndex("Spacecraft Z"))->setText(QString::number(pos[2]));
511  }
512 
513  else if (cvp->projection() != NULL) {
514  // Determine the projection type
516 
517  if (cvp->projection()->SetWorld(sample, line)) {
518  if (projType == Projection::Triaxial) {
519  TProjection *tproj = (TProjection *) cvp->projection();
520  double lat = tproj->UniversalLatitude();
521  double lon = tproj->UniversalLongitude();
522 
523  double glat = tproj->ToPlanetographic(lat);
524  double wlon = -lon;
525  while(wlon < 0.0) wlon += 360.0;
526  if (tproj->IsSky()) {
527  lon = tproj->Longitude();
528  p_tableWin->table()->item(row, getIndex("Right Ascension"))->
529  setText(QString::number(lon, 'f', 15));
530  p_tableWin->table()->item(row, getIndex("Declination"))->
531  setText(QString::number(lat, 'f', 15));
532  }
533  else {
534  double radius = tproj->LocalRadius();
535  p_tableWin->table()->item(row, getIndex("Planetocentric Latitude"))->
536  setText(QString::number(lat, 'f', 15));
537  p_tableWin->table()->item(row, getIndex("Planetographic Latitude"))->
538  setText(QString::number(glat, 'f', 15));
539  p_tableWin->table()->item(row, getIndex("360 Positive East Longitude"))->
540  setText(QString::number(lon, 'f', 15));
541  p_tableWin->table()->item(row, getIndex("180 Positive East Longitude"))->
542  setText(QString::number(TProjection::To180Domain(lon), 'f', 15));
543  p_tableWin->table()->item(row, getIndex("360 Positive West Longitude"))->
544  setText(QString::number(wlon, 'f', 15));
545  p_tableWin->table()->item(row, getIndex("180 Positive East Longitude"))->
546  setText(QString::number(TProjection::To180Domain(wlon), 'f', 15));
547  p_tableWin->table()->item(row, getIndex("Local Radius"))->setText(QString::number(radius, 'f', 15));
548  }
549  }
550  else { // RingPlane
552  double lat = rproj->UniversalRingRadius();
553  double lon = rproj->UniversalRingLongitude();
554 
555  double wlon = -lon;
556  while(wlon < 0.0) wlon += 360.0;
557  double radius = lat;
558  p_tableWin->table()->item(row, getIndex("Planetocentric Latitude"))->setText("0.0");
559  p_tableWin->table()->item(row, getIndex("Planetographic Latitude"))->setText("0.0");
560  p_tableWin->table()->item(row, getIndex("360 Positive East Longitude"))->
561  setText(QString::number(lon, 'f', 15));
562  p_tableWin->table()->item(row, getIndex("180 Positive East Longitude"))->
563  setText(QString::number(RingPlaneProjection::To180Domain(lon), 'f', 15));
564  p_tableWin->table()->item(row, getIndex("360 Positive West Longitude"))->
565  setText(QString::number(wlon, 'f', 15));
566  p_tableWin->table()->item(row, getIndex("180 Positive West Longitude"))->
567  setText(QString::number(RingPlaneProjection::To180Domain(wlon), 'f', 15));
568  p_tableWin->table()->item(row, getIndex("Local Radius"))->
569  setText(QString::number(radius, 'f', 15));
570  }
571  }
572  }
573 
574  //If there is a projection add the Projected X and Y coords to the table
575  if(cvp->projection() != NULL) {
576  if(cvp->projection()->SetWorld(sample, line)) {
577  double projX = cvp->projection()->XCoord();
578  double projY = cvp->projection()->YCoord();
579  p_tableWin->table()->item(row, getIndex("Projected X"))->
580  setText(QString::number(projX, 'f', 15));
581  p_tableWin->table()->item(row, getIndex("Projected Y"))->
582  setText(QString::number(projY, 'f', 15));
583  }
584  }
585 
586  // Track the Mosaic Origin - Index (Zero based) and FileName
587  if (cvp->cube()->hasTable("InputImages") || cvp->cube()->hasGroup("Tracking")) {
588  int iMosaicOrigin = -1;
589  QString sSrcFileName = "";
590  QString sSrcSerialNum = "";
591  TrackMosaicOrigin(cvp, iline, isample, iMosaicOrigin, sSrcFileName, sSrcSerialNum);
592  p_tableWin->table()->item(row, getIndex("Track Mosaic Index"))->
593  setText(QString::number(iMosaicOrigin));
594  p_tableWin->table()->item(row, getIndex("Track Mosaic FileName"))->
595  setText(QString(sSrcFileName));
596  p_tableWin->table()->item(row, getIndex("Track Mosaic Serial Number"))->
597  setText(QString(sSrcSerialNum));
598  }
599  }
600 
601 
619  int piSample, int &piOrigin, QString &psSrcFileName,
620  QString &psSrcSerialNum) {
621  try {
622  Cube *cCube = cvp->cube();
623  int iTrackBand = -1;
624 
625  // This is a mosaic in the new format or the external tracking cube itself
626  if(cCube->hasGroup("Tracking") ||
627  (cCube->hasTable(trackingTableName) && cCube->bandCount() == 1)) {
628  Cube *trackingCube;
629  if(cCube->hasGroup("Tracking")) {
630  trackingCube = cvp->trackingCube();
631  }
632  else {
633  trackingCube = cCube;
634  }
635 
636  // Read the cube DN value from TRACKING cube at location (piLine, piSample)
637  Portal trackingPortal(trackingCube->sampleCount(), 1, trackingCube->pixelType());
638  trackingPortal.SetPosition(piSample, piLine, 1);
639  trackingCube->read(trackingPortal);
640 
641  unsigned int currentPixel = trackingPortal[0];
642  if (currentPixel != NULLUI4) { // If from an image
643  Table table(trackingTableName); // trackingTableName from TrackingTable
644  trackingCube->read(table);
645  TrackingTable trackingTable(table);
646 
647  FileName trackingFileName = trackingTable.pixelToFileName(currentPixel);
648  psSrcFileName = trackingFileName.name();
649  psSrcSerialNum = trackingTable.pixelToSN(currentPixel);
650  piOrigin = trackingTable.fileNameToIndex(trackingFileName, psSrcSerialNum);
651  }
652  }
653  // Backwards compatability. Have this tool work with attached TRACKING bands
654  else if(cCube->hasTable(trackingTableName)) {
655  Pvl *cPvl = cCube->label();
656  PvlObject cObjIsisCube = cPvl->findObject("IsisCube");
657  PvlGroup cGrpBandBin = cObjIsisCube.findGroup("BandBin");
658  for(int i = 0; i < cGrpBandBin.keywords(); i++) {
659  PvlKeyword &cKeyTrackBand = cGrpBandBin[i];
660  for(int j = 0; j < cKeyTrackBand.size(); j++) {
661  if(cKeyTrackBand[j] == "TRACKING") {
662  iTrackBand = j;
663  break;
664  }
665  }
666  }
667 
668  if(iTrackBand > 0 && iTrackBand <= cCube->bandCount()) {
669  Portal cOrgPortal(cCube->sampleCount(), 1,
670  cCube->pixelType());
671  cOrgPortal.SetPosition(piSample, piLine, iTrackBand + 1); // 1 based
672  cCube->read(cOrgPortal);
673  piOrigin = (int)cOrgPortal[0];
674  switch(SizeOf(cCube->pixelType())) {
675  case 1:
676  piOrigin -= VALID_MIN1;
677  break;
678 
679  case 2:
680  piOrigin -= VALID_MIN2;
681  break;
682 
683  case 4:
684  piOrigin -= FLOAT_MIN;
685  break;
686  }
687 
688  // Get the input file name and serial number
689  Table cFileTable(trackingTableName);
690  cCube->read(cFileTable);
691  int iRecs = cFileTable.Records();
692  if(piOrigin >= 0 && piOrigin < iRecs) {
693  psSrcFileName = QString(cFileTable[piOrigin][0]);
694  psSrcSerialNum = QString(cFileTable[piOrigin][1]);
695  }
696  }
697  }
698 
699  if (piOrigin == -1) { // If not from an image, display N/A
700  psSrcFileName = "N/A";
701  psSrcSerialNum = "N/A";
702  }
703  }
704  catch (IException &e) {
705  QMessageBox::warning((QWidget *)parent(), "Warning", e.toString());
706  }
707  }
708 
709 
716 
718 
719  QVBoxLayout *dialogLayout = new QVBoxLayout;
720  helpDialog->setLayout(dialogLayout);
721  QLabel *dialogTitle = new QLabel("<h3>Advanced Tracking Tool</h3>");
722  dialogLayout->addWidget(dialogTitle);
723 
724  QTabWidget *tabArea = new QTabWidget;
725  dialogLayout->addWidget(tabArea);
726 
727  QScrollArea *recordTab = new QScrollArea;
728  QWidget *recordContainer = new QWidget;
729  QVBoxLayout *recordLayout = new QVBoxLayout;
730  recordContainer->setLayout(recordLayout);
731  QLabel *recordText = new QLabel("To record, click on the viewport of interest and"
732  " press (r) while the mouse is hovering over the image.");
733  recordText->setWordWrap(true);
734  recordLayout->addWidget(recordText);
735  recordTab->setWidget(recordContainer);
736 
737  QScrollArea *helpTab = new QScrollArea;
738  QWidget *helpContainer = new QWidget;
739  QVBoxLayout *helpLayout = new QVBoxLayout;
740  helpContainer->setLayout(helpLayout);
741  QLabel *helpText = new QLabel("In order to use <i>ctrl+c</i> to copy and <i>ctrl+v</i> to"
742  " paste, you need to double click on the cell you are copying"
743  " from (the text should be highlighted). Then double click on"
744  " the cell you are pasting to (you should see a cursor if the"
745  " cell is blank). When a cell is in this editing mode, most"
746  " keyboard shortcuts work.");
747  helpText->setWordWrap(true);
748  recordText->setWordWrap(true);
749  helpLayout->addWidget(helpText);
750  helpTab->setWidget(helpContainer);
751 
752  tabArea->addTab(recordTab, "Record");
753  tabArea->addTab(helpTab, "Table Help");
754 
755  QPushButton *okButton = new QPushButton("OK");
756  dialogLayout->addStretch();
757  dialogLayout->addWidget(okButton);
758  helpDialog->show();
759  connect(okButton, SIGNAL(clicked()), helpDialog, SLOT(accept()));
760  }
761 
762 
768  if(p_tableWin->table()->isHidden()) return;
769  if(p_tableWin->table()->item(p_tableWin->currentRow(), 0)->text() == "") return;
770 
771  int row = 0;
774  while(p_tableWin->currentRow() >= p_tableWin->table()->rowCount()) {
775 
776  row = p_tableWin->table()->rowCount();
777 
778  p_tableWin->table()->insertRow(row);
779  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
780  QTableWidgetItem *item = new QTableWidgetItem("");
781  p_tableWin->table()->setItem(row, c, item);
782  }
783  }
784 
785  QApplication::sendPostedEvents(p_tableWin->table(), 0);
786  p_tableWin->table()->scrollToItem(p_tableWin->table()->item(p_tableWin->currentRow(), 0),
787  QAbstractItemView::PositionAtBottom);
788 
789  //Keep track of number times user presses 'R' (record command)
790  p_id = p_tableWin->table()->item(p_tableWin->currentRow() - 1, 0)->text().toInt() + 1;
791  }
792 
793 
812  void AdvancedTrackTool::record(QPoint p) {
814  updateRow(p);
815  record();
816  }
817 
818 
824  //Check if the current row is 0
825  if(p_tableWin->currentRow() == 0)
826  p_id = 0;
827  else
828  p_id = p_tableWin->table()->item(p_tableWin->currentRow() - 1, getIndex("ID"))->text().toInt() + 1;
829  }
830 
831 
838 
839  QSettings settings(settingsFilePath() , QSettings::NativeFormat);
840 
841  m_showHelpOnStart = settings.value("showHelpOnStart", m_showHelpOnStart).toBool();
842  }
843 
844 
850 
851  QSettings settings(settingsFilePath(), QSettings::NativeFormat);
852 
853  settings.setValue("showHelpOnStart", m_showHelpOnStart);
854  }
855 
856 
863 
864  if (QApplication::applicationName() == "") {
865  throw IException(IException::Programmer, "You must set QApplication's "
866  "application name before using the Isis::MainWindow class. Window "
867  "state and geometry can not be saved and restored", _FILEINFO_);
868  }
869 
870  FileName config(FileName("$HOME/.Isis/" + QApplication::applicationName() + "/").path() + "/" +
871  "advancedTrackTool.config");
872 
873  return config.expanded();
874  }
875 }
Cube display widget for certain Isis MDI applications.
void LocalPhotometricAngles(Angle &phase, Angle &incidence, Angle &emission, bool &success)
Calculates LOCAL photometric angles using the DEM (not ellipsoid).
Definition: Camera.cpp:1661
int Records() const
Returns the number of records.
Definition: Table.cpp:224
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition: Sensor.cpp:211
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:100
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:119
double RightAscension()
Returns the right ascension angle (sky longitude).
Definition: Sensor.cpp:576
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
int cubeLines() const
Return the number of lines in the cube.
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
void setStatusMessage(QString message)
sets the status message in the lower lefthand corner of the window.
void updateRow(QPoint p)
This method updates the row with data from the point given.
Cube * cube() const
Definition: CubeViewport.h:348
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
AdvancedTrackTool(QWidget *parent)
Constructs an AdvancedTrackTool object.
double SunAzimuth()
Returns the Sun Azimuth.
Definition: Camera.cpp:1939
void addTo(QMenu *menu)
This method adds the action to bring up the track tool to the menu.
void record()
This method records data to the current row.
File name manipulation and expansion.
Definition: FileName.h:116
ProjectionType projectionType() const
Returns an enum value for the projection type.
Definition: Projection.cpp:213
Parse and return pieces of a time string.
Definition: iTime.h:78
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition: Camera.cpp:2838
bool isGray() const
Definition: CubeViewport.h:199
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:225
int getIndex(QString keyword)
This method finds the index of the header in checkBoxItems by looping through checkBoxItems, grabbing the header from each QList, and parsing the header at ":" to account for check boxes selecting multiple columns.
double UndistortedFocalPlaneZ() const
Gets the z-value in the undistorted focal plane coordinate system.
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
Buffer for containing a two dimensional section of an image.
Definition: Portal.h:52
int p_id
The record id.
Base class for Map TProjections.
Definition: TProjection.h:182
void clearRow(int row)
This method clears the text of the given row.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
double SpacecraftAzimuth()
Return the Spacecraft Azimuth.
Definition: Camera.cpp:1953
int sampleCount() const
Definition: Cube.cpp:1452
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition: PixelType.h:62
void writeSettings()
Write out this tool&#39;s preserved state between runs.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
double ObliquePixelResolution()
Returns the oblique pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:704
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:402
bool IsValidPixel(const double d)
Returns if the input pixel is valid.
Definition: SpecialPixel.h:238
double SlantDistance() const
Return the distance between the spacecraft and surface point in kmv.
Definition: Sensor.cpp:648
TableMainWindow * p_tableWin
The table window.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
bool m_showHelpOnStart
True to show dialog When tool is started.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
Distance measurement, usually in meters.
Definition: Distance.h:47
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:249
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:282
double redPixel(int sample, int line)
Gets the red pixel.
void setTrackListItems(bool track=false)
If this property is true, the class will keep track of the checked/unchecked items in the dock area w...
double EmissionAngle() const
Returns the emission angle in degrees.
Definition: Sensor.cpp:339
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:170
double grayPixel(int sample, int line)
Gets the gray pixel.
QString settingsFilePath() const
Generate the correct path for the config file.
Camera * camera() const
Definition: CubeViewport.h:358
FileName pixelToFileName(unsigned int pixel)
Returns the FileName that corresponds to a pixel value.
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
bool eventFilter(QObject *o, QEvent *e)
An event filter that calls methods on certain events.
Convert between distorted focal plane and detector coordinates.
void instrumentPosition(double p[3]) const
Returns the spacecraft position in body-fixed frame km units.
Definition: Spice.cpp:747
static double To180Domain(const double lon)
This method converts a longitude into the -180 to 180 domain.
bool hasTable(const QString &name)
Check to see if the cube contains a pvl table by the provided name.
Definition: Cube.cpp:1663
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1290
bool hasGroup(const QString &group) const
Return if the cube has a specified group in the labels.
Definition: Cube.cpp:1649
double Longitude() const
This returns a longitude with correct longitude direction and domain as specified in the label object...
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
int grayBand() const
Definition: CubeViewport.h:204
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
int currentRow() const
Returns the current row.
bool IsSky() const
Returns true if projection is sky and false if it is land.
Definition: Projection.cpp:223
A single keyword-value pair.
Definition: PvlKeyword.h:98
void helpDialog()
This method creates a dialog box that shows help tips.
double UniversalRingRadius()
This returns a universal radius, which is just the radius in meters.
double LocalRadius(double lat) const
This method returns the local radius in meters at the specified latitude position.
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:415
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:724
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
Distort/undistort focal plane coordinates.
double NorthAzimuth()
Returns the North Azimuth.
Definition: Camera.cpp:1912
QAction * p_action
Action to bring up the track tool.
bool isLinked() const
Is the viewport linked with other viewports.
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:615
virtual void mouseMove(QPoint p)
This method is called when the mouse has moved across the viewport and updates the row accordingly...
Container for cube-like labels.
Definition: Pvl.h:135
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:248
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
PixelType pixelType() const
Definition: Cube.cpp:1403
double PhaseAngle() const
Returns the phase angle in degrees.
Definition: Sensor.cpp:327
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Definition: Portal.h:109
int fileNameToIndex(FileName file, QString serialNumber)
Returns the index of the filename/serialnumber combination.
void setCurrentRow(int row)
Sets the current row to row.
double UniversalLatitude()
This returns a universal latitude (planetocentric).
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2848
a subclass of the qisis mainwindow, tablemainwindow handles all of the table tasks.
virtual void mouseLeave()
This method is called when the mouse leaves the viewport and clears any rows accordingly.
int cubeSamples() const
Return the number of samples in the cube.
bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
Definition: Projection.cpp:512
Defines an angle and provides unit conversions.
Definition: Angle.h:62
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
int p_numRows
The number of rows in the table.
void readSettings()
Read this tool&#39;s preserved state.
QTableWidget * table() const
Returns the table.
QString pixelToSN(unsigned int pixel)
Returns the serial number that corresponds to a pixel value.
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:537
Base class for Map Projections of plane shapes.
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1346
Cube * trackingCube() const
Definition: CubeViewport.h:368
Class for storing Table blobs information.
Definition: Table.h:77
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
Table to store tracking information for a mosaic.
Definition: TrackingTable.h:53
QString PixelToString(double d)
Takes a double pixel value and returns the name of the pixel type as a string.
Definition: SpecialPixel.h:386
double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:689
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition: Cube.cpp:1125
Projection * projection() const
Definition: CubeViewport.h:353
Base class for the Qisis tools.
Definition: Tool.h:81
double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition: Sensor.cpp:350
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
void addToTable(bool setOn, const QString &heading, const QString &menuText="", int insertAt=-1, Qt::Orientation o=Qt::Horizontal, QString toolTip="")
Adds a new column to the table when a new curve is added to the plot.
double LocalSolarTime()
Return the local solar time in hours.
Definition: Sensor.cpp:671
int redBand() const
Definition: CubeViewport.h:209
void TrackMosaicOrigin(MdiCubeViewport *cvp, int piLine, int piSample, int &piOrigin, QString &psSrcFileName, QString &psSrcSerialNum)
TrackMosaicOrigin - Given the pointer to Cube and line and sample index, finds the origin of the mosa...
void activate(bool)
Activates the tool.
Definition: Tool.cpp:131
static double To180Domain(const double lon)
This method converts a ring longitude into the -180 to 180 domain.
double UndistortedFocalPlaneY() const
Gets the y-value in the undistorted focal plane coordinate system.
void showTable()
This method checks to see if the table has been created.
void radii(Distance r[3]) const
Returns the radii of the body in km.
Definition: Spice.cpp:855
int currentIndex() const
Returns the current index.
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
void updateID()
This method updates the record ID.
Longitude solarLongitude()
Returns the solar longitude.
Definition: Spice.cpp:1376
double UndistortedFocalPlaneX() const
Gets the x-value in the undistorted focal plane coordinate system.
ProjectionType
This enum defines the subclasses of Projection supported in Isis.
Definition: Projection.h:182
void addToPermanent(QToolBar *perm)
This method adds the action to bring up the track tool to the permanent tool bar. ...
double UniversalRingLongitude()
This returns a universal ring longitude (clockwise in 0 to 360 domain).
void setCurrentIndex(int currentIndex)
Sets the current index to currentIndex.
double Declination()
Returns the declination angle (sky latitude).
Definition: Sensor.cpp:587
These projections are used to map triaxial and irregular-shaped bodies.
Definition: Projection.h:182
IO Handler for Isis Cubes.
Definition: Cube.h:170
iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions...
Definition: Spice.cpp:809