Isis 3 Programmer Reference
ProcessMapMosaic.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "ProcessMapMosaic.h"
8
9#include <QTime>
10#include <QDebug>
11
12#include "Application.h"
13#include "Displacement.h"
14#include "IException.h"
15#include "ProcessByLine.h"
16#include "Preference.h"
17#include "Projection.h"
18#include "ProjectionFactory.h"
19#include "Pvl.h"
20#include "RingPlaneProjection.h"
21#include "SpecialPixel.h"
22#include "TProjection.h"
23#include "UniqueIOCachingAlgorithm.h"
24
25using namespace std;
26
27
28namespace Isis {
33
34
37
38
44 "ProcessMapMosaic does not support the SetInputCube method",
45 _FILEINFO_);
46 }
47
48
52 bool ProcessMapMosaic::StartProcess(QString inputFile) {
53 if (InputCubes.size() != 0) {
54 QString msg = "Input cubes already exist; do not call SetInputCube when using ";
55 msg += "ProcessMosaic::StartProcess(QString)";
56 throw IException(IException::Programmer, msg, _FILEINFO_);
57 }
58
59 if (OutputCubes.size() == 0) {
60 QString msg = "An output cube must be set before calling StartProcess";
61 throw IException(IException::Programmer, msg, _FILEINFO_);
62 }
63
64 CubeAttributeInput inAtt(inputFile);
65 Cube *inCube = ProcessMosaic::SetInputCube(inputFile, inAtt);
67
68 Cube *mosaicCube = OutputCubes[0];
69 Projection *iproj = inCube->projection();
70 Projection *oproj = mosaicCube->projection();
71 int nsMosaic = mosaicCube->sampleCount();
72 int nlMosaic = mosaicCube->lineCount();
73
74 if (*iproj != *oproj) {
75 QString msg = "Mapping groups do not match between cube [" + inputFile + "] and mosaic";
76 throw IException(IException::User, msg, _FILEINFO_);
77 }
78
79 int outSample, outSampleEnd, outLine, outLineEnd;
80
81
82 if (oproj->ToWorldX(iproj->ToProjectionX(1.0)) < 0) {
83 outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) - 0.5);
84 }
85 else {
86 outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) + 0.5);
87 }
88 if (oproj->ToWorldY(iproj->ToProjectionY(1.0)) < 0) {
89 outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) - 0.5);
90 }
91 else {
92 outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) + 0.5);
93 }
94
95 int ins = InputCubes[0]->sampleCount();
96 int inl = InputCubes[0]->lineCount();
97 outSampleEnd = outSample + ins;
98 outLineEnd = outLine + inl;
99
100 bool wrapPossible = iproj->IsEquatorialCylindrical();
101 int worldSize = 0;
102 if (wrapPossible) {
103 // Figure out how many samples 360 degrees is
104 wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 0);
105 int worldStart = (int)(oproj->WorldX() + 0.5);
106 wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 180);
107 int worldEnd = (int)(oproj->WorldX() + 0.5);
108
109 worldSize = abs(worldEnd - worldStart) * 2;
110
111 wrapPossible = wrapPossible && (worldSize > 0);
112
113 // This is EquatorialCylindrical, so shift to the left all the way
114 if (wrapPossible) {
115 // While some data would still be put in the mosaic, move left
116 // >1 for end because 0 still means no data, whereas 1 means 1 line of data
117 while (outSampleEnd - worldSize > 1) {
118 outSample -= worldSize;
119 outSampleEnd -= worldSize;
120 }
121 // Now we have the sample range to the furthest left
122 }
123 }
124
125 // Check overlaps of input image along the mosaic edges before
126 // calling ProcessMosaic::StartProcess
127 // Left edge
128 if (outSample < 1) {
129 ins = ins + outSample - 1;
130 }
131
132 // Top edge
133 if (outLine < 1) {
134 inl = inl + outLine - 1;
135 }
136
137 // Right edge
138 if ((outSample + ins - 1) > nsMosaic) {
139 ins = nsMosaic - outSample + 1;
140 }
141
142 // Bottom edge
143 if ((outLine + inl - 1) > nlMosaic) {
144 inl = nlMosaic - outLine + 1;
145 }
146
147 if (outSampleEnd < 1 || outLineEnd < 1 || outSample > nsMosaic || outLine > nlMosaic || ins < 1 || inl < 1) {
148 // Add a PvlKeyword naming which files are not included in output mosaic
150 return false;
151 }
152 else {
153 // Place the input in the mosaic
154 Progress()->SetText("Mosaicking " + FileName(inputFile).name());
155
156 try {
157 do {
158 int outBand = 1;
159
160 ProcessMosaic::StartProcess(outSample, outLine, outBand);
161 // Reset the creation flag to ensure that the data within the tracking cube written from
162 // this call of StartProcess isn't over-written in the next. This needs to occur since the
163 // tracking cube is created in ProcessMosaic if the m_createOutputMosaic flag is set to
164 // true and the cube would then be completely re-created (setting all pixels to Null).
166
167 // Increment for projections where occurrances may happen multiple times
168 outSample += worldSize;
169 outSampleEnd += worldSize;
170 }
171 while (wrapPossible && outSample < nsMosaic);
172 }
173 catch (IException &e) {
174 QString msg = "Unable to mosaic cube [" + FileName(inputFile).name() + "]";
175 throw IException(e, IException::User, msg, _FILEINFO_);
176 }
177 }
178
179 WriteHistory(*mosaicCube);
180
181 // Don't propagate any more histories now that we've done one
182 p_propagateHistory = false;
183
185
186 return true;
187 }
188
189
190 //*************************************************************************************************
196 const QString &mosaicFile) {
197 int bands = 0;
198 double xmin = DBL_MAX;
199 double xmax = -DBL_MAX;
200 double ymin = DBL_MAX;
201 double ymax = -DBL_MAX;
202 double slat = DBL_MAX;
203 double elat = -DBL_MAX;
204 double slon = DBL_MAX;
205 double elon = -DBL_MAX;
206 bool latlonflag = true;
207
208 TProjection *proj = NULL;
209
210 if (propagationCubes.size() < 1) {
211 QString msg = "The list does not contain any data";
212 throw IException(IException::Programmer, msg, _FILEINFO_);
213 }
214
215 for (int i = 0; i < propagationCubes.size(); i++) {
216 // Open the cube and get the maximum number of band in all cubes
217 Cube cube;
218 cube.open(propagationCubes[i].toString());
219 bands = max(bands, cube.bandCount());
220
221 // See if the cube has a projection and make sure it matches
222 // previous input cubes
223 TProjection *projNew =
225 if ((proj != NULL) && (*proj != *projNew)) {
226 QString msg = "Mapping groups do not match between cubes [" +
227 propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
228 throw IException(IException::User, msg, _FILEINFO_);
229 }
230
231 // Figure out the x/y range as it may be needed later
232 double x = projNew->ToProjectionX(0.5);
233 double y = projNew->ToProjectionY(0.5);
234 if (x < xmin) xmin = x;
235 if (y < ymin) ymin = y;
236 if (x > xmax) xmax = x;
237 if (y > ymax) ymax = y;
238
239 x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
240 y = projNew->ToProjectionY(cube.lineCount() + 0.5);
241 if (x < xmin) xmin = x;
242 if (y < ymin) ymin = y;
243 if (x > xmax) xmax = x;
244 if (y > ymax) ymax = y;
245
246 if (projNew->MinimumLatitude() == 0.0 && projNew->MaximumLatitude() == 0.0 &&
247 projNew->MinimumLongitude() == 0.0 && projNew->MaximumLongitude() == 0.0) {
248 latlonflag = false;
249 }
250
251 slat = min(slat, projNew->MinimumLatitude());
252 elat = max(elat, projNew->MaximumLatitude());
253 slon = min(slon, projNew->MinimumLongitude());
254 elon = max(elon, projNew->MaximumLongitude());
255
256 // Cleanup
257 cube.close();
258 if (proj) delete proj;
259 proj = projNew;
260 }
261
262 if (proj) delete proj;
263
264 return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
265 slat, elat, slon, elon, bands, oAtt, mosaicFile, latlonflag);
266 }
267
268
269 //*************************************************************************************************
275 const QString &mosaicFile) {
276 int bands = 0;
277 double xmin = DBL_MAX;
278 double xmax = -DBL_MAX;
279 double ymin = DBL_MAX;
280 double ymax = -DBL_MAX;
281 double srad = DBL_MAX; // starting ring radius
282 double erad = -DBL_MAX; // ending ring radius
283 double saz = DBL_MAX; // starting azimuth (ring longitude)
284 double eaz = -DBL_MAX; // ending azimuth (ring longitude)
285
286 RingPlaneProjection *proj = NULL;
287
288 if (propagationCubes.size() < 1) {
289 QString msg = "The list does not contain any data";
290 throw IException(IException::Programmer, msg, _FILEINFO_);
291 }
292
293 for (int i = 0; i < propagationCubes.size(); i++) {
294 // Open the cube and get the maximum number of band in all cubes
295 Cube cube;
296 cube.open(propagationCubes[i].toString());
297 bands = max(bands, cube.bandCount());
298
299 // See if the cube has a projection and make sure it matches
300 // previous input cubes
301 RingPlaneProjection *projNew =
303 if ((proj != NULL) && (*proj != *projNew)) {
304 QString msg = "Mapping groups do not match between cubes [" +
305 propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]";
306 throw IException(IException::User, msg, _FILEINFO_);
307 }
308
309 // Figure out the x/y range as it may be needed later
310 double x = projNew->ToProjectionX(0.5);
311 double y = projNew->ToProjectionY(0.5);
312 if (x < xmin) xmin = x;
313 if (y < ymin) ymin = y;
314 if (x > xmax) xmax = x;
315 if (y > ymax) ymax = y;
316
317 x = projNew->ToProjectionX(cube.sampleCount() + 0.5);
318 y = projNew->ToProjectionY(cube.lineCount() + 0.5);
319 if (x < xmin) xmin = x;
320 if (y < ymin) ymin = y;
321 if (x > xmax) xmax = x;
322 if (y > ymax) ymax = y;
323
324 srad = min(srad, projNew->MinimumRingRadius());
325 erad = max(erad, projNew->MaximumRingRadius());
326 saz = min(saz, projNew->MinimumRingLongitude());
327 eaz = max(eaz, projNew->MaximumRingLongitude());
328
329 // Cleanup
330 cube.close();
331 if (proj) delete proj;
332 proj = projNew;
333 }
334
335 if (proj) delete proj;
336
337 return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
338 srad, erad, saz, eaz, bands, oAtt, mosaicFile);
339 }
340
341
342 //*************************************************************************************************
348 double slat, double elat, double slon, double elon,
349 CubeAttributeOutput &oAtt, const QString &mosaicFile) {
350 if (propagationCubes.size() < 1) {
351 QString msg = "The list does not contain any data";
352 throw IException(IException::Programmer, msg, _FILEINFO_);
353 }
354
355 int samples, lines, bands = 0;
356 Pvl label;
357 label.read(propagationCubes[0].toString());
358 PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
359
360 // All mosaicking programs use only the upper left x and y to determine where to
361 // place an image into a mosaic. For clarity purposes, the mosaic programs do
362 // not use lat/lon ranges for anything except creating the mosaic. By specifying
363 // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
364 // All map projected cubes must have an upper left x/y and do not require a lat/lon
365 // range. If the current values for the latitude and longitude range are out of
366 // order or equal, then we don't write them to the labels.
367 if (slat < elat && slon < elon) {
368 mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
369 mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
370 mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
371 mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
372 }
373
374 if (mGroup.hasKeyword("UpperLeftCornerX"))
375 mGroup.deleteKeyword("UpperLeftCornerX");
376
377 if (mGroup.hasKeyword("UpperLeftCornerY"))
378 mGroup.deleteKeyword("UpperLeftCornerY");
379
380 Pvl mapPvl;
381 mapPvl += mGroup;
382
383 // Use CreateForCube because our range differs from any of the cubes (manually specified)
384 Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false);
385
386 double xmin, xmax, ymin, ymax;
387 proj->XYRange(xmin, xmax, ymin, ymax);
388
389 // The xmin/ymax should be rounded for the labels
390 xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
391 ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
392
393 for (int i = 0; i < propagationCubes.size(); i++) {
394 Cube cube;
395 cube.open(propagationCubes[i].toString());
396 bands = max(cube.bandCount(), bands);
397
398 // See if the cube has a projection and make sure it matches
399 // previous input cubes
400 Projection *projNew =
402
403 if (proj == NULL) {
404 }
405 else if (*proj != *projNew) {
406 QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
407 "] and [" + propagationCubes[0].toString() + "]";
408 throw IException(IException::User, msg, _FILEINFO_);
409 }
410
411 if (proj) delete proj;
412 proj = projNew;
413 }
414
415 if (proj) delete proj;
416
417 return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
418 slat, elat, slon, elon, bands, oAtt, mosaicFile);
419 }
420
421
422 //*************************************************************************************************
437 double srad, double erad, double saz, double eaz,
438 CubeAttributeOutput &oAtt, const QString &mosaicFile) {
439 if (propagationCubes.size() < 1) {
440 QString msg = "The list does not contain any data";
441 throw IException(IException::Programmer, msg, _FILEINFO_);
442 }
443
444 int samples, lines, bands = 0;
445 Pvl label;
446 label.read(propagationCubes[0].toString());
447 PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
448 mGroup.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
449 mGroup.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
450 mGroup.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
451 mGroup.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
452
453 if (mGroup.hasKeyword("UpperLeftCornerX"))
454 mGroup.deleteKeyword("UpperLeftCornerX");
455
456 if (mGroup.hasKeyword("UpperLeftCornerY"))
457 mGroup.deleteKeyword("UpperLeftCornerY");
458
459 Pvl mapPvl;
460 mapPvl += mGroup;
461
462 // Use CreateForCube because our range differs from any of the cubes (manually specified)
463 Projection *proj = Isis::ProjectionFactory::RingsCreateForCube(mapPvl, samples, lines, false);
464
465 double xmin, xmax, ymin, ymax;
466 proj->XYRange(xmin, xmax, ymin, ymax);
467
468 // The xmin/ymax should be rounded for the labels
469 xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
470 ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];
471
472 for (int i = 0; i < propagationCubes.size(); i++) {
473 Cube cube;
474 cube.open(propagationCubes[i].toString());
475 bands = max(cube.bandCount(), bands);
476
477 // See if the cube has a projection and make sure it matches
478 // previous input cubes
480
481 if (proj == NULL) {
482 }
483 else if (*proj != *projNew) {
484 QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
485 "] and [" + propagationCubes[0].toString() + "]";
486 throw IException(IException::User, msg, _FILEINFO_);
487 }
488
489 if (proj) delete proj;
490 proj = projNew;
491 }
492
493 if (proj) delete proj;
494
495 return RingsSetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
496 srad, erad, saz, eaz, bands, oAtt, mosaicFile);
497 }
498
499
500 //NExt
501 //*************************************************************************************************
502
508 double xmin, double xmax, double ymin, double ymax,
509 double slat, double elat, double slon, double elon, int nbands,
510 CubeAttributeOutput &oAtt, const QString &mosaicFile, bool latlonflag) {
511 Pvl fileLab(inputFile);
512 PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
513
514 // All mosaicking programs use only the upper left x and y to determine where to
515 // place an image into a mosaic. For clarity purposes, the mosaic programs do
516 // not use lat/lon ranges for anything except creating the mosaic. By specifying
517 // the lat/lon range of the mosaic, we compute the upper left x/y of the mosaic.
518 // All map projected cubes must have an upper left x/y and do not require a lat/lon
519 // range. If the current values for the latitude and longitude range are out of
520 // order or equal, then we don't write them to the labels.
521 if (latlonflag && slat < elat && slon < elon) {
522 mapping.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
523 mapping.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
524 mapping.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
525 mapping.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);
526 }
527 else {
528 if (mapping.hasKeyword("MinimumLatitude")) {
529 mapping.deleteKeyword("MinimumLatitude");
530 }
531 if (mapping.hasKeyword("MaximumLatitude")) {
532 mapping.deleteKeyword("MaximumLatitude");
533 }
534 if (mapping.hasKeyword("MinimumLongitude")) {
535 mapping.deleteKeyword("MinimumLongitude");
536 }
537 if (mapping.hasKeyword("MaximumLongitude")) {
538 mapping.deleteKeyword("MaximumLongitude");
539 }
540 }
541
542 Projection *firstProj = ProjectionFactory::CreateFromCube(fileLab);
543 firstProj->SetUpperLeftCorner(Displacement(xmin, Displacement::Meters),
545
546 int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
547 int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
548
549 if (p_createMosaic) {
550 Pvl newMap;
551 newMap.addGroup(firstProj->Mapping());
552
553 // Initialize the mosaic
554 CubeAttributeInput inAtt;
555
557 p.SetInputCube(inputFile, inAtt);
558 p.PropagateHistory(false);
559 p.PropagateLabels(false);
560 p.PropagateTables(false);
561 p.PropagatePolygons(false);
562 p.PropagateOriginalLabel(false);
563
564 // For average priority, get the new band count
565 if (GetImageOverlay() == AverageImageWithMosaic) {
566 nbands *= 2;
567 }
568
569 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
570 p.Progress()->SetText("Initializing mosaic");
571 p.ClearInputCubes();
572 p.StartProcess(ProcessMapMosaic::FillNull);
573
574 // CreateForCube created some keywords in the mapping group that needs to be added
575 ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
576 p.EndProcess();
577 }
578 delete firstProj;
579
580 Cube *mosaicCube = new Cube();
581 mosaicCube->open(mosaicFile, "rw");
582 mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
583
584 AddOutputCube(mosaicCube);
585 return mosaicCube;
586 }
587
588
589 //NExt
590 //*************************************************************************************************
591
610 double xmin, double xmax, double ymin, double ymax,
611 double srad, double erad, double saz, double eaz, int nbands,
612 CubeAttributeOutput &oAtt, const QString &mosaicFile) {
613 Pvl fileLab(inputFile);
614 PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);
615
616 mapping["UpperLeftCornerX"] = toString(xmin);
617 mapping["UpperLeftCornerY"] = toString(ymax);
618 mapping.addKeyword(PvlKeyword("MinimumRingRadius", toString(srad)), Pvl::Replace);
619 mapping.addKeyword(PvlKeyword("MaximumRingRadius", toString(erad)), Pvl::Replace);
620 mapping.addKeyword(PvlKeyword("MinimumRingLongitude", toString(saz)), Pvl::Replace);
621 mapping.addKeyword(PvlKeyword("MaximumRingLongitude", toString(eaz)), Pvl::Replace);
622
624 int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
625 int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
626 delete firstProj;
627
628 if (p_createMosaic) {
629 Pvl newMap;
630 newMap.addGroup(mapping);
631
632 // Initialize the mosaic
633 CubeAttributeInput inAtt;
634
636 p.SetInputCube(inputFile, inAtt);
637 p.PropagateHistory(false);
638 p.PropagateLabels(false);
639 p.PropagateTables(false);
640 p.PropagatePolygons(false);
641 p.PropagateOriginalLabel(false);
642
643 // For average priority, get the new band count
644 if (GetImageOverlay() == AverageImageWithMosaic) {
645 nbands *= 2;
646 }
647
648 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
649 p.Progress()->SetText("Initializing mosaic");
650 p.ClearInputCubes();
651 p.StartProcess(ProcessMapMosaic::FillNull);
652
653 // CreateForCube created some keywords in the mapping group that needs to be added
654 ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
655 p.EndProcess();
656 }
657
658 Cube *mosaicCube = new Cube();
659 mosaicCube->open(mosaicFile, "rw");
660 mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
661
662 AddOutputCube(mosaicCube);
663 return mosaicCube;
664 }
665
666
667 //*************************************************************************************************
668
673 Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile, PvlGroup mapping,
674 CubeAttributeOutput &oAtt, const QString &mosaicFile) {
675 if (OutputCubes.size() != 0) {
676 QString msg = "You can only specify one output cube and projection";
677 throw IException(IException::Programmer, msg, _FILEINFO_);
678 }
679
680 if (mapping.hasKeyword("UpperLeftCornerX"))
681 mapping.deleteKeyword("UpperLeftCornerX");
682
683 if (mapping.hasKeyword("UpperLeftCornerY"))
684 mapping.deleteKeyword("UpperLeftCornerY");
685
686 if (p_createMosaic) {
687 Pvl newMap;
688 newMap.addGroup(mapping);
689 int samps, lines, bands;
690 delete ProjectionFactory::CreateForCube(newMap, samps, lines, false);
691
692 // Initialize the mosaic
694 CubeAttributeInput inAtt(inputFile);
695 Cube *propCube = p.SetInputCube(inputFile, inAtt);
696 bands = propCube->bandCount();
697
698 // For average priority, get the new band count
699 if (GetImageOverlay() == AverageImageWithMosaic) {
700 bands *= 2;
701 }
702
703 p.PropagateHistory(false);
704 p.PropagateLabels(false);
705 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
706 p.Progress()->SetText("Initializing mosaic");
707 p.ClearInputCubes();
708
709 p.StartProcess(ProcessMapMosaic::FillNull);
710
711 // CreateForCube created some keywords in the mapping group that needs to be added
712 ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
713 p.EndProcess();
714 }
715
716 Cube *mosaicCube = new Cube();
717 AddOutputCube(mosaicCube);
718 mosaicCube->open(mosaicFile, "rw");
719 mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
720
721 return mosaicCube;
722 }
723
724
725 //*************************************************************************************************
726
731 Isis::Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &inputFile, PvlGroup mapping,
732 CubeAttributeOutput &oAtt, const QString &mosaicFile) {
733 if (OutputCubes.size() != 0) {
734 QString msg = "You can only specify one output cube and projection";
735 throw IException(IException::Programmer, msg, _FILEINFO_);
736 }
737
738 if (mapping.hasKeyword("UpperLeftCornerX"))
739 mapping.deleteKeyword("UpperLeftCornerX");
740
741 if (mapping.hasKeyword("UpperLeftCornerY"))
742 mapping.deleteKeyword("UpperLeftCornerY");
743
744 if (p_createMosaic) {
745 Pvl newMap;
746 newMap.addGroup(mapping);
747 int samps, lines, bands;
748 delete ProjectionFactory::RingsCreateForCube(newMap, samps, lines, false);
749
750 // Initialize the mosaic
752 CubeAttributeInput inAtt(inputFile);
753 Cube *propCube = p.SetInputCube(inputFile, inAtt);
754 bands = propCube->bandCount();
755
756 // For average priority, get the new band count
757 if (GetImageOverlay() == AverageImageWithMosaic) {
758 bands *= 2;
759 }
760
761 p.PropagateHistory(false);
762 p.PropagateLabels(false);
763 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
764 p.Progress()->SetText("Initializing mosaic");
765 p.ClearInputCubes();
766
767 p.StartProcess(ProcessMapMosaic::FillNull);
768
769 // CreateForCube created some keywords in the mapping group that needs to be added
770 ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
771 p.EndProcess();
772 }
773
774 Cube *mosaicCube = new Cube();
775 AddOutputCube(mosaicCube);
776 mosaicCube->open(mosaicFile, "rw");
777 mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));
778
779 return mosaicCube;
780 }
781
782
783 //*************************************************************************************************
784
788 Cube *ProcessMapMosaic::SetOutputCube(const QString &mosaicFile) {
789 p_createMosaic = false;
790 Cube mosaic;
791 mosaic.open(mosaicFile);
792
793 PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
795 // The other SetOutput will not use the attribute or filename
796 Cube *ocube = SetOutputCube("", mapping, oAtt, mosaicFile);
797 p_createMosaic = true;
798
799 return ocube;
800 }
801
802
803 //*************************************************************************************************
804
808 Cube *ProcessMapMosaic::RingsSetOutputCube(const QString &mosaicFile) {
809 p_createMosaic = false;
810 Cube mosaic;
811 mosaic.open(mosaicFile);
812
813 PvlGroup &mapping = mosaic.label()->findGroup("Mapping", Pvl::Traverse);
815 // The other SetOutput will not use the attribute or filename
816 Cube *ocube = RingsSetOutputCube("", mapping, oAtt, mosaicFile);
817 p_createMosaic = true;
818
819 return ocube;
820 }
821
822
823 //*************************************************************************************************
828 for (int i = 0; i < data.size(); i++) data[i] = Isis::Null;
829 }
830} // end namespace isis
Buffer for reading and writing cube data.
Definition Buffer.h:53
int size() const
Returns the total number of pixels in the shape buffer.
Definition Buffer.h:97
Manipulate and parse attributes of input cube filenames.
Manipulate and parse attributes of output cube filenames.
IO Handler for Isis Cubes.
Definition Cube.h:168
void addCachingAlgorithm(CubeCachingAlgorithm *)
This will add the given caching algorithm to the list of attempted caching algorithms.
Definition Cube.cpp:1928
int lineCount() const
Definition Cube.cpp:1740
int sampleCount() const
Definition Cube.cpp:1813
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
Definition Cube.cpp:2062
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
Definition Cube.cpp:622
void close(bool remove=false)
Closes the cube and updates the labels.
Definition Cube.cpp:255
Projection * projection()
Definition Cube.cpp:1800
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition Cube.cpp:1416
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1707
Displacement is a signed length, usually in meters.
@ Meters
The distance is being specified in meters.
Internalizes a list of files.
Definition FileList.h:54
File name manipulation and expansion.
Definition FileName.h:100
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition FileName.cpp:162
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Process cubes by line.
Isis::Cube * SetInputCube(const QString &parameter, const int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
std::vector< Isis::Cube * > InputCubes
A vector of pointers to opened Cube objects.
Definition Process.h:185
void WriteHistory(Cube &cube)
Writes out the History blob to the cube.
Definition Process.cpp:822
bool p_propagateHistory
Flag indicating if history is to be propagated to output cubes.
Definition Process.h:161
Isis::Progress * Progress()
This method returns a pointer to a Progress object.
Definition Process.h:259
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition Process.h:191
void ClearInputCubes()
Close owned input cubes from the list and clear the list.
Definition Process.cpp:614
virtual Isis::Cube * SetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt, const QString &mosaicFile)
Set the output cube to specified file name and specified input images and output attributes.
Isis::Cube * RingsSetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt, const QString &mosaicFile)
Set the output cube to specified file name and specified input images and output attributes.
virtual Isis::Cube * SetInputCube()
Input cube cannot be set here.
virtual bool StartProcess(QString inputFile)
Mosaic Processing method, returns false if the cube is not inside the mosaic.
static void FillNull(Buffer &data)
Reset the buffer with NULL pixels.
ProcessMapMosaic()
Constructs a Mosaic object.
bool p_createMosaic
Internal use; SetOutputMosaic (const QString &) sets to false to not attempt creation when using SetO...
virtual ~ProcessMapMosaic()
Destructor.
virtual void StartProcess(const int &piOutSample, const int &piOutLine, const int &piOutBand)
This method invokes the process by mosaic operation over a single input cube and single output cube.
@ AverageImageWithMosaic
average priority
void SetCreateFlag(bool createOutputMosaic)
Flag to indicate that the mosaic is being newly created Indication that the new label specific to the...
virtual Isis::Cube * SetInputCube(const QString &parameter, const int ss, const int sl, const int sb, const int ns, const int nl, const int nb)
Opens an input cube specified by the user.
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
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.
static Isis::Projection * RingsCreateFromCube(Isis::Cube &cube)
This method is a helper method.
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.
Base class for Map Projections.
Definition Projection.h:155
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
void read(const QString &file)
Loads PVL information from a stream.
Definition Pvl.cpp:90
A single keyword-value pair.
Definition PvlKeyword.h:87
@ Traverse
Search child objects.
Definition PvlObject.h:158
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition PvlObject.h:186
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition PvlObject.h:129
Base class for Map Projections of plane shapes.
Base class for Map TProjections.
This algorithm is designed for applications that jump around between a couple of spots in the cube wi...
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.