Isis 3 Programmer Reference
ProcessMapMosaic.cpp
Go to the documentation of this file.
1 
22 #include "ProcessMapMosaic.h"
23 
24 #include <QTime>
25 #include <QDebug>
26 
27 #include "Application.h"
28 #include "IException.h"
29 #include "ProcessByLine.h"
30 #include "Preference.h"
31 #include "Projection.h"
32 #include "ProjectionFactory.h"
33 #include "Pvl.h"
34 #include "RingPlaneProjection.h"
35 #include "SpecialPixel.h"
36 #include "TProjection.h"
38 
39 using namespace std;
40 
41 
42 namespace Isis {
44  ProcessMapMosaic::ProcessMapMosaic() {
45  p_createMosaic = true;
46  }
47 
48 
50  ProcessMapMosaic::~ProcessMapMosaic() { }
51 
52 
56  Isis::Cube *ProcessMapMosaic::SetInputCube() {
57  throw IException(IException::Programmer,
58  "ProcessMapMosaic does not support the SetInputCube method",
59  _FILEINFO_);
60  }
61 
62 
66  bool ProcessMapMosaic::StartProcess(QString inputFile) {
67  if (InputCubes.size() != 0) {
68  QString msg = "Input cubes already exist; do not call SetInputCube when using ";
69  msg += "ProcessMosaic::StartProcess(QString)";
70  throw IException(IException::Programmer, msg, _FILEINFO_);
71  }
72 
73  if (OutputCubes.size() == 0) {
74  QString msg = "An output cube must be set before calling StartProcess";
75  throw IException(IException::Programmer, msg, _FILEINFO_);
76  }
77 
78  CubeAttributeInput inAtt(inputFile);
79  Cube *inCube = ProcessMosaic::SetInputCube(inputFile, inAtt);
80 
81  Cube *mosaicCube = OutputCubes[0];
82  Projection *iproj = inCube->projection();
83  Projection *oproj = mosaicCube->projection();
84  int nsMosaic = mosaicCube->sampleCount();
85  int nlMosaic = mosaicCube->lineCount();
86 
87  if (*iproj != *oproj) {
88  QString msg = "Mapping groups do not match between cube [" + inputFile + "] and mosaic";
89  throw IException(IException::User, msg, _FILEINFO_);
90  }
91 
92  int outSample, outSampleEnd, outLine, outLineEnd;
93 
94 
95  if (oproj->ToWorldX(iproj->ToProjectionX(1.0)) < 0) {
96  outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) - 0.5);
97  }
98  else {
99  outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) + 0.5);
100  }
101  if (oproj->ToWorldY(iproj->ToProjectionY(1.0)) < 0) {
102  outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) - 0.5);
103  }
104  else {
105  outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) + 0.5);
106  }
107 
108  int ins = InputCubes[0]->sampleCount();
109  int inl = InputCubes[0]->lineCount();
110  outSampleEnd = outSample + ins;
111  outLineEnd = outLine + inl;
112 
113  bool wrapPossible = iproj->IsEquatorialCylindrical();
114  int worldSize = 0;
115  if (wrapPossible) {
116  // Figure out how many samples 360 degrees is
117  wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 0);
118  int worldStart = (int)(oproj->WorldX() + 0.5);
119  wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 180);
120  int worldEnd = (int)(oproj->WorldX() + 0.5);
121 
122  worldSize = abs(worldEnd - worldStart) * 2;
123 
124  wrapPossible = wrapPossible && (worldSize > 0);
125 
126  // This is EquatorialCylindrical, so shift to the left all the way
127  if (wrapPossible) {
128  // While some data would still be put in the mosaic, move left
129  // >1 for end because 0 still means no data, whereas 1 means 1 line of data
130  while (outSampleEnd - worldSize > 1) {
131  outSample -= worldSize;
132  outSampleEnd -= worldSize;
133  }
134  // Now we have the sample range to the furthest left
135  }
136  }
137 
138  // Check overlaps of input image along the mosaic edges before
139  // calling ProcessMosaic::StartProcess
140  // Left edge
141  if (outSample < 1) {
142  ins = ins + outSample - 1;
143  }
144 
145  // Top edge
146  if (outLine < 1) {
147  inl = inl + outLine - 1;
148  }
149 
150  // Right edge
151  if ((outSample + ins - 1) > nsMosaic) {
152  ins = nsMosaic - outSample + 1;
153  }
154 
155  // Bottom edge
156  if ((outLine + inl - 1) > nlMosaic) {
157  inl = nlMosaic - outLine + 1;
158  }
159 
160  if (outSampleEnd < 1 || outLineEnd < 1 || outSample > nsMosaic || outLine > nlMosaic || ins < 1 || inl < 1) {
161  // Add a PvlKeyword naming which files are not included in output mosaic
162  ClearInputCubes();
163  return false;
164  }
165  else {
166  // Place the input in the mosaic
167  Progress()->SetText("Mosaicking " + FileName(inputFile).name());
168 
169  try {
170  do {
171  int outBand = 1;
172 
173  ProcessMosaic::StartProcess(outSample, outLine, outBand);
174  // Reset the creation flag to ensure that the data within the tracking cube written from
175  // this call of StartProcess isn't over-written in the next. This needs to occur since the
176  // tracking cube is created in ProcessMosaic if the m_createOutputMosaic flag is set to
177  // true and the cube would then be completely re-created (setting all pixels to Null).
178  ProcessMosaic::SetCreateFlag(false);
179 
180  // Increment for projections where occurrances may happen multiple times
181  outSample += worldSize;
182  outSampleEnd += worldSize;
183  }
184  while (wrapPossible && outSample < nsMosaic);
185  }
186  catch (IException &e) {
187  QString msg = "Unable to mosaic cube [" + FileName(inputFile).name() + "]";
188  throw IException(e, IException::User, msg, _FILEINFO_);
189  }
190  }
191 
192  WriteHistory(*mosaicCube);
193 
194  // Don't propagate any more histories now that we've done one
195  p_propagateHistory = false;
196 
197  ClearInputCubes();
198 
199  return true;
200  }
201 
202 
203  //*************************************************************************************************
208  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt,
209  const QString &mosaicFile) {
210  int bands = 0;
211  double xmin = DBL_MAX;
212  double xmax = -DBL_MAX;
213  double ymin = DBL_MAX;
214  double ymax = -DBL_MAX;
215  double slat = DBL_MAX;
216  double elat = -DBL_MAX;
217  double slon = DBL_MAX;
218  double elon = -DBL_MAX;
219  bool latlonflag = true;
220 
221  TProjection *proj = NULL;
222 
223  if (propagationCubes.size() < 1) {
224  QString msg = "The list does not contain any data";
225  throw IException(IException::Programmer, msg, _FILEINFO_);
226  }
227 
228  for (int i = 0; i < propagationCubes.size(); i++) {
229  // Open the cube and get the maximum number of band in all cubes
230  Cube cube;
231  cube.open(propagationCubes[i].toString());
232  bands = max(bands, cube.bandCount());
233 
234  // See if the cube has a projection and make sure it matches
235  // previous input cubes
236  TProjection *projNew =
238  if ((proj != NULL) && (*proj != *projNew)) {
239  QString msg = "Mapping groups do not match between cubes [" +
240  propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
241  throw IException(IException::User, msg, _FILEINFO_);
242  }
243 
244  // Figure out the x/y range as it may be needed later
245  double x = projNew->ToProjectionX(0.5);
246  double y = projNew->ToProjectionY(0.5);
247  if (x < xmin) xmin = x;
248  if (y < ymin) ymin = y;
249  if (x > xmax) xmax = x;
250  if (y > ymax) ymax = y;
251 
252  x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
253  y = projNew->ToProjectionY(cube.lineCount() + 0.5);
254  if (x < xmin) xmin = x;
255  if (y < ymin) ymin = y;
256  if (x > xmax) xmax = x;
257  if (y > ymax) ymax = y;
258 
259  if (projNew->MinimumLatitude() == 0.0 && projNew->MaximumLatitude() == 0.0 &&
260  projNew->MinimumLongitude() == 0.0 && projNew->MaximumLongitude() == 0.0) {
261  latlonflag = false;
262  }
263 
264  slat = min(slat, projNew->MinimumLatitude());
265  elat = max(elat, projNew->MaximumLatitude());
266  slon = min(slon, projNew->MinimumLongitude());
267  elon = max(elon, projNew->MaximumLongitude());
268 
269  // Cleanup
270  cube.close();
271  if (proj) delete proj;
272  proj = projNew;
273  }
274 
275  if (proj) delete proj;
276 
277  return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
278  slat, elat, slon, elon, bands, oAtt, mosaicFile, latlonflag);
279  }
280 
281 
282  //*************************************************************************************************
287  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt,
288  const QString &mosaicFile) {
289  int bands = 0;
290  double xmin = DBL_MAX;
291  double xmax = -DBL_MAX;
292  double ymin = DBL_MAX;
293  double ymax = -DBL_MAX;
294  double srad = DBL_MAX; // starting ring radius
295  double erad = -DBL_MAX; // ending ring radius
296  double saz = DBL_MAX; // starting azimuth (ring longitude)
297  double eaz = -DBL_MAX; // ending azimuth (ring longitude)
298 
299  RingPlaneProjection *proj = NULL;
300 
301  if (propagationCubes.size() < 1) {
302  QString msg = "The list does not contain any data";
303  throw IException(IException::Programmer, msg, _FILEINFO_);
304  }
305 
306  for (int i = 0; i < propagationCubes.size(); i++) {
307  // Open the cube and get the maximum number of band in all cubes
308  Cube cube;
309  cube.open(propagationCubes[i].toString());
310  bands = max(bands, cube.bandCount());
311 
312  // See if the cube has a projection and make sure it matches
313  // previous input cubes
314  RingPlaneProjection *projNew =
316  if ((proj != NULL) && (*proj != *projNew)) {
317  QString msg = "Mapping groups do not match between cubes [" +
318  propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
319  throw IException(IException::User, msg, _FILEINFO_);
320  }
321 
322  // Figure out the x/y range as it may be needed later
323  double x = projNew->ToProjectionX(0.5);
324  double y = projNew->ToProjectionY(0.5);
325  if (x < xmin) xmin = x;
326  if (y < ymin) ymin = y;
327  if (x > xmax) xmax = x;
328  if (y > ymax) ymax = y;
329 
330  x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
331  y = projNew->ToProjectionY(cube.lineCount() + 0.5);
332  if (x < xmin) xmin = x;
333  if (y < ymin) ymin = y;
334  if (x > xmax) xmax = x;
335  if (y > ymax) ymax = y;
336 
337  srad = min(srad, projNew->MinimumRingRadius());
338  erad = max(erad, projNew->MaximumRingRadius());
339  saz = min(saz, projNew->MinimumRingLongitude());
340  eaz = max(eaz, projNew->MaximumRingLongitude());
341 
342  // Cleanup
343  cube.close();
344  if (proj) delete proj;
345  proj = projNew;
346  }
347 
348  if (proj) delete proj;
349 
350  return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
351  srad, erad, saz, eaz, bands, oAtt, mosaicFile);
352  }
353 
354 
355  //*************************************************************************************************
360  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes,
361  double slat, double elat, double slon, double elon,
362  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
363  if (propagationCubes.size() < 1) {
364  QString msg = "The list does not contain any data";
365  throw IException(IException::Programmer, msg, _FILEINFO_);
366  }
367 
368  int samples, lines, bands = 0;
369  Pvl label;
370  label.read(propagationCubes[0].toString());
371  PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
372 
373  // All mosaicking programs use only the upper left x and y to determine where to
374  // place an image into a mosaic. For clarity purposes, the mosaic programs do
375  // not use lat/lon ranges for anything except creating the mosaic. By specifying
376  // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
377  // All map projected cubes must have an upper left x/y and do not require a lat/lon
378  // range. If the current values for the latitude and longitude range are out of
379  // order or equal, then we don't write them to the labels.
380  if (slat < elat && slon < elon) {
381  mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
382  mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
383  mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
384  mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
385  }
386 
387  if (mGroup.hasKeyword("UpperLeftCornerX"))
388  mGroup.deleteKeyword("UpperLeftCornerX");
389 
390  if (mGroup.hasKeyword("UpperLeftCornerY"))
391  mGroup.deleteKeyword("UpperLeftCornerY");
392 
393  Pvl mapPvl;
394  mapPvl += mGroup;
395 
396  // Use CreateForCube because our range differs from any of the cubes (manually specified)
397  Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false);
398 
399  double xmin, xmax, ymin, ymax;
400  proj->XYRange(xmin, xmax, ymin, ymax);
401 
402  // The xmin/ymax should be rounded for the labels
403  xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
404  ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
405 
406  for (int i = 0; i < propagationCubes.size(); i++) {
407  Cube cube;
408  cube.open(propagationCubes[i].toString());
409  bands = max(cube.bandCount(), bands);
410 
411  // See if the cube has a projection and make sure it matches
412  // previous input cubes
413  Projection *projNew =
415 
416  if (proj == NULL) {
417  }
418  else if (*proj != *projNew) {
419  QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
420  "] and [" + propagationCubes[0].toString() + "]";
421  throw IException(IException::User, msg, _FILEINFO_);
422  }
423 
424  if (proj) delete proj;
425  proj = projNew;
426  }
427 
428  if (proj) delete proj;
429 
430  return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
431  slat, elat, slon, elon, bands, oAtt, mosaicFile);
432  }
433 
434 
435  //*************************************************************************************************
449  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(FileList &propagationCubes,
450  double srad, double erad, double saz, double eaz,
451  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
452  if (propagationCubes.size() < 1) {
453  QString msg = "The list does not contain any data";
454  throw IException(IException::Programmer, msg, _FILEINFO_);
455  }
456 
457  int samples, lines, bands = 0;
458  Pvl label;
459  label.read(propagationCubes[0].toString());
460  PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
461  mGroup.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
462  mGroup.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
463  mGroup.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
464  mGroup.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
465 
466  if (mGroup.hasKeyword("UpperLeftCornerX"))
467  mGroup.deleteKeyword("UpperLeftCornerX");
468 
469  if (mGroup.hasKeyword("UpperLeftCornerY"))
470  mGroup.deleteKeyword("UpperLeftCornerY");
471 
472  Pvl mapPvl;
473  mapPvl += mGroup;
474 
475  // Use CreateForCube because our range differs from any of the cubes (manually specified)
476  Projection *proj = Isis::ProjectionFactory::RingsCreateForCube(mapPvl, samples, lines, false);
477 
478  double xmin, xmax, ymin, ymax;
479  proj->XYRange(xmin, xmax, ymin, ymax);
480 
481  // The xmin/ymax should be rounded for the labels
482  xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
483  ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
484 
485  for (int i = 0; i < propagationCubes.size(); i++) {
486  Cube cube;
487  cube.open(propagationCubes[i].toString());
488  bands = max(cube.bandCount(), bands);
489 
490  // See if the cube has a projection and make sure it matches
491  // previous input cubes
493 
494  if (proj == NULL) {
495  }
496  else if (*proj != *projNew) {
497  QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
498  "] and [" + propagationCubes[0].toString() + "]";
499  throw IException(IException::User, msg, _FILEINFO_);
500  }
501 
502  if (proj) delete proj;
503  proj = projNew;
504  }
505 
506  if (proj) delete proj;
507 
508  return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
509  srad, erad, saz, eaz, bands, oAtt, mosaicFile);
510  }
511 
512 
513  //NExt
514  //*************************************************************************************************
515 
520  Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile,
521  double xmin, double xmax, double ymin, double ymax,
522  double slat, double elat, double slon, double elon, int nbands,
523  CubeAttributeOutput &oAtt, const QString &mosaicFile, bool latlonflag) {
524  Pvl fileLab(inputFile);
525  PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
526 
527  mapping["UpperLeftCornerX"] = toString(xmin);
528  mapping["UpperLeftCornerY"] = toString(ymax);
529 
530  // All mosaicking programs use only the upper left x and y to determine where to
531  // place an image into a mosaic. For clarity purposes, the mosaic programs do
532  // not use lat/lon ranges for anything except creating the mosaic. By specifying
533  // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
534  // All map projected cubes must have an upper left x/y and do not require a lat/lon
535  // range. If the current values for the latitude and longitude range are out of
536  // order or equal, then we don't write them to the labels.
537  if (latlonflag && slat < elat && slon < elon) {
538  mapping.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
539  mapping.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
540  mapping.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
541  mapping.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
542  }
543  else {
544  if (mapping.hasKeyword("MinimumLatitude")) {
545  mapping.deleteKeyword("MinimumLatitude");
546  }
547  if (mapping.hasKeyword("MaximumLatitude")) {
548  mapping.deleteKeyword("MaximumLatitude");
549  }
550  if (mapping.hasKeyword("MinimumLongitude")) {
551  mapping.deleteKeyword("MinimumLongitude");
552  }
553  if (mapping.hasKeyword("MaximumLongitude")) {
554  mapping.deleteKeyword("MaximumLongitude");
555  }
556  }
557 
558  Projection *firstProj = ProjectionFactory::CreateFromCube(fileLab);
559  int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
560  int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
561  delete firstProj;
562 
563  if (p_createMosaic) {
564  Pvl newMap;
565  newMap.addGroup(mapping);
566 
567  // Initialize the mosaic
568  CubeAttributeInput inAtt;
569 
570  ProcessByLine p;
571  p.SetInputCube(inputFile, inAtt);
572  p.PropagateHistory(false);
573  p.PropagateLabels(false);
574  p.PropagateTables(false);
575  p.PropagatePolygons(false);
576  p.PropagateOriginalLabel(false);
577 
578  // For average priority, get the new band count
579  if (GetImageOverlay() == AverageImageWithMosaic) {
580  nbands *= 2;
581  }
582 
583  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
584  p.Progress()->SetText("Initializing mosaic");
585  p.ClearInputCubes();
586  p.StartProcess(ProcessMapMosaic::FillNull);
587 
588  // CreateForCube created some keywords in the mapping group that needs to be added
589  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
590  p.EndProcess();
591  }
592 
593  Cube *mosaicCube = new Cube();
594  mosaicCube->open(mosaicFile, "rw");
595  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
596 
597  AddOutputCube(mosaicCube);
598  return mosaicCube;
599  }
600 
601 
602  //NExt
603  //*************************************************************************************************
604 
622  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &inputFile,
623  double xmin, double xmax, double ymin, double ymax,
624  double srad, double erad, double saz, double eaz, int nbands,
625  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
626  Pvl fileLab(inputFile);
627  PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
628 
629  mapping["UpperLeftCornerX"] = toString(xmin);
630  mapping["UpperLeftCornerY"] = toString(ymax);
631  mapping.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
632  mapping.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
633  mapping.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
634  mapping.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
635 
636  Projection *firstProj = ProjectionFactory::RingsCreateFromCube(fileLab);
637  int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
638  int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
639  delete firstProj;
640 
641  if (p_createMosaic) {
642  Pvl newMap;
643  newMap.addGroup(mapping);
644 
645  // Initialize the mosaic
646  CubeAttributeInput inAtt;
647 
648  ProcessByLine p;
649  p.SetInputCube(inputFile, inAtt);
650  p.PropagateHistory(false);
651  p.PropagateLabels(false);
652  p.PropagateTables(false);
653  p.PropagatePolygons(false);
654  p.PropagateOriginalLabel(false);
655 
656  // For average priority, get the new band count
657  if (GetImageOverlay() == AverageImageWithMosaic) {
658  nbands *= 2;
659  }
660 
661  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
662  p.Progress()->SetText("Initializing mosaic");
663  p.ClearInputCubes();
664  p.StartProcess(ProcessMapMosaic::FillNull);
665 
666  // CreateForCube created some keywords in the mapping group that needs to be added
667  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
668  p.EndProcess();
669  }
670 
671  Cube *mosaicCube = new Cube();
672  mosaicCube->open(mosaicFile, "rw");
673  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
674 
675  AddOutputCube(mosaicCube);
676  return mosaicCube;
677  }
678 
679 
680  //*************************************************************************************************
681 
686  Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile, PvlGroup mapping,
687  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
688  if (OutputCubes.size() != 0) {
689  QString msg = "You can only specify one output cube and projection";
690  throw IException(IException::Programmer, msg, _FILEINFO_);
691  }
692 
693  if (mapping.hasKeyword("UpperLeftCornerX"))
694  mapping.deleteKeyword("UpperLeftCornerX");
695 
696  if (mapping.hasKeyword("UpperLeftCornerY"))
697  mapping.deleteKeyword("UpperLeftCornerY");
698 
699  if (p_createMosaic) {
700  Pvl newMap;
701  newMap.addGroup(mapping);
702  int samps, lines, bands;
703  delete ProjectionFactory::CreateForCube(newMap, samps, lines, false);
704 
705  // Initialize the mosaic
706  ProcessByLine p;
707  CubeAttributeInput inAtt(inputFile);
708  Cube *propCube = p.SetInputCube(inputFile, inAtt);
709  bands = propCube->bandCount();
710 
711  // For average priority, get the new band count
712  if (GetImageOverlay() == AverageImageWithMosaic) {
713  bands *= 2;
714  }
715 
716  p.PropagateHistory(false);
717  p.PropagateLabels(false);
718  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
719  p.Progress()->SetText("Initializing mosaic");
720  p.ClearInputCubes();
721 
722  p.StartProcess(ProcessMapMosaic::FillNull);
723 
724  // CreateForCube created some keywords in the mapping group that needs to be added
725  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
726  p.EndProcess();
727  }
728 
729  Cube *mosaicCube = new Cube();
730  AddOutputCube(mosaicCube);
731  mosaicCube->open(mosaicFile, "rw");
732  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
733 
734  return mosaicCube;
735  }
736 
737 
738  //*************************************************************************************************
739 
744  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &inputFile, PvlGroup mapping,
745  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
746  if (OutputCubes.size() != 0) {
747  QString msg = "You can only specify one output cube and projection";
748  throw IException(IException::Programmer, msg, _FILEINFO_);
749  }
750 
751  if (mapping.hasKeyword("UpperLeftCornerX"))
752  mapping.deleteKeyword("UpperLeftCornerX");
753 
754  if (mapping.hasKeyword("UpperLeftCornerY"))
755  mapping.deleteKeyword("UpperLeftCornerY");
756 
757  if (p_createMosaic) {
758  Pvl newMap;
759  newMap.addGroup(mapping);
760  int samps, lines, bands;
761  delete ProjectionFactory::RingsCreateForCube(newMap, samps, lines, false);
762 
763  // Initialize the mosaic
764  ProcessByLine p;
765  CubeAttributeInput inAtt(inputFile);
766  Cube *propCube = p.SetInputCube(inputFile, inAtt);
767  bands = propCube->bandCount();
768 
769  // For average priority, get the new band count
770  if (GetImageOverlay() == AverageImageWithMosaic) {
771  bands *= 2;
772  }
773 
774  p.PropagateHistory(false);
775  p.PropagateLabels(false);
776  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
777  p.Progress()->SetText("Initializing mosaic");
778  p.ClearInputCubes();
779 
780  p.StartProcess(ProcessMapMosaic::FillNull);
781 
782  // CreateForCube created some keywords in the mapping group that needs to be added
783  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
784  p.EndProcess();
785  }
786 
787  Cube *mosaicCube = new Cube();
788  AddOutputCube(mosaicCube);
789  mosaicCube->open(mosaicFile, "rw");
790  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
791 
792  return mosaicCube;
793  }
794 
795 
796  //*************************************************************************************************
797 
801  Cube *ProcessMapMosaic::SetOutputCube(const QString &mosaicFile) {
802  p_createMosaic = false;
803  Cube mosaic;
804  mosaic.open(mosaicFile);
805 
806  PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
807  CubeAttributeOutput oAtt;
808  // The other SetOutput will not use the attribute or filename
809  Cube *ocube = SetOutputCube("", mapping, oAtt, mosaicFile);
810  p_createMosaic = true;
811 
812  return ocube;
813  }
814 
815 
816  //*************************************************************************************************
817 
821  Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &mosaicFile) {
822  p_createMosaic = false;
823  Cube mosaic;
824  mosaic.open(mosaicFile);
825 
826  PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
827  CubeAttributeOutput oAtt;
828  // The other SetOutput will not use the attribute or filename
829  Cube *ocube = RingsSetOutputCube("", mapping, oAtt, mosaicFile);
830  p_createMosaic = true;
831 
832  return ocube;
833  }
834 
835 
836  //*************************************************************************************************
840  void ProcessMapMosaic::FillNull(Buffer &data) {
841  for (int i = 0; i < data.size(); i++) data[i] = Isis::Null;
842  }
843 } // end namespace isis
void PropagateTables(const bool prop)
This method allows the programmer to propagate input tables to the output cube (default is true) ...
Definition: Process.cpp:594
Buffer for reading and writing cube data.
Definition: Buffer.h:69
Manipulate and parse attributes of input cube filenames.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
Isis::Cube * SetInputCube(const QString &parameter, const int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
File name manipulation and expansion.
Definition: FileName.h:116
Base class for Map TProjections.
Definition: TProjection.h:182
void PropagatePolygons(const bool prop)
This method allows the programmer to propagate input blobs to the output cube (default is true) ...
Definition: Process.cpp:641
int sampleCount() const
Definition: Cube.cpp:1452
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:198
double ToProjectionX(const double worldX) const
This method converts a world x value to a projection x value.
Definition: Projection.cpp:637
Namespace for the standard library.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
Internalizes a list of files.
Definition: FileList.h:70
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Projection * projection()
Definition: Cube.cpp:1439
static Isis::Projection * RingsCreateForCube(Isis::Pvl &label, int &samples, int &lines, bool sizeMatch)
This method creates a projection for a cube to a ring plane given a label.
This algorithm is designed for applications that jump around between a couple of spots in the cube wi...
void PropagateOriginalLabel(const bool prop)
This method allows the programmer to propagate original labels to the output cube (default is true) ...
Definition: Process.cpp:662
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:113
double WorldX() const
This returns the world X coordinate provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:539
double ToWorldX(const double projectionX) const
This method converts a projection x value to a world x value.
Definition: Projection.cpp:581
Base class for Map Projections.
Definition: Projection.h:171
Program progress reporter.
Definition: Progress.h:58
void PropagateHistory(const bool prop)
This method allows the programmer to propagate history to the output cube (default is true) ...
Definition: Process.cpp:651
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition: Progress.cpp:77
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
static Isis::Projection * CreateForCube(Isis::Pvl &label, int &ns, int &nl, bool sizeMatch=true)
This method creates a map projection for a cube given a label.
double ToProjectionY(const double worldY) const
This method converts a world y value to a projection y value.
Definition: Projection.cpp:665
Manipulate and parse attributes of output cube filenames.
static Isis::Projection * RingsCreateFromCube(Isis::Cube &cube)
This method is a helper method.
A single keyword-value pair.
Definition: PvlKeyword.h:98
void PropagateLabels(const bool prop)
This method allows the programmer to turn on/off the propagation of labels from the 1st input cube to...
Definition: Process.cpp:555
void ClearInputCubes()
Close owned input cubes from the list and clear the list.
Definition: Process.cpp:519
void close(bool remove=false)
Closes the cube and updates the labels.
Definition: Cube.cpp:177
void open(const QString &cfile, QString access="r")
This method will open an isis cube for reading or reading/writing.
Definition: Cube.cpp:544
void addCachingAlgorithm(CubeCachingAlgorithm *)
This will add the given caching algorithm to the list of attempted caching algorithms.
Definition: Cube.cpp:1567
Container for cube-like labels.
Definition: Pvl.h:135
void StartProcess(void funct(Isis::Buffer &inout))
This method invokes the process by line operation over a single input or output cube.
Isis::Progress * Progress()
This method returns a pointer to a Progress object.
Definition: Process.h:270
Base class for Map Projections of plane shapes.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1346
int lineCount() const
Definition: Cube.cpp:1379
virtual bool SetUniversalGround(const double coord1, const double coord2)
This method is used to set the lat/lon or radius/azimuth (i.e.
Definition: Projection.cpp:432
Isis exception class.
Definition: IException.h:107
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
double ToWorldY(const double projectionY) const
This method converts a projection y value to a world y value.
Definition: Projection.cpp:609
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
Definition: Cube.cpp:1688
virtual bool IsEquatorialCylindrical()
This method returns true if the projection is equatorial cylindrical.
Definition: Projection.cpp:237
Process cubes by line.
void read(const QString &file)
Loads PVL information from a stream.
Definition: Pvl.cpp:76
void deleteKeyword(const QString &name)
Remove a specified keyword.
IO Handler for Isis Cubes.
Definition: Cube.h:170