7#include "ProcessMapMosaic.h"
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"
20#include "RingPlaneProjection.h"
21#include "SpecialPixel.h"
22#include "TProjection.h"
23#include "UniqueIOCachingAlgorithm.h"
44 "ProcessMapMosaic does not support the SetInputCube method",
54 QString msg =
"Input cubes already exist; do not call SetInputCube when using ";
55 msg +=
"ProcessMosaic::StartProcess(QString)";
60 QString msg =
"An output cube must be set before calling StartProcess";
71 int nsMosaic = mosaicCube->sampleCount();
72 int nlMosaic = mosaicCube->lineCount();
74 if (*iproj != *oproj) {
75 QString msg =
"Mapping groups do not match between cube [" + inputFile +
"] and mosaic";
79 int outSample, outSampleEnd, outLine, outLineEnd;
82 if (oproj->ToWorldX(iproj->ToProjectionX(1.0)) < 0) {
83 outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) - 0.5);
86 outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) + 0.5);
88 if (oproj->ToWorldY(iproj->ToProjectionY(1.0)) < 0) {
89 outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) - 0.5);
92 outLine = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) + 0.5);
97 outSampleEnd = outSample + ins;
98 outLineEnd = outLine + inl;
100 bool wrapPossible = iproj->IsEquatorialCylindrical();
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);
109 worldSize = abs(worldEnd - worldStart) * 2;
111 wrapPossible = wrapPossible && (worldSize > 0);
117 while (outSampleEnd - worldSize > 1) {
118 outSample -= worldSize;
119 outSampleEnd -= worldSize;
129 ins = ins + outSample - 1;
134 inl = inl + outLine - 1;
138 if ((outSample + ins - 1) > nsMosaic) {
139 ins = nsMosaic - outSample + 1;
143 if ((outLine + inl - 1) > nlMosaic) {
144 inl = nlMosaic - outLine + 1;
147 if (outSampleEnd < 1 || outLineEnd < 1 || outSample > nsMosaic || outLine > nlMosaic || ins < 1 || inl < 1) {
168 outSample += worldSize;
169 outSampleEnd += worldSize;
171 while (wrapPossible && outSample < nsMosaic);
174 QString msg =
"Unable to mosaic cube [" +
FileName(inputFile).
name() +
"]";
196 const QString &mosaicFile) {
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;
210 if (propagationCubes.size() < 1) {
211 QString msg =
"The list does not contain any data";
215 for (
int i = 0; i < propagationCubes.size(); i++) {
225 if ((proj != NULL) && (*proj != *projNew)) {
226 QString msg =
"Mapping groups do not match between cubes [" +
227 propagationCubes[0].toString() +
"] and [" + propagationCubes[i].toString() +
"]";
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;
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;
246 if (projNew->MinimumLatitude() == 0.0 && projNew->MaximumLatitude() == 0.0 &&
247 projNew->MinimumLongitude() == 0.0 && projNew->MaximumLongitude() == 0.0) {
251 slat = min(slat, projNew->MinimumLatitude());
252 elat = max(elat, projNew->MaximumLatitude());
253 slon = min(slon, projNew->MinimumLongitude());
254 elon = max(elon, projNew->MaximumLongitude());
258 if (proj)
delete proj;
262 if (proj)
delete proj;
265 slat, elat, slon, elon, bands, oAtt, mosaicFile, latlonflag);
275 const QString &mosaicFile) {
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;
282 double erad = -DBL_MAX;
283 double saz = DBL_MAX;
284 double eaz = -DBL_MAX;
288 if (propagationCubes.size() < 1) {
289 QString msg =
"The list does not contain any data";
293 for (
int i = 0; i < propagationCubes.size(); i++) {
303 if ((proj != NULL) && (*proj != *projNew)) {
304 QString msg =
"Mapping groups do not match between cubes [" +
305 propagationCubes[0].toString() +
"] and [" + propagationCubes[i].toString() +
"]";
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;
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;
324 srad = min(srad, projNew->MinimumRingRadius());
325 erad = max(erad, projNew->MaximumRingRadius());
326 saz = min(saz, projNew->MinimumRingLongitude());
327 eaz = max(eaz, projNew->MaximumRingLongitude());
331 if (proj)
delete proj;
335 if (proj)
delete proj;
338 srad, erad, saz, eaz, bands, oAtt, mosaicFile);
348 double slat,
double elat,
double slon,
double elon,
350 if (propagationCubes.size() < 1) {
351 QString msg =
"The list does not contain any data";
355 int samples, lines, bands = 0;
367 if (slat < elat && slon < elon) {
374 if (mGroup.hasKeyword(
"UpperLeftCornerX"))
375 mGroup.deleteKeyword(
"UpperLeftCornerX");
377 if (mGroup.hasKeyword(
"UpperLeftCornerY"))
378 mGroup.deleteKeyword(
"UpperLeftCornerY");
386 double xmin, xmax, ymin, ymax;
387 proj->XYRange(xmin, xmax, ymin, ymax);
390 xmin = mapPvl.findGroup(
"Mapping")[
"UpperLeftCornerX"];
391 ymax = mapPvl.findGroup(
"Mapping")[
"UpperLeftCornerY"];
393 for (
int i = 0; i < propagationCubes.size(); i++) {
405 else if (*proj != *projNew) {
406 QString msg =
"Mapping groups do not match between cube [" + propagationCubes[i].toString() +
407 "] and [" + propagationCubes[0].toString() +
"]";
411 if (proj)
delete proj;
415 if (proj)
delete proj;
418 slat, elat, slon, elon, bands, oAtt, mosaicFile);
437 double srad,
double erad,
double saz,
double eaz,
439 if (propagationCubes.size() < 1) {
440 QString msg =
"The list does not contain any data";
444 int samples, lines, bands = 0;
453 if (mGroup.hasKeyword(
"UpperLeftCornerX"))
454 mGroup.deleteKeyword(
"UpperLeftCornerX");
456 if (mGroup.hasKeyword(
"UpperLeftCornerY"))
457 mGroup.deleteKeyword(
"UpperLeftCornerY");
465 double xmin, xmax, ymin, ymax;
466 proj->XYRange(xmin, xmax, ymin, ymax);
469 xmin = mapPvl.findGroup(
"Mapping")[
"UpperLeftCornerX"];
470 ymax = mapPvl.findGroup(
"Mapping")[
"UpperLeftCornerY"];
472 for (
int i = 0; i < propagationCubes.size(); i++) {
483 else if (*proj != *projNew) {
484 QString msg =
"Mapping groups do not match between cube [" + propagationCubes[i].toString() +
485 "] and [" + propagationCubes[0].toString() +
"]";
489 if (proj)
delete proj;
493 if (proj)
delete proj;
496 srad, erad, saz, eaz, bands, oAtt, mosaicFile);
508 double xmin,
double xmax,
double ymin,
double ymax,
509 double slat,
double elat,
double slon,
double elon,
int nbands,
511 Pvl fileLab(inputFile);
521 if (latlonflag && slat < elat && slon < elon) {
528 if (mapping.hasKeyword(
"MinimumLatitude")) {
529 mapping.deleteKeyword(
"MinimumLatitude");
531 if (mapping.hasKeyword(
"MaximumLatitude")) {
532 mapping.deleteKeyword(
"MaximumLatitude");
534 if (mapping.hasKeyword(
"MinimumLongitude")) {
535 mapping.deleteKeyword(
"MinimumLongitude");
537 if (mapping.hasKeyword(
"MaximumLongitude")) {
538 mapping.deleteKeyword(
"MaximumLongitude");
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);
551 newMap.
addGroup(firstProj->Mapping());
558 p.PropagateHistory(
false);
559 p.PropagateLabels(
false);
560 p.PropagateTables(
false);
561 p.PropagatePolygons(
false);
562 p.PropagateOriginalLabel(
false);
569 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
570 p.Progress()->SetText(
"Initializing mosaic");
581 mosaicCube->open(mosaicFile,
"rw");
584 AddOutputCube(mosaicCube);
610 double xmin,
double xmax,
double ymin,
double ymax,
611 double srad,
double erad,
double saz,
double eaz,
int nbands,
613 Pvl fileLab(inputFile);
616 mapping[
"UpperLeftCornerX"] =
toString(xmin);
617 mapping[
"UpperLeftCornerY"] =
toString(ymax);
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);
637 p.PropagateHistory(
false);
638 p.PropagateLabels(
false);
639 p.PropagateTables(
false);
640 p.PropagatePolygons(
false);
641 p.PropagateOriginalLabel(
false);
648 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
649 p.Progress()->SetText(
"Initializing mosaic");
659 mosaicCube->open(mosaicFile,
"rw");
662 AddOutputCube(mosaicCube);
676 QString msg =
"You can only specify one output cube and projection";
680 if (mapping.hasKeyword(
"UpperLeftCornerX"))
681 mapping.deleteKeyword(
"UpperLeftCornerX");
683 if (mapping.hasKeyword(
"UpperLeftCornerY"))
684 mapping.deleteKeyword(
"UpperLeftCornerY");
689 int samps, lines, bands;
695 Cube *propCube = p.SetInputCube(inputFile, inAtt);
696 bands = propCube->bandCount();
703 p.PropagateHistory(
false);
704 p.PropagateLabels(
false);
705 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
706 p.Progress()->SetText(
"Initializing mosaic");
717 AddOutputCube(mosaicCube);
718 mosaicCube->open(mosaicFile,
"rw");
734 QString msg =
"You can only specify one output cube and projection";
738 if (mapping.hasKeyword(
"UpperLeftCornerX"))
739 mapping.deleteKeyword(
"UpperLeftCornerX");
741 if (mapping.hasKeyword(
"UpperLeftCornerY"))
742 mapping.deleteKeyword(
"UpperLeftCornerY");
747 int samps, lines, bands;
753 Cube *propCube = p.SetInputCube(inputFile, inAtt);
754 bands = propCube->bandCount();
761 p.PropagateHistory(
false);
762 p.PropagateLabels(
false);
763 Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, bands);
764 p.Progress()->SetText(
"Initializing mosaic");
775 AddOutputCube(mosaicCube);
776 mosaicCube->open(mosaicFile,
"rw");
791 mosaic.
open(mosaicFile);
811 mosaic.
open(mosaicFile);
Buffer for reading and writing cube data.
int size() const
Returns the total number of pixels in the shape buffer.
Manipulate and parse attributes of output cube filenames.
IO Handler for Isis Cubes.
void addCachingAlgorithm(CubeCachingAlgorithm *)
This will add the given caching algorithm to the list of attempted caching algorithms.
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
void close(bool remove=false)
Closes the cube and updates the labels.
Projection * projection()
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Displacement is a signed length, usually in meters.
@ Meters
The distance is being specified in meters.
Internalizes a list of files.
File name manipulation and expansion.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
Isis::Cube * SetInputCube(const QString ¶meter, 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.
void WriteHistory(Cube &cube)
Writes out the History blob to the cube.
bool p_propagateHistory
Flag indicating if history is to be propagated to output cubes.
Isis::Progress * Progress()
This method returns a pointer to a Progress object.
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
void ClearInputCubes()
Close owned input cubes from the list and clear the list.
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 ¶meter, 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.
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.
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Contains multiple PvlContainers.
Container for cube-like labels.
void read(const QString &file)
Loads PVL information from a stream.
A single keyword-value pair.
@ Traverse
Search child objects.
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
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.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.