Isis 3 Programmer Reference
InterestOperator.cpp
1 #include "Chip.h"
2 #include "Pvl.h"
3 #include "InterestOperator.h"
4 #include "Plugin.h"
5 #include "IException.h"
6 #include "FileName.h"
7 #include "Statistics.h"
8 #include "PolygonTools.h"
9 #include "SpecialPixel.h"
10 #include "ControlNet.h"
11 #include "ControlPoint.h"
12 #include "ControlMeasure.h"
13 #include "ImageOverlapSet.h"
14 #include "ImagePolygon.h"
16 #include "PolygonTools.h"
17 
18 namespace Isis {
19 
30  mOperatorGrp = PvlGroup("InterestOptions");
31  Parse(pPvl);
32  }
33 
40  p_interestAmount = 0.0;
41  p_worstInterest = 0.0;
42  p_lines = 1;
43  p_samples = 1;
44  p_deltaSamp = 0;
45  p_deltaLine = 0;
46  p_clipPolygon = NULL;
47  mbOverlaps = false;
48  }
49 
54  if (p_clipPolygon != NULL) {
55  delete p_clipPolygon;
56  p_clipPolygon = NULL;
57  }
58  }
59 
84  try {
85  // Get info from the operator group
86  // Required Parameters
87  PvlGroup &op = pPvl.findGroup("Operator", Pvl::Traverse);
88 
89  mOperatorGrp += Isis::PvlKeyword(op["Name"]);
90 
91  p_samples = op["Samples"];
92  mOperatorGrp += Isis::PvlKeyword("Samples", toString(p_samples));
93 
94  p_lines = op["Lines"];
95  mOperatorGrp += Isis::PvlKeyword("Lines", toString(p_lines));
96 
97  p_deltaLine = op["DeltaLine"];
98  mOperatorGrp += Isis::PvlKeyword("DeltaLine", toString(p_deltaLine));
99 
100  p_deltaSamp = op["DeltaSamp"];
102 
103  p_minimumInterest = op["MinimumInterest"];
105 
106  }
107  catch (IException &e) {
108  QString msg = "Improper format for InterestOperator PVL [" + pPvl.fileName() + "]";
110  }
111  }
112 
121  mtInterestResults[piIndex].msSerialNum = "";
127  mtInterestResults[piIndex].mdEmission = 135;
128  mtInterestResults[piIndex].mdIncidence = 135;
130  mtInterestResults[piIndex].mdResolution = DBL_MAX ;
131  mtInterestResults[piIndex].miDeltaSample = 0;
132  mtInterestResults[piIndex].miDeltaLine = 0;
133  mtInterestResults[piIndex].mbValid = false;
134  }
135 
156  int piSample, int piLine) {
157 
158  if (!pUnivGrndMap.HasCamera())
159  // Level 3 images/mosaic or bad image
160  {
161  QString msg = "Cannot run interest on images with no camera. Image " +
162  pCube.fileName() + " has no Camera";
164  }
165 
166  int pad = Padding();
167  Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
168  chip.TackCube(piSample, piLine);
169  if (p_clipPolygon != NULL)
171  chip.Load(pCube);
172 
173  // Walk the search chip and find the best interest
174  int iBestSamp = 0;
175  int iBestLine = 0;
176  double dSmallestDist = DBL_MAX;
177  double dBestInterest = Isis::Null;
178  int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
179  int iSamples = 2 * p_deltaSamp + p_samples / 2 + 1;
180  bool bCalculateInterest = false;
181 
182  for (int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
183  for (int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
184  // Cannot take dnValues from the chip as it contains the interpolated dnValue
185  // hence get the dn values directly from the cube
186  chip.SetChipPosition((double)samp, (double)lin);
187 
188  bCalculateInterest = false;
189  MeasureValidationResults results =
190  ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCube);
191  if (results.isValid()) {
192  bCalculateInterest = true;
193  }
194 
195  if (bCalculateInterest) {
196  Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
197  double interest = Interest(subChip);
198  if (interest != Isis::Null) {
199  if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
200  double dist = std::sqrt(std::pow(piSample - samp, 2.0) + std::pow(piLine - lin, 2.0));
201  if (interest == dBestInterest && dist > dSmallestDist) {
202  continue;
203  }
204  else {
205  dBestInterest = interest;
206  iBestSamp = samp;
207  iBestLine = lin;
208  dSmallestDist = dist;
209  }
210  }
211  }
212  }
213  }
214  }
215 
216  // Check to see if we went through the interest chip and never got a interest at
217  // any location.
218  if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
219  if (pUnivGrndMap.SetImage(piSample, piLine)) {
220  p_interestAmount = dBestInterest;
221  }
222  return false;
223  }
224 
225  p_interestAmount = dBestInterest;
226  chip.SetChipPosition(iBestSamp, iBestLine);
227  p_cubeSample = chip.CubeSample();
228  p_cubeLine = chip.CubeLine();
229 
230  return true;
231  }
232 
246  void InterestOperator::Operate(ControlNet &pNewNet, QString psSerialNumFile,
247  QString psOverlapListFile) {
248  ReadSerialNumbers(psSerialNumFile);
249 
250  // Find all the overlaps between the images in the FROMLIST
251  // The overlap polygon coordinates are in Lon/Lat order
252  if (psOverlapListFile != "") {
253  mOverlaps.ReadImageOverlaps(psOverlapListFile);
254  mbOverlaps = true;
255  }
256 
257  // Process the entire control net by calculating interest and moving the
258  // point to a more interesting area
259  FindCnetRef(pNewNet);
260  }
261 
271  ControlPoint &pCPoint, PvlObject &pPvlObj, int &piMeasuresModified) {
272  int iNumMeasures = pCPoint.GetNumMeasures();
273  bool bPntEditLock = pCPoint.IsEditLocked();
274  int iMsrIgnored = 0;
275 
276  // Log Point Details
277  if (bPntEditLock) {
278  pPvlObj += Isis::PvlKeyword("Reference", "No Change, PointEditLock");
279  }
280 
281  for (int measure = 0; measure < iNumMeasures; measure++) {
282  ControlMeasure *newMeasure = new ControlMeasure(*pCPoint[measure]);
283  newMeasure->SetDateTime();
284  newMeasure->SetChooserName("Application cnetref(interest)");
285  bool bMeasureLocked = newMeasure->IsEditLocked();
286 
287  QString sn = newMeasure->GetCubeSerialNumber();
288  //double dSample = newMeasure->GetSample();
289  //double dLine = newMeasure->GetLine();
290 
291  // Log
292  PvlGroup pvlMeasureGrp("MeasureDetails");
293  pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
294  pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation",
295  LocationString(newMeasure->GetSample(), newMeasure->GetLine()));
296 
297  if (bMeasureLocked) {
298  pvlMeasureGrp += Isis::PvlKeyword("EditLock", "True");
299  }
300 
301  if (!newMeasure->IsIgnored()) {
302  Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn));
303 
304  MeasureValidationResults results =
305  ValidStandardOptions(newMeasure, measureCube);
306  if (!results.isValid()) {
307  if (bPntEditLock) {
308  pvlMeasureGrp += Isis::PvlKeyword("UnIgnored", "Failed Validation Test but not "
309  "Ignored as Point EditLock is True");
310  }
311  else if (bMeasureLocked == measure) {
312  pvlMeasureGrp += Isis::PvlKeyword("Error", "Failed the Validation Test "
313  "but is Locked");
314  }
315  else {
316  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Emission, Incidence, Resolution "
317  "and/or Dn Value Test");
318  newMeasure->SetIgnored(true);
319  iMsrIgnored++;
320  piMeasuresModified++;
321  }
322  }
323  }
324  else {
325  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Originally Ignored");
326  iMsrIgnored++;
327  }
328 
329  pPvlObj += pvlMeasureGrp;
330  }
331 
332  if ((iNumMeasures - iMsrIgnored) < 2) {
333  if (bPntEditLock) {
334  pPvlObj += Isis::PvlKeyword("UnIgnored", "Good Measures less than 2 "
335  "but Point EditLock is True");
336  }
337  else {
338  pCPoint.SetIgnored(true);
339  pPvlObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
340  }
341  }
342  }
343 
364  int iPointsModified = 0;
365  int iMeasuresModified = 0;
366  int iRefChanged = 0;
367 
368  // Status Report
369  mStatus.SetText("Choosing Reference by Interest...");
372 
373  // Process each existing control point in the network
374  for (int point = 0; point < pNewNet.GetNumPoints(); ++point) {
375  ControlPoint *newPnt = pNewNet.GetPoint(point);
376 
377  // Create a copy of original control point
378  const ControlPoint origPnt(*newPnt);
379 
380  // Logging
381  PvlObject pvlPointObj("PointDetails");
382  pvlPointObj += Isis::PvlKeyword("PointId", newPnt->GetId());
383 
384  // Get number of measures locked and check if Reference
385  // Measure is locked
386  int iNumMeasuresLocked = newPnt->GetNumLockedMeasures();
387  int numMeasures = newPnt->GetNumMeasures();
388 
389  bool bRefLocked = false;
390  int iOrigRefIndex = -1;
391  try {
392  iOrigRefIndex = newPnt->IndexOfRefMeasure();
393  bRefLocked = newPnt->GetRefMeasure()->IsEditLocked();
394  }
395  catch(IException &) {
396  }
397 
398  // Only perform the interest operation on points of type "Free" and
399  // Points having atleast 1 measure and Point is not Ignored
400  if (!newPnt->IsIgnored() && newPnt->GetType() == ControlPoint::Free && numMeasures > 0 &&
401  (iNumMeasuresLocked == 0 || (iNumMeasuresLocked > 0 && bRefLocked))) {
402 
403  // Check only the validity of the Point / Measures only if Point and/or
404  // Reference Measure is locked.
405  if (newPnt->IsEditLocked() || iNumMeasuresLocked > 0) {
406  ProcessLocked_Point_Reference(*newPnt, pvlPointObj, iMeasuresModified);
407 
408  mPvlLog += pvlPointObj;
410 
411  if (*newPnt != origPnt) {
412  iPointsModified ++;
413  }
414  continue;
415  }
416 
417  int iBestMeasureIndex = InterestByPoint(*newPnt);
418 
419  // Process for point with good interest and a best index
420  double dReferenceLat = 0, dReferenceLon = 0;
421  if (iBestMeasureIndex >= 0) {
422  QString sn = mtInterestResults[iBestMeasureIndex].msSerialNum;
423  Cube *bestCube = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn));
424 
425  // Get the Camera for the reference image and get the lat/lon from that measurment
426  Camera *bestCamera;
427  try {
428  bestCamera = bestCube->camera();
429  }
430  catch (IException &e) {
431  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(sn);
433  }
434 
435  double dBestSample = mtInterestResults[iBestMeasureIndex].mdBestSample;
436  double dBestLine = mtInterestResults[iBestMeasureIndex].mdBestLine;
437 
438  bestCamera->SetImage(dBestSample, dBestLine);
439  dReferenceLat = bestCamera->UniversalLatitude();
440  dReferenceLon = bestCamera->UniversalLongitude();
441 
442  // Set the point reference
443  newPnt->SetRefMeasure(iBestMeasureIndex);
444  }
445 
446  // Create a measurment for each image in this point using
447  // the reference lat/lon.
448  int iNumIgnore = 0;
449  for (int measure = 0; measure < numMeasures; ++measure) {
450  ControlMeasure *newMeasure = newPnt->GetMeasure(measure);
451  newMeasure->SetDateTime();
452  newMeasure->SetChooserName("Application cnetref(interest)");
453  QString sn = newMeasure->GetCubeSerialNumber();
454 
455  // Log
456  PvlGroup pvlMeasureGrp("MeasureDetails");
457  pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
458  pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation", LocationString(newMeasure->GetSample(),
459  newMeasure->GetLine()));
460 
461  // Initialize the UGM of this cube with the reference lat/lon
462  if (!newMeasure->IsIgnored() && iBestMeasureIndex >= 0 &&
463  mtInterestResults[iBestMeasureIndex].mdInterest != WorstInterest()) {
464  Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn));
465 
466  // default setting
467  newMeasure->SetIgnored(false);
468  newMeasure->SetType(ControlMeasure::Candidate);
469 
470  // Get the Camera
471  Camera *measureCamera;
472  try {
473  measureCamera = measureCube->camera();
474  }
475  catch (IException &e) {
476  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(sn);
477  throw IException(e, IException::User, msg, _FILEINFO_);
478  }
479 
480  if (measureCamera->SetUniversalGround(dReferenceLat, dReferenceLon) &&
481  measureCamera->InCube()) {
482  // Check for reference, Put the corresponding line/samp into a newMeasure
483  if (measure == iBestMeasureIndex) {
484  newMeasure->SetCoordinate(mtInterestResults[measure].mdBestSample,
485  mtInterestResults[measure].mdBestLine, ControlMeasure::Candidate);
486  // newMeasure->SetType(ControlMeasure::Reference);
487 
488 
489 
490  pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[measure].mdBestSample,
491  mtInterestResults[measure].mdBestLine));
492  pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString(mtInterestResults[measure].miDeltaSample));
493  pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString(mtInterestResults[measure].miDeltaLine));
494  pvlMeasureGrp += Isis::PvlKeyword("Reference", "true");
495  }
496  else {
497  double dSample = measureCamera->Sample();
498  double dLine = measureCamera->Line();
499 
500  double origSample = newMeasure->GetSample();
501  double origLine = newMeasure->GetLine();
502 
503  newMeasure->SetCoordinate(dSample, dLine);
504 
505  MeasureValidationResults results =
506  ValidStandardOptions(newMeasure, measureCube);
507  if (!results.isValid()) {
508  iNumIgnore++;
509  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Validation Test-" + results.toString());
510  newMeasure->SetIgnored(true);
511  }
512  pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(dSample, dLine));
513  pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString((int)abs((int)dSample - (int)origSample)));
514  pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString((int)abs((int)dLine - (int)origLine)));
515  pvlMeasureGrp += Isis::PvlKeyword("Reference", "false");
516  }
517  }
518  else {
519  iNumIgnore++;
520  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
521  newMeasure->SetIgnored(true);
522  if (!measureCamera->InCube()) {
523  pvlMeasureGrp += Isis::PvlKeyword("Comments", "New location is not in the Image");
524  }
525  }
526  }
527  // No best interest, ignore the measure
528  else {
529  iNumIgnore++;
530  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
531  newMeasure->SetIgnored(true);
532  }
533 
534  if (newMeasure != origPnt[measure]) {
535  iMeasuresModified ++;
536  }
537 
538  pvlMeasureGrp += Isis::PvlKeyword("BestInterest", toString(mtInterestResults[measure].mdInterest));
539  pvlMeasureGrp += Isis::PvlKeyword("EmissionAngle", toString(mtInterestResults[measure].mdEmission));
540  pvlMeasureGrp += Isis::PvlKeyword("IncidenceAngle", toString(mtInterestResults[measure].mdIncidence));
541  pvlMeasureGrp += Isis::PvlKeyword("Resolution", toString(mtInterestResults[measure].mdResolution));
542  pvlMeasureGrp += Isis::PvlKeyword("DNValue", toString(mtInterestResults[measure].mdDn));
543  pvlPointObj += pvlMeasureGrp;
544  } // Measures Loop
545 
546  // Check the ignored measures number
547  if ((numMeasures - iNumIgnore) < 2) {
548  newPnt->SetIgnored(true);
549  pvlPointObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
550  }
551 
552  iNumIgnore = 0;
553 
554  if (*newPnt != origPnt) {
555  iPointsModified ++;
556  }
557 
558  if (!newPnt->IsIgnored() && iBestMeasureIndex != iOrigRefIndex) {
559  iRefChanged ++;
560  PvlGroup pvlRefChangeGrp("ReferenceChangeDetails");
561  if (iOrigRefIndex >= 0) {
562  pvlRefChangeGrp += Isis::PvlKeyword("PrevSerialNumber", mtInterestResults[iOrigRefIndex].msSerialNum);
563  pvlRefChangeGrp += Isis::PvlKeyword("PrevBestInterest", toString(mtInterestResults[iOrigRefIndex].mdInterest));
564  pvlRefChangeGrp += Isis::PvlKeyword("PrevLocation", LocationString(mtInterestResults[iOrigRefIndex].mdOrigSample,
565  mtInterestResults[iOrigRefIndex].mdOrigLine));
566  }
567  else {
568  pvlRefChangeGrp += Isis::PvlKeyword("PrevReference", "Not Set");
569  }
570  pvlRefChangeGrp += Isis::PvlKeyword("NewSerialNumber", mtInterestResults[iBestMeasureIndex].msSerialNum);
571  pvlRefChangeGrp += Isis::PvlKeyword("NewBestInterest", toString(mtInterestResults[iBestMeasureIndex].mdInterest));
572  pvlRefChangeGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[iBestMeasureIndex].mdBestSample,
573  mtInterestResults[iBestMeasureIndex].mdBestLine));
574 
575  // Log info, if Point not locked, apriori source == Reference and a new reference
576  if (newPnt->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::Reference) {
577  pvlRefChangeGrp += Isis::PvlKeyword("AprioriSource", "Reference is the source and has changed");
578  }
579 
580  pvlPointObj += pvlRefChangeGrp;
581  }
582  else {
583  pvlPointObj += Isis::PvlKeyword("Reference", "No Change");
584  }
585  // Clean up the results structure
586  delete [] mtInterestResults;
587  }
588  else {
589  // Process Ignored, non Free points or Measures=0
590  int iComment = 0;
591 
592  if (numMeasures == 0) {
593  QString sComment = "Comment";
594  sComment += toString(++iComment);
595  pvlPointObj += Isis::PvlKeyword(sComment, "No Measures in the Point");
596  }
597 
598  if (newPnt->IsIgnored()) {
599  QString sComment = "Comment";
600  sComment += toString(++iComment);
601  pvlPointObj += Isis::PvlKeyword(sComment, "Point was originally Ignored");
602  }
603 
604  if (newPnt->GetType() == ControlPoint::Fixed) {
605  QString sComment = "Comment";
606  sComment += toString(++iComment);
607  pvlPointObj += Isis::PvlKeyword(sComment, "Fixed Point");
608  }
609  else if (newPnt->GetType() == ControlPoint::Constrained) {
610  QString sComment = "Comment";
611  sComment += toString(++iComment);
612  pvlPointObj += Isis::PvlKeyword(sComment, "Constrained Point");
613  }
614 
615  if (iNumMeasuresLocked > 0 && !bRefLocked) {
616  pvlPointObj += Isis::PvlKeyword("Error", "Point has a Measure with EditLock set to true "
617  "but the Reference is not Locked");
618  }
619  else {
620  for (int measure = 0; measure < newPnt->GetNumMeasures(); measure++) {
621  ControlMeasure *cm = newPnt->GetMeasure(measure);
622  cm->SetDateTime();
623  cm->SetChooserName("Application cnetref(Interest)");
624  }
625  }
626  } // End of if point is of type free
627 
628  mPvlLog += pvlPointObj;
629 
631  } // Point loop
632 
633  // CnetRef Change Statistics
634  mStatisticsGrp += Isis::PvlKeyword("PointsModified", toString(iPointsModified));
635  mStatisticsGrp += Isis::PvlKeyword("ReferenceChanged", toString(iRefChanged));
636  mStatisticsGrp += Isis::PvlKeyword("MeasuresModified", toString(iMeasuresModified));
637 
639  }
640 
650  // Find the overlap this point is inside of if the overlap list is entered
651  const geos::geom::MultiPolygon *overlapPoly = NULL;
652 
653  if (mbOverlaps) {
654  overlapPoly = FindOverlap(pCnetPoint);
655  if (overlapPoly == NULL) {
656  QString msg = "Unable to find overlap polygon for point [" +
657  pCnetPoint.GetId() + "]";
659  }
660  }
661 
662  std::vector <PvlGroup> pvlGrpVector;
663 
664  // Create an array of Interest Results structure of measures size
665  mtInterestResults = new InterestResults[pCnetPoint.GetNumMeasures()];
666 
667  int iBestMeasureIndex = -1;
668  double dBestInterestValue = Isis::Null;
669 
670  for (int measure = 0; measure < pCnetPoint.GetNumMeasures(); ++measure) {
671  ControlMeasure *origMsr = pCnetPoint[measure];
672  QString sn = origMsr->GetCubeSerialNumber();
673 
674  // Do not process Ignored Measures
675  try {
676  if (!origMsr->IsIgnored()) {
677  InitInterestResults(measure);
679 
680  // Set the clipping polygon for this point
681  // Convert the lon/lat overlap polygon to samp/line using the UGM for
682  // this image
683  if (mbOverlaps) {
684  UniversalGroundMap unvGround = UniversalGroundMap(*inCube);
685  geos::geom::MultiPolygon *poly = PolygonTools::LatLonToSampleLine(*overlapPoly,
686  &unvGround);
687  SetClipPolygon(*poly);
688  delete poly;
689  }
690 
691  // Run the interest operator on this measurment
692  if (InterestByMeasure(measure, *origMsr, *inCube)) {
693  if (dBestInterestValue == Isis::Null ||
694  CompareInterests(mtInterestResults[measure].mdInterest, dBestInterestValue)) {
695  dBestInterestValue = mtInterestResults[measure].mdInterest;
696  iBestMeasureIndex = measure;
697  }
698  }
699  }
700  }
701  catch (IException &e) {
702  // e.print();
703  }
704  }
705  return iBestMeasureIndex;
706  }
707 
720  bool InterestOperator::InterestByMeasure(int piMeasure, ControlMeasure &pCnetMeasure,
721  Cube &pCube) {
722  QString serialNum = pCnetMeasure.GetCubeSerialNumber();
723 
724  int iOrigSample = (int)(pCnetMeasure.GetSample() + 0.5);
725  int iOrigLine = (int)(pCnetMeasure.GetLine() + 0.5);
726 
727  mtInterestResults[piMeasure].msSerialNum = serialNum;
728  mtInterestResults[piMeasure].mdOrigSample = pCnetMeasure.GetSample();
729  mtInterestResults[piMeasure].mdOrigLine = pCnetMeasure.GetLine();
730 
731  int pad = Padding();
732  Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
733  chip.TackCube(iOrigSample, iOrigLine);
734  if (p_clipPolygon != NULL)
736  chip.Load(pCube);
737 
738  // Walk the search chip and find the best interest
739  int iBestSamp = 0;
740  int iBestLine = 0;
741  double dSmallestDist = DBL_MAX;
742  double dBestInterest = Isis::Null;
743  int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
744  int iSamples = 2 * p_deltaSamp + p_samples / 2 + 1;
745  bool bCalculateInterest = false;
746  for (int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
747  for (int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
748  // Cannot take dnValues from the chip as it contains the interpolated dnValue
749  // hence get the dn values directly from the cube
750  chip.SetChipPosition((double)samp, (double)lin);
751 
752  bCalculateInterest = false;
753 
754  MeasureValidationResults results =
755  ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCnetMeasure, &pCube);
756  if (results.isValid()) {
757  bCalculateInterest = true;
758  }
759 
760  if (bCalculateInterest) {
761  Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
762  double interest = Interest(subChip);
763 
764  if (interest != Isis::Null) {
765  if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
766  double dist = std::sqrt(std::pow(iOrigSample - samp, 2.0) +
767  std::pow(iOrigLine - lin, 2.0));
768  if (interest == dBestInterest && dist > dSmallestDist) {
769  continue;
770  }
771  else {
772  dBestInterest = interest;
773  dSmallestDist = dist;
774  iBestSamp = samp;
775  iBestLine = lin;
776 
779  mtInterestResults[piMeasure].mdDn = mdDnValue;
781  mtInterestResults[piMeasure].mbValid = true;
782  }
783  }
784  }
785  }
786  }
787  }
788 
789  // Check to see if we went through the interest chip and never got a interest at
790  // any location.But record the Emission, Incidence Angles and DN Value for the failed
791  // Measure at the original location
792  if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
793  // Get the Camera
794  Camera *camera;
795  try {
796  camera = pCube.camera();
797  }
798  catch (IException &e) {
799  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(serialNum);
801  }
802 
803  if (camera->SetImage(iOrigSample, iOrigLine)) {
804  Portal inPortal(1, 1, pCube.pixelType());
805  inPortal.SetPosition(iOrigSample, iOrigLine, 1);
806  pCube.read(inPortal);
807 
808  mtInterestResults[piMeasure].mdInterest = dBestInterest;
811  mtInterestResults[piMeasure].mdOrigSample = iOrigSample;
812  mtInterestResults[piMeasure].mdOrigLine = iOrigLine;
813  mtInterestResults[piMeasure].mdEmission = camera->EmissionAngle();
814  mtInterestResults[piMeasure].mdIncidence = camera->IncidenceAngle();
815  mtInterestResults[piMeasure].mdDn = inPortal[0];
816  mtInterestResults[piMeasure].mdResolution = camera->PixelResolution();
817  mtInterestResults[piMeasure].mbValid = false;
818  }
819  return false;
820  }
821 
822  chip.SetChipPosition(iBestSamp, iBestLine);
823  mtInterestResults[piMeasure].mdInterest = dBestInterest;
824  mtInterestResults[piMeasure].mdBestSample = chip.CubeSample();
825  mtInterestResults[piMeasure].mdBestLine = chip.CubeLine();
826  mtInterestResults[piMeasure].miDeltaSample = qAbs(mtInterestResults[piMeasure].mdBestSample -
827  iOrigSample);
828  mtInterestResults[piMeasure].miDeltaLine = qAbs(mtInterestResults[piMeasure].mdBestLine -
829  iOrigLine);
830  return true;
831  }
832 
838  const geos::geom::MultiPolygon *InterestOperator::FindOverlap(ControlPoint &pCnetPoint) {
839  int exactMatchIndex = -1;
840 
841  for (int overlapIndex = 0; ((exactMatchIndex == -1) && (overlapIndex < mOverlaps.Size()));
842  overlapIndex ++) {
843  const Isis::ImageOverlap *overlap = mOverlaps[overlapIndex];
844 
845  // Exact matches only; skip if # SNs don't match
846  if (overlap->Size() != pCnetPoint.GetNumMeasures())
847  continue;
848 
849  // If # SNs match and each SN is contained in both then we're good, there
850  // should never be two measures with the same SN
851  int numMatches = 0;
852 
853  for (int measureIndex = 0;
854  measureIndex < pCnetPoint.GetNumMeasures();
855  measureIndex ++) {
856  if (measureIndex == numMatches) {
857  const ControlMeasure &controlMeasure = *pCnetPoint[measureIndex];
858  QString serialNum = controlMeasure.GetCubeSerialNumber();
859  if (overlap->HasSerialNumber(serialNum)) {
860  numMatches++;
861  }
862  }
863  }
864 
865  if (numMatches == pCnetPoint.GetNumMeasures()) {
866  exactMatchIndex = overlapIndex;
867  }
868  }
869 
870  if (exactMatchIndex < 0) {
871  return (FindOverlapByImageFootPrint(pCnetPoint));
872  }
873 
874  return mOverlaps[exactMatchIndex]->Polygon();
875  }
876 
887  const geos::geom::MultiPolygon *InterestOperator::FindOverlapByImageFootPrint
888  (Isis::ControlPoint &pCnetPoint) {
889  ImagePolygon measPolygon1, measPolygon2, measPolygon3;
890  geos::geom::Geometry *geomIntersect1, *geomIntersect2;
891 
892  // Create Multipolygon for the first Control Measure
893  QString sn1 = pCnetPoint[0]->GetCubeSerialNumber();
894  Cube *inCube1 = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn1));
895  inCube1->read((Blob &)measPolygon1);
896 
897  // Create Multipolygon for the Second Control Measure
898  QString sn2 = pCnetPoint[1]->GetCubeSerialNumber();
899  Cube *inCube2 = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn2));
900  inCube2->read((Blob &)measPolygon2);
901 
902  // Get the interesection for the first 2 polgons
903  geomIntersect1 = PolygonTools::Intersect((const geos::geom::Geometry *)measPolygon1.Polys(),
904  (const geos::geom::Geometry *)measPolygon2.Polys());
905 
906  for (int measureIndex = 2; measureIndex < pCnetPoint.GetNumMeasures(); measureIndex ++) {
907  QString sn3 = pCnetPoint[measureIndex]->GetCubeSerialNumber();
908  Cube *inCube3 = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn3));
909  inCube3->read((Blob &)measPolygon3);
910 
911  // Get the intersection of the intersection and the measure Image Polygon
912  geomIntersect2 = PolygonTools::Intersect(geomIntersect1,
913  (const geos::geom::Geometry *)measPolygon3.Polys());
914  geomIntersect1 = geomIntersect2;
915  }
916  return PolygonTools::MakeMultiPolygon(geomIntersect1);
917  }
918 
926  bool InterestOperator::CompareInterests(double int1, double int2) {
927  return(int1 >= int2);
928  }
929 
930 
931  // add this object's group to the pvl
932  void InterestOperator::addGroup(Isis::PvlObject &obj) {
933  Isis::PvlGroup group;
934  obj.addGroup(group);
935  }
936 
937 
944  void InterestOperator::SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon) {
945  if (p_clipPolygon != NULL)
946  delete p_clipPolygon;
948  }
949 
957  return 0;
958  }
959 
968  return mOperatorGrp;
969  }
970 }
Status SetType(MeasureType type)
Set how the coordinate was obtained.
InterestOperator(Pvl &pPvl)
Create InterestOperator object.
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
Definition: Chip.cpp:665
const geos::geom::MultiPolygon * FindOverlapByImageFootPrint(Isis::ControlPoint &pCnetPoint)
Find imageoverlaps by finding the intersection of image footprints.
void Parse(Pvl &pPvl)
Parse the Interest specific keywords.
int p_deltaSamp
Specified in the Pvl Operator group for the box car size.
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
static geos::geom::MultiPolygon * CopyMultiPolygon(const geos::geom::MultiPolygon *mpolygon)
This static method will create a deep copy of a geos::geom::MultiPolygon.
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:101
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
Definition: ControlPoint.h:391
static geos::geom::MultiPolygon * LatLonToSampleLine(const geos::geom::MultiPolygon &lonLatPoly, UniversalGroundMap *ugm)
This method will return a geos::geom::MultiPolygon which contains the sample/line coordinates of the ...
const double ValidMinimum
The minimum valid double value for Isis pixels.
Definition: SpecialPixel.h:102
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
Definition: ControlPoint.h:386
Universal Ground Map.
geos::geom::MultiPolygon * p_clipPolygon
Clipping polygon set by SetClipPolygon (line,samp)
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:225
void ReadImageOverlaps(const QString &filename)
Create polygons of overlap from the file specified.
Camera * camera()
Return a camera associated with the cube.
Definition: Cube.cpp:1166
bool InterestByMeasure(int piMeasure, Isis::ControlMeasure &pCnetMeasure, Isis::Cube &pCube)
Calculate interest for a measure by index.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube&#39;s serial number.
A small chip of data used for pattern matching.
Definition: Chip.h:102
Buffer for containing a two dimensional section of an image.
Definition: Portal.h:52
Status SetIgnored(bool newIgnoreStatus)
Set whether to ignore or use control point.
Structure to hold Interest Results.
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:198
bool InCube()
This returns true if the current Sample() or Line() value is outside of the cube (meaning the point m...
Definition: Camera.cpp:2631
bool mbOverlaps
If Overlaplist exists.
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition: Chip.cpp:204
bool HasSerialNumber(QString &sn) const
This method will return true if input serial number exists in the ImageOverlap.
double mdEmissionAngle
Store current Measure&#39;s Emission Angle.
Progress mStatus
Monitor the status of the app.
int InterestByPoint(ControlPoint &pCnetPoint)
Calculate interest for a Control Point.
Search child objects.
Definition: PvlObject.h:170
int Size()
Returns the total number of latitude and longitude overlaps.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
Isis::PvlGroup mOperatorGrp
Operator group that created this projection.
SerialNumberList mSerialNumbers
Serial numbers list.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
int miDeltaSample
The number of Samples the point has been moved.
CubeManager mCubeMgr
CubeManager to open and read cubes.
Chip Extract(int samples, int lines, int samp, int line)
Extract a sub-chip from a chip.
Definition: Chip.cpp:749
Create cube polygons, read/write polygons to blobs.
Definition: ImagePolygon.h:167
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:121
static geos::geom::Geometry * Intersect(const geos::geom::Geometry *geom1, const geos::geom::Geometry *geom2)
This applies the geos Intersect operator.
A Free point is a Control Point that identifies common measurements between two or more cubes...
Definition: ControlPoint.h:399
PvlGroup mStatisticsGrp
Pvl output Statistics Group.
QString fileName(const QString &sn)
Return a filename given a serial number.
virtual ~InterestOperator()
Destroy InterestOperator object.
QString msSerialNum
Serial Number of the Measure.
bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:396
double mdResolution
Camera resolution at most interesting sample,line.
bool mbValid
Value of the interest operator result (success)
double EmissionAngle() const
Returns the emission angle in degrees.
Definition: Sensor.cpp:339
bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:170
int GetNumPoints() const
Return the number of control points in the network.
double mdIncidence
Incidence angle at most interesting sample,line.
const geos::geom::MultiPolygon * FindOverlap(Isis::ControlPoint &pCnetPoint)
Find if a point is in the overlap.
double mdBestLine
Most interesting line.
double mdInterest
Resulting interest amt from InterestOperator.
double mdDn
Cube DN value at most interesting sample,line.
Isis::ImageOverlapSet mOverlaps
Holds the overlaps from the Overlaplist.
int miDeltaLine
The number of Lines the point has been moved.
a control network
Definition: ControlNet.h:271
int GetNumLockedMeasures() const
Returns the number of locked control measures.
QString GetId() const
Return the Id of the control point.
double mdIncidenceAngle
Store current Measure&#39;s Incidence Angle.
void FindCnetRef(ControlNet &pNewNet)
Find best ref for an entire control net by calculating the interest and moving point to a better inte...
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition: Progress.cpp:77
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
Status SetRefMeasure(ControlMeasure *cm)
Set the point&#39;s reference measure.
Isis::PvlGroup Operator()
Return the Operator name.
double CubeLine() const
Definition: Chip.h:226
double Sample()
Returns the current sample number.
Definition: Camera.cpp:2702
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
A single keyword-value pair.
Definition: PvlKeyword.h:98
double CubeSample() const
Definition: Chip.h:219
virtual int Padding()
Sets an offset to pass in larger chips if operator requires it This is used to offset the subchip siz...
InterestResults * mtInterestResults
Holds the results of an interest computation.
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:724
A single control point.
Definition: ControlPoint.h:369
void InitInterestResults(int piIndex)
Init Interest Results structure.
void ReadSerialNumbers(QString psSerialNumfile)
Read the Serial Numbers from the file and open assocaited cubes.
Container for cube-like labels.
Definition: Pvl.h:135
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:248
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Definition: Chip.cpp:225
PixelType pixelType() const
Definition: Cube.cpp:1403
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Definition: Portal.h:109
QString LocationString(double pdSample, double pdLine) const
API to display location in the form "Sample,Line".
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Sets the clipping polygon for this chip.
Definition: Chip.cpp:1030
void InitInterestOptions()
Initialise Interest Options to defaults.
virtual double Interest(Chip &subCube)=0
Calculate the interest.
double mdDnValue
Store current Measure&#39;s DN Value.
const ControlMeasure * GetRefMeasure() const
Get the reference control measure.
Pvl mPvlLog
Pvl Log of all the processing.
double WorstInterest() const
Return the Worst(least value) Interest.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
double p_cubeLine
Point in a cube from a chip perspective.
MeasureValidationResults class.
int IndexOfRefMeasure() const
MeasureValidationResults ValidStandardOptions(const ControlMeasure *pMeasure, Cube *pCube, PvlGroup *pMeasureGrp=NULL)
Validate Standard options to pick a reference based on a particular criteria.
bool HasCamera()
Returns whether the ground map has a camera or not.
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
double Line()
Returns the current line number.
Definition: Camera.cpp:2722
QString fileName() const
Returns the filename used to initialise the Pvl object.
Definition: PvlContainer.h:246
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Set the Clip Polygon for points to be contained in the overlaps.
double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:689
Isis exception class.
Definition: IException.h:107
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
double p_minimumInterest
Specified in the Pvl Operator group.
a control measurement
double mdOrigLine
Control Measure&#39;s original line.
double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition: Sensor.cpp:350
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
double mdEmission
Emission angle at most interesting sample,line.
Status SetDateTime()
Date Time - Creation Time.
double mdBestSample
Most interesting sample.
Individual overlap container.
Definition: ImageOverlap.h:56
void ProcessLocked_Point_Reference(ControlPoint &pCPoint, PvlObject &pPvlObj, int &piMeasuresModified)
Process (Validate and Log) Point with Lock or with Referemce Measure Locked.
PointType GetType() const
bool Operate(Cube &pCube, UniversalGroundMap &pUnivGrndMap, int piSample, int piLine)
Operate used by the app interestcube- to calculate interest by sample,line.
double mdResolution
Store current Measure&#39;s Resolution.
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
Cube * OpenCube(const QString &cubeFileName)
This method opens a cube.
Definition: CubeManager.cpp:89
double mdOrigSample
Control Measure&#39;s original sample.
ControlNetValidMeasure class.
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
virtual bool CompareInterests(double int1, double int2)
Compare for int1 greater than / equal to int2.
IO Handler for Isis Cubes.
Definition: Cube.h:170