Isis 3 Programmer Reference
InterestOperator.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "Chip.h"
10#include "Pvl.h"
11#include "InterestOperator.h"
12#include "Plugin.h"
13#include "IException.h"
14#include "FileName.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"
25
26namespace Isis {
27
41
48 p_interestAmount = 0.0;
49 p_worstInterest = 0.0;
50 p_lines = 1;
51 p_samples = 1;
52 p_deltaSamp = 0;
53 p_deltaLine = 0;
54 p_clipPolygon = NULL;
55 mbOverlaps = false;
56 }
57
62 if (p_clipPolygon != NULL) {
63 delete p_clipPolygon;
64 p_clipPolygon = NULL;
65 }
66 }
67
92 try {
93 // Get info from the operator group
94 // Required Parameters
95 PvlGroup &op = pPvl.findGroup("Operator", Pvl::Traverse);
96
97 mOperatorGrp += Isis::PvlKeyword(op["Name"]);
98
99 p_samples = op["Samples"];
100 mOperatorGrp += Isis::PvlKeyword("Samples", toString(p_samples));
101
102 p_lines = op["Lines"];
103 mOperatorGrp += Isis::PvlKeyword("Lines", toString(p_lines));
104
105 p_deltaLine = op["DeltaLine"];
106 mOperatorGrp += Isis::PvlKeyword("DeltaLine", toString(p_deltaLine));
107
108 p_deltaSamp = op["DeltaSamp"];
110
111 p_minimumInterest = op["MinimumInterest"];
113
114 }
115 catch (IException &e) {
116 QString msg = "Improper format for InterestOperator PVL [" + pPvl.fileName() + "]";
117 throw IException(IException::User, msg, _FILEINFO_);
118 }
119 }
120
143
164 int piSample, int piLine) {
165
166 if (!pUnivGrndMap.HasCamera())
167 // Level 3 images/mosaic or bad image
168 {
169 QString msg = "Cannot run interest on images with no camera. Image " +
170 pCube.fileName() + " has no Camera";
171 throw IException(IException::Programmer, msg, _FILEINFO_);
172 }
173
174 int pad = Padding();
175 Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
176 chip.TackCube(piSample, piLine);
177 if (p_clipPolygon != NULL)
179 chip.Load(pCube);
180
181 // Walk the search chip and find the best interest
182 int iBestSamp = 0;
183 int iBestLine = 0;
184 double dSmallestDist = DBL_MAX;
185 double dBestInterest = Isis::Null;
186 int iLines = 2 * p_deltaLine + p_lines / 2 + 1;
187 int iSamples = 2 * p_deltaSamp + p_samples / 2 + 1;
188 bool bCalculateInterest = false;
189
190 for (int lin = p_lines / 2 + 1; lin <= iLines; lin++) {
191 for (int samp = p_samples / 2 + 1; samp <= iSamples; samp++) {
192 // Cannot take dnValues from the chip as it contains the interpolated dnValue
193 // hence get the dn values directly from the cube
194 chip.SetChipPosition((double)samp, (double)lin);
195
196 bCalculateInterest = false;
198 ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCube);
199 if (results.isValid()) {
200 bCalculateInterest = true;
201 }
202
203 if (bCalculateInterest) {
204 Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
205 double interest = Interest(subChip);
206 if (interest != Isis::Null) {
207 if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
208 double dist = std::sqrt(std::pow(piSample - samp, 2.0) + std::pow(piLine - lin, 2.0));
209 if (interest == dBestInterest && dist > dSmallestDist) {
210 continue;
211 }
212 else {
213 dBestInterest = interest;
214 iBestSamp = samp;
215 iBestLine = lin;
216 dSmallestDist = dist;
217 }
218 }
219 }
220 }
221 }
222 }
223
224 // Check to see if we went through the interest chip and never got a interest at
225 // any location.
226 if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
227 if (pUnivGrndMap.SetImage(piSample, piLine)) {
228 p_interestAmount = dBestInterest;
229 }
230 return false;
231 }
232
233 p_interestAmount = dBestInterest;
234 chip.SetChipPosition(iBestSamp, iBestLine);
235 p_cubeSample = chip.CubeSample();
236 p_cubeLine = chip.CubeLine();
237
238 return true;
239 }
240
254 void InterestOperator::Operate(ControlNet &pNewNet, QString psSerialNumFile,
255 QString psOverlapListFile) {
256 ReadSerialNumbers(psSerialNumFile);
257
258 // Find all the overlaps between the images in the FROMLIST
259 // The overlap polygon coordinates are in Lon/Lat order
260 if (psOverlapListFile != "") {
261 mOverlaps.ReadImageOverlaps(psOverlapListFile);
262 mbOverlaps = true;
263 }
264
265 // Process the entire control net by calculating interest and moving the
266 // point to a more interesting area
267 FindCnetRef(pNewNet);
268 }
269
279 ControlPoint &pCPoint, PvlObject &pPvlObj, int &piMeasuresModified) {
280 int iNumMeasures = pCPoint.GetNumMeasures();
281 bool bPntEditLock = pCPoint.IsEditLocked();
282 int iMsrIgnored = 0;
283
284 // Log Point Details
285 if (bPntEditLock) {
286 pPvlObj += Isis::PvlKeyword("Reference", "No Change, PointEditLock");
287 }
288
289 for (int measure = 0; measure < iNumMeasures; measure++) {
290 ControlMeasure *newMeasure = new ControlMeasure(*pCPoint[measure]);
291 newMeasure->SetDateTime();
292 newMeasure->SetChooserName("Application cnetref(interest)");
293 bool bMeasureLocked = newMeasure->IsEditLocked();
294
295 QString sn = newMeasure->GetCubeSerialNumber();
296 //double dSample = newMeasure->GetSample();
297 //double dLine = newMeasure->GetLine();
298
299 // Log
300 PvlGroup pvlMeasureGrp("MeasureDetails");
301 pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
302 pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation",
303 LocationString(newMeasure->GetSample(), newMeasure->GetLine()));
304
305 if (bMeasureLocked) {
306 pvlMeasureGrp += Isis::PvlKeyword("EditLock", "True");
307 }
308
309 if (!newMeasure->IsIgnored()) {
310 Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn));
311
313 ValidStandardOptions(newMeasure, measureCube);
314 if (!results.isValid()) {
315 if (bPntEditLock) {
316 pvlMeasureGrp += Isis::PvlKeyword("UnIgnored", "Failed Validation Test but not "
317 "Ignored as Point EditLock is True");
318 }
319 else if (bMeasureLocked == measure) {
320 pvlMeasureGrp += Isis::PvlKeyword("Error", "Failed the Validation Test "
321 "but is Locked");
322 }
323 else {
324 pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Emission, Incidence, Resolution "
325 "and/or Dn Value Test");
326 newMeasure->SetIgnored(true);
327 iMsrIgnored++;
328 piMeasuresModified++;
329 }
330 }
331 }
332 else {
333 pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Originally Ignored");
334 iMsrIgnored++;
335 }
336
337 pPvlObj += pvlMeasureGrp;
338 }
339
340 if ((iNumMeasures - iMsrIgnored) < 2) {
341 if (bPntEditLock) {
342 pPvlObj += Isis::PvlKeyword("UnIgnored", "Good Measures less than 2 "
343 "but Point EditLock is True");
344 }
345 else {
346 pCPoint.SetIgnored(true);
347 pPvlObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
348 }
349 }
350 }
351
372 int iPointsModified = 0;
373 int iMeasuresModified = 0;
374 int iRefChanged = 0;
375
376 // Status Report
377 mStatus.SetText("Choosing Reference by Interest...");
378 mStatus.SetMaximumSteps(pNewNet.GetNumPoints());
380
381 // Process each existing control point in the network
382 for (int point = 0; point < pNewNet.GetNumPoints(); ++point) {
383 ControlPoint *newPnt = pNewNet.GetPoint(point);
384
385 // Create a copy of original control point
386 const ControlPoint origPnt(*newPnt);
387
388 // Logging
389 PvlObject pvlPointObj("PointDetails");
390 pvlPointObj += Isis::PvlKeyword("PointId", newPnt->GetId());
391
392 // Get number of measures locked and check if Reference
393 // Measure is locked
394 int iNumMeasuresLocked = newPnt->GetNumLockedMeasures();
395 int numMeasures = newPnt->GetNumMeasures();
396
397 bool bRefLocked = false;
398 int iOrigRefIndex = -1;
399 try {
400 iOrigRefIndex = newPnt->IndexOfRefMeasure();
401 bRefLocked = newPnt->GetRefMeasure()->IsEditLocked();
402 }
403 catch(IException &) {
404 }
405
406 // Only perform the interest operation on points of type "Free" and
407 // Points having atleast 1 measure and Point is not Ignored
408 if (!newPnt->IsIgnored() && newPnt->GetType() == ControlPoint::Free && numMeasures > 0 &&
409 (iNumMeasuresLocked == 0 || (iNumMeasuresLocked > 0 && bRefLocked))) {
410
411 // Check only the validity of the Point / Measures only if Point and/or
412 // Reference Measure is locked.
413 if (newPnt->IsEditLocked() || iNumMeasuresLocked > 0) {
414 ProcessLocked_Point_Reference(*newPnt, pvlPointObj, iMeasuresModified);
415
416 mPvlLog += pvlPointObj;
418
419 if (*newPnt != origPnt) {
420 iPointsModified ++;
421 }
422 continue;
423 }
424
425 int iBestMeasureIndex = InterestByPoint(*newPnt);
426
427 // Process for point with good interest and a best index
428 double dReferenceLat = 0, dReferenceLon = 0;
429 if (iBestMeasureIndex >= 0) {
430 QString sn = mtInterestResults[iBestMeasureIndex].msSerialNum;
432
433 // Get the Camera for the reference image and get the lat/lon from that measurment
434 Camera *bestCamera;
435 try {
436 bestCamera = bestCube->camera();
437 }
438 catch (IException &e) {
439 QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(sn);
440 throw IException(IException::User, msg, _FILEINFO_);
441 }
442
443 double dBestSample = mtInterestResults[iBestMeasureIndex].mdBestSample;
444 double dBestLine = mtInterestResults[iBestMeasureIndex].mdBestLine;
445
446 bestCamera->SetImage(dBestSample, dBestLine);
447 dReferenceLat = bestCamera->UniversalLatitude();
448 dReferenceLon = bestCamera->UniversalLongitude();
449
450 // Set the point reference
451 newPnt->SetRefMeasure(iBestMeasureIndex);
452 }
453
454 // Create a measurment for each image in this point using
455 // the reference lat/lon.
456 int iNumIgnore = 0;
457 for (int measure = 0; measure < numMeasures; ++measure) {
458 ControlMeasure *newMeasure = newPnt->GetMeasure(measure);
459 newMeasure->SetDateTime();
460 newMeasure->SetChooserName("Application cnetref(interest)");
461 QString sn = newMeasure->GetCubeSerialNumber();
462
463 // Log
464 PvlGroup pvlMeasureGrp("MeasureDetails");
465 pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
466 pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation", LocationString(newMeasure->GetSample(),
467 newMeasure->GetLine()));
468
469 // Initialize the UGM of this cube with the reference lat/lon
470 if (!newMeasure->IsIgnored() && iBestMeasureIndex >= 0 &&
471 mtInterestResults[iBestMeasureIndex].mdInterest != WorstInterest()) {
472 Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.fileName(sn));
473
474 // default setting
475 newMeasure->SetIgnored(false);
477
478 // Get the Camera
479 Camera *measureCamera;
480 try {
481 measureCamera = measureCube->camera();
482 }
483 catch (IException &e) {
484 QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(sn);
485 throw IException(e, IException::User, msg, _FILEINFO_);
486 }
487
488 if (measureCamera->SetUniversalGround(dReferenceLat, dReferenceLon) &&
489 measureCamera->InCube()) {
490 // Check for reference, Put the corresponding line/samp into a newMeasure
491 if (measure == iBestMeasureIndex) {
492 newMeasure->SetCoordinate(mtInterestResults[measure].mdBestSample,
493 mtInterestResults[measure].mdBestLine, ControlMeasure::Candidate);
494 // newMeasure->SetType(ControlMeasure::Reference);
495
496
497
498 pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[measure].mdBestSample,
499 mtInterestResults[measure].mdBestLine));
500 pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString(mtInterestResults[measure].miDeltaSample));
501 pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString(mtInterestResults[measure].miDeltaLine));
502 pvlMeasureGrp += Isis::PvlKeyword("Reference", "true");
503 }
504 else {
505 double dSample = measureCamera->Sample();
506 double dLine = measureCamera->Line();
507
508 double origSample = newMeasure->GetSample();
509 double origLine = newMeasure->GetLine();
510
511 newMeasure->SetCoordinate(dSample, dLine);
512
514 ValidStandardOptions(newMeasure, measureCube);
515 if (!results.isValid()) {
516 iNumIgnore++;
517 pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Validation Test-" + results.toString());
518 newMeasure->SetIgnored(true);
519 }
520 pvlMeasureGrp += Isis::PvlKeyword("NewLocation", LocationString(dSample, dLine));
521 pvlMeasureGrp += Isis::PvlKeyword("DeltaSample", toString((int)abs((int)dSample - (int)origSample)));
522 pvlMeasureGrp += Isis::PvlKeyword("DeltaLine", toString((int)abs((int)dLine - (int)origLine)));
523 pvlMeasureGrp += Isis::PvlKeyword("Reference", "false");
524 }
525 }
526 else {
527 iNumIgnore++;
528 pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
529 newMeasure->SetIgnored(true);
530 if (!measureCamera->InCube()) {
531 pvlMeasureGrp += Isis::PvlKeyword("Comments", "New location is not in the Image");
532 }
533 }
534 }
535 // No best interest, ignore the measure
536 else {
537 iNumIgnore++;
538 pvlMeasureGrp += Isis::PvlKeyword("Ignored", "True");
539 newMeasure->SetIgnored(true);
540 }
541
542 if (newMeasure != origPnt[measure]) {
543 iMeasuresModified ++;
544 }
545
546 pvlMeasureGrp += Isis::PvlKeyword("BestInterest", toString(mtInterestResults[measure].mdInterest));
547 pvlMeasureGrp += Isis::PvlKeyword("EmissionAngle", toString(mtInterestResults[measure].mdEmission));
548 pvlMeasureGrp += Isis::PvlKeyword("IncidenceAngle", toString(mtInterestResults[measure].mdIncidence));
549 pvlMeasureGrp += Isis::PvlKeyword("Resolution", toString(mtInterestResults[measure].mdResolution));
550 pvlMeasureGrp += Isis::PvlKeyword("DNValue", toString(mtInterestResults[measure].mdDn));
551 pvlPointObj += pvlMeasureGrp;
552 } // Measures Loop
553
554 // Check the ignored measures number
555 if ((numMeasures - iNumIgnore) < 2) {
556 newPnt->SetIgnored(true);
557 pvlPointObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
558 }
559
560 iNumIgnore = 0;
561
562 if (*newPnt != origPnt) {
563 iPointsModified ++;
564 }
565
566 if (!newPnt->IsIgnored() && iBestMeasureIndex != iOrigRefIndex) {
567 iRefChanged ++;
568 PvlGroup pvlRefChangeGrp("ReferenceChangeDetails");
569 if (iOrigRefIndex >= 0) {
570 pvlRefChangeGrp += Isis::PvlKeyword("PrevSerialNumber", mtInterestResults[iOrigRefIndex].msSerialNum);
571 pvlRefChangeGrp += Isis::PvlKeyword("PrevBestInterest", toString(mtInterestResults[iOrigRefIndex].mdInterest));
572 pvlRefChangeGrp += Isis::PvlKeyword("PrevLocation", LocationString(mtInterestResults[iOrigRefIndex].mdOrigSample,
573 mtInterestResults[iOrigRefIndex].mdOrigLine));
574 }
575 else {
576 pvlRefChangeGrp += Isis::PvlKeyword("PrevReference", "Not Set");
577 }
578 pvlRefChangeGrp += Isis::PvlKeyword("NewSerialNumber", mtInterestResults[iBestMeasureIndex].msSerialNum);
579 pvlRefChangeGrp += Isis::PvlKeyword("NewBestInterest", toString(mtInterestResults[iBestMeasureIndex].mdInterest));
580 pvlRefChangeGrp += Isis::PvlKeyword("NewLocation", LocationString(mtInterestResults[iBestMeasureIndex].mdBestSample,
581 mtInterestResults[iBestMeasureIndex].mdBestLine));
582
583 // Log info, if Point not locked, apriori source == Reference and a new reference
584 if (newPnt->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::Reference) {
585 pvlRefChangeGrp += Isis::PvlKeyword("AprioriSource", "Reference is the source and has changed");
586 }
587
588 pvlPointObj += pvlRefChangeGrp;
589 }
590 else {
591 pvlPointObj += Isis::PvlKeyword("Reference", "No Change");
592 }
593 // Clean up the results structure
594 delete [] mtInterestResults;
595 }
596 else {
597 // Process Ignored, non Free points or Measures=0
598 int iComment = 0;
599
600 if (numMeasures == 0) {
601 QString sComment = "Comment";
602 sComment += toString(++iComment);
603 pvlPointObj += Isis::PvlKeyword(sComment, "No Measures in the Point");
604 }
605
606 if (newPnt->IsIgnored()) {
607 QString sComment = "Comment";
608 sComment += toString(++iComment);
609 pvlPointObj += Isis::PvlKeyword(sComment, "Point was originally Ignored");
610 }
611
612 if (newPnt->GetType() == ControlPoint::Fixed) {
613 QString sComment = "Comment";
614 sComment += toString(++iComment);
615 pvlPointObj += Isis::PvlKeyword(sComment, "Fixed Point");
616 }
617 else if (newPnt->GetType() == ControlPoint::Constrained) {
618 QString sComment = "Comment";
619 sComment += toString(++iComment);
620 pvlPointObj += Isis::PvlKeyword(sComment, "Constrained Point");
621 }
622
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");
626 }
627 else {
628 for (int measure = 0; measure < newPnt->GetNumMeasures(); measure++) {
629 ControlMeasure *cm = newPnt->GetMeasure(measure);
630 cm->SetDateTime();
631 cm->SetChooserName("Application cnetref(Interest)");
632 }
633 }
634 } // End of if point is of type free
635
636 mPvlLog += pvlPointObj;
637
639 } // Point loop
640
641 // CnetRef Change Statistics
642 mStatisticsGrp += Isis::PvlKeyword("PointsModified", toString(iPointsModified));
643 mStatisticsGrp += Isis::PvlKeyword("ReferenceChanged", toString(iRefChanged));
644 mStatisticsGrp += Isis::PvlKeyword("MeasuresModified", toString(iMeasuresModified));
645
647 }
648
658 // Find the overlap this point is inside of if the overlap list is entered
659 const geos::geom::MultiPolygon *overlapPoly = NULL;
660
661 if (mbOverlaps) {
662 overlapPoly = FindOverlap(pCnetPoint);
663 if (overlapPoly == NULL) {
664 QString msg = "Unable to find overlap polygon for point [" +
665 pCnetPoint.GetId() + "]";
666 throw IException(IException::User, msg, _FILEINFO_);
667 }
668 }
669
670 std::vector <PvlGroup> pvlGrpVector;
671
672 // Create an array of Interest Results structure of measures size
673 mtInterestResults = new InterestResults[pCnetPoint.GetNumMeasures()];
674
675 int iBestMeasureIndex = -1;
676 double dBestInterestValue = Isis::Null;
677
678 for (int measure = 0; measure < pCnetPoint.GetNumMeasures(); ++measure) {
679 ControlMeasure *origMsr = pCnetPoint[measure];
680 QString sn = origMsr->GetCubeSerialNumber();
681
682 // Do not process Ignored Measures
683 try {
684 if (!origMsr->IsIgnored()) {
685 InitInterestResults(measure);
687
688 // Set the clipping polygon for this point
689 // Convert the lon/lat overlap polygon to samp/line using the UGM for
690 // this image
691 if (mbOverlaps) {
692 UniversalGroundMap unvGround = UniversalGroundMap(*inCube);
693 geos::geom::MultiPolygon *poly = PolygonTools::LatLonToSampleLine(*overlapPoly,
694 &unvGround);
695 SetClipPolygon(*poly);
696 delete poly;
697 }
698
699 // Run the interest operator on this measurment
700 if (InterestByMeasure(measure, *origMsr, *inCube)) {
701 if (dBestInterestValue == Isis::Null ||
702 CompareInterests(mtInterestResults[measure].mdInterest, dBestInterestValue)) {
703 dBestInterestValue = mtInterestResults[measure].mdInterest;
704 iBestMeasureIndex = measure;
705 }
706 }
707 }
708 }
709 catch (IException &e) {
710 // e.print();
711 }
712 }
713 return iBestMeasureIndex;
714 }
715
728 bool InterestOperator::InterestByMeasure(int piMeasure, ControlMeasure &pCnetMeasure,
729 Cube &pCube) {
730 QString serialNum = pCnetMeasure.GetCubeSerialNumber();
731
732 int iOrigSample = (int)(pCnetMeasure.GetSample() + 0.5);
733 int iOrigLine = (int)(pCnetMeasure.GetLine() + 0.5);
734
735 mtInterestResults[piMeasure].msSerialNum = serialNum;
736 mtInterestResults[piMeasure].mdOrigSample = pCnetMeasure.GetSample();
737 mtInterestResults[piMeasure].mdOrigLine = pCnetMeasure.GetLine();
738
739 int pad = Padding();
740 Chip chip(2 * p_deltaSamp + p_samples + pad, 2 * p_deltaLine + p_lines + pad);
741 chip.TackCube(iOrigSample, iOrigLine);
742 if (p_clipPolygon != NULL)
744 chip.Load(pCube);
745
746 // Walk the search chip and find the best interest
747 int iBestSamp = 0;
748 int iBestLine = 0;
749 double dSmallestDist = DBL_MAX;
750 double dBestInterest = Isis::Null;
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++) {
756 // Cannot take dnValues from the chip as it contains the interpolated dnValue
757 // hence get the dn values directly from the cube
758 chip.SetChipPosition((double)samp, (double)lin);
759
760 bCalculateInterest = false;
761
763 ValidStandardOptions(chip.CubeSample(), chip.CubeLine(), &pCnetMeasure, &pCube);
764 if (results.isValid()) {
765 bCalculateInterest = true;
766 }
767
768 if (bCalculateInterest) {
769 Chip subChip = chip.Extract(p_samples + pad, p_lines + pad, samp, lin);
770 double interest = Interest(subChip);
771
772 if (interest != Isis::Null) {
773 if ((dBestInterest == Isis::Null) || CompareInterests(interest, dBestInterest)) {
774 double dist = std::sqrt(std::pow(iOrigSample - samp, 2.0) +
775 std::pow(iOrigLine - lin, 2.0));
776 if (interest == dBestInterest && dist > dSmallestDist) {
777 continue;
778 }
779 else {
780 dBestInterest = interest;
781 dSmallestDist = dist;
782 iBestSamp = samp;
783 iBestLine = lin;
784
787 mtInterestResults[piMeasure].mdDn = mdDnValue;
789 mtInterestResults[piMeasure].mbValid = true;
790 }
791 }
792 }
793 }
794 }
795 }
796
797 // Check to see if we went through the interest chip and never got a interest at
798 // any location.But record the Emission, Incidence Angles and DN Value for the failed
799 // Measure at the original location
800 if (dBestInterest == Isis::Null || dBestInterest < p_minimumInterest) {
801 // Get the Camera
802 Camera *camera;
803 try {
804 camera = pCube.camera();
805 }
806 catch (IException &e) {
807 QString msg = "Cannot Create Camera for Image:" + mSerialNumbers.fileName(serialNum);
808 throw IException(IException::User, msg, _FILEINFO_);
809 }
810
811 if (camera->SetImage(iOrigSample, iOrigLine)) {
812 Portal inPortal(1, 1, pCube.pixelType());
813 inPortal.SetPosition(iOrigSample, iOrigLine, 1);
814 pCube.read(inPortal);
815
816 mtInterestResults[piMeasure].mdInterest = dBestInterest;
819 mtInterestResults[piMeasure].mdOrigSample = iOrigSample;
820 mtInterestResults[piMeasure].mdOrigLine = iOrigLine;
821 mtInterestResults[piMeasure].mdEmission = camera->EmissionAngle();
822 mtInterestResults[piMeasure].mdIncidence = camera->IncidenceAngle();
823 mtInterestResults[piMeasure].mdDn = inPortal[0];
824 mtInterestResults[piMeasure].mdResolution = camera->PixelResolution();
825 mtInterestResults[piMeasure].mbValid = false;
826 }
827 return false;
828 }
829
830 chip.SetChipPosition(iBestSamp, iBestLine);
831 mtInterestResults[piMeasure].mdInterest = dBestInterest;
832 mtInterestResults[piMeasure].mdBestSample = chip.CubeSample();
833 mtInterestResults[piMeasure].mdBestLine = chip.CubeLine();
834 mtInterestResults[piMeasure].miDeltaSample = qAbs(mtInterestResults[piMeasure].mdBestSample -
835 iOrigSample);
836 mtInterestResults[piMeasure].miDeltaLine = qAbs(mtInterestResults[piMeasure].mdBestLine -
837 iOrigLine);
838 return true;
839 }
840
846 const geos::geom::MultiPolygon *InterestOperator::FindOverlap(ControlPoint &pCnetPoint) {
847 int exactMatchIndex = -1;
848
849 for (int overlapIndex = 0; ((exactMatchIndex == -1) && (overlapIndex < mOverlaps.Size()));
850 overlapIndex ++) {
851 const Isis::ImageOverlap *overlap = mOverlaps[overlapIndex];
852
853 // Exact matches only; skip if # SNs don't match
854 if (overlap->Size() != pCnetPoint.GetNumMeasures())
855 continue;
856
857 // If # SNs match and each SN is contained in both then we're good, there
858 // should never be two measures with the same SN
859 int numMatches = 0;
860
861 for (int measureIndex = 0;
862 measureIndex < pCnetPoint.GetNumMeasures();
863 measureIndex ++) {
864 if (measureIndex == numMatches) {
865 const ControlMeasure &controlMeasure = *pCnetPoint[measureIndex];
866 QString serialNum = controlMeasure.GetCubeSerialNumber();
867 if (overlap->HasSerialNumber(serialNum)) {
868 numMatches++;
869 }
870 }
871 }
872
873 if (numMatches == pCnetPoint.GetNumMeasures()) {
874 exactMatchIndex = overlapIndex;
875 }
876 }
877
878 if (exactMatchIndex < 0) {
879 return (FindOverlapByImageFootPrint(pCnetPoint));
880 }
881
882 return mOverlaps[exactMatchIndex]->Polygon();
883 }
884
895 const geos::geom::MultiPolygon *InterestOperator::FindOverlapByImageFootPrint
896 (Isis::ControlPoint &pCnetPoint) {
897 ImagePolygon measPolygon1, measPolygon2, measPolygon3;
898 geos::geom::Geometry *geomIntersect1, *geomIntersect2;
899
900 // Create Multipolygon for the first Control Measure
901 QString sn1 = pCnetPoint[0]->GetCubeSerialNumber();
903 inCube1->read((Blob &)measPolygon1);
904
905 // Create Multipolygon for the Second Control Measure
906 QString sn2 = pCnetPoint[1]->GetCubeSerialNumber();
908 inCube2->read((Blob &)measPolygon2);
909
910 // Get the interesection for the first 2 polgons
911 geomIntersect1 = PolygonTools::Intersect((const geos::geom::Geometry *)measPolygon1.Polys(),
912 (const geos::geom::Geometry *)measPolygon2.Polys());
913
914 for (int measureIndex = 2; measureIndex < pCnetPoint.GetNumMeasures(); measureIndex ++) {
915 QString sn3 = pCnetPoint[measureIndex]->GetCubeSerialNumber();
917 inCube3->read((Blob &)measPolygon3);
918
919 // Get the intersection of the intersection and the measure Image Polygon
920 geomIntersect2 = PolygonTools::Intersect(geomIntersect1,
921 (const geos::geom::Geometry *)measPolygon3.Polys());
922 geomIntersect1 = geomIntersect2;
923 }
924 return PolygonTools::MakeMultiPolygon(geomIntersect1);
925 }
926
934 bool InterestOperator::CompareInterests(double int1, double int2) {
935 return(int1 >= int2);
936 }
937
938
939 // add this object's group to the pvl
940 void InterestOperator::addGroup(Isis::PvlObject &obj) {
941 Isis::PvlGroup group;
942 obj.addGroup(group);
943 }
944
945
952 void InterestOperator::SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon) {
953 if (p_clipPolygon != NULL)
954 delete p_clipPolygon;
956 }
957
965 return 0;
966 }
967
978}
virtual double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition Camera.cpp:681
virtual 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:156
A small chip of data used for pattern matching.
Definition Chip.h:86
double CubeLine() const
Definition Chip.h:210
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
Definition Chip.cpp:643
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Sets the clipping polygon for this chip.
Definition Chip.cpp:1008
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition Chip.cpp:182
double CubeSample() const
Definition Chip.h:203
Chip Extract(int samples, int lines, int samp, int line)
Extract a sub-chip from a chip.
Definition Chip.cpp:727
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:203
a control measurement
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.
a control network
Definition ControlNet.h:258
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.
A single control point.
@ 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.
Definition Cube.h:168
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition Cube.cpp:813
Cube * OpenCube(const QString &cubeFileName)
This method opens a cube.
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
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.
static geos::geom::MultiPolygon * CopyMultiPolygon(const geos::geom::MultiPolygon *mpolygon)
This static method will create a deep copy of a geos::geom::MultiPolygon.
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
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 ...
static geos::geom::Geometry * Intersect(const geos::geom::Geometry *geom1, const geos::geom::Geometry *geom2)
This applies the geos Intersect operator.
Buffer for containing a two dimensional section of an image.
Definition Portal.h:36
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
@ Traverse
Search child objects.
Definition PvlObject.h:158
virtual double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition Sensor.cpp:339
virtual double EmissionAngle() const
Returns the emission angle in degrees.
Definition Sensor.cpp:328
QString fileName(const QString &sn)
Return a filename given a serial number.
Universal Ground Map.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
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.