16#include "geos/operation/distance/DistanceOp.h"
17#include "geos/util/IllegalArgumentException.h"
18#include "geos/geom/Point.h"
20#include "geos/operation/overlay/snap/SnapOverlayOp.h"
22#include "IException.h"
23#include "ImageOverlapSet.h"
24#include "ImagePolygon.h"
25#include "PolygonTools.h"
27#include "SerialNumberList.h"
62 for (
int i = 0; i <
Size(); i++) {
82 for (
int i = 0; i < sns.
size(); i++) {
89 QString msg =
"Unable to open cube for serial number [";
102 geos::geom::MultiPolygon *mp = NULL;
105 if(!tmp->isValid()) {
109 "] has an invalid footprint";
117 if (tmp->isValid()) {
129 p_lonLatOverlapsMutex.lock();
131 p_lonLatOverlapsMutex.unlock();
178 string msg =
"FindImageOverlaps(SerialNumberList&,QString) may not be called on " \
179 "an ImageOverlapSet which already contains overlaps.";
302 std::vector<geos::geom::MultiPolygon *> polygons) {
304 if (sns.size() != polygons.size()) {
305 string message =
"Invalid argument sizes. Sizes must match.";
310 for (
unsigned int i = 0; i < sns.size(); ++i) {
311 p_lonLatOverlapsMutex.lock();
313 p_lonLatOverlapsMutex.unlock();
335 std::ifstream inStream;
336 QByteArray fileArray = file.toLatin1();
337 inStream.open(fileArray.constData(), fstream::in | fstream::binary);
339 while (!inStream.eof()) {
340 p_lonLatOverlapsMutex.lock();
342 p_lonLatOverlapsMutex.unlock();
348 p_lonLatOverlapsMutex.unlock();
349 QString msg =
"The overlap file [" + filename +
"] does not contain a "
350 "valid list of image overlaps";
354 p_lonLatOverlapsMutex.unlock();
355 QString msg =
"The overlap file [" + filename +
"] does not contain a "
356 "valid list of image overlaps";
384 bool success =
false;
389 if (!multiPolygon->isValid() ||
390 (multiPolygon->getArea() < 1.0e-10 && !multiPolygon->isEmpty())) {
392 multiPolygon = Isis::globalFactory->createMultiPolygon().release();
400 if (!multiPolygon->isEmpty()) {
403 multiPolygon = despiked;
409 if (multiPolygon->isValid() &&
410 (multiPolygon->isEmpty() || multiPolygon->getArea() > 1.0e-14)) {
418 else if (!multiPolygon->isEmpty()) {
430 p_lonLatOverlapsMutex.lock();
432 p_lonLatOverlapsMutex.unlock();
451 bool noOverlaps =
false;
458 std::ofstream outStream;
461 QByteArray fileArray = file.toLatin1();
463 outStream.open(fileArray.constData(), fstream::out | fstream::trunc | fstream::binary);
466 outStream.open(fileArray.constData(), fstream::out | fstream::app | fstream::binary);
469 failed |= outStream.fail();
473 p_lonLatOverlapsMutex.lock();
484 outStream << std::endl;
495 p_lonLatOverlapsMutex.unlock();
498 failed |= outStream.fail();
501 failed |= outStream.fail();
522 QString msg =
"Unable to write the image overlap list to [" + filename +
"]";
525 else if (noOverlaps) {
528 QString msg =
"No overlaps were found.";
542 bool foundOverlap =
false;
546 p.
SetText(
"Calculating Image Overlaps");
550 geos::geom::MultiPolygon *emptyPolygon = Isis::globalFactory->createMultiPolygon().release();
566 for (
int inside = outside + 1; inside <
p_lonLatOverlaps.size(); ++inside) {
572 const geos::geom::MultiPolygon *poly1 =
p_lonLatOverlaps.at(outside)->Polygon();
573 const geos::geom::MultiPolygon *poly2 =
p_lonLatOverlaps.at(inside)->Polygon();
577 if (PolygonTools::Equal(poly1, poly2)) {
578 p_lonLatOverlapsMutex.lock();
581 p_lonLatOverlapsMutex.unlock();
587 if (poly2->isEmpty() || poly2->getArea() < 1.0e-14) {
588 p_lonLatOverlapsMutex.lock();
590 p_lonLatOverlapsMutex.unlock();
595 geos::geom::Geometry *intersected = NULL;
601 QString error =
"Intersection of overlaps failed.";
606 double outsideArea = poly1->getArea();
607 double insideArea = poly2->getArea();
608 double areaRatio = std::min(outsideArea, insideArea) /
609 std::max(outsideArea, insideArea);
614 if (areaRatio < 0.1) {
615 if (poly1->getArea() > poly2->getArea()) {
616 error +=
" The first polygon will be removed.";
618 p_lonLatOverlapsMutex.lock();
620 p_lonLatOverlapsMutex.unlock();
624 error +=
" The second polygon will be removed.";
626 p_lonLatOverlapsMutex.lock();
628 p_lonLatOverlapsMutex.unlock();
633 error +=
" Both polygons will be removed to prevent the "
634 "possibility of double counted areas.";
636 p_lonLatOverlapsMutex.lock();
639 p_lonLatOverlapsMutex.unlock();
646 if (intersected->isEmpty() || intersected->getArea() < 1.0e-14) {
655 geos::geom::MultiPolygon *overlap = NULL;
663 if (!intersected->isValid()) {
677 catch (geos::util::GEOSException *exc) {
684 if (!overlap->isValid()) {
687 HandleError(snlist,
"Intersection produced invalid overlap area", inside, outside);
692 if (overlap->isEmpty() || overlap->getArea() < 1.0e-14) {
699 if (PolygonTools::Equal(poly1, overlap)) {
700 geos::geom::Geometry *tmpGeom = NULL;
705 HandleError(e, snlist,
"Differencing overlap polygons failed."
706 "The first polygon will be removed.", inside, outside);
710 p_lonLatOverlapsMutex.lock();
712 p_lonLatOverlapsMutex.unlock();
721 else if (PolygonTools::Equal(poly2, overlap)) {
722 geos::geom::Geometry *tmpGeom = NULL;
727 HandleError(e, snlist,
"Differencing overlap polygons failed."
728 "The second polygon will be removed.", inside, outside);
731 p_lonLatOverlapsMutex.lock();
733 p_lonLatOverlapsMutex.unlock();
744 geos::geom::Geometry *tmpGeom = NULL;
755 if (tmpGeom == NULL) {
761 HandleError(e, snlist,
"Differencing overlap polygons failed", inside, outside);
766 if (
SetPolygon(Isis::globalFactory->createMultiPolygon().release(), outside))
773 int newSteps = newSize - oldSize;
776 if (newSize != oldSize) inside++;
782 HandleError(e, snlist,
"Unable to find overlap.", inside, outside);
785 catch (geos::util::IllegalArgumentException *ill) {
786 HandleError(NULL, snlist,
"Unable to find overlap", inside, outside);
788 catch (geos::util::GEOSException *exc) {
789 HandleError(exc, snlist,
"Unable to find overlap", inside, outside);
792 HandleError(snlist,
"Unknown Error: Unable to find overlap", inside, outside);
803 if (foundOverlap ==
false) {
804 p_lonLatOverlapsMutex.lock();
806 p_lonLatOverlapsMutex.unlock();
827 for (
int i = 0; i < from->Size(); i++) {
828 QString s = (*from)[i];
841 geos::geom::MultiPolygon *latLonPolygon) {
860 vector<ImageOverlap *> matches;
889 int overlap1,
int overlap2) {
894 PvlKeyword serialNumbers(
"PolySerialNumbers");
901 if (snlist != NULL) {
907 err += serialNumbers;
909 if (filename.
size() != 0) {
918 PvlKeyword serialNumbers(
"PolySerialNumbers");
925 if (snlist != NULL) {
931 err += serialNumbers;
933 if (filename.
size() != 0) {
942 if (!msg.isEmpty()) {
965 int overlap1,
int overlap2) {
970 PvlKeyword serialNumbers(
"PolySerialNumbers");
976 if (snlist != NULL) {
981 err += serialNumbers;
983 if (filename.
size() != 0) {
990 PvlKeyword serialNumbers(
"PolySerialNumbers");
996 if (snlist != NULL) {
1001 err += serialNumbers;
1003 if (filename.
size() != 0) {
1010 if (!msg.isEmpty()) {
1035 int overlap1,
int overlap2) {
1040 PvlKeyword serialNumbers(
"PolySerialNumbers");
1046 if (snlist != NULL) {
1051 err += serialNumbers;
1053 if (filename.
size() != 0) {
1060 PvlKeyword serialNumbers(
"PolySerialNumbers");
1066 if (snlist != NULL) {
1071 err += serialNumbers;
1073 if (filename.
size() != 0) {
1095 for (
int i = 0; i <
Size(); i++) {
IO Handler for Isis Cubes.
ImagePolygon readFootprint() const
Read the footprint polygon for 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.
File name manipulation and expansion.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
@ Unknown
A type of error that cannot be classified as any of the other error types.
@ 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.
@ Io
A type of error that occurred when performing an actual I/O operation.
const char * what() const
Returns a string representation of this exception in its current state.
Individual overlap container.
virtual void SetPolygon(const geos::geom::MultiPolygon &polygon)
This method will replace the existing polygon that defines the overlap with a new one.
void Add(QString &sn)
This method will add a new serial number to the list of serial numbers alread associated with the ove...
void ReadImageOverlaps(const QString &filename)
Create polygons of overlap from the file specified.
QList< ImageOverlap * > p_lonLatOverlaps
The list of lat/lon overlaps.
void FindAllOverlaps(SerialNumberList *snlist=NULL)
Find the overlaps between all the existing ImageOverlap Objects.
std::vector< PvlGroup > p_errorLog
This is a list of detailed* errors including all known information.
int p_calculatedSoFar
The index of the last overlap that is done calculating (number calculated-1)
ImageOverlap * CreateNewOverlap(QString serialNumber, geos::geom::MultiPolygon *lonLatPolygon)
Create an overlap item to hold the overlap poly and its SN.
virtual ~ImageOverlapSet()
Delete this object.
void HandleError(IException &e, SerialNumberList *snlist, QString msg="", int overlap1=-1, int overlap2=-1)
If a problem occurred when searching for image overlaps, this method will handle it.
void AddSerialNumbers(ImageOverlap *to, ImageOverlap *from)
Add the serial numbers from the second overlap to the first.
int p_writtenSoFar
The index of the last overlap that is done writing (number written-1)
bool SetPolygon(geos::geom::Geometry *poly, int position, ImageOverlap *sncopy=NULL, bool insert=false)
This method inserts or overwrites a polygon in the overlap list based on parameters.
ImageOverlapSet(bool continueOnError=false, bool useThread=true)
Create FindImageOverlaps object.
SerialNumberList * p_snlist
This is used for multi-threaded calls to FindAllOverlaps only; this class never gets ownership of thi...
void DespikeLonLatOverlaps()
Despikes all of the overlaps in p_lonLatOverlaps.
QMutex p_calculatePolygonMutex
This mutex will be used to have blocking on the write method when multi-threading (instead of busy wa...
void FindImageOverlaps(SerialNumberList &boundaries)
Create polygons of overlap from the images specified in the serial number list.
int Size()
Returns the total number of latitude and longitude overlaps.
bool p_threadedCalculate
True if we want to do calculations in a threaded way.
bool p_continueAfterError
If false iExceptions will be thrown from FindImageOverlaps(...)
void WriteImageOverlaps(const QString &filename)
Write polygons of overlap to the file specified.
const ImageOverlap * operator[](int index)
Returns the images which overlap at a given loverlap.
Create cube polygons, read/write polygons to blobs.
geos::geom::MultiPolygon * Polys()
Return a geos Multipolygon.
Program progress reporter.
void AddSteps(const int steps)
If the initial step size was a guess, it can be modified using this method.
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
void CheckStatus()
Checks and updates the status.
Contains multiple PvlContainers.
A single keyword-value pair.
int size() const
Returns the number of values stored in this keyword.
Serial Number list generator.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
int size() const
How many serial number / filename combos are in the list.
QString fileName(const QString &sn)
Return a filename given a serial number.
This is free and unencumbered software released into the public domain.
Namespace for the standard library.