Isis 3 Programmer Reference
ControlPoint.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "ControlPoint.h"
10
11#include <boost/numeric/ublas/symmetric.hpp>
12#include <boost/numeric/ublas/io.hpp>
13
14#include <QDebug>
15#include <QHash>
16#include <QString>
17#include <QStringList>
18
19#include "Application.h"
20#include "CameraDetectorMap.h"
21#include "CameraDistortionMap.h"
22#include "CameraFocalPlaneMap.h"
23#include "CameraGroundMap.h"
24#include "ControlMeasure.h"
25#include "ControlMeasureLogData.h"
26#include "ControlNet.h"
27#include "Cube.h"
28#include "IString.h"
29#include "Latitude.h"
30#include "Longitude.h"
31#include "PvlObject.h"
32#include "SerialNumberList.h"
33#include "SpecialPixel.h"
34#include "Statistics.h"
35
36using boost::numeric::ublas::symmetric_matrix;
37using boost::numeric::ublas::upper;
38using namespace std;
39
40namespace Isis {
47 ControlPoint::ControlPoint() : invalid(false) {
48 measures = NULL;
49 cubeSerials = NULL;
50
51 measures = new QHash< QString, ControlMeasure * >;
52 cubeSerials = new QStringList;
53
54 type = Free;
55 dateTime = "";
56 editLock = false;
57 ignore = false;
58 jigsawRejected = false;
60 aprioriSurfacePointSource = SurfacePointSource::None;
61 aprioriRadiusSource = RadiusSource::None;
62 parentNetwork = NULL;
63 referenceMeasure = NULL;
65 constraintStatus.reset();
66 }
67
68
75 measures = NULL;
76 cubeSerials = NULL;
77 referenceMeasure = NULL;
78 parentNetwork = NULL;
79
80 editLock = false;
81
82 measures = new QHash< QString, ControlMeasure * >;
83 cubeSerials = new QStringList;
84
85 QListIterator<QString> i(*other.cubeSerials);
86 while (i.hasNext()) {
87 QString sn = i.next();
88
89 const ControlMeasure *otherCm = other.GetMeasure(sn);
90 ControlMeasure *newMeasure = new ControlMeasure(*otherCm);
91 AddMeasure(newMeasure);
92
93 if (other.referenceMeasure == otherCm) {
94 SetRefMeasure(newMeasure);
95 }
96 }
97
98 id = other.id;
99 chooserName = other.chooserName;
100 dateTime = other.dateTime;
101 type = other.type;
102 invalid = other.invalid;
103 editLock = other.editLock;
104 jigsawRejected = other.jigsawRejected;
105 referenceExplicitlySet = other.referenceExplicitlySet;
106 ignore = other.ignore;
107 aprioriSurfacePointSource = other.aprioriSurfacePointSource;
108 aprioriSurfacePointSourceFile = other.aprioriSurfacePointSourceFile;
109 aprioriRadiusSource = other.aprioriRadiusSource;
110 aprioriRadiusSourceFile = other.aprioriRadiusSourceFile;
111 aprioriSurfacePoint = other.aprioriSurfacePoint;
112 adjustedSurfacePoint = other.adjustedSurfacePoint;
113 numberOfRejectedMeasures = other.numberOfRejectedMeasures;
114 constraintStatus = other.constraintStatus;
115 }
116
117
123 ControlPoint::ControlPoint(const QString &newId) : invalid(false) {
124 parentNetwork = NULL;
125 measures = NULL;
126 referenceMeasure = NULL;
128 measures = new QHash< QString, ControlMeasure * >;
129 cubeSerials = new QStringList;
130
131 id = newId;
132 type = Free;
133 editLock = false;
134 jigsawRejected = false;
136 ignore = false;
137 aprioriSurfacePointSource = SurfacePointSource::None;
138 aprioriRadiusSource = RadiusSource::None;
139 constraintStatus.reset();
140 }
141
147 if (measures != NULL) {
148 QList< QString > keys = measures->keys();
149 for (int i = 0; i < keys.size(); i++) {
150 delete(*measures)[keys[i]];
151 (*measures)[keys[i]] = NULL;
152 }
153
154 delete measures;
155 measures = NULL;
156 }
157
158 if (cubeSerials) {
159 delete cubeSerials;
160 cubeSerials = NULL;
161 }
162
163 referenceMeasure = NULL;
164 }
165
212
213 }
214
215
224 AddMeasure(measure);
225 }
226
227
233 // Make sure measure is unique
234 foreach(ControlMeasure * m, measures->values()) {
235 if (m->GetCubeSerialNumber() == measure->GetCubeSerialNumber()) {
236 QString msg = "The SerialNumber is not unique. A measure with "
237 "serial number [" + measure->GetCubeSerialNumber() + "] already "
238 "exists for ControlPoint [" + GetId() + "]";
239 throw IException(IException::Programmer, msg, _FILEINFO_);
240 }
241 }
242
243 if (!measures->size()) {
244 referenceMeasure = measure;
245 }
246 else if (referenceMeasure->IsIgnored() && !measure->IsIgnored() &&
247 !IsReferenceExplicit() && !IsEditLocked()) {
248 // The current "implicit" reference is ignored, but this new measure
249 // isn't, and the point is not edit locked, so make this measure the new
250 // reference
251 referenceMeasure = measure;
252 }
253
254 measure->parentPoint = this;
255 QString newSerial = measure->GetCubeSerialNumber();
256 measures->insert(newSerial, measure);
257 cubeSerials->append(newSerial);
258
259 // notify parent network if we have one
260 if (parentNetwork) {
261 parentNetwork->measureAdded(measure);
262 parentNetwork->emitNetworkStructureModified();
263 }
264 }
265
266
274 void ControlPoint::ValidateMeasure(QString serialNumber) const {
275 if (!measures->contains(serialNumber)) {
276 QString msg = "No measure with serial number [" + serialNumber +
277 "] is owned by this point";
278 throw IException(IException::Programmer, msg, _FILEINFO_);
279 }
280 }
281
282
289 int ControlPoint::Delete(QString serialNumber) {
290 ValidateMeasure(serialNumber);
291 ControlMeasure *cm = (*measures)[serialNumber];
292
293 // notify parent network of the change
294 if (parentNetwork) {
295 parentNetwork->measureDeleted(cm);
296
297 if (!IsIgnored() && !cm->IsIgnored()) {
298 parentNetwork->emitNetworkStructureModified();
299 }
300 }
301
302 if (cm->IsEditLocked()) {
303 return ControlMeasure::MeasureLocked;
304 }
305
306 // remove measure from the point's data structures
307 measures->remove(serialNumber);
308 cubeSerials->removeAt(cubeSerials->indexOf(serialNumber));
309
310 // update the reference measure
311 if (cubeSerials->size()) {
312 if (referenceMeasure == cm) {
313 referenceMeasure = (*measures)[cubeSerials->at(0)];
315 }
316 }
317 else {
318 referenceMeasure = NULL;
319 }
320
321 delete cm;
322 cm = NULL;
323
325
326 return ControlMeasure::Success;
327 }
328
329
339 void ControlPoint::emitMeasureModified(ControlMeasure *measure, ControlMeasure::ModType modType, QVariant oldValue, QVariant newValue) {
340 if (parentNetwork) {
341 parentNetwork->emitMeasureModified(measure, modType, oldValue, newValue);
342 }
343 }
344
345
353 return Delete(measure->GetCubeSerialNumber());
354 }
355
356
363 int ControlPoint::Delete(int index) {
364 if (index < 0 || index >= cubeSerials->size()) {
365 QString msg = "index [" + QString(index) + "] out of bounds";
366 throw IException(IException::Programmer, msg, _FILEINFO_);
367 }
368
369 return Delete(cubeSerials->at(index));
370 }
371
372
379 if (IsEditLocked()) {
380 return PointLocked;
381 }
382
383 aprioriSurfacePointSource = SurfacePointSource::None;
385 aprioriRadiusSource = RadiusSource::None;
387
389 constraintStatus.reset();
390
391 return Success;
392 }
393
394
402 ValidateMeasure(serialNumber);
403 return (*measures)[serialNumber];
404 }
405
406
413 const ControlMeasure *ControlPoint::GetMeasure(QString serialNumber) const {
414 ValidateMeasure(serialNumber);
415 return measures->value(serialNumber);
416 }
417
418
419 const ControlMeasure *ControlPoint::GetMeasure(int index) const {
420 if (index < 0 || index >= cubeSerials->size()) {
421 QString msg = "Index [" + toString(index) + "] out of range";
422 throw IException(IException::Programmer, msg, _FILEINFO_);
423 }
424
425 return GetMeasure(cubeSerials->at(index));
426 }
427
428
429 ControlMeasure *ControlPoint::GetMeasure(int index) {
430 if (index < 0 || index >= cubeSerials->size()) {
431 QString msg = "Index [" + toString(index) + "] out of range";
432 throw IException(IException::Programmer, msg, _FILEINFO_);
433 }
434
435 return GetMeasure(cubeSerials->at(index));
436 }
437
438
445 return !(referenceMeasure == NULL);
446 }
447
448
455 if (!HasRefMeasure()) {
456 QString msg = "Control point [" + GetId() + "] has no reference measure!";
457 throw IException(IException::Programmer, msg, _FILEINFO_);
458 }
459
460 return referenceMeasure;
461 }
462
463
468 if (!HasRefMeasure()) {
469 QString msg = "Control point [" + GetId() + "] has no reference measure!";
470 throw IException(IException::Programmer, msg, _FILEINFO_);
471 }
472
473 return referenceMeasure;
474 }
475
476
485 if (editLock) {
486 return PointLocked;
487 }
488 chooserName = name;
489 return Success;
490 }
491
492
502 if (editLock) {
503 return PointLocked;
504 }
505 dateTime = newDateTime;
506 return Success;
507 }
508
509
520 if (parentNetwork) {
521 parentNetwork->emitPointModified(this, ControlPoint::EditLockModified, editLock, lock);
522 }
523 editLock = lock;
524 return Success;
525 }
526
527
537 jigsawRejected = reject;
538 return Success;
539 }
540
541
550 if (editLock) {
551 return PointLocked;
552 }
553 QString oldId = id;
554 id = newId;
555 if (parentNetwork) {
556 parentNetwork->UpdatePointReference(this, oldId);
557 }
558 return Success;
559 }
560
561
568 if (editLock) {
569 return PointLocked;
570 }
571
573 return Success;
574 }
575
576
583 if (editLock) {
584 return PointLocked;
585 }
586
587 if (index < 0 || index >= cubeSerials->size()) {
588 QString msg = "Index [";
589 msg += toString(index) + "] out of range";
590 throw IException(IException::Programmer, msg, _FILEINFO_);
591 }
592
593 SetExplicitReference((*measures)[cubeSerials->at(index)]);
594 return Success;
595 }
596
597
604 if (editLock) {
605 return PointLocked;
606 }
607
608 if (!cubeSerials->contains(sn)) {
609 QString msg = "Point [" + id + "] has no measure with serial number [" +
610 sn + "]";
611 throw IException(IException::Programmer, msg, _FILEINFO_);
612 }
613
614 SetExplicitReference((*measures)[sn]);
615 return Success;
616 }
617
618
639 referenceMeasure = measure;
640 }
641
642
650 if (editLock) {
651 return PointLocked;
652 }
653
654 bool oldStatus = ignore;
655 ignore = newIgnoreStatus;
656
657 // only update if there was a change in status
658 if (oldStatus != ignore) {
660 if (parentNetwork) {
661 if (ignore) {
662 parentNetwork->pointIgnored(this);
663 }
664 else {
665 parentNetwork->pointUnIgnored(this);
666 }
667 parentNetwork->emitPointModified(this, ControlPoint::IgnoredModified, oldStatus, ignore);
668 }
669 }
670
671 return Success;
672 }
673
674
689 SurfacePoint newSurfacePoint) {
690
692 adjustedSurfacePoint = newSurfacePoint;
693 return Success;
694 }
695
696
706 if (type != Fixed && type != Free && type != Constrained) {
707 QString msg = "Invalid Point Enumeration, [" + QString(type) + "], for "
708 "Control Point [" + GetId() + "]";
709 throw IException(IException::Programmer, msg, _FILEINFO_);
710 }
711
712 if (editLock) {
713 return PointLocked;
714 }
715 if (parentNetwork) {
716 parentNetwork->emitPointModified(this, ControlPoint::TypeModified, type, newType);
717 }
718
720 type = newType;
721 return Success;
722 }
723
724
733 RadiusSource::Source source) {
734 if (editLock) {
735 return PointLocked;
736 }
738 aprioriRadiusSource = source;
739 return Success;
740 }
741
742
752 QString sourceFile) {
753 if (editLock) {
754 return PointLocked;
755 }
757 aprioriRadiusSourceFile = sourceFile;
758 return Success;
759 }
760
761
776 SurfacePoint aprioriSP) {
778 if (parentNetwork) {
779 coordType = parentNetwork->GetCoordType();
780 }
781 if (editLock) {
782 return PointLocked;
783 }
784 // ***TBD*** Does it make sense to try to do a generic check here? The
785 // data types are different (angles vs distance) so for now do a switch.
786 switch (coordType) {
788 if (aprioriSP.GetLatSigma().isValid())
789 constraintStatus.set(Coord1Constrained);
790 if (aprioriSP.GetLonSigma().isValid())
791 constraintStatus.set(Coord2Constrained);
792 if (aprioriSP.GetLocalRadiusSigma().isValid())
793 constraintStatus.set(Coord3Constrained);
794 break;
796 if (aprioriSP.GetXSigma().isValid())
797 constraintStatus.set(Coord1Constrained);
798 if (aprioriSP.GetYSigma().isValid())
799 constraintStatus.set(Coord2Constrained);
800 if (aprioriSP.GetZSigma().isValid())
801 constraintStatus.set(Coord3Constrained);
802 }
803
805 aprioriSurfacePoint = aprioriSP;
806 return Success;
807 }
808
809
818 SurfacePointSource::Source source) {
819 if (editLock) {
820 return PointLocked;
821 }
824 return Success;
825 }
826
827
836 QString sourceFile) {
837 if (editLock) {
838 return PointLocked;
839 }
842 return Success;
843 }
844
845
896 // TODO (KLE): where should call this go? Also, what's the point? The method has no description.
898
899 // if point is fixed or constrained, ensure valid a priori point coordinates exist
900 if ( (IsFixed() || IsConstrained()) && !aprioriSurfacePoint.Valid() ) {
901 QString msg = "In method ControlPoint::ComputeApriori(). ControlPoint [" + GetId() + "] is ";
902 msg += "fixed or constrained and requires a priori coordinates";
903 throw IException(IException::User, msg, _FILEINFO_);
904 }
905
906 double xB = 0.0; // body-fixed x
907 double yB = 0.0; // body-fixed y
908 double zB = 0.0; // body-fixed z
909 double r2B = 0.0; // radius squared in body-fixed
910 int goodMeasures = 0;
911 double pB[3];
912
913 // loop over measures to ...
914 // 1) set focal plane x,y coordinates for all unignored measures;
915 // 2) sum latitude, longitude, and radius coordinates in preparation for computing a priori
916 // coordinates by averaging.
917 for (int i = 0; i < cubeSerials->size(); i++) {
919 if (m->IsIgnored()) {
920 continue;
921 }
922
923 Camera *cam = m->Camera();
924 if (cam == NULL) {
925 QString cubeSN = m->GetCubeSerialNumber();
926 QString msg = "in method ControlPoint::ComputeApriori(). Camera has not been set in ";
927 msg += "measure for cube serial number [" + cubeSN + "], Control Point id ";
928 msg += "[" + GetId() + "]. Camera must be set prior to calculating a priori coordinates";
929 throw IException(IException::Programmer, msg, _FILEINFO_);
930 }
931
932 bool setImageSuccess = cam->SetImage(m->GetSample(), m->GetLine());
933 // CSM cameras do not have focal planes so use sample and line instead
934 if (cam->GetCameraType() == Camera::Csm) {
935 m->SetFocalPlaneMeasured(m->GetSample(),
936 m->GetLine());
937 }
938 else {
939 m->SetFocalPlaneMeasured(cam->DistortionMap()->UndistortedFocalPlaneX(),
940 cam->DistortionMap()->UndistortedFocalPlaneY());
941 }
942
943 // TODO: Seems like we should be able to skip this computation if point is fixed or
944 // constrained in any coordinate. Currently we are always summing coordinates here. We could
945 // save time by not doing this for fixed or constrained points.
946 if (setImageSuccess) {
947 goodMeasures++;
948 cam->Coordinate(pB);
949 xB += pB[0];
950 yB += pB[1];
951 zB += pB[2];
952 r2B += pB[0]*pB[0] + pB[1]*pB[1] + pB[2]*pB[2];
953 }
954 }
955
956 // if point is Fixed or Constrained in any number of coordinates, initialize adjusted surface
957 // point to a priori coordinates (set in e.g. qnet or cneteditor) and exit
958 if( IsFixed() || IsConstrained() || id.contains("Lidar")) {
960 return Success;
961 }
962
963 // if point is Free, we continue to compute a priori coordinates
964
965 // if no good measures, we're done
966 // TODO: is the message true/meaningful?
967 if (goodMeasures == 0) {
968 QString msg = "in method ControlPoint::ComputeApriori(). ControlPoint [" + GetId() + "] has ";
969 msg += "no measures which project to the body";
970 throw IException(IException::User, msg, _FILEINFO_);
971 }
972
973 // Compute the averages if all coordinates are free
974 // TODO: confirm if this "if" statement is necessary
975 if (GetType() == Free || NumberOfConstrainedCoordinates() == 0) {
976 double avgX = xB / goodMeasures;
977 double avgY = yB / goodMeasures;
978 double avgZ = zB / goodMeasures;
979 double avgR2 = r2B / goodMeasures;
980 double scale = sqrt(avgR2/(avgX*avgX+avgY*avgY+avgZ*avgZ));
981
986 }
987
989 SetAprioriSurfacePointSource(SurfacePointSource::AverageOfMeasures);
990 SetAprioriRadiusSource(RadiusSource::AverageOfMeasures);
991
992 return Success;
993 }
994
995
1025 if (IsIgnored()) {
1026 return Failure;
1027 }
1028
1029 PointModified();
1030
1031 // Loop for each measure to compute the error
1032 QList<QString> keys = measures->keys();
1033
1034 for (int j = 0; j < keys.size(); j++) {
1035 ControlMeasure *m = (*measures)[keys[j]];
1036 if (m->IsIgnored()) {
1037 continue;
1038 }
1039
1040 Camera *cam = m->Camera();
1041
1042 double cuSamp;
1043 double cuLine;
1044 CameraFocalPlaneMap *fpmap = m->Camera()->FocalPlaneMap();
1045
1046 // Map the coordinates of the control point through the Spice of the
1047 // measurement sample/line to get the computed sample/line. This must be
1048 // done manually because the camera will compute a new time for line scanners,
1049 // instead of using the measured time.
1051
1052 // Convert the residuals in millimeters to undistorted pixels
1053 if (cam->GetCameraType() == Isis::Camera::Radar) {
1054 // For radar line is calculated from time in the camera. Use the
1055 // closest line to scale the focal plane y (doppler shift) to image line
1056 // for computing the line residual. Get a local ratio
1057 // measureLine = adjacentLine
1058 // ------------ -------------- in both cases, doppler shift
1059 // dopplerMLine dopplerAdjLine is calculated using SPICE
1060 // at the time of the measurement
1061 //
1062 // 1. Get the surface point mapped to by an adjacent pixel above (if
1063 // doppler is < 0) or below (if doppler is > 0) the measured pixel
1064 // 2. Set image to the measured sample/line to load the SPICE for the
1065 // time of the measurement.
1066 // 3. Map the surface point from the adjacent pixel through the SPICE
1067 // into the image plane to get a scale for mapping from doppler
1068 // shift to line. Apply the scale to get the line residual
1069 double sample = m->GetSample();
1070 double computedY = m->GetFocalPlaneComputedY();
1071 double computedX = m->GetFocalPlaneComputedX();
1072 double adjLine;
1073
1074 // Step 1. What happens if measured line is 1??? TODO
1075 if (computedY < 0) {
1076 adjLine = m->GetLine() - 1.;
1077 }
1078 else {
1079 adjLine = m->GetLine() + 1.;
1080 }
1081
1082 cam->SetImage(sample, adjLine);
1083 SurfacePoint sp = cam->GetSurfacePoint();
1084
1085 // Step 2.
1086 cam->SetImage(sample, m->GetLine());
1087 double focalplaneX;
1088 double scalingY;
1089
1090 // Step 3.
1091 // The default bool value will come from CameraGroundMap instead of
1092 // RadarGroundMap so be explicit to turn off back-of-planet test.
1093 cam->GroundMap()->GetXY(sp, &focalplaneX, &scalingY, false);
1094 double deltaLine;
1095
1096 if (computedY < 0) {
1097 deltaLine = -computedY/scalingY;
1098 }
1099 else {
1100 deltaLine = computedY/scalingY;
1101 }
1102
1103 // Now map through the camera steps to take X from slant range to ground
1104 // range to pixels. Y just tracks through as 0.
1105 if (cam->DistortionMap()->SetUndistortedFocalPlane(computedX,
1106 computedY)){
1107 double focalPlaneX = cam->DistortionMap()->FocalPlaneX();
1108 double focalPlaneY = cam->DistortionMap()->FocalPlaneY();
1109 fpmap->SetFocalPlane(focalPlaneX,focalPlaneY);
1110 }
1111 cuSamp = fpmap->DetectorSample();
1112 cuLine = m->GetLine() + deltaLine;
1113 }
1114 else if (cam->GetCameraType() == Isis::Camera::Csm) {
1115 //
1116 cuSamp = m->GetFocalPlaneComputedX();
1117 cuLine = m->GetFocalPlaneComputedY();
1118 }
1119 else {
1120 // Now things get tricky. We want to produce errors in pixels not mm
1121 // but some of the camera maps could fail. One that won't is the
1122 // FocalPlaneMap which takes x/y to detector s/l. We will bypass the
1123 // distortion map and have residuals in undistorted pixels.
1124 if (!fpmap->SetFocalPlane(m->GetFocalPlaneComputedX(), m->GetFocalPlaneComputedY())) {
1125 QString msg = "Sanity check #1 for ControlPoint [" + GetId() +
1126 "], ControlMeasure [" + m->GetCubeSerialNumber() + "]";
1127 throw IException(IException::Programmer, msg, _FILEINFO_);
1128 // This error shouldn't happen but check anyways
1129 }
1130
1131 cuSamp = fpmap->DetectorSample();
1132 cuLine = fpmap->DetectorLine();
1133 }
1134
1135 // Compute the measures sample and line
1136
1137 double muSamp;
1138 double muLine;
1139
1140 if (cam->GetCameraType() == Isis::Camera::Radar ||
1141 cam->GetCameraType() == Isis::Camera::Csm) {
1142 // For CSM and Radar we use distorted pixels
1143 muSamp = m->GetSample();
1144 muLine = m->GetLine();
1145 }
1146 else {
1147 // For other sensors conver to undistorted pixels
1148 // Again we will bypass the distortion map and have residuals in undistorted pixels.
1149 if (!fpmap->SetFocalPlane(m->GetFocalPlaneMeasuredX(), m->GetFocalPlaneMeasuredY())) {
1150 QString msg = "Sanity check #2 for ControlPoint [" + GetId() +
1151 "], ControlMeasure [" + m->GetCubeSerialNumber() + "]";
1152 throw IException(IException::Programmer, msg, _FILEINFO_);
1153 // This error shouldn't happen but check anyways
1154 }
1155 muSamp = fpmap->DetectorSample();
1156 muLine = fpmap->DetectorLine();
1157 }
1158
1159 // The units are in detector sample/lines. We will apply the instrument
1160 // summing mode to get close to real pixels. Note however we are in
1161 // undistorted pixels except for radar and CSM instruments.
1162 double sampResidual = muSamp - cuSamp;
1163 double lineResidual = muLine - cuLine;
1164 m->SetResidual(sampResidual, lineResidual);
1165 }
1166
1167 return Success;
1168 }
1169
1189 if (IsIgnored()) {
1190 return Failure;
1191 }
1192
1193 PointModified();
1194
1195 // Loop for each measure to compute the error
1196 QList<QString> keys = measures->keys();
1197
1198 for (int j = 0; j < keys.size(); j++) {
1199 ControlMeasure *m = (*measures)[keys[j]];
1200 if (m->IsIgnored()) {
1201 continue;
1202 }
1203
1204 Camera *cam = m->Camera();
1205 double cudx, cudy;
1206
1207 // Map the coordinates of the control point through the Spice of the
1208 // measurement sample/line to get the computed undistorted focal plane
1209 // coordinates (mm if not radar).
1210 // This works for radar too because in the undistorted focal plane,
1211 // y has not been set to 0 (set to 0 when going to distorted focal plane
1212 // or ground range in this case), so we can hold the Spice to calculate
1213 // residuals in undistorted focal plane coordinates.
1214 // This does not work with CSM as it does not have a focal plane so
1215 // just use the sample and line
1216 if (cam->GetCameraType() == Camera::Csm) {
1217 cam->SetGround(GetAdjustedSurfacePoint());
1218 cudx = cam->Sample();
1219 cudy = cam->Line();
1220 // Reset to measure
1221 cam->SetImage(m->GetSample(), m->GetLine());
1222 }
1223 else {
1224 // no need to call setimage for framing camera
1225 if (cam->GetCameraType() != 0) {
1226 cam->SetImage(m->GetSample(), m->GetLine());
1227 }
1228 // The default bool value is true. Turn back-of-planet test off for bundle adjustment.
1229 cam->GroundMap()->GetXY(GetAdjustedSurfacePoint(), &cudx, &cudy, false);
1230 }
1231
1232 m->SetFocalPlaneComputed(cudx, cudy);
1233 }
1234
1235 return Success;
1236 }
1237
1238 QString ControlPoint::GetChooserName() const {
1239 if (chooserName != "") {
1240 return chooserName;
1241 }
1242 else {
1243 return FileName(Application::Name()).name();
1244 }
1245 }
1246
1249 return !chooserName.isEmpty();
1250 }
1251
1254 return !dateTime.isEmpty();
1255 }
1256
1257
1258 QString ControlPoint::GetDateTime() const {
1259 if (dateTime != "") {
1260 return dateTime;
1261 }
1262 else {
1263 return Application::DateTime();
1264 }
1265 }
1266
1267
1268 bool ControlPoint::IsEditLocked() const {
1269 return editLock;
1270 }
1271
1272
1273 bool ControlPoint::IsRejected() const {
1274 return jigsawRejected;
1275 }
1276
1277
1278 SurfacePoint ControlPoint::GetAdjustedSurfacePoint() const {
1279 return adjustedSurfacePoint;
1280 }
1281
1282
1288 if (adjustedSurfacePoint.Valid()) {
1289 return adjustedSurfacePoint;
1290 }
1291 else {
1292 return aprioriSurfacePoint;
1293 }
1294 }
1295
1296
1302 QString ControlPoint::GetId() const {
1303 return id;
1304 }
1305
1306
1307 bool ControlPoint::IsIgnored() const {
1308 return ignore;
1309 }
1310
1311
1312 bool ControlPoint::IsValid() const {
1313 return !invalid;
1314 }
1315
1316
1317 bool ControlPoint::IsInvalid() const {
1318 return invalid;
1319 }
1320
1321
1330 QString str;
1331
1332 switch (pointType) {
1333 case Fixed:
1334 str = "Fixed";
1335 break;
1336 case Constrained:
1337 str = "Constrained";
1338 break;
1339 case Free:
1340 str = "Free";
1341 break;
1342 }
1343
1344 return str;
1345 }
1346
1347
1356 QString pointTypeString) {
1357
1358 // On failure assume Free
1360
1361 QString errMsg = "There is no PointType that has a string representation"
1362 " of \"";
1363 errMsg += pointTypeString;
1364 errMsg += "\".";
1365
1366 if (pointTypeString == "Fixed") {
1368 }
1369 else if (pointTypeString == "Constrained") {
1371 }
1372 else if (pointTypeString == "Free") {
1374 }
1375 else {
1376 throw IException(IException::Programmer, errMsg, _FILEINFO_);
1377 }
1378
1379 return type;
1380 }
1381
1382
1389 return PointTypeToString(GetType());
1390 }
1391
1392
1400
1401
1409 QString ControlPoint::RadiusSourceToString(RadiusSource::Source source) {
1410 QString str;
1411
1412 switch (source) {
1413 case RadiusSource::None:
1414 str = "None";
1415 break;
1416 case RadiusSource::User:
1417 str = "User";
1418 break;
1419 case RadiusSource::AverageOfMeasures:
1420 str = "AverageOfMeasures";
1421 break;
1422 case RadiusSource::Ellipsoid:
1423 str = "Ellipsoid";
1424 break;
1425 case RadiusSource::DEM:
1426 str = "DEM";
1427 break;
1428 case RadiusSource::BundleSolution:
1429 str = "BundleSolution";
1430 break;
1431 }
1432
1433 return str;
1434 }
1435
1436
1444 ControlPoint::RadiusSource::Source ControlPoint::StringToRadiusSource(
1445 QString str) {
1446
1447 str = str.toLower();
1448 RadiusSource::Source source = RadiusSource::None;
1449
1450 if (str == "user") {
1451 source = RadiusSource::User;
1452 }
1453 else if (str == "averageofmeasures") {
1454 source = RadiusSource::AverageOfMeasures;
1455 }
1456 else if (str == "ellipsoid") {
1457 source = RadiusSource::Ellipsoid;
1458 }
1459 else if (str == "dem") {
1460 source = RadiusSource::DEM;
1461 }
1462 else if (str == "bundlesolution") {
1463 source = RadiusSource::BundleSolution;
1464 }
1465
1466 return source;
1467 }
1468
1469
1470
1479
1480
1489 SurfacePointSource::Source source) {
1490
1491 QString str;
1492
1493 switch (source) {
1494 case SurfacePointSource::None:
1495 str = "None";
1496 break;
1497 case SurfacePointSource::User:
1498 str = "User";
1499 break;
1500 case SurfacePointSource::AverageOfMeasures:
1501 str = "AverageOfMeasures";
1502 break;
1503 case SurfacePointSource::Reference:
1504 str = "Reference";
1505 break;
1506 case SurfacePointSource::Basemap:
1507 str = "Basemap";
1508 break;
1509 case SurfacePointSource::BundleSolution:
1510 str = "BundleSolution";
1511 break;
1512 }
1513
1514 return str;
1515 }
1516
1517
1525 ControlPoint::SurfacePointSource::Source
1527 QString str) {
1528
1529 str = str.toLower();
1530 SurfacePointSource::Source source = SurfacePointSource::None;
1531
1532 if (str == "user") {
1533 source = SurfacePointSource::User;
1534 }
1535 else if (str == "averageofmeasures") {
1536 source = SurfacePointSource::AverageOfMeasures;
1537 }
1538 else if (str == "reference") {
1539 source = SurfacePointSource::Reference;
1540 }
1541 else if (str == "basemap") {
1542 source = SurfacePointSource::Basemap;
1543 }
1544 else if (str == "bundlesolution") {
1545 source = SurfacePointSource::BundleSolution;
1546 }
1547
1548 return source;
1549 }
1550
1551
1560
1561
1562 SurfacePoint ControlPoint::GetAprioriSurfacePoint() const {
1563 return aprioriSurfacePoint;
1564 }
1565
1566
1567 ControlPoint::RadiusSource::Source ControlPoint::GetAprioriRadiusSource()
1568 const {
1569 return aprioriRadiusSource;
1570 }
1571
1572
1573 bool ControlPoint::HasAprioriCoordinates() {
1574 if (aprioriSurfacePoint.GetX().isValid() &&
1575 aprioriSurfacePoint.GetY().isValid() &&
1576 aprioriSurfacePoint.GetZ().isValid()) {
1577 return true;
1578 }
1579
1580 return false;
1581 // return aprioriSurfacePoint.Valid(); ???
1582 }
1583
1584
1591 return (type != Fixed && type != Constrained);
1592 }
1593
1594
1601 return (type == Fixed);
1602 }
1603
1604
1611 // if point type is Free, we ignore any a priori sigmas on the coordinates
1612 if (type == Free) {
1613 return false;
1614 }
1615
1616 return constraintStatus.any();
1617 }
1618
1619
1627 return constraintStatus[Coord1Constrained];
1628 }
1629
1630
1638 return constraintStatus[Coord2Constrained];
1639 }
1640
1648 return constraintStatus[Coord3Constrained];
1649 }
1650
1651
1660
1661
1668 return !( aprioriRadiusSourceFile.isEmpty() || aprioriRadiusSourceFile.isNull() );
1669 }
1670
1671
1672 QString ControlPoint::GetAprioriRadiusSourceFile() const {
1674 }
1675
1676
1677 ControlPoint::SurfacePointSource::Source
1678 ControlPoint::GetAprioriSurfacePointSource() const {
1680 }
1681
1682
1691
1692
1693 QString ControlPoint::GetAprioriSurfacePointSourceFile() const {
1695 }
1696
1697
1698 int ControlPoint::GetNumMeasures() const {
1699 return measures->size();
1700 }
1701
1702
1708 int size = 0;
1709 QList<QString> keys = measures->keys();
1710 for (int cm = 0; cm < keys.size(); cm++) {
1711 if (!(*measures)[keys[cm]]->IsIgnored()) {
1712 size++;
1713 }
1714 }
1715 return size;
1716 }
1717
1718
1725 int size = 0;
1726 QList<QString> keys = measures->keys();
1727 for (int cm = 0; cm < keys.size(); cm++) {
1728 if ((*measures)[keys[cm]]->IsEditLocked()) {
1729 size++;
1730 }
1731 }
1732 return size;
1733 }
1734
1735
1742 bool ControlPoint::HasSerialNumber(QString serialNumber) const {
1743 return cubeSerials->contains(serialNumber);
1744 }
1745
1746
1754
1755
1760 if (!HasRefMeasure()) {
1761 QString msg = "There is no reference measure set in the ControlPoint [" +
1762 GetId() + "]";
1763 throw IException(IException::Programmer, msg, _FILEINFO_);
1764 }
1765
1766 return referenceMeasure->GetCubeSerialNumber();
1767 }
1768
1769
1778 int ControlPoint::IndexOf(ControlMeasure *cm, bool throws) const {
1779 return IndexOf(cm->GetCubeSerialNumber(), throws);
1780 }
1781
1782
1791 int ControlPoint::IndexOf(QString sn, bool throws) const {
1792 int index = cubeSerials->indexOf(sn);
1793
1794 if (throws && index == -1) {
1795 QString msg = "ControlMeasure [" + sn + "] does not exist in point [" +
1796 id + "]";
1797 throw IException(IException::Programmer, msg, _FILEINFO_);
1798 }
1799
1800 return index;
1801 }
1802
1803
1813 if (!HasRefMeasure()) {
1814 QString msg = "There is no reference measure for point [" + id + "]."
1815 " This also means of course that the point is empty!";
1816 throw IException(IException::Programmer, msg, _FILEINFO_);
1817 }
1818
1819 int index = cubeSerials->indexOf(referenceMeasure->GetCubeSerialNumber());
1820
1821 return index;
1822 }
1823
1824
1837 double(ControlMeasure::*statFunc)() const) const {
1838 Statistics stats;
1839 foreach(ControlMeasure * cm, *measures) {
1840 if (!cm->IsIgnored()) {
1841 stats.AddData((cm->*statFunc)());
1842 }
1843 }
1844
1845 return stats;
1846 }
1847
1848
1849 Statistics ControlPoint::GetStatistic(long dataType) const {
1850 Statistics stats;
1851 foreach(ControlMeasure * cm, *measures) {
1852 if (!cm->IsIgnored()) {
1853 stats.AddData(cm->GetLogData(dataType).GetNumericalValue());
1854 }
1855 }
1856
1857 return stats;
1858 }
1859
1860
1867 QList< ControlMeasure * > ControlPoint::getMeasures(
1868 bool excludeIgnored) const {
1869 QList< ControlMeasure * > orderedMeasures;
1870 for (int i = 0; i < cubeSerials->size(); i++) {
1871 ControlMeasure *measure = measures->value((*cubeSerials)[i]);
1872 if (!excludeIgnored || !measure->IsIgnored()) {
1873 orderedMeasures.append(measures->value((*cubeSerials)[i]));
1874 }
1875 }
1876 return orderedMeasures;
1877 }
1878
1879
1883 QList< QString > ControlPoint::getCubeSerialNumbers() const {
1884 return *cubeSerials;
1885 }
1886
1887
1895 const ControlMeasure *ControlPoint::operator[](QString serialNumber) const {
1896 return GetMeasure(serialNumber);
1897 }
1898
1899
1907 ControlMeasure *ControlPoint::operator[](QString serialNumber) {
1908 return GetMeasure(serialNumber);
1909 }
1910
1911
1920 const ControlMeasure *ControlPoint::operator[](int index) const {
1921 return GetMeasure(index);
1922 }
1923
1924
1933 ControlMeasure *ControlPoint::operator[](int index) {
1934 return GetMeasure(index);
1935 }
1936
1937
1945 bool ControlPoint::operator!=(const ControlPoint &other) const {
1946 return !(*this == other);
1947 }
1948
1949
1958 bool ControlPoint::operator==(const ControlPoint &other) const {
1959 return other.GetNumMeasures() == GetNumMeasures() &&
1960 other.id == id &&
1961 other.type == type &&
1962 other.chooserName == chooserName &&
1963 other.editLock == editLock &&
1964 other.ignore == ignore &&
1965 other.aprioriSurfacePointSource == aprioriSurfacePointSource &&
1966 other.aprioriSurfacePointSourceFile == aprioriSurfacePointSourceFile &&
1967 other.aprioriRadiusSource == aprioriRadiusSource &&
1968 other.aprioriRadiusSourceFile == aprioriRadiusSourceFile &&
1969 other.aprioriSurfacePoint == aprioriSurfacePoint &&
1970 other.adjustedSurfacePoint == adjustedSurfacePoint &&
1971 other.invalid == invalid &&
1972 other.measures == measures &&
1973 other.dateTime == dateTime &&
1974 other.jigsawRejected == jigsawRejected &&
1975 other.constraintStatus == constraintStatus &&
1976 other.referenceExplicitlySet == referenceExplicitlySet &&
1977 other.numberOfRejectedMeasures == numberOfRejectedMeasures &&
1978 other.cubeSerials == cubeSerials &&
1979 other.referenceMeasure == referenceMeasure;
1980 }
1981
1982
1999 const ControlPoint &ControlPoint::operator=(const ControlPoint &other) {
2000
2001 if (this != &other) {
2002 bool oldLock = editLock;
2003 editLock = false;
2004 for (int i = cubeSerials->size() - 1; i >= 0; i--) {
2005 (*measures)[cubeSerials->at(i)]->SetEditLock(false);
2006 Delete(cubeSerials->at(i));
2007 }
2008
2009 //measures->clear(); = new QHash< QString, ControlMeasure * >;
2010
2011 QHashIterator< QString, ControlMeasure * > i(*other.measures);
2012 while (i.hasNext()) {
2013 i.next();
2014 ControlMeasure *newMeasure = new ControlMeasure;
2015 *newMeasure = *i.value();
2016 AddMeasure(newMeasure);
2017 if (other.referenceMeasure == i.value()) {
2018 SetRefMeasure(newMeasure);
2019 }
2020 }
2021
2022 invalid = other.invalid;
2023 referenceExplicitlySet = other.referenceExplicitlySet;
2024 numberOfRejectedMeasures = other.numberOfRejectedMeasures;
2025 constraintStatus = other.constraintStatus;
2026
2027 SetId(other.id);
2028 SetChooserName(other.chooserName);
2029 SetDateTime(other.dateTime);
2030 SetType(other.type);
2031 SetRejected(other.jigsawRejected);
2032 SetIgnored(other.ignore);
2033 SetAprioriSurfacePointSource(other.aprioriSurfacePointSource);
2034 SetAprioriSurfacePointSourceFile(other.aprioriSurfacePointSourceFile);
2035 SetAprioriRadiusSource(other.aprioriRadiusSource);
2036 SetAprioriRadiusSourceFile(other.aprioriRadiusSourceFile);
2037 SetAprioriSurfacePoint(other.aprioriSurfacePoint);
2038 SetAdjustedSurfacePoint(other.adjustedSurfacePoint);
2039
2040 // Set edit lock last so the it doesn't interfere with copying the other fields over.
2041 editLock = oldLock;
2042 SetEditLock(other.editLock);
2043 }
2044
2045 return *this;
2046 }
2047
2048
2052 void ControlPoint::PointModified() {
2053 dateTime = "";
2054 }
2055
2056
2058 void ControlPoint::ZeroNumberOfRejectedMeasures()
2059
2060 {
2061 numberOfRejectedMeasures = 0;
2062 }
2063
2064
2071 void ControlPoint::SetNumberOfRejectedMeasures(int numRejected) {
2072 numberOfRejectedMeasures = numRejected;
2073 }
2074
2075
2082 int ControlPoint::GetNumberOfRejectedMeasures() const {
2083 return numberOfRejectedMeasures;
2084 }
2085
2092 double ControlPoint::GetSampleResidualRms() const {
2093 int nmeasures = measures->size();
2094 if ( nmeasures <= 0 ) {
2095 return 0.0;
2096 }
2097
2098 Statistics stats;
2099
2100 for( int i = 0; i < nmeasures; i++) {
2101 const ControlMeasure* m = GetMeasure(i);
2102 if ( !m ) {
2103 continue;
2104 }
2105
2106 if ( !m->IsIgnored() || m->IsRejected() ) {
2107 continue;
2108 }
2109
2110 stats.AddData(m->GetSampleResidual());
2111 }
2112
2113 return stats.Rms();
2114 }
2115
2116
2123 double ControlPoint::GetLineResidualRms() const {
2124 int nmeasures = measures->size();
2125 if ( nmeasures <= 0 ) {
2126 return 0.0;
2127 }
2128
2129 Statistics stats;
2130
2131 for( int i = 0; i < nmeasures; i++) {
2132 const ControlMeasure* m = GetMeasure(i);
2133 if ( !m ) {
2134 continue;
2135 }
2136
2137 if ( !m->IsIgnored() || m->IsRejected() ) {
2138 continue;
2139 }
2140
2141 stats.AddData(m->GetLineResidual());
2142 }
2143
2144 return stats.Rms();
2145 }
2146
2147
2154 double ControlPoint::GetResidualRms() const {
2155 int nmeasures = measures->size();
2156 if ( nmeasures <= 0 ) {
2157 return 0.0;
2158 }
2159
2160 Statistics stats;
2161
2162 for( int i = 0; i < nmeasures; i++) {
2163 const ControlMeasure* m = GetMeasure(i);
2164 if ( !m ) {
2165 continue;
2166 }
2167
2168 if ( m->IsIgnored() || m->IsRejected() ) {
2169 continue;
2170 }
2171
2172 stats.AddData(m->GetSampleResidual());
2173 stats.AddData(m->GetLineResidual());
2174 }
2175
2176 return stats.Rms();
2177 }
2178
2184 void ControlPoint::ClearJigsawRejected() {
2185 int nmeasures = measures->size();
2186 if ( nmeasures <= 0 ) {
2187 return;
2188 }
2189
2190 for( int i = 0; i < nmeasures; i++) {
2191 ControlMeasure* m = GetMeasure(i);
2192 if ( !m ) {
2193 continue;
2194 }
2195
2196 m->SetRejected(false);
2197 }
2198
2199 SetRejected(false);
2200 }
2201
2202}
static QString DateTime(time_t *curtime=0)
Returns the date and time as a QString.
static QString Name()
Returns the name of the application.
Convert between distorted focal plane and detector coordinates.
Camera(Cube &cube)
Constructs the Camera object.
Definition Camera.cpp:56
@ Radar
Radar Camera.
Definition Camera.h:362
@ Csm
Community Sensor Model Camera.
Definition Camera.h:365
a control measurement
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
ControlPoint * parentPoint
Pointer to parent ControlPoint, may be null.
ModType
Control Measure Modification Types.
void pointIgnored(ControlPoint *point)
Update the ControlNet's internal structure when a ControlPoint is ignored.
SurfacePoint::CoordinateType GetCoordType()
Get the control point coordinate type (see the available types in SurfacePoint.h).
void emitPointModified(ControlPoint *point, ControlPoint::ModType type, QVariant oldValue, QVariant newValue)
This method is a wrapper to emit the pointModified() signal and is called whenever a change is made t...
void emitNetworkStructureModified()
This method is a wrapper to emit the networkStructureModified() signal.
void measureAdded(ControlMeasure *measure)
Updates the ControlNet graph for the measure's serial number to reflect the addition.
void UpdatePointReference(ControlPoint *point, QString oldId)
Updates the key reference (poind Id) from the old one to what the point id was changet to.
void measureDeleted(ControlMeasure *measure)
Updates the node for this measure's serial number to reflect the deletion.
void emitMeasureModified(ControlMeasure *measure, ControlMeasure::ModType type, QVariant oldValue, QVariant newValue)
This method is a wrapper to emit the measureModified() signal and is called whenever a change is made...
void pointUnIgnored(ControlPoint *point)
Update the ControlNet's internal structure when a ControlPoint is un-ignored.
A single control point.
const ControlMeasure * GetRefMeasure() const
Get the reference control measure.
static QString RadiusSourceToString(RadiusSource::Source source)
Obtain a string representation of a given RadiusSource.
static SurfacePointSource::Source StringToSurfacePointSource(QString str)
Obtain a SurfacePoint::Source from a string.
Status
This is a return status for many of the mutating (setter) method calls.
@ PointLocked
This is returned when the operation requires Edit Lock to be false but it is currently true.
@ Success
This is returned when the operation successfully took effect.
@ Failure
This is returned when an operation cannot be performed due to a problem such as the point is ignored ...
int NumberOfConstrainedCoordinates()
Return bool indicating if point is Constrained or not.
Status SetEditLock(bool editLock)
Set the EditLock state.
QString dateTime
This is the last modified date and time.
bool editLock
This stores the edit lock state.
bool IsFree() const
Return bool indicating if point is Free or not.
static RadiusSource::Source StringToRadiusSource(QString str)
Obtain a RadiusSource::Source from a string.
bool invalid
If we forced a build that we would normally have thrown an exception for then this is set to true.
Status SetAprioriSurfacePoint(SurfacePoint aprioriSP)
This updates the apriori surface point.
QString id
This is the control point ID.
void ValidateMeasure(QString serialNumber) const
Throws an exception if none of the point's measures have the given serial number.
QString aprioriRadiusSourceFile
The name of the file that derives the apriori surface point's radius.
Status SetId(QString id)
Sets the Id of the control point.
QString aprioriSurfacePointSourceFile
FileName where the apriori surface point originated from.
Status SetAprioriRadiusSource(RadiusSource::Source source)
This updates the source of the radius of the apriori surface point.
SurfacePoint aprioriSurfacePoint
The apriori surface point.
bool jigsawRejected
This stores the jigsaw rejected state.
RadiusSource::Source aprioriRadiusSource
Where the apriori surface point's radius originated from, most commonly used by jigsaw.
bool IsReferenceExplicit() const
Status ComputeResiduals_Millimeters()
This method computes the residuals for a point.
virtual ~ControlPoint()
This destroys the current instance and cleans up any and all allocated memory.
bool HasDateTime() const
Returns true if the datetime is not empty.
Status SetChooserName(QString name)
Set the point's chooser name.
bool HasRefMeasure() const
Checks to see if a reference measure is set.
int GetNumValidMeasures() const
int GetNumLockedMeasures() const
Returns the number of locked control measures.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
Status SetRejected(bool rejected)
Set the jigsawRejected state.
SurfacePoint adjustedSurfacePoint
This is the calculated, or aposterori, surface point.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
PointType GetType() const
Status SetAdjustedSurfacePoint(SurfacePoint newSurfacePoint)
Set or update the surface point relating to this control point.
void SetExplicitReference(ControlMeasure *measure)
Explicitly defines a new reference measure by pointer.
int numberOfRejectedMeasures
This parameter is used and maintained by BundleAdjust for the jigsaw application.
PointType
These are the valid 'types' of 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.
Status SetType(PointType newType)
Updates the control point's type.
Status SetAprioriSurfacePointSourceFile(QString sourceFile)
This updates the filename of where the apriori surface point came from.
int IndexOfRefMeasure() const
Status SetAprioriSurfacePointSource(SurfacePointSource::Source source)
This updates the source of the surface point.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
PointType type
What this control point is tying together.
bool ignore
True if we should preserve but ignore the entire control point and its measures.
bool IsCoord2Constrained()
Return bool indicating if 2nd coordinate is Constrained or not.
bool HasAprioriRadiusSourceFile() const
Checks to see if the radius source file has been set.
bool IsCoord1Constrained()
Return bool indicating if 1st coordinate is Constrained or not.
QString GetPointTypeString() const
Obtain a string representation of the PointType.
bool HasChooserName() const
Returns true if the choosername is not empty.
Status SetIgnored(bool newIgnoreStatus)
Set whether to ignore or use control point.
Status SetDateTime(QString newDateTime)
Set the point's last modified time.
bool IsCoord3Constrained()
Return bool indicating if 3rd coordinate is Constrained or not.
ControlPoint()
Construct a control point.
Statistics GetStatistic(double(ControlMeasure::*statFunc)() const) const
This function will call a given method on every control measure that this point has.
bool IsConstrained()
Return bool indicating if point is Constrained or not.
void PointModified()
List of Control Measures.
QString chooserName
This is the user name of the person who last modified this control point.
static QString PointTypeToString(PointType type)
Obtain a string representation of a given PointType.
void AddMeasure(ControlMeasure *measure)
Do the actual work of adding a measure to this point, without changing any extra data.
static PointType StringToPointType(QString pointTypeString)
Obtain a PointType given a string representation of it.
bool referenceExplicitlySet
This indicates if a program has explicitely set the reference in this point or the implicit reference...
Status ComputeResiduals()
This method computes the BundleAdjust residuals for a point.
QString GetId() const
Return the Id of the control point.
static QString SurfacePointSourceToString(SurfacePointSource::Source source)
Obtain a string representation of a given SurfacePointSource.
std::bitset< 3 > constraintStatus
This stores the constraint status of the a priori SurfacePoint.
Status ResetApriori()
Reset all the Apriori info to defaults.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
int IndexOf(ControlMeasure *, bool throws=true) const
bool HasAprioriSurfacePointSourceFile() const
Checks to see if the surface point source file has been set.
void Load(PvlObject &p)
Loads the PvlObject into a ControlPoint.
SurfacePoint GetBestSurfacePoint() const
Returns the adjusted surface point if it exists, otherwise returns the a priori surface point.
Status SetRefMeasure(ControlMeasure *cm)
Set the point's reference measure.
Status ComputeApriori()
Computes a priori lat/lon/radius point coordinates by determining the average lat/lon/radius of all m...
bool IsFixed() const
Return bool indicating if point is Fixed or not.
Status SetAprioriRadiusSourceFile(QString sourceFile)
This updates the filename of the DEM that the apriori radius came from.
SurfacePointSource::Source aprioriSurfacePointSource
Where the apriori surface point originated from.
QString GetRadiusSourceString() const
Obtain a string representation of the RadiusSource.
void emitMeasureModified(ControlMeasure *measure, ControlMeasure::ModType modType, QVariant oldValue, QVariant newValue)
This method is a wrapper to emit the measureModified() signal in the parent network is called wheneve...
QString GetReferenceSN() const
QString GetSurfacePointSourceString() const
Obtain a string representation of the SurfacePointSource.
Displacement is a signed length, usually in meters.
bool isValid() const
Test if this displacement has been initialized or not.
@ Kilometers
The distance is being specified in kilometers.
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
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:94
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
This class defines a body-fixed surface point.
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
@ Latitudinal
Planetocentric latitudinal (lat/lon/rad) coordinates.
@ Rectangular
Body-fixed rectangular x/y/z coordinates.
void SetRectangular(const Displacement &x, const Displacement &y, const Displacement &z, const Distance &xSigma=Distance(), const Distance &ySigma=Distance(), const Distance &zSigma=Distance())
Set surface point in rectangular body-fixed coordinates wtih optional sigmas.
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
Namespace for the standard library.