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++) {
86 cube.
open(sns.fileName(i));
89 QString msg =
"Unable to open cube for serial number [";
90 msg += sns.serialNumber(i) +
"] filename [" + sns.fileName(i) +
"]";
102 geos::geom::MultiPolygon *mp = NULL;
105 if(!tmp->isValid()) {
108 QString msg =
"The image [" + sns.fileName(sns.serialNumber(i)) +
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()) {
420 imageOverlap->SetPolygon(multiPolygon);
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;
774 p.AddSteps(newSteps);
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.
Individual overlap container.
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.
Program progress reporter.
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Contains multiple PvlContainers.
A single keyword-value pair.
int size() const
Returns the number of values stored in this keyword.
Serial Number list generator.
This is free and unencumbered software released into the public domain.
Namespace for the standard library.