USGS

Isis 3.0 Object Programmers' Reference

Home

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 
175  // Increment for projections where occurrances may happen multiple times
176  outSample += worldSize;
177  outSampleEnd += worldSize;
178  }
179  while (wrapPossible && outSample < nsMosaic);
180  }
181  catch (IException &e) {
182  QString msg = "Unable to mosaic cube [" + FileName(inputFile).name() + "]";
183  throw IException(e, IException::User, msg, _FILEINFO_);
184  }
185  }
186 
187  WriteHistory(*mosaicCube);
188 
189  // Don't propagate any more histories now that we've done one
190  p_propagateHistory = false;
191 
192  ClearInputCubes();
193 
194  return true;
195  }
196 
197 
198  //*************************************************************************************************
203  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt,
204  const QString &mosaicFile) {
205  int bands = 0;
206  double xmin = DBL_MAX;
207  double xmax = -DBL_MAX;
208  double ymin = DBL_MAX;
209  double ymax = -DBL_MAX;
210  double slat = DBL_MAX;
211  double elat = -DBL_MAX;
212  double slon = DBL_MAX;
213  double elon = -DBL_MAX;
214  bool latlonflag = true;
215 
216  TProjection *proj = NULL;
217 
218  if (propagationCubes.size() < 1) {
219  QString msg = "The list does not contain any data";
220  throw IException(IException::Programmer, msg, _FILEINFO_);
221  }
222 
223  for (int i = 0; i < propagationCubes.size(); i++) {
224  // Open the cube and get the maximum number of band in all cubes
225  Cube cube;
226  cube.open(propagationCubes[i].toString());
227  bands = max(bands, cube.bandCount());
228 
229  // See if the cube has a projection and make sure it matches
230  // previous input cubes
231  TProjection *projNew =
233  if ((proj != NULL) && (*proj != *projNew)) {
234  QString msg = "Mapping groups do not match between cubes [" +
235  propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
236  throw IException(IException::User, msg, _FILEINFO_);
237  }
238 
239  // Figure out the x/y range as it may be needed later
240  double x = projNew->ToProjectionX(0.5);
241  double y = projNew->ToProjectionY(0.5);
242  if (x < xmin) xmin = x;
243  if (y < ymin) ymin = y;
244  if (x > xmax) xmax = x;
245  if (y > ymax) ymax = y;
246 
247  x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
248  y = projNew->ToProjectionY(cube.lineCount() + 0.5);
249  if (x < xmin) xmin = x;
250  if (y < ymin) ymin = y;
251  if (x > xmax) xmax = x;
252  if (y > ymax) ymax = y;
253 
254  if (projNew->MinimumLatitude() == 0.0 && projNew->MaximumLatitude() == 0.0 &&
255  projNew->MinimumLongitude() == 0.0 && projNew->MaximumLongitude() == 0.0) {
256  latlonflag = false;
257  }
258 
259  slat = min(slat, projNew->MinimumLatitude());
260  elat = max(elat, projNew->MaximumLatitude());
261  slon = min(slon, projNew->MinimumLongitude());
262  elon = max(elon, projNew->MaximumLongitude());
263 
264  // Cleanup
265  cube.close();
266  if (proj) delete proj;
267  proj = projNew;
268  }
269 
270  if (proj) delete proj;
271 
272  return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
273  slat, elat, slon, elon, bands, oAtt, mosaicFile, latlonflag);
274  }
275 
276 
277  //*************************************************************************************************
282  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt,
283  const QString &mosaicFile) {
284  int bands = 0;
285  double xmin = DBL_MAX;
286  double xmax = -DBL_MAX;
287  double ymin = DBL_MAX;
288  double ymax = -DBL_MAX;
289  double srad = DBL_MAX; // starting ring radius
290  double erad = -DBL_MAX; // ending ring radius
291  double saz = DBL_MAX; // starting azimuth (ring longitude)
292  double eaz = -DBL_MAX; // ending azimuth (ring longitude)
293 
294  RingPlaneProjection *proj = NULL;
295 
296  if (propagationCubes.size() < 1) {
297  QString msg = "The list does not contain any data";
298  throw IException(IException::Programmer, msg, _FILEINFO_);
299  }
300 
301  for (int i = 0; i < propagationCubes.size(); i++) {
302  // Open the cube and get the maximum number of band in all cubes
303  Cube cube;
304  cube.open(propagationCubes[i].toString());
305  bands = max(bands, cube.bandCount());
306 
307  // See if the cube has a projection and make sure it matches
308  // previous input cubes
309  RingPlaneProjection *projNew =
311  if ((proj != NULL) && (*proj != *projNew)) {
312  QString msg = "Mapping groups do not match between cubes [" +
313  propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
314  throw IException(IException::User, msg, _FILEINFO_);
315  }
316 
317  // Figure out the x/y range as it may be needed later
318  double x = projNew->ToProjectionX(0.5);
319  double y = projNew->ToProjectionY(0.5);
320  if (x < xmin) xmin = x;
321  if (y < ymin) ymin = y;
322  if (x > xmax) xmax = x;
323  if (y > ymax) ymax = y;
324 
325  x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
326  y = projNew->ToProjectionY(cube.lineCount() + 0.5);
327  if (x < xmin) xmin = x;
328  if (y < ymin) ymin = y;
329  if (x > xmax) xmax = x;
330  if (y > ymax) ymax = y;
331 
332  srad = min(srad, projNew->MinimumRingRadius());
333  erad = max(erad, projNew->MaximumRingRadius());
334  saz = min(saz, projNew->MinimumRingLongitude());
335  eaz = max(eaz, projNew->MaximumRingLongitude());
336 
337  // Cleanup
338  cube.close();
339  if (proj) delete proj;
340  proj = projNew;
341  }
342 
343  if (proj) delete proj;
344 
345  return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
346  srad, erad, saz, eaz, bands, oAtt, mosaicFile);
347  }
348 
349 
350  //*************************************************************************************************
355  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes,
356  double slat, double elat, double slon, double elon,
357  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
358  if (propagationCubes.size() < 1) {
359  QString msg = "The list does not contain any data";
360  throw IException(IException::Programmer, msg, _FILEINFO_);
361  }
362 
363  int samples, lines, bands = 0;
364  Pvl label;
365  label.read(propagationCubes[0].toString());
366  PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
367 
368  // All mosaicking programs use only the upper left x and y to determine where to
369  // place an image into a mosaic. For clarity purposes, the mosaic programs do
370  // not use lat/lon ranges for anything except creating the mosaic. By specifying
371  // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
372  // All map projected cubes must have an upper left x/y and do not require a lat/lon
373  // range. If the current values for the latitude and longitude range are out of
374  // order or equal, then we don't write them to the labels.
375  if (slat < elat && slon < elon) {
376  mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
377  mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
378  mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
379  mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
380  }
381 
382  if (mGroup.hasKeyword("UpperLeftCornerX"))
383  mGroup.deleteKeyword("UpperLeftCornerX");
384 
385  if (mGroup.hasKeyword("UpperLeftCornerY"))
386  mGroup.deleteKeyword("UpperLeftCornerY");
387 
388  Pvl mapPvl;
389  mapPvl += mGroup;
390 
391  // Use CreateForCube because our range differs from any of the cubes (manually specified)
392  Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false);
393 
394  double xmin, xmax, ymin, ymax;
395  proj->XYRange(xmin, xmax, ymin, ymax);
396 
397  // The xmin/ymax should be rounded for the labels
398  xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
399  ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
400 
401  for (int i = 0; i < propagationCubes.size(); i++) {
402  Cube cube;
403  cube.open(propagationCubes[i].toString());
404  bands = max(cube.bandCount(), bands);
405 
406  // See if the cube has a projection and make sure it matches
407  // previous input cubes
408  Projection *projNew =
410 
411  if (proj == NULL) {
412  }
413  else if (*proj != *projNew) {
414  QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
415  "] and [" + propagationCubes[0].toString() + "]";
416  throw IException(IException::User, msg, _FILEINFO_);
417  }
418 
419  if (proj) delete proj;
420  proj = projNew;
421  }
422 
423  if (proj) delete proj;
424 
425  return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
426  slat, elat, slon, elon, bands, oAtt, mosaicFile);
427  }
428 
429 
430  //*************************************************************************************************
444  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(FileList &propagationCubes,
445  double srad, double erad, double saz, double eaz,
446  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
447  if (propagationCubes.size() < 1) {
448  QString msg = "The list does not contain any data";
449  throw IException(IException::Programmer, msg, _FILEINFO_);
450  }
451 
452  int samples, lines, bands = 0;
453  Pvl label;
454  label.read(propagationCubes[0].toString());
455  PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
456  mGroup.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
457  mGroup.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
458  mGroup.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
459  mGroup.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
460 
461  if (mGroup.hasKeyword("UpperLeftCornerX"))
462  mGroup.deleteKeyword("UpperLeftCornerX");
463 
464  if (mGroup.hasKeyword("UpperLeftCornerY"))
465  mGroup.deleteKeyword("UpperLeftCornerY");
466 
467  Pvl mapPvl;
468  mapPvl += mGroup;
469 
470  // Use CreateForCube because our range differs from any of the cubes (manually specified)
471  Projection *proj = Isis::ProjectionFactory::RingsCreateForCube(mapPvl, samples, lines, false);
472 
473  double xmin, xmax, ymin, ymax;
474  proj->XYRange(xmin, xmax, ymin, ymax);
475 
476  // The xmin/ymax should be rounded for the labels
477  xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
478  ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
479 
480  for (int i = 0; i < propagationCubes.size(); i++) {
481  Cube cube;
482  cube.open(propagationCubes[i].toString());
483  bands = max(cube.bandCount(), bands);
484 
485  // See if the cube has a projection and make sure it matches
486  // previous input cubes
488 
489  if (proj == NULL) {
490  }
491  else if (*proj != *projNew) {
492  QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
493  "] and [" + propagationCubes[0].toString() + "]";
494  throw IException(IException::User, msg, _FILEINFO_);
495  }
496 
497  if (proj) delete proj;
498  proj = projNew;
499  }
500 
501  if (proj) delete proj;
502 
503  return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
504  srad, erad, saz, eaz, bands, oAtt, mosaicFile);
505  }
506 
507 
508  //NExt
509  //*************************************************************************************************
510 
515  Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile,
516  double xmin, double xmax, double ymin, double ymax,
517  double slat, double elat, double slon, double elon, int nbands,
518  CubeAttributeOutput &oAtt, const QString &mosaicFile, bool latlonflag) {
519  Pvl fileLab(inputFile);
520  PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
521 
522  mapping["UpperLeftCornerX"] = toString(xmin);
523  mapping["UpperLeftCornerY"] = toString(ymax);
524 
525  // All mosaicking programs use only the upper left x and y to determine where to
526  // place an image into a mosaic. For clarity purposes, the mosaic programs do
527  // not use lat/lon ranges for anything except creating the mosaic. By specifying
528  // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
529  // All map projected cubes must have an upper left x/y and do not require a lat/lon
530  // range. If the current values for the latitude and longitude range are out of
531  // order or equal, then we don't write them to the labels.
532  if (latlonflag && slat < elat && slon < elon) {
533  mapping.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
534  mapping.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
535  mapping.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
536  mapping.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
537  }
538  else {
539  if (mapping.hasKeyword("MinimumLatitude")) {
540  mapping.deleteKeyword("MinimumLatitude");
541  }
542  if (mapping.hasKeyword("MaximumLatitude")) {
543  mapping.deleteKeyword("MaximumLatitude");
544  }
545  if (mapping.hasKeyword("MinimumLongitude")) {
546  mapping.deleteKeyword("MinimumLongitude");
547  }
548  if (mapping.hasKeyword("MaximumLongitude")) {
549  mapping.deleteKeyword("MaximumLongitude");
550  }
551  }
552 
553  Projection *firstProj = ProjectionFactory::CreateFromCube(fileLab);
554  int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
555  int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
556  delete firstProj;
557 
558  if (p_createMosaic) {
559  Pvl newMap;
560  newMap.addGroup(mapping);
561 
562  // Initialize the mosaic
563  CubeAttributeInput inAtt;
564 
565  ProcessByLine p;
566  p.SetInputCube(inputFile, inAtt);
567  p.PropagateHistory(false);
568  p.PropagateLabels(false);
569  p.PropagateTables(false);
570  p.PropagatePolygons(false);
571  p.PropagateOriginalLabel(false);
572 
573  // If track set, create the origin band
574  if (GetTrackFlag()) {
575  nbands += 1;
576  }
577  // For average priority, get the new band count
578  else if (GetImageOverlay() == AverageImageWithMosaic) {
579  nbands *= 2;
580  }
581 
582  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
583  p.Progress()->SetText("Initializing mosaic");
584  p.ClearInputCubes();
585  p.StartProcess(ProcessMapMosaic::FillNull);
586 
587  // CreateForCube created some keywords in the mapping group that needs to be added
588  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
589  p.EndProcess();
590  }
591 
592  Cube *mosaicCube = new Cube();
593  mosaicCube->open(mosaicFile, "rw");
594  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
595 
596  AddOutputCube(mosaicCube);
597  return mosaicCube;
598  }
599 
600 
601  //NExt
602  //*************************************************************************************************
603 
621  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &inputFile,
622  double xmin, double xmax, double ymin, double ymax,
623  double srad, double erad, double saz, double eaz, int nbands,
624  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
625  Pvl fileLab(inputFile);
626  PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
627 
628  mapping["UpperLeftCornerX"] = toString(xmin);
629  mapping["UpperLeftCornerY"] = toString(ymax);
630  mapping.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
631  mapping.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
632  mapping.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
633  mapping.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
634 
635  Projection *firstProj = ProjectionFactory::RingsCreateFromCube(fileLab);
636  int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
637  int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
638  delete firstProj;
639 
640  if (p_createMosaic) {
641  Pvl newMap;
642  newMap.addGroup(mapping);
643 
644  // Initialize the mosaic
645  CubeAttributeInput inAtt;
646 
647  ProcessByLine p;
648  p.SetInputCube(inputFile, inAtt);
649  p.PropagateHistory(false);
650  p.PropagateLabels(false);
651  p.PropagateTables(false);
652  p.PropagatePolygons(false);
653  p.PropagateOriginalLabel(false);
654 
655  // If track set, create the origin band
656  if (GetTrackFlag()) {
657  nbands += 1;
658  }
659  // For average priority, get the new band count
660  else if (GetImageOverlay() == AverageImageWithMosaic) {
661  nbands *= 2;
662  }
663 
664  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
665  p.Progress()->SetText("Initializing mosaic");
666  p.ClearInputCubes();
667  p.StartProcess(ProcessMapMosaic::FillNull);
668 
669  // CreateForCube created some keywords in the mapping group that needs to be added
670  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
671  p.EndProcess();
672  }
673 
674  Cube *mosaicCube = new Cube();
675  mosaicCube->open(mosaicFile, "rw");
676  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
677 
678  AddOutputCube(mosaicCube);
679  return mosaicCube;
680  }
681 
682 
683  //*************************************************************************************************
684 
689  Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile, PvlGroup mapping,
690  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
691  if (OutputCubes.size() != 0) {
692  QString msg = "You can only specify one output cube and projection";
693  throw IException(IException::Programmer, msg, _FILEINFO_);
694  }
695 
696  if (mapping.hasKeyword("UpperLeftCornerX"))
697  mapping.deleteKeyword("UpperLeftCornerX");
698 
699  if (mapping.hasKeyword("UpperLeftCornerY"))
700  mapping.deleteKeyword("UpperLeftCornerY");
701 
702  if (p_createMosaic) {
703  Pvl newMap;
704  newMap.addGroup(mapping);
705  int samps, lines, bands;
706  delete ProjectionFactory::CreateForCube(newMap, samps, lines, false);
707 
708  // Initialize the mosaic
709  ProcessByLine p;
710  CubeAttributeInput inAtt(inputFile);
711  Cube *propCube = p.SetInputCube(inputFile, inAtt);
712  bands = propCube->bandCount();
713 
714  // If track set, create the origin band
715  if (GetTrackFlag()) {
716  bands += 1;
717  }
718  // For average priority, get the new band count
719  else if (GetImageOverlay() == AverageImageWithMosaic) {
720  bands *= 2;
721  }
722 
723  p.PropagateHistory(false);
724  p.PropagateLabels(false);
725  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
726  p.Progress()->SetText("Initializing mosaic");
727  p.ClearInputCubes();
728 
729  p.StartProcess(ProcessMapMosaic::FillNull);
730 
731  // CreateForCube created some keywords in the mapping group that needs to be added
732  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
733  p.EndProcess();
734  }
735 
736  Cube *mosaicCube = new Cube();
737  AddOutputCube(mosaicCube);
738  mosaicCube->open(mosaicFile, "rw");
739  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
740 
741  return mosaicCube;
742  }
743 
744 
745  //*************************************************************************************************
746 
751  Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &inputFile, PvlGroup mapping,
752  CubeAttributeOutput &oAtt, const QString &mosaicFile) {
753  if (OutputCubes.size() != 0) {
754  QString msg = "You can only specify one output cube and projection";
755  throw IException(IException::Programmer, msg, _FILEINFO_);
756  }
757 
758  if (mapping.hasKeyword("UpperLeftCornerX"))
759  mapping.deleteKeyword("UpperLeftCornerX");
760 
761  if (mapping.hasKeyword("UpperLeftCornerY"))
762  mapping.deleteKeyword("UpperLeftCornerY");
763 
764  if (p_createMosaic) {
765  Pvl newMap;
766  newMap.addGroup(mapping);
767  int samps, lines, bands;
768  delete ProjectionFactory::RingsCreateForCube(newMap, samps, lines, false);
769 
770  // Initialize the mosaic
771  ProcessByLine p;
772  CubeAttributeInput inAtt(inputFile);
773  Cube *propCube = p.SetInputCube(inputFile, inAtt);
774  bands = propCube->bandCount();
775 
776  // If track set, create the origin band
777  if (GetTrackFlag()) {
778  bands += 1;
779  }
780  // For average priority, get the new band count
781  else if (GetImageOverlay() == AverageImageWithMosaic) {
782  bands *= 2;
783  }
784 
785  p.PropagateHistory(false);
786  p.PropagateLabels(false);
787  Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
788  p.Progress()->SetText("Initializing mosaic");
789  p.ClearInputCubes();
790 
791  p.StartProcess(ProcessMapMosaic::FillNull);
792 
793  // CreateForCube created some keywords in the mapping group that needs to be added
794  ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
795  p.EndProcess();
796  }
797 
798  Cube *mosaicCube = new Cube();
799  AddOutputCube(mosaicCube);
800  mosaicCube->open(mosaicFile, "rw");
801  mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
802 
803  return mosaicCube;
804  }
805 
806 
807  //*************************************************************************************************
808 
812  Cube *ProcessMapMosaic::SetOutputCube(const QString &mosaicFile) {
813  p_createMosaic = false;
814  Cube mosaic;
815  mosaic.open(mosaicFile);
816 
817  PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
818  CubeAttributeOutput oAtt;
819  // The other SetOutput will not use the attribute or filename
820  Cube *ocube = SetOutputCube("", mapping, oAtt, mosaicFile);
821  p_createMosaic = true;
822 
823  return ocube;
824  }
825 
826 
827  //*************************************************************************************************
828 
832  Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &mosaicFile) {
833  p_createMosaic = false;
834  Cube mosaic;
835  mosaic.open(mosaicFile);
836 
837  PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
838  CubeAttributeOutput oAtt;
839  // The other SetOutput will not use the attribute or filename
840  Cube *ocube = RingsSetOutputCube("", mapping, oAtt, mosaicFile);
841  p_createMosaic = true;
842 
843  return ocube;
844  }
845 
846 
847  //*************************************************************************************************
851  void ProcessMapMosaic::FillNull(Buffer &data) {
852  for (int i = 0; i < data.size(); i++) data[i] = Isis::Null;
853  }
854 } // end namespace isis