USGS

Isis 3.0 Object Programmers' Reference

Home

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 
153  int piSample, int piLine) {
154 
155  if (!pUnivGrndMap.HasCamera())
156  // Level 3 images/mosaic or bad image
157  {
158  QString msg = "Cannot run interest on images with no camera. Image " +
159  pCube.fileName() + " has no Camera";
161  }
162 
163  int pad = Padding();
164  Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
165  chip.TackCube(piSample, piLine);
166  if (p_clipPolygon != NULL)
168  chip.Load(pCube);
169 
170  // Walk the search chip and find the best interest
171  int iBestSamp = 0;
172  int iBestLine = 0;
173  double dSmallestDist = DBL_MAX;
174  double dBestInterest = Isis::Null;
175  int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
176  int iSamples = 2 * p_deltaSamp + p_samples / 2 + 1;
177  bool bCalculateInterest = false;
178 
179  for (int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
180  for (int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
181  // Cannot take dnValues from the chip as it contains the interpolated dnValue
182  // hence get the dn values directly from the cube
183  chip.SetChipPosition((double)samp, (double)lin);
184 
185  bCalculateInterest = false;
186  MeasureValidationResults results =
187  ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCube);
188  if (results.isValid()) {
189  bCalculateInterest = true;
190  }
191 
192  if (bCalculateInterest) {
193  Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
194  double interest = Interest(subChip);
195  if (interest != Isis::Null) {
196  if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
197  double dist = std::sqrt(std::pow(piSample - samp, 2.0) + std::pow(piLine - lin, 2.0));
198  if (interest == dBestInterest && dist > dSmallestDist) {
199  continue;
200  }
201  else {
202  dBestInterest = interest;
203  iBestSamp = samp;
204  iBestLine = lin;
205  dSmallestDist = dist;
206  }
207  }
208  }
209  }
210  }
211  }
212 
213  // Check to see if we went through the interest chip and never got a interest at
214  // any location.
215  if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
216  if (pUnivGrndMap.SetImage(piSample, piLine)) {
217  p_interestAmount = dBestInterest;
218  }
219  return false;
220  }
221 
222  p_interestAmount = dBestInterest;
223  chip.SetChipPosition(iBestSamp, iBestLine);
224  p_cubeSample = chip.CubeSample();
225  p_cubeLine = chip.CubeLine();
226 
227  return true;
228  }
229 
243  void InterestOperator::Operate(ControlNet &pNewNet, QString psSerialNumFile,
244  QString psOverlapListFile) {
245  ReadSerialNumbers(psSerialNumFile);
246 
247  // Find all the overlaps between the images in the FROMLIST
248  // The overlap polygon coordinates are in Lon/Lat order
249  if (psOverlapListFile != "") {
250  mOverlaps.ReadImageOverlaps(psOverlapListFile);
251  mbOverlaps = true;
252  }
253 
254  // Process the entire control net by calculating interest and moving the
255  // point to a more interesting area
256  FindCnetRef(pNewNet);
257  }
258 
268  ControlPoint &pCPoint, PvlObject &pPvlObj, int &piMeasuresModified) {
269  int iNumMeasures = pCPoint.GetNumMeasures();
270  bool bPntEditLock = pCPoint.IsEditLocked();
271  int iMsrIgnored = 0;
272 
273  // Log Point Details
274  if (bPntEditLock) {
275  pPvlObj += Isis::PvlKeyword("Reference", "No Change, PointEditLock");
276  }
277 
278  for (int measure = 0; measure < iNumMeasures; measure++) {
279  ControlMeasure *newMeasure = new ControlMeasure(*pCPoint[measure]);
280  newMeasure->SetDateTime();
281  newMeasure->SetChooserName("Application cnetref(interest)");
282  bool bMeasureLocked = newMeasure->IsEditLocked();
283 
284  QString sn = newMeasure->GetCubeSerialNumber();
285  //double dSample = newMeasure->GetSample();
286  //double dLine = newMeasure->GetLine();
287 
288  // Log
289  PvlGroup pvlMeasureGrp("MeasureDetails");
290  pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
291  pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation",
292  LocationString(newMeasure->GetSample(), newMeasure->GetLine()));
293 
294  if (bMeasureLocked) {
295  pvlMeasureGrp += Isis::PvlKeyword("EditLock", "True");
296  }
297 
298  if (!newMeasure->IsIgnored()) {
299  Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn));
300 
301  MeasureValidationResults results =
302  ValidStandardOptions(newMeasure, measureCube);
303  if (!results.isValid()) {
304  if (bPntEditLock) {
305  pvlMeasureGrp += Isis::PvlKeyword("UnIgnored", "Failed Validation Test but not "
306  "Ignored as Point EditLock is True");
307  }
308  else if (bMeasureLocked == measure) {
309  pvlMeasureGrp += Isis::PvlKeyword("Error", "Failed the Validation Test "
310  "but is Locked");
311  }
312  else {
313  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Emission, Incidence, Resolution "
314  "and/or Dn Value Test");
315  newMeasure->SetIgnored(true);
316  iMsrIgnored++;
317  piMeasuresModified++;
318  }
319  }
320  }
321  else {
322  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Originally Ignored");
323  iMsrIgnored++;
324  }
325 
326  pPvlObj += pvlMeasureGrp;
327  }
328 
329  if ((iNumMeasures - iMsrIgnored) < 2) {
330  if (bPntEditLock) {
331  pPvlObj += Isis::PvlKeyword("UnIgnored", "Good Measures less than 2 "
332  "but Point EditLock is True");
333  }
334  else {
335  pCPoint.SetIgnored(true);
336  pPvlObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
337  }
338  }
339  }
340 
361  int iPointsModified = 0;
362  int iMeasuresModified = 0;
363  int iRefChanged = 0;
364 
365  // Status Report
366  mStatus.SetText("Choosing Reference by Interest...");
369 
370  // Process each existing control point in the network
371  for (int point = 0; point < pNewNet.GetNumPoints(); ++point) {
372  ControlPoint *newPnt = pNewNet.GetPoint(point);
373 
374  // Create a copy of original control point
375  const ControlPoint origPnt(*newPnt);
376 
377  // Logging
378  PvlObject pvlPointObj("PointDetails");
379  pvlPointObj += Isis::PvlKeyword("PointId", newPnt->GetId());
380 
381  // Get number of measures locked and check if Reference
382  // Measure is locked
383  int iNumMeasuresLocked = newPnt->GetNumLockedMeasures();
384  int numMeasures = newPnt->GetNumMeasures();
385 
386  bool bRefLocked = false;
387  int iOrigRefIndex = -1;
388  try {
389  iOrigRefIndex = newPnt->IndexOfRefMeasure();
390  bRefLocked = newPnt->GetRefMeasure()->IsEditLocked();
391  }
392  catch(IException &) {
393  }
394 
395  // Only perform the interest operation on points of type "Free" and
396  // Points having atleast 1 measure and Point is not Ignored
397  if (!newPnt->IsIgnored() && newPnt->GetType() == ControlPoint::Free && numMeasures > 0 &&
398  (iNumMeasuresLocked == 0 || (iNumMeasuresLocked > 0 && bRefLocked))) {
399 
400  // Check only the validity of the Point / Measures only if Point and/or
401  // Reference Measure is locked.
402  if (newPnt->IsEditLocked() || iNumMeasuresLocked > 0) {
403  ProcessLocked_Point_Reference(*newPnt, pvlPointObj, iMeasuresModified);
404 
405  mPvlLog += pvlPointObj;
407 
408  if (*newPnt != origPnt) {
409  iPointsModified ++;
410  }
411  continue;
412  }
413 
414  int iBestMeasureIndex = InterestByPoint(*newPnt);
415 
416  // Process for point with good interest and a best index
417  double dReferenceLat = 0, dReferenceLon = 0;
418  if (iBestMeasureIndex >= 0) {
419  QString sn = mtInterestResults[iBestMeasureIndex].msSerialNum;
420  Cube *bestCube = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn));
421 
422  // Get the Camera for the reference image and get the lat/lon from that measurment
423  Camera *bestCamera;
424  try {
425  bestCamera = bestCube->camera();
426  }
427  catch (IException &e) {
428  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.FileName(sn);
430  }
431 
432  double dBestSample = mtInterestResults[iBestMeasureIndex].mdBestSample;
433  double dBestLine = mtInterestResults[iBestMeasureIndex].mdBestLine;
434 
435  bestCamera->SetImage(dBestSample, dBestLine);
436  dReferenceLat = bestCamera->UniversalLatitude();
437  dReferenceLon = bestCamera->UniversalLongitude();
438 
439  // Set the point reference
440  newPnt->SetRefMeasure(iBestMeasureIndex);
441  }
442 
443  // Create a measurment for each image in this point using
444  // the reference lat/lon.
445  int iNumIgnore = 0;
446  for (int measure = 0; measure < numMeasures; ++measure) {
447  ControlMeasure *newMeasure = newPnt->GetMeasure(measure);
448  newMeasure->SetDateTime();
449  newMeasure->SetChooserName("Application cnetref(interest)");
450  QString sn = newMeasure->GetCubeSerialNumber();
451 
452  // Log
453  PvlGroup pvlMeasureGrp("MeasureDetails");
454  pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
455  pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation", LocationString(newMeasure->GetSample(),
456  newMeasure->GetLine()));
457 
458  // Initialize the UGM of this cube with the reference lat/lon
459  if (!newMeasure->IsIgnored() && iBestMeasureIndex >= 0 &&
460  mtInterestResults[iBestMeasureIndex].mdInterest != WorstInterest()) {
461  Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn));
462 
463  // default setting
464  newMeasure->SetIgnored(false);
465  newMeasure->SetType(ControlMeasure::Candidate);
466 
467  // Get the Camera
468  Camera *measureCamera;
469  try {
470  measureCamera = measureCube->camera();
471  }
472  catch (IException &e) {
473  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.FileName(sn);
474  throw IException(e, IException::User, msg, _FILEINFO_);
475  }
476 
477  if (measureCamera->SetUniversalGround(dReferenceLat, dReferenceLon) &&
478  measureCamera->InCube()) {
479  // Check for reference, Put the corresponding line/samp into a newMeasure
480  if (measure == iBestMeasureIndex) {
481  newMeasure->SetCoordinate(mtInterestResults[measure].mdBestSample,
482  mtInterestResults[measure].mdBestLine, ControlMeasure::Candidate);
483  // newMeasure->SetType(ControlMeasure::Reference);
484 
485 
486 
487  pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[measure].mdBestSample,
488  mtInterestResults[measure].mdBestLine));
489  pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString(mtInterestResults[measure].miDeltaSample));
490  pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString(mtInterestResults[measure].miDeltaLine));
491  pvlMeasureGrp += Isis::PvlKeyword("Reference", "true");
492  }
493  else {
494  double dSample = measureCamera->Sample();
495  double dLine = measureCamera->Line();
496 
497  double origSample = newMeasure->GetSample();
498  double origLine = newMeasure->GetLine();
499 
500  newMeasure->SetCoordinate(dSample, dLine);
501 
502  MeasureValidationResults results =
503  ValidStandardOptions(newMeasure, measureCube);
504  if (!results.isValid()) {
505  iNumIgnore++;
506  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Validation Test-" + results.toString());
507  newMeasure->SetIgnored(true);
508  }
509  pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(dSample, dLine));
510  pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString((int)abs((int)dSample - (int)origSample)));
511  pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString((int)abs((int)dLine - (int)origLine)));
512  pvlMeasureGrp += Isis::PvlKeyword("Reference", "false");
513  }
514  }
515  else {
516  iNumIgnore++;
517  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
518  newMeasure->SetIgnored(true);
519  if (!measureCamera->InCube()) {
520  pvlMeasureGrp += Isis::PvlKeyword("Comments", "New location is not in the Image");
521  }
522  }
523  }
524  // No best interest, ignore the measure
525  else {
526  iNumIgnore++;
527  pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
528  newMeasure->SetIgnored(true);
529  }
530 
531  if (newMeasure != origPnt[measure]) {
532  iMeasuresModified ++;
533  }
534 
535  pvlMeasureGrp += Isis::PvlKeyword("BestInterest", toString(mtInterestResults[measure].mdInterest));
536  pvlMeasureGrp += Isis::PvlKeyword("EmissionAngle", toString(mtInterestResults[measure].mdEmission));
537  pvlMeasureGrp += Isis::PvlKeyword("IncidenceAngle", toString(mtInterestResults[measure].mdIncidence));
538  pvlMeasureGrp += Isis::PvlKeyword("Resolution", toString(mtInterestResults[measure].mdResolution));
539  pvlMeasureGrp += Isis::PvlKeyword("DNValue", toString(mtInterestResults[measure].mdDn));
540  pvlPointObj += pvlMeasureGrp;
541  } // Measures Loop
542 
543  // Check the ignored measures number
544  if ((numMeasures - iNumIgnore) < 2) {
545  newPnt->SetIgnored(true);
546  pvlPointObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
547  }
548 
549  iNumIgnore = 0;
550 
551  if (*newPnt != origPnt) {
552  iPointsModified ++;
553  }
554 
555  if (!newPnt->IsIgnored() && iBestMeasureIndex != iOrigRefIndex) {
556  iRefChanged ++;
557  PvlGroup pvlRefChangeGrp("ReferenceChangeDetails");
558  if (iOrigRefIndex >= 0) {
559  pvlRefChangeGrp += Isis::PvlKeyword("PrevSerialNumber", mtInterestResults[iOrigRefIndex].msSerialNum);
560  pvlRefChangeGrp += Isis::PvlKeyword("PrevBestInterest", toString(mtInterestResults[iOrigRefIndex].mdInterest));
561  pvlRefChangeGrp += Isis::PvlKeyword("PrevLocation", LocationString(mtInterestResults[iOrigRefIndex].mdOrigSample,
562  mtInterestResults[iOrigRefIndex].mdOrigLine));
563  }
564  else {
565  pvlRefChangeGrp += Isis::PvlKeyword("PrevReference", "Not Set");
566  }
567  pvlRefChangeGrp += Isis::PvlKeyword("NewSerialNumber", mtInterestResults[iBestMeasureIndex].msSerialNum);
568  pvlRefChangeGrp += Isis::PvlKeyword("NewBestInterest", toString(mtInterestResults[iBestMeasureIndex].mdInterest));
569  pvlRefChangeGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[iBestMeasureIndex].mdBestSample,
570  mtInterestResults[iBestMeasureIndex].mdBestLine));
571 
572  // Log info, if Point not locked, apriori source == Reference and a new reference
573  if (newPnt->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::Reference) {
574  pvlRefChangeGrp += Isis::PvlKeyword("AprioriSource", "Reference is the source and has changed");
575  }
576 
577  pvlPointObj += pvlRefChangeGrp;
578  }
579  else {
580  pvlPointObj += Isis::PvlKeyword("Reference", "No Change");
581  }
582  // Clean up the results structure
583  delete [] mtInterestResults;
584  }
585  else {
586  // Process Ignored, non Free points or Measures=0
587  int iComment = 0;
588 
589  if (numMeasures == 0) {
590  QString sComment = "Comment";
591  sComment += toString(++iComment);
592  pvlPointObj += Isis::PvlKeyword(sComment, "No Measures in the Point");
593  }
594 
595  if (newPnt->IsIgnored()) {
596  QString sComment = "Comment";
597  sComment += toString(++iComment);
598  pvlPointObj += Isis::PvlKeyword(sComment, "Point was originally Ignored");
599  }
600 
601  if (newPnt->GetType() == ControlPoint::Fixed) {
602  QString sComment = "Comment";
603  sComment += toString(++iComment);
604  pvlPointObj += Isis::PvlKeyword(sComment, "Fixed Point");
605  }
606  else if (newPnt->GetType() == ControlPoint::Constrained) {
607  QString sComment = "Comment";
608  sComment += toString(++iComment);
609  pvlPointObj += Isis::PvlKeyword(sComment, "Constrained Point");
610  }
611 
612  if (iNumMeasuresLocked > 0 && !bRefLocked) {
613  pvlPointObj += Isis::PvlKeyword("Error", "Point has a Measure with EditLock set to true "
614  "but the Reference is not Locked");
615  }
616  else {
617  for (int measure = 0; measure < newPnt->GetNumMeasures(); measure++) {
618  ControlMeasure *cm = newPnt->GetMeasure(measure);
619  cm->SetDateTime();
620  cm->SetChooserName("Application cnetref(Interest)");
621  }
622  }
623  } // End of if point is of type free
624 
625  mPvlLog += pvlPointObj;
626 
628  } // Point loop
629 
630  // CnetRef Change Statistics
631  mStatisticsGrp += Isis::PvlKeyword("PointsModified", toString(iPointsModified));
632  mStatisticsGrp += Isis::PvlKeyword("ReferenceChanged", toString(iRefChanged));
633  mStatisticsGrp += Isis::PvlKeyword("MeasuresModified", toString(iMeasuresModified));
634 
636  }
637 
647  // Find the overlap this point is inside of if the overlap list is entered
648  const geos::geom::MultiPolygon *overlapPoly = NULL;
649 
650  if (mbOverlaps) {
651  overlapPoly = FindOverlap(pCnetPoint);
652  if (overlapPoly == NULL) {
653  QString msg = "Unable to find overlap polygon for point [" +
654  pCnetPoint.GetId() + "]";
656  }
657  }
658 
659  std::vector <PvlGroup> pvlGrpVector;
660 
661  // Create an array of Interest Results structure of measures size
662  mtInterestResults = new InterestResults[pCnetPoint.GetNumMeasures()];
663 
664  int iBestMeasureIndex = -1;
665  double dBestInterestValue = Isis::Null;
666 
667  for (int measure = 0; measure < pCnetPoint.GetNumMeasures(); ++measure) {
668  ControlMeasure *origMsr = pCnetPoint[measure];
669  QString sn = origMsr->GetCubeSerialNumber();
670 
671  // Do not process Ignored Measures
672  try {
673  if (!origMsr->IsIgnored()) {
674  InitInterestResults(measure);
676 
677  // Set the clipping polygon for this point
678  // Convert the lon/lat overlap polygon to samp/line using the UGM for
679  // this image
680  if (mbOverlaps) {
681  UniversalGroundMap unvGround = UniversalGroundMap(*inCube);
682  geos::geom::MultiPolygon *poly = PolygonTools::LatLonToSampleLine(*overlapPoly,
683  &unvGround);
684  SetClipPolygon(*poly);
685  delete poly;
686  }
687 
688  // Run the interest operator on this measurment
689  if (InterestByMeasure(measure, *origMsr, *inCube)) {
690  if (dBestInterestValue == Isis::Null ||
691  CompareInterests(mtInterestResults[measure].mdInterest, dBestInterestValue)) {
692  dBestInterestValue = mtInterestResults[measure].mdInterest;
693  iBestMeasureIndex = measure;
694  }
695  }
696  }
697  }
698  catch (IException &e) {
699  // e.print();
700  }
701  }
702  return iBestMeasureIndex;
703  }
704 
717  bool InterestOperator::InterestByMeasure(int piMeasure, ControlMeasure &pCnetMeasure,
718  Cube &pCube) {
719  QString serialNum = pCnetMeasure.GetCubeSerialNumber();
720 
721  int iOrigSample = (int)(pCnetMeasure.GetSample() + 0.5);
722  int iOrigLine = (int)(pCnetMeasure.GetLine() + 0.5);
723 
724  mtInterestResults[piMeasure].msSerialNum = serialNum;
725  mtInterestResults[piMeasure].mdOrigSample = pCnetMeasure.GetSample();
726  mtInterestResults[piMeasure].mdOrigLine = pCnetMeasure.GetLine();
727 
728  int pad = Padding();
729  Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
730  chip.TackCube(iOrigSample, iOrigLine);
731  if (p_clipPolygon != NULL)
733  chip.Load(pCube);
734 
735  // Walk the search chip and find the best interest
736  int iBestSamp = 0;
737  int iBestLine = 0;
738  double dSmallestDist = DBL_MAX;
739  double dBestInterest = Isis::Null;
740  int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
741  int iSamples = 2 * p_deltaSamp + p_samples / 2 + 1;
742  bool bCalculateInterest = false;
743  for (int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
744  for (int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
745  // Cannot take dnValues from the chip as it contains the interpolated dnValue
746  // hence get the dn values directly from the cube
747  chip.SetChipPosition((double)samp, (double)lin);
748 
749  bCalculateInterest = false;
750 
751  MeasureValidationResults results =
752  ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCnetMeasure, &pCube);
753  if (results.isValid()) {
754  bCalculateInterest = true;
755  }
756 
757  if (bCalculateInterest) {
758  Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
759  double interest = Interest(subChip);
760 
761  if (interest != Isis::Null) {
762  if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
763  double dist = std::sqrt(std::pow(iOrigSample - samp, 2.0) +
764  std::pow(iOrigLine - lin, 2.0));
765  if (interest == dBestInterest && dist > dSmallestDist) {
766  continue;
767  }
768  else {
769  dBestInterest = interest;
770  dSmallestDist = dist;
771  iBestSamp = samp;
772  iBestLine = lin;
773 
776  mtInterestResults[piMeasure].mdDn = mdDnValue;
778  mtInterestResults[piMeasure].mbValid = true;
779  }
780  }
781  }
782  }
783  }
784  }
785 
786  // Check to see if we went through the interest chip and never got a interest at
787  // any location.But record the Emission, Incidence Angles and DN Value for the failed
788  // Measure at the original location
789  if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
790  // Get the Camera
791  Camera *camera;
792  try {
793  camera = pCube.camera();
794  }
795  catch (IException &e) {
796  QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.FileName(serialNum);
798  }
799 
800  if (camera->SetImage(iOrigSample, iOrigLine)) {
801  Portal inPortal(1, 1, pCube.pixelType());
802  inPortal.SetPosition(iOrigSample, iOrigLine, 1);
803  pCube.read(inPortal);
804 
805  mtInterestResults[piMeasure].mdInterest = dBestInterest;
808  mtInterestResults[piMeasure].mdOrigSample = iOrigSample;
809  mtInterestResults[piMeasure].mdOrigLine = iOrigLine;
810  mtInterestResults[piMeasure].mdEmission = camera->EmissionAngle();
811  mtInterestResults[piMeasure].mdIncidence = camera->IncidenceAngle();
812  mtInterestResults[piMeasure].mdDn = inPortal[0];
813  mtInterestResults[piMeasure].mdResolution = camera->PixelResolution();
814  mtInterestResults[piMeasure].mbValid = false;
815  }
816  return false;
817  }
818 
819  chip.SetChipPosition(iBestSamp, iBestLine);
820  mtInterestResults[piMeasure].mdInterest = dBestInterest;
821  mtInterestResults[piMeasure].mdBestSample = chip.CubeSample();
822  mtInterestResults[piMeasure].mdBestLine = chip.CubeLine();
823  mtInterestResults[piMeasure].miDeltaSample = (int)abs(mtInterestResults[piMeasure].mdBestSample -
824  iOrigSample);
825  mtInterestResults[piMeasure].miDeltaLine = (int)abs(mtInterestResults[piMeasure].mdBestLine -
826  iOrigLine);
827  return true;
828  }
829 
835  const geos::geom::MultiPolygon *InterestOperator::FindOverlap(ControlPoint &pCnetPoint) {
836  int exactMatchIndex = -1;
837 
838  for (int overlapIndex = 0; ((exactMatchIndex == -1) && (overlapIndex < mOverlaps.Size()));
839  overlapIndex ++) {
840  const Isis::ImageOverlap *overlap = mOverlaps[overlapIndex];
841 
842  // Exact matches only; skip if # SNs don't match
843  if (overlap->Size() != pCnetPoint.GetNumMeasures())
844  continue;
845 
846  // If # SNs match and each SN is contained in both then we're good, there
847  // should never be two measures with the same SN
848  int numMatches = 0;
849 
850  for (int measureIndex = 0;
851  measureIndex < pCnetPoint.GetNumMeasures();
852  measureIndex ++) {
853  if (measureIndex == numMatches) {
854  const ControlMeasure &controlMeasure = *pCnetPoint[measureIndex];
855  QString serialNum = controlMeasure.GetCubeSerialNumber();
856  if (overlap->HasSerialNumber(serialNum)) {
857  numMatches++;
858  }
859  }
860  }
861 
862  if (numMatches == pCnetPoint.GetNumMeasures()) {
863  exactMatchIndex = overlapIndex;
864  }
865  }
866 
867  if (exactMatchIndex < 0) {
868  return (FindOverlapByImageFootPrint(pCnetPoint));
869  }
870 
871  return mOverlaps[exactMatchIndex]->Polygon();
872  }
873 
884  const geos::geom::MultiPolygon *InterestOperator::FindOverlapByImageFootPrint
885  (Isis::ControlPoint &pCnetPoint) {
886  ImagePolygon measPolygon1, measPolygon2, measPolygon3;
887  geos::geom::Geometry *geomIntersect1, *geomIntersect2;
888 
889  // Create Multipolygon for the first Control Measure
890  QString sn1 = pCnetPoint[0]->GetCubeSerialNumber();
891  Cube *inCube1 = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn1));
892  inCube1->read((Blob &)measPolygon1);
893 
894  // Create Multipolygon for the Second Control Measure
895  QString sn2 = pCnetPoint[1]->GetCubeSerialNumber();
896  Cube *inCube2 = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn2));
897  inCube2->read((Blob &)measPolygon2);
898 
899  // Get the interesection for the first 2 polgons
900  geomIntersect1 = PolygonTools::Intersect((const geos::geom::Geometry *)measPolygon1.Polys(),
901  (const geos::geom::Geometry *)measPolygon2.Polys());
902 
903  for (int measureIndex = 2; measureIndex < pCnetPoint.GetNumMeasures(); measureIndex ++) {
904  QString sn3 = pCnetPoint[measureIndex]->GetCubeSerialNumber();
905  Cube *inCube3 = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn3));
906  inCube3->read((Blob &)measPolygon3);
907 
908  // Get the intersection of the intersection and the measure Image Polygon
909  geomIntersect2 = PolygonTools::Intersect(geomIntersect1,
910  (const geos::geom::Geometry *)measPolygon3.Polys());
911  geomIntersect1 = geomIntersect2;
912  }
913  return PolygonTools::MakeMultiPolygon(geomIntersect1);
914  }
915 
923  bool InterestOperator::CompareInterests(double int1, double int2) {
924  return(int1 >= int2);
925  }
926 
927 
928  // add this object's group to the pvl
929  void InterestOperator::addGroup(Isis::PvlObject &obj) {
930  Isis::PvlGroup group;
931  obj.addGroup(group);
932  }
933 
934 
941  void InterestOperator::SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon) {
942  if (p_clipPolygon != NULL)
943  delete p_clipPolygon;
945  }
946 
954  return 0;
955  }
956 
965  return mOperatorGrp;
966  }
967 }