11#include "InterestOperator.h"
13#include "IException.h"
15#include "Statistics.h"
16#include "PolygonTools.h"
17#include "SpecialPixel.h"
18#include "ControlNet.h"
19#include "ControlPoint.h"
20#include "ControlMeasure.h"
21#include "ImageOverlapSet.h"
22#include "ImagePolygon.h"
23#include "MeasureValidationResults.h"
24#include "PolygonTools.h"
48 p_interestAmount = 0.0;
49 p_worstInterest = 0.0;
99 p_samples = op[
"Samples"];
102 p_lines = op[
"Lines"];
105 p_deltaLine = op[
"DeltaLine"];
116 QString msg =
"Improper format for InterestOperator PVL [" + pPvl.fileName() +
"]";
164 int piSample,
int piLine) {
166 if (!pUnivGrndMap.HasCamera())
169 QString msg =
"Cannot run interest on images with no camera. Image " +
170 pCube.fileName() +
" has no Camera";
175 Chip chip(2 *
p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
184 double dSmallestDist = DBL_MAX;
186 int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
187 int iSamples = 2 *
p_deltaSamp + p_samples / 2 + 1;
188 bool bCalculateInterest =
false;
190 for (
int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
191 for (
int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
196 bCalculateInterest =
false;
199 if (results.isValid()) {
200 bCalculateInterest =
true;
203 if (bCalculateInterest) {
204 Chip subChip = chip.
Extract(p_samples + pad, p_lines + pad, samp, lin);
205 double interest =
Interest(subChip);
208 double dist = std::sqrt(std::pow(piSample - samp, 2.0) + std::pow(piLine - lin, 2.0));
209 if (interest == dBestInterest && dist > dSmallestDist) {
213 dBestInterest = interest;
216 dSmallestDist = dist;
227 if (pUnivGrndMap.SetImage(piSample, piLine)) {
228 p_interestAmount = dBestInterest;
233 p_interestAmount = dBestInterest;
255 QString psOverlapListFile) {
260 if (psOverlapListFile !=
"") {
280 int iNumMeasures = pCPoint.GetNumMeasures();
281 bool bPntEditLock = pCPoint.IsEditLocked();
289 for (
int measure = 0; measure < iNumMeasures; measure++) {
300 PvlGroup pvlMeasureGrp(
"MeasureDetails");
305 if (bMeasureLocked) {
309 if (!newMeasure->IsIgnored()) {
314 if (!results.isValid()) {
316 pvlMeasureGrp +=
Isis::PvlKeyword(
"UnIgnored",
"Failed Validation Test but not "
317 "Ignored as Point EditLock is True");
319 else if (bMeasureLocked == measure) {
324 pvlMeasureGrp +=
Isis::PvlKeyword(
"Ignored",
"Failed Emission, Incidence, Resolution "
325 "and/or Dn Value Test");
326 newMeasure->SetIgnored(
true);
328 piMeasuresModified++;
337 pPvlObj += pvlMeasureGrp;
340 if ((iNumMeasures - iMsrIgnored) < 2) {
343 "but Point EditLock is True");
346 pCPoint.SetIgnored(
true);
372 int iPointsModified = 0;
373 int iMeasuresModified = 0;
382 for (
int point = 0; point < pNewNet.GetNumPoints(); ++point) {
394 int iNumMeasuresLocked = newPnt->GetNumLockedMeasures();
395 int numMeasures = newPnt->GetNumMeasures();
397 bool bRefLocked =
false;
398 int iOrigRefIndex = -1;
400 iOrigRefIndex = newPnt->IndexOfRefMeasure();
401 bRefLocked = newPnt->GetRefMeasure()->IsEditLocked();
408 if (!newPnt->IsIgnored() && newPnt->GetType() ==
ControlPoint::Free && numMeasures > 0 &&
409 (iNumMeasuresLocked == 0 || (iNumMeasuresLocked > 0 && bRefLocked))) {
413 if (newPnt->IsEditLocked() || iNumMeasuresLocked > 0) {
419 if (*newPnt != origPnt) {
428 double dReferenceLat = 0, dReferenceLon = 0;
429 if (iBestMeasureIndex >= 0) {
436 bestCamera = bestCube->camera();
446 bestCamera->SetImage(dBestSample, dBestLine);
447 dReferenceLat = bestCamera->UniversalLatitude();
448 dReferenceLon = bestCamera->UniversalLongitude();
451 newPnt->SetRefMeasure(iBestMeasureIndex);
457 for (
int measure = 0; measure < numMeasures; ++measure) {
464 PvlGroup pvlMeasureGrp(
"MeasureDetails");
467 newMeasure->GetLine()));
470 if (!newMeasure->IsIgnored() && iBestMeasureIndex >= 0 &&
475 newMeasure->SetIgnored(
false);
481 measureCamera = measureCube->camera();
488 if (measureCamera->SetUniversalGround(dReferenceLat, dReferenceLon) &&
489 measureCamera->InCube()) {
491 if (measure == iBestMeasureIndex) {
505 double dSample = measureCamera->Sample();
506 double dLine = measureCamera->Line();
508 double origSample = newMeasure->GetSample();
509 double origLine = newMeasure->GetLine();
515 if (!results.isValid()) {
517 pvlMeasureGrp +=
Isis::PvlKeyword(
"Ignored",
"Failed Validation Test-" + results.toString());
518 newMeasure->SetIgnored(
true);
529 newMeasure->SetIgnored(
true);
530 if (!measureCamera->InCube()) {
531 pvlMeasureGrp +=
Isis::PvlKeyword(
"Comments",
"New location is not in the Image");
539 newMeasure->SetIgnored(
true);
542 if (newMeasure != origPnt[measure]) {
543 iMeasuresModified ++;
551 pvlPointObj += pvlMeasureGrp;
555 if ((numMeasures - iNumIgnore) < 2) {
556 newPnt->SetIgnored(
true);
562 if (*newPnt != origPnt) {
566 if (!newPnt->IsIgnored() && iBestMeasureIndex != iOrigRefIndex) {
568 PvlGroup pvlRefChangeGrp(
"ReferenceChangeDetails");
569 if (iOrigRefIndex >= 0) {
584 if (newPnt->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::Reference) {
585 pvlRefChangeGrp +=
Isis::PvlKeyword(
"AprioriSource",
"Reference is the source and has changed");
588 pvlPointObj += pvlRefChangeGrp;
600 if (numMeasures == 0) {
601 QString sComment =
"Comment";
606 if (newPnt->IsIgnored()) {
607 QString sComment =
"Comment";
613 QString sComment =
"Comment";
618 QString sComment =
"Comment";
623 if (iNumMeasuresLocked > 0 && !bRefLocked) {
624 pvlPointObj +=
Isis::PvlKeyword(
"Error",
"Point has a Measure with EditLock set to true "
625 "but the Reference is not Locked");
628 for (
int measure = 0; measure < newPnt->GetNumMeasures(); measure++) {
631 cm->SetChooserName(
"Application cnetref(Interest)");
659 const geos::geom::MultiPolygon *overlapPoly = NULL;
663 if (overlapPoly == NULL) {
664 QString msg =
"Unable to find overlap polygon for point [" +
665 pCnetPoint.GetId() +
"]";
670 std::vector <PvlGroup> pvlGrpVector;
675 int iBestMeasureIndex = -1;
678 for (
int measure = 0; measure < pCnetPoint.GetNumMeasures(); ++measure) {
684 if (!origMsr->IsIgnored()) {
704 iBestMeasureIndex = measure;
713 return iBestMeasureIndex;
730 QString serialNum = pCnetMeasure.GetCubeSerialNumber();
732 int iOrigSample = (int)(pCnetMeasure.GetSample() + 0.5);
733 int iOrigLine = (int)(pCnetMeasure.GetLine() + 0.5);
740 Chip chip(2 *
p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
741 chip.
TackCube(iOrigSample, iOrigLine);
749 double dSmallestDist = DBL_MAX;
751 int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
752 int iSamples = 2 *
p_deltaSamp + p_samples / 2 + 1;
753 bool bCalculateInterest =
false;
754 for (
int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
755 for (
int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
760 bCalculateInterest =
false;
764 if (results.isValid()) {
765 bCalculateInterest =
true;
768 if (bCalculateInterest) {
769 Chip subChip = chip.
Extract(p_samples + pad, p_lines + pad, samp, lin);
770 double interest =
Interest(subChip);
774 double dist = std::sqrt(std::pow(iOrigSample - samp, 2.0) +
775 std::pow(iOrigLine - lin, 2.0));
776 if (interest == dBestInterest && dist > dSmallestDist) {
780 dBestInterest = interest;
781 dSmallestDist = dist;
804 camera = pCube.camera();
811 if (camera->
SetImage(iOrigSample, iOrigLine)) {
812 Portal inPortal(1, 1, pCube.pixelType());
813 inPortal.SetPosition(iOrigSample, iOrigLine, 1);
814 pCube.read(inPortal);
847 int exactMatchIndex = -1;
849 for (
int overlapIndex = 0; ((exactMatchIndex == -1) && (overlapIndex <
mOverlaps.
Size()));
854 if (overlap->Size() != pCnetPoint.GetNumMeasures())
861 for (
int measureIndex = 0;
862 measureIndex < pCnetPoint.GetNumMeasures();
864 if (measureIndex == numMatches) {
867 if (overlap->HasSerialNumber(serialNum)) {
873 if (numMatches == pCnetPoint.GetNumMeasures()) {
874 exactMatchIndex = overlapIndex;
878 if (exactMatchIndex < 0) {
882 return mOverlaps[exactMatchIndex]->Polygon();
898 geos::geom::Geometry *geomIntersect1, *geomIntersect2;
901 QString sn1 = pCnetPoint[0]->GetCubeSerialNumber();
903 inCube1->
read((
Blob &)measPolygon1);
906 QString sn2 = pCnetPoint[1]->GetCubeSerialNumber();
908 inCube2->
read((
Blob &)measPolygon2);
912 (
const geos::geom::Geometry *)measPolygon2.Polys());
914 for (
int measureIndex = 2; measureIndex < pCnetPoint.GetNumMeasures(); measureIndex ++) {
915 QString sn3 = pCnetPoint[measureIndex]->GetCubeSerialNumber();
917 inCube3->
read((
Blob &)measPolygon3);
921 (
const geos::geom::Geometry *)measPolygon3.Polys());
922 geomIntersect1 = geomIntersect2;
935 return(int1 >= int2);
virtual double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
A small chip of data used for pattern matching.
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Sets the clipping polygon for this chip.
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
double CubeSample() const
Chip Extract(int samples, int lines, int samp, int line)
Extract a sub-chip from a chip.
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
@ Candidate
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Status SetDateTime()
Date Time - Creation Time.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
ControlNetValidMeasure class.
MeasureValidationResults ValidStandardOptions(const ControlMeasure *pMeasure, Cube *pCube, PvlGroup *pMeasureGrp=NULL)
Validate Standard options to pick a reference based on a particular criteria.
CubeManager mCubeMgr
CubeManager to open and read cubes.
PvlGroup mStatisticsGrp
Pvl output Statistics Group.
double mdEmissionAngle
Store current Measure's Emission Angle.
double mdDnValue
Store current Measure's DN Value.
QString LocationString(double pdSample, double pdLine) const
API to display location in the form "Sample,Line".
SerialNumberList mSerialNumbers
Serial numbers list.
Pvl mPvlLog
Pvl Log of all the processing.
Progress mStatus
Monitor the status of the app.
double mdResolution
Store current Measure's Resolution.
void ReadSerialNumbers(QString psSerialNumfile)
Read the Serial Numbers from the file and open assocaited cubes.
double mdIncidenceAngle
Store current Measure's Incidence Angle.
@ Constrained
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
@ Free
A Free point is a Control Point that identifies common measurements between two or more cubes.
@ Fixed
A Fixed point is a Control Point whose lat/lon is well established and should not be changed.
IO Handler for Isis Cubes.
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Cube * OpenCube(const QString &cubeFileName)
This method opens a cube.
@ 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.
Individual overlap container.
void ReadImageOverlaps(const QString &filename)
Create polygons of overlap from the file specified.
int Size()
Returns the total number of latitude and longitude overlaps.
Create cube polygons, read/write polygons to blobs.
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Set the Clip Polygon for points to be contained in the overlaps.
const geos::geom::MultiPolygon * FindOverlap(Isis::ControlPoint &pCnetPoint)
Find if a point is in the overlap.
virtual int Padding()
Sets an offset to pass in larger chips if operator requires it This is used to offset the subchip siz...
InterestOperator(Pvl &pPvl)
Create InterestOperator object.
Isis::ImageOverlapSet mOverlaps
Holds the overlaps from the Overlaplist.
bool InterestByMeasure(int piMeasure, Isis::ControlMeasure &pCnetMeasure, Isis::Cube &pCube)
Calculate interest for a measure by index.
const geos::geom::MultiPolygon * FindOverlapByImageFootPrint(Isis::ControlPoint &pCnetPoint)
Find imageoverlaps by finding the intersection of image footprints.
bool mbOverlaps
If Overlaplist exists.
int p_deltaSamp
Specified in the Pvl Operator group for the box car size.
double p_minimumInterest
Specified in the Pvl Operator group.
void ProcessLocked_Point_Reference(ControlPoint &pCPoint, PvlObject &pPvlObj, int &piMeasuresModified)
Process (Validate and Log) Point with Lock or with Referemce Measure Locked.
double p_cubeLine
Point in a cube from a chip perspective.
bool Operate(Cube &pCube, UniversalGroundMap &pUnivGrndMap, int piSample, int piLine)
Operate used by the app interestcube- to calculate interest by sample,line.
geos::geom::MultiPolygon * p_clipPolygon
Clipping polygon set by SetClipPolygon (line,samp)
void InitInterestResults(int piIndex)
Init Interest Results structure.
void FindCnetRef(ControlNet &pNewNet)
Find best ref for an entire control net by calculating the interest and moving point to a better inte...
double WorstInterest() const
Return the Worst(least value) Interest.
int InterestByPoint(ControlPoint &pCnetPoint)
Calculate interest for a Control Point.
virtual ~InterestOperator()
Destroy InterestOperator object.
void Parse(Pvl &pPvl)
Parse the Interest specific keywords.
virtual double Interest(Chip &subCube)=0
Calculate the interest.
virtual bool CompareInterests(double int1, double int2)
Compare for int1 greater than / equal to int2.
Isis::PvlGroup Operator()
Return the Operator name.
InterestResults * mtInterestResults
Holds the results of an interest computation.
Isis::PvlGroup mOperatorGrp
Operator group that created this projection.
void InitInterestOptions()
Initialise Interest Options to defaults.
MeasureValidationResults class.
Buffer for containing a two dimensional section of an image.
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.
Container for cube-like labels.
A single keyword-value pair.
Contains Pvl Groups and Pvl Objects.
@ Traverse
Search child objects.
virtual double IncidenceAngle() const
Returns the incidence angle in degrees.
virtual double EmissionAngle() const
Returns the emission angle in degrees.
QString fileName(const QString &sn)
Return a filename given a serial number.
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.
const double ValidMinimum
The minimum valid double value for Isis pixels.
Structure to hold Interest Results.
QString msSerialNum
Serial Number of the Measure.
bool mbValid
Value of the interest operator result (success)
double mdOrigLine
Control Measure's original line.
double mdDn
Cube DN value at most interesting sample,line.
double mdEmission
Emission angle at most interesting sample,line.
double mdOrigSample
Control Measure's original sample.
double mdInterest
Resulting interest amt from InterestOperator.
double mdBestSample
Most interesting sample.
double mdBestLine
Most interesting line.
int miDeltaSample
The number of Samples the point has been moved.
int miDeltaLine
The number of Lines the point has been moved.
double mdIncidence
Incidence angle at most interesting sample,line.
double mdResolution
Camera resolution at most interesting sample,line.