USGS

Isis 3.0 Object Programmers' Reference

Home

ImageOverlapSet.cpp
1 #include <string>
2 #include <iostream>
3 #include <sstream>
4 #include <iomanip>
5 #include <vector>
6 #include <cmath>
7 
8 #include "geos/operation/distance/DistanceOp.h"
9 #include "geos/util/IllegalArgumentException.h"
10 #include "geos/geom/Point.h"
11 #include "geos/opOverlay.h"
12 #include "IException.h"
13 #include "Cube.h"
14 #include "SerialNumberList.h"
15 #include "PolygonTools.h"
16 #include "ImagePolygon.h"
17 #include "FileName.h"
18 #include "ImageOverlapSet.h"
19 #include "Progress.h"
20 
21 using namespace std;
22 
23 namespace Isis {
33  ImageOverlapSet::ImageOverlapSet(bool continueOnError) {
34  p_continueAfterError = continueOnError;
35  p_writtenSoFar = 0;
36  p_calculatedSoFar = -1;
37  p_threadedCalculate = false;
38  p_snlist = NULL;
39  }
40 
41 
48  ImageOverlapSet::~ImageOverlapSet() {
49  for(int i = 0; i < Size(); i++) {
50  if(p_lonLatOverlaps[i]) delete p_lonLatOverlaps[i];
51  }
52 
53  // This class should not retain ownership of p_snlist,
54  // so this member should not need destroyed.
55  };
56 
57 
66  void ImageOverlapSet::FindImageOverlaps(SerialNumberList &sns) {
67  // Create an ImageOverlap for each image boundary
68  for(int i = 0; i < sns.Size(); i++) {
69  // Open the cube
70  Cube cube;
71  try {
72  cube.open(sns.FileName(i));
73  }
74  catch(IException &error) {
75  QString msg = "Unable to open cube for serial number [";
76  msg += sns.SerialNumber(i) + "] filename [" + sns.FileName(i) + "]";
77 
78  HandleError(error, &sns, msg);
79  }
80 
81  // Read the bounding polygon
82  ImagePolygon *poly = new ImagePolygon();
83  cube.read(*poly);
84  cube.close();
85 
86  // Create a ImageOverlap with the serial number and the bounding
87  // polygon and save it
88  geos::geom::MultiPolygon *tmp = PolygonTools::MakeMultiPolygon(
89  poly->Polys());
90 
91  delete poly;
92  poly = NULL;
93 
94  geos::geom::MultiPolygon *mp = NULL;
95 
96  // If footprint is invalid throw exception
97  if(!tmp->isValid()) {
98  delete tmp;
99  tmp = NULL;
100  IString msg = "The image [" + sns.FileName(sns.SerialNumber(i)) +
101  "] has an invalid footprint";
102  throw IException(IException::Programmer, msg, _FILEINFO_);
103  }
104 
105  try {
106  mp = PolygonTools::Despike(tmp);
107  }
108  catch(IException &e) {
109  if(tmp->isValid()) {
110  mp = tmp;
111  tmp = NULL;
112  }
113  else {
114  delete tmp;
115  tmp = NULL;
116  HandleError(e, &sns);
117  continue;
118  }
119  }
120 
121  p_lonLatOverlaps.push_back(CreateNewOverlap(sns.SerialNumber(i), mp));
122 
123  if(mp) {
124  delete mp;
125  mp = NULL;
126  }
127 
128  if(tmp) {
129  delete tmp;
130  tmp = NULL;
131  }
132  }
133 
134  // Despikes the polygons from the Serial Numbers prior to overlap
135  // determination
136  DespikeLonLatOverlaps();
137 
138  if(p_threadedCalculate) {
139  // Call FindAllOverlaps in other thread
140  start();
141  }
142  else {
143  // Determine the overlap between each boundary polygon
144  FindAllOverlaps(&sns);
145  }
146  }
147 
163  void ImageOverlapSet::FindImageOverlaps(SerialNumberList &boundaries, QString outputFile) {
164  // Do a common sense programmer check, this should be empty before we start
165  if(!p_lonLatOverlaps.empty()) {
166  string msg = "FindImageOverlaps(SerialNumberList&,QString) may not be called on " \
167  "an ImageOverlapSet which already contains overlaps.";
168  throw IException(IException::Programmer, msg, _FILEINFO_);
169  }
170 
171  p_writtenSoFar = 0;
172  p_calculatedSoFar = -1;
173 
174  p_snlist = &boundaries;
175 
176  // This will enable using mutexes and spawning threads where necessary.
177  p_threadedCalculate = true;
178 
179  FindImageOverlaps(boundaries);
180 
181  // While our exit condition is not true, call WriteImageOverlaps with the filename. The
182  // WriteImageOverlaps call will block if it is waiting on calculations.
183  while(p_calculatedSoFar != p_lonLatOverlaps.size()) {
184  WriteImageOverlaps(outputFile);
185  }
186 
187  // flush the output if we're still not done writing
188  if(p_calculatedSoFar != p_writtenSoFar)
189  WriteImageOverlaps(outputFile);
190 
191  // Wait for the calculation thread to actually exit, this has more than likely already occurred.
192  wait();
193 
194  // re-initialize object to original state
195  p_lonLatOverlaps.clear();
196  p_writtenSoFar = 0;
197  p_calculatedSoFar = -1;
198  p_threadedCalculate = false;
199  p_snlist = NULL;
200  }
201 
202 
291  void ImageOverlapSet::FindImageOverlaps(std::vector<QString> sns,
292  std::vector<geos::geom::MultiPolygon *> polygons) {
293 
294  if(sns.size() != polygons.size()) {
295  string message = "Invalid argument sizes. Sizes must match.";
296  throw IException(IException::Programmer, message, _FILEINFO_);
297  }
298 
299  // Create one ImageOverlap for each image sn
300  for(unsigned int i = 0; i < sns.size(); ++i) {
301  p_lonLatOverlaps.push_back(CreateNewOverlap(sns[i], polygons[i]));
302  }
303 
304  // Despikes the polygons from the Serial Numbers prior to overlap determination
305  DespikeLonLatOverlaps();
306 
307  // Determine the overlap between each boundary polygon
308  FindAllOverlaps();
309  }
310 
316  void ImageOverlapSet::ReadImageOverlaps(const QString &filename) {
317  IString file = FileName(filename).expanded();
318 
319  try {
320  // Let's get an istream pointed at our file
321  std::ifstream inStream;
322  inStream.open(file.c_str(), fstream::in | fstream::binary);
323 
324  while(!inStream.eof()) {
325  p_lonLatOverlaps.push_back(new ImageOverlap(inStream));
326  }
327 
328  inStream.close();
329  }
330  catch(IException &e) {
331  IString msg = "The overlap file [" + filename + "] does not contain a "
332  "valid list of image overlaps";
333  throw IException(e, IException::Unknown, msg, _FILEINFO_);
334  }
335  catch(...) {
336  IString msg = "The overlap file [" + filename + "] does not contain a "
337  "valid list of image overlaps";
338  throw IException(IException::Unknown, msg, _FILEINFO_);
339  }
340  }
341 
342 
360  bool ImageOverlapSet::SetPolygon(geos::geom::Geometry *poly, int position, ImageOverlap *sncopy, bool insert) {
361  bool success = false;
362  geos::geom::MultiPolygon *multiPolygon = PolygonTools::MakeMultiPolygon(poly);
363  delete poly;
364  poly = NULL;
365 
366  if(!multiPolygon->isValid() || (multiPolygon->getArea() < 1.0e-10 && !multiPolygon->isEmpty())) {
367  delete multiPolygon;
368  multiPolygon = Isis::globalFactory.createMultiPolygon();
369  }
370 
371  if(position > p_lonLatOverlaps.size()) {
372  position = p_lonLatOverlaps.size();
373  }
374 
375  try {
376  if(!multiPolygon->isEmpty()) {
377  geos::geom::MultiPolygon *despiked = PolygonTools::Despike(multiPolygon);
378  delete multiPolygon;
379  multiPolygon = despiked;
380  }
381  }
382  catch(IException &) {
383  }
384 
385  if(multiPolygon->isValid() && (multiPolygon->isEmpty() || multiPolygon->getArea() > 1.0e-14)) {
386  if(!insert) {
387  p_lonLatOverlaps.at(position)->SetPolygon(multiPolygon);
388 
389  if(sncopy) {
390  AddSerialNumbers(p_lonLatOverlaps.at(position), sncopy);
391  }
392  }
393  else if(!multiPolygon->isEmpty()) {
394  ImageOverlap *imageOverlap = new ImageOverlap();
395  imageOverlap->SetPolygon(multiPolygon);
396  delete multiPolygon;
397  multiPolygon = NULL;
398 
399  if(sncopy) {
400  AddSerialNumbers(imageOverlap, sncopy);
401  }
402 
403  // Insert could cause a reallocate of the overlap list, so lock it with
404  // the writing code so that we don't conflict
405  QMutexLocker locker(&p_lonLatOverlapsMutex);
406  p_lonLatOverlaps.insert(p_lonLatOverlaps.begin() + position, imageOverlap);
407  }
408 
409  success = true;
410  }
411 
412  return success;
413  }
414 
415 
421  void ImageOverlapSet::WriteImageOverlaps(const QString &filename) {
422  IString file = FileName(filename).expanded();
423  bool failed = false;
424  if(p_threadedCalculate) p_calculatePolygonMutex.lock();
425 
426  if(p_lonLatOverlaps.size() == 0) {
427  IString msg = "No overlaps were found.";
428  throw IException(IException::User, msg, _FILEINFO_);
429  }
430 
431  try {
432  // Let's get an ostream pointed at our file
433  std::ofstream outStream;
434 
435  if(p_writtenSoFar == 0) {
436  outStream.open(file.c_str(), fstream::out | fstream::trunc | fstream::binary);
437  }
438  else {
439  outStream.open(file.c_str(), fstream::out | fstream::app | fstream::binary);
440  }
441 
442  failed |= outStream.fail();
443 
444  static bool overlapWritten = false;
445  for(int overlap = p_writtenSoFar; !failed && overlap <= p_calculatedSoFar; overlap++) {
446  // Let's not try anything during a possible reallocate
447  QMutexLocker locker(&p_lonLatOverlapsMutex);
448 
449  if(overlap < p_lonLatOverlaps.size() && p_lonLatOverlaps[overlap]) {
450  if(!p_lonLatOverlaps[overlap]->Polygon()->isEmpty()) {
451  if(overlapWritten) {
452  outStream << std::endl;
453  }
454 
455  p_lonLatOverlaps[overlap]->Write(outStream);
456  overlapWritten = true;
457  }
458 
459  delete p_lonLatOverlaps[overlap];
460  p_lonLatOverlaps[overlap] = NULL;
461  p_writtenSoFar ++;
462  }
463  }
464 
465  failed |= outStream.fail();
466  outStream.close();
467 
468  failed |= outStream.fail();
469  }
470  catch(...) {
471  failed = true;
472  }
473 
478  if(p_calculatedSoFar == p_lonLatOverlaps.size()) {
479  if(p_threadedCalculate) p_calculatePolygonMutex.unlock();
480  }
481 
482  if(failed) {
483  IString msg = "Unable to write the image overlap list to [" + filename + "]";
484  throw IException(IException::Io, msg, _FILEINFO_);
485  }
486  }
487 
488 
495  void ImageOverlapSet::FindAllOverlaps(SerialNumberList *snlist) {
496  if(p_lonLatOverlaps.size() <= 1) return;
497 
498  Progress p;
499  p.SetText("Calculating Image Overlaps");
500  p.SetMaximumSteps(p_lonLatOverlaps.size() - 1);
501  p.CheckStatus();
502 
503  geos::geom::MultiPolygon *emptyPolygon = Isis::globalFactory.createMultiPolygon();
504 
505  // Compare each polygon with all of the others
506  for(int outside = 0; outside < p_lonLatOverlaps.size() - 1; ++outside) {
507  p_calculatedSoFar = outside - 1;
508 
509  // unblock the writing process after every 10 polygons if we need to write
510  if(p_calculatedSoFar % 10 == 0 && (!snlist || p_lonLatOverlaps.size() > snlist->Size())) {
511  if(p_threadedCalculate) p_calculatePolygonMutex.unlock();
512  }
513 
514  // Intersect the current polygon (from the outside loop) with all others
515  // below it
516  for(int inside = outside + 1; inside < p_lonLatOverlaps.size(); ++inside) {
517  try {
518  if(p_lonLatOverlaps.at(outside)->HasAnySameSerialNumber(*p_lonLatOverlaps.at(inside))) continue;
519 
520  // We know these are valid because they were filtered early on
521  const geos::geom::MultiPolygon *poly1 = p_lonLatOverlaps.at(outside)->Polygon();
522  const geos::geom::MultiPolygon *poly2 = p_lonLatOverlaps.at(inside)->Polygon();
523 
524  // Check to see if the two poygons are equivalent.
525  // If they are, then we can get rid of one of them
526  if(PolygonTools::Equal(poly1, poly2)) {
527  AddSerialNumbers(p_lonLatOverlaps[outside], p_lonLatOverlaps[inside]);
528  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + inside);
529  inside --;
530  continue;
531  }
532 
533  // We can get empty polygons in our list sometimes; try to avoid extra processing
534  if(poly2->isEmpty() || poly2->getArea() < 1.0e-14) {
535  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + inside);
536  inside --;
537  continue;
538  }
539 
540  geos::geom::Geometry *intersected = NULL;
541  try {
542  intersected = PolygonTools::Intersect(poly1, poly2);
543  }
544  catch(IException &e) {
545  intersected = NULL;
546  QString error = "Intersection of overlaps failed.";
547 
548  // We never want to double seed, so we must delete one or both
549  // of these polygons because they more than likely have an intersection
550  // that we simply can't calculate.
551  double outsideArea = poly1->getArea();
552  double insideArea = poly2->getArea();
553  double areaRatio = std::min(outsideArea, insideArea) / std::max(outsideArea, insideArea);
554 
555  // If one of the polygons is < 1% the area of the other, then only throw out the small one to
556  // try to minimize the impact of this failure.
557  if(areaRatio < 0.1) {
558  if(poly1->getArea() > poly2->getArea()) {
559  error += " The first polygon will be removed.";
560  HandleError(e, snlist, error, inside, outside);
561  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + inside);
562  inside --;
563  }
564  else {
565  error += " The second polygon will be removed.";
566  HandleError(e, snlist, error, inside, outside);
567  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + outside);
568  inside = outside;
569  }
570  }
571  else {
572  error += " Both polygons will be removed to prevent the possibility of double counted areas.";
573  HandleError(e, snlist, error, inside, outside);
574  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + inside);
575  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + outside);
576  inside = outside;
577  }
578 
579  continue;
580  }
581 
582  if(intersected->isEmpty() || intersected->getArea() < 1.0e-14) {
583  delete intersected;
584  intersected = NULL;
585  continue;
586  }
587 
588  // We are only interested in overlaps that result in polygon(s)
589  // and not any that are lines or points, so create a new multipolygon
590  // with only the polygons of overlap
591  geos::geom::MultiPolygon *overlap = NULL;
592  try {
593  overlap = PolygonTools::Despike(intersected);
594 
595  delete intersected;
596  intersected = NULL;
597  }
598  catch(IException &e) {
599  if(!intersected->isValid()) {
600  delete intersected;
601  intersected = NULL;
602 
603  HandleError(e, snlist, "", inside, outside);
604  continue;
605  }
606  else {
607  overlap = PolygonTools::MakeMultiPolygon(intersected);
608 
609  delete intersected;
610  intersected = NULL;
611  }
612  }
613  catch(geos::util::GEOSException *exc) {
614  delete intersected;
615  intersected = NULL;
616  HandleError(exc, snlist, "", inside, outside);
617  continue;
618  }
619 
620  if(!overlap->isValid()) {
621  delete overlap;
622  overlap = NULL;
623  HandleError(snlist, "Intersection produced invalid overlap area", inside, outside);
624  continue;
625  }
626 
627  // is there really overlap?
628  if(overlap->isEmpty() || overlap->getArea() < 1.0e-14) {
629  delete overlap;
630  overlap = NULL;
631  continue;
632  }
633 
634  // poly1 is completly inside poly2
635  if(PolygonTools::Equal(poly1, overlap)) {
636  geos::geom::Geometry *tmpGeom = NULL;
637  try {
638  tmpGeom = PolygonTools::Difference(poly2, poly1);
639  }
640  catch(IException &e) {
641  HandleError(e, snlist, "Differencing overlap polygons failed. The first polygon will be removed.", inside, outside);
642 
643  // Delete outside polygon directly and reset outside loop
644  // - current outside is thrown out!
645  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + outside);
646  inside = outside;
647 
648  continue;
649  }
650 
651  SetPolygon(tmpGeom, inside);
652  SetPolygon(overlap, outside, p_lonLatOverlaps[inside]);
653  }
654 
655  // poly2 is completly inside poly1
656  else if(PolygonTools::Equal(poly2, overlap)) {
657  geos::geom::Geometry *tmpGeom = NULL;
658  try {
659  tmpGeom = PolygonTools::Difference(poly1, poly2);
660  }
661  catch(IException &e) {
662  HandleError(e, snlist, "Differencing overlap polygons failed. The second polygon will be removed.", inside, outside);
663 
664 
665  // Delete inside polygon directly and process next inside
666  p_lonLatOverlaps.erase(p_lonLatOverlaps.begin() + inside);
667  inside --;
668 
669  continue;
670  }
671 
672  SetPolygon(tmpGeom, outside);
673  SetPolygon(overlap, inside, p_lonLatOverlaps[outside]);
674  }
675  // There is partial overlap
676  else {
677  // Subtract overlap from poly1 and set poly1 to the result
678  geos::geom::Geometry *tmpGeom = NULL;
679  try {
680  tmpGeom = PolygonTools::Difference(poly1, overlap);
681  }
682  catch(IException &e) {
683  tmpGeom = NULL;
684  }
685 
686  // If we failed to subtract overlap, try to subtract poly2 from poly1 and set poly1 to the result
687  try {
688  if(tmpGeom == NULL) {
689  tmpGeom = PolygonTools::Difference(poly1, poly2);
690  }
691  }
692  catch(IException &e) {
693  tmpGeom = NULL;
694  HandleError(e, snlist, "Differencing overlap polygons failed", inside, outside);
695  continue;
696  }
697 
698  if(!SetPolygon(tmpGeom, outside)) {
699  SetPolygon(Isis::globalFactory.createMultiPolygon(), outside);
700  }
701 
702  int oldSize = p_lonLatOverlaps.size();
703  if(SetPolygon(overlap, inside + 1, p_lonLatOverlaps[outside], true)) {
704  int newSize = p_lonLatOverlaps.size();
705  int newSteps = newSize - oldSize;
706  p.AddSteps(newSteps);
707 
708  if(newSize != oldSize) inside++;
709  }
710  } // End of partial overlap else
711  }
712  // Collections are illegal as intersection argument
713  catch(IException &e) {
714  HandleError(e, snlist, "Unable to find overlap.", inside, outside);
715  }
716  // Collections are illegal as intersection argument
717  catch(geos::util::IllegalArgumentException *ill) {
718  HandleError(NULL, snlist, "Unable to find overlap", inside, outside);
719  }
720  catch(geos::util::GEOSException *exc) {
721  HandleError(exc, snlist, "Unable to find overlap", inside, outside);
722  }
723  catch(...) {
724  HandleError(snlist, "Unknown Error: Unable to find overlap", inside, outside);
725  }
726  }
727 
728  p.CheckStatus();
729  }
730 
731  p_calculatedSoFar = p_lonLatOverlaps.size();
732  delete emptyPolygon;
733 
734  // Do not write empty overlap files
735  if(snlist) {
736  if(p_lonLatOverlaps.size() == snlist->Size()) {
737  p_lonLatOverlaps.clear();
738  }
739  }
740 
741  // unblock the writing process
742  p_calculatePolygonMutex.unlock();
743  }
744 
745 
756  void ImageOverlapSet::AddSerialNumbers(ImageOverlap *to, ImageOverlap *from) {
757  for(int i = 0; i < from->Size(); i++) {
758  QString s = (*from)[i];
759  to->Add(s);
760  }
761  }
762 
763 
772  ImageOverlap *ImageOverlapSet::CreateNewOverlap(QString serialNumber,
773  geos::geom::MultiPolygon *latLonPolygon) {
774 
775  return new ImageOverlap(serialNumber, *latLonPolygon);
776  }
777 
778 
791  std::vector<ImageOverlap *> ImageOverlapSet::operator[](QString serialNumber) {
792  vector<ImageOverlap *> matches;
793 
794  // Look at all the ImageOverlaps we have and return the ones that
795  // have this sn
796  for(int ov = 0; ov < p_lonLatOverlaps.size(); ++ov) {
797  for(int sn = 0; sn < p_lonLatOverlaps[ov]->Size(); ++sn) {
798  if((*p_lonLatOverlaps[ov])[sn] == serialNumber) {
799  matches.push_back(p_lonLatOverlaps[ov]);
800  }
801  }
802  }
803 
804  return matches;
805  }
806 
817  void ImageOverlapSet::HandleError(IException &e, SerialNumberList *snlist, QString msg, int overlap1, int overlap2) {
818  PvlGroup err("ImageOverlapError");
819 
820  if(overlap1 >= 0 && overlap1 < p_lonLatOverlaps.size()) {
821  PvlKeyword serialNumbers("PolySerialNumbers");
822  PvlKeyword filename("FileNames");
823  PvlKeyword polygon("Polygon");
824 
825  for(int i = 0; i < p_lonLatOverlaps.at(overlap1)->Size(); i++) {
826  serialNumbers += (*p_lonLatOverlaps.at(overlap1))[i];
827 
828  if(snlist != NULL) {
829  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap1))[i]);
830  }
831  }
832  polygon += p_lonLatOverlaps.at(overlap1)->Polygon()->toString().c_str();
833 
834  err += serialNumbers;
835 
836  if(filename.size() != 0) {
837  err += filename;
838  }
839 
840  err += polygon;
841  }
842 
843  if(overlap2 >= 0 && overlap1 < p_lonLatOverlaps.size() && overlap2 < p_lonLatOverlaps.size()) {
844  PvlKeyword serialNumbers("PolySerialNumbers");
845  PvlKeyword filename("FileNames");
846  PvlKeyword polygon("Polygon");
847 
848  for(int i = 0; i < p_lonLatOverlaps.at(overlap2)->Size(); i++) {
849  serialNumbers += (*p_lonLatOverlaps.at(overlap2))[i];
850 
851  if(snlist != NULL) {
852  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap2))[i]);
853  }
854  }
855  polygon += p_lonLatOverlaps.at(overlap2)->Polygon()->toString().c_str();
856 
857  err += serialNumbers;
858 
859  if(filename.size() != 0) {
860  err += filename;
861  }
862 
863  err += polygon;
864  }
865 
866  err += PvlKeyword("Error", e.what());
867 
868  if(!msg.isEmpty()) {
869  err += PvlKeyword("Description", msg);
870  }
871 
872  p_errorLog.push_back(err);
873 
874  if(!p_continueAfterError) throw;
875  }
876 
887  void ImageOverlapSet::HandleError(geos::util::GEOSException *exc, SerialNumberList *snlist, QString msg, int overlap1, int overlap2) {
888  PvlGroup err("ImageOverlapError");
889 
890  if(overlap1 >= 0 && overlap1 < p_lonLatOverlaps.size()) {
891  PvlKeyword serialNumbers("PolySerialNumbers");
892  PvlKeyword filename("FileNames");
893 
894  for(int i = 0; i < p_lonLatOverlaps.at(overlap1)->Size(); i++) {
895  serialNumbers += (*p_lonLatOverlaps.at(overlap1))[i];
896 
897  if(snlist != NULL) {
898  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap1))[i]);
899  }
900  }
901 
902  err += serialNumbers;
903 
904  if(filename.size() != 0) {
905  err += filename;
906  }
907  }
908 
909  if(overlap2 >= 0 && overlap1 < p_lonLatOverlaps.size() && overlap2 < p_lonLatOverlaps.size()) {
910  PvlKeyword serialNumbers("PolySerialNumbers");
911  PvlKeyword filename("FileNames");
912 
913  for(int i = 0; i < p_lonLatOverlaps.at(overlap2)->Size(); i++) {
914  serialNumbers += (*p_lonLatOverlaps.at(overlap2))[i];
915 
916  if(snlist != NULL) {
917  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap2))[i]);
918  }
919  }
920 
921  err += serialNumbers;
922 
923  if(filename.size() != 0) {
924  err += filename;
925  }
926  }
927 
928  err += PvlKeyword("Error", exc->what());
929 
930  if(!msg.isEmpty()) {
931  err += PvlKeyword("Description", msg);
932  }
933 
934  p_errorLog.push_back(err);
935 
936  delete exc;
937 
938  if(!p_continueAfterError) {
939  throw IException(IException::Programmer,
940  err["Description"][0],
941  _FILEINFO_);
942  }
943  }
944 
945 
955  void ImageOverlapSet::HandleError(SerialNumberList *snlist, QString msg, int overlap1, int overlap2) {
956  PvlGroup err("ImageOverlapError");
957 
958  if(overlap1 >= 0 && overlap1 < p_lonLatOverlaps.size()) {
959  PvlKeyword serialNumbers("PolySerialNumbers");
960  PvlKeyword filename("FileNames");
961 
962  for(int i = 0; i < p_lonLatOverlaps.at(overlap1)->Size(); i++) {
963  serialNumbers += (*p_lonLatOverlaps.at(overlap1))[i];
964 
965  if(snlist != NULL) {
966  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap1))[i]);
967  }
968  }
969 
970  err += serialNumbers;
971 
972  if(filename.size() != 0) {
973  err += filename;
974  }
975  }
976 
977  if(overlap2 >= 0 && overlap1 < p_lonLatOverlaps.size() && overlap2 < p_lonLatOverlaps.size()) {
978  PvlKeyword serialNumbers("PolySerialNumbers");
979  PvlKeyword filename("FileNames");
980 
981  for(int i = 0; i < p_lonLatOverlaps.at(overlap2)->Size(); i++) {
982  serialNumbers += (*p_lonLatOverlaps.at(overlap2))[i];
983 
984  if(snlist != NULL) {
985  filename += snlist->FileName((*p_lonLatOverlaps.at(overlap2))[i]);
986  }
987  }
988 
989  err += serialNumbers;
990 
991  if(filename.size() != 0) {
992  err += filename;
993  }
994  }
995 
996  err += PvlKeyword("Description", msg);
997 
998  p_errorLog.push_back(err);
999 
1000  if(!p_continueAfterError) {
1001  throw IException(IException::Programmer,
1002  err["Description"][0],
1003  _FILEINFO_);
1004  }
1005  }
1006 
1007 
1013  void ImageOverlapSet::DespikeLonLatOverlaps() {
1014  for(int i = 0; i < Size(); i++) {
1015  try {
1016  p_lonLatOverlaps[i]->SetPolygon(
1017  PolygonTools::Despike(p_lonLatOverlaps[i]->Polygon()));
1018  }
1019  catch(IException &e) {
1020  }
1021  }
1022  }
1023 
1024 
1025 }