Isis 3 Programmer Reference
ControlPointV0001.cpp
1 
7 /* SPDX-License-Identifier: CC0-1.0 */
8 
9 #include "ControlPointV0001.h"
10 
11 #include <QString>
12 
13 #include "ControlMeasureLogData.h"
14 #include "Distance.h"
15 #include "IException.h"
16 #include "Latitude.h"
17 #include "Longitude.h"
18 #include "NaifStatus.h"
19 #include "Pvl.h"
20 #include "PvlContainer.h"
21 #include "SpecialPixel.h"
22 #include "SurfacePoint.h"
23 #include "Target.h"
24 
25 using namespace std;
26 
27 namespace Isis {
28 
35  ControlPointV0001::ControlPointV0001(
38  : m_pointData(pointData), m_logData(logData) {
39 
40  }
41 
42 
49  ControlPointV0001::ControlPointV0001(PvlObject &pointObject, const QString targetName)
50  : m_pointData(new ControlNetFileProtoV0001_PBControlPoint),
51  m_logData(new ControlNetLogDataProtoV0001_Point) {
52  // Clean up the Pvl control point
53  // Anything that doesn't have a value is removed
54  for (int cpKeyIndex = 0; cpKeyIndex < pointObject.keywords(); cpKeyIndex ++) {
55  if (pointObject[cpKeyIndex][0] == "") {
56  pointObject.deleteKeyword(cpKeyIndex);
57  }
58  }
59 
60  // Copy over POD values
61  copy(pointObject, "PointId",
62  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_id);
63  copy(pointObject, "ChooserName",
64  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_choosername);
65  copy(pointObject, "DateTime",
66  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_datetime);
67  copy(pointObject, "AprioriXYZSourceFile",
68  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_apriorisurfpointsourcefile);
69  copy(pointObject, "AprioriLatLonSourceFile",
70  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_apriorisurfpointsourcefile);
71  copy(pointObject, "AprioriRadiusSourceFile",
72  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_aprioriradiussourcefile);
73  copy(pointObject, "JigsawRejected",
74  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_jigsawrejected);
75  copy(pointObject, "EditLock",
76  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_editlock);
77  copy(pointObject, "Ignore",
78  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_ignore);
79  copy(pointObject, "LatitudeConstrained",
80  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_latitudeconstrained);
81  copy(pointObject, "LongitudeConstrained",
82  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_longitudeconstrained);
83  copy(pointObject, "RadiusConstrained",
84  m_pointData, &ControlNetFileProtoV0001_PBControlPoint::set_radiusconstrained);
85  // Copy over the adjusted surface point
86  if ( pointObject.hasKeyword("Latitude")
87  && pointObject.hasKeyword("Longitude")
88  && pointObject.hasKeyword("Radius") ) {
89  SurfacePoint adjustedPoint(
90  Latitude(toDouble(pointObject["Latitude"][0]), Angle::Degrees),
91  Longitude(toDouble(pointObject["Longitude"][0]), Angle::Degrees),
92  Distance(toDouble(pointObject["Radius"][0]), Distance::Meters));
93 
94  m_pointData->set_adjustedx( adjustedPoint.GetX().meters() );
95  m_pointData->set_adjustedy( adjustedPoint.GetY().meters() );
96  m_pointData->set_adjustedz( adjustedPoint.GetZ().meters() );
97  }
98  else if ( pointObject.hasKeyword("X")
99  && pointObject.hasKeyword("Y")
100  && pointObject.hasKeyword("Z") ) {
101  m_pointData->set_adjustedx( toDouble(pointObject["X"][0]) );
102  m_pointData->set_adjustedy( toDouble(pointObject["Y"][0]) );
103  m_pointData->set_adjustedz( toDouble(pointObject["Z"][0]) );
104  }
105 
106  // copy over the apriori surface point
107  if ( pointObject.hasKeyword("AprioriLatitude")
108  && pointObject.hasKeyword("AprioriLongitude")
109  && pointObject.hasKeyword("AprioriRadius") ) {
110  SurfacePoint aprioriPoint(
111  Latitude(toDouble(pointObject["AprioriLatitude"][0]), Angle::Degrees),
112  Longitude(toDouble(pointObject["AprioriLongitude"][0]), Angle::Degrees),
113  Distance(toDouble(pointObject["AprioriRadius"][0]), Distance::Meters));
114 
115  m_pointData->set_apriorix( aprioriPoint.GetX().meters() );
116  m_pointData->set_aprioriy( aprioriPoint.GetY().meters() );
117  m_pointData->set_aprioriz( aprioriPoint.GetZ().meters() );
118  }
119  else if ( pointObject.hasKeyword("AprioriX")
120  && pointObject.hasKeyword("AprioriY")
121  && pointObject.hasKeyword("AprioriZ") ) {
122  m_pointData->set_apriorix( toDouble(pointObject["AprioriX"][0]) );
123  m_pointData->set_aprioriy( toDouble(pointObject["AprioriY"][0]) );
124  m_pointData->set_aprioriz( toDouble(pointObject["AprioriZ"][0]) );
125  }
126  // If the apriori values are missing, copy them from the adjusted.
127  else if ( m_pointData->has_adjustedx()
128  && m_pointData->has_adjustedy()
129  && m_pointData->has_adjustedz() ) {
130  m_pointData->set_apriorix( m_pointData->adjustedx() );
131  m_pointData->set_aprioriy( m_pointData->adjustedy() );
132  m_pointData->set_aprioriz( m_pointData->adjustedz() );
133  }
134 
135  // Ground points were previously flagged by the Held keyword being true.
136  if ( (pointObject.hasKeyword("Held") && pointObject["Held"][0] == "True")
137  || (pointObject["PointType"][0] == "Ground") ) {
138  m_pointData->set_type(ControlNetFileProtoV0001_PBControlPoint::Ground);
139  }
140  else if (pointObject["PointType"][0] == "Tie") {
141  m_pointData->set_type(ControlNetFileProtoV0001_PBControlPoint::Tie);
142  }
143  else {
144  QString msg = "Invalid ControlPoint type [" + pointObject["PointType"][0] + "].";
145  throw IException(IException::User, msg, _FILEINFO_);
146  }
147 
148  if (pointObject.hasKeyword("AprioriXYZSource")) {
149  QString source = pointObject["AprioriXYZSource"][0];
150 
151  if (source == "None") {
152  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::None);
153  }
154  else if (source == "User") {
155  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::User);
156  }
157  else if (source == "AverageOfMeasures") {
158  m_pointData->set_apriorisurfpointsource(
159  ControlNetFileProtoV0001_PBControlPoint::AverageOfMeasures);
160  }
161  else if (source == "Reference") {
162  m_pointData->set_apriorisurfpointsource(
163  ControlNetFileProtoV0001_PBControlPoint::Reference);
164  }
165  else if (source == "Basemap") {
166  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::Basemap);
167  }
168  else if (source == "BundleSolution") {
169  m_pointData->set_apriorisurfpointsource(
170  ControlNetFileProtoV0001_PBControlPoint::BundleSolution);
171  }
172  else {
173  QString msg = "Invalid AprioriXYZSource [" + source + "]";
174  throw IException(IException::User, msg, _FILEINFO_);
175  }
176  }
177 
178  if (pointObject.hasKeyword("AprioriLatLonSource")) {
179  QString source = pointObject["AprioriLatLonSource"][0];
180 
181  if (source == "None") {
182  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::None);
183  }
184  else if (source == "User") {
185  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::User);
186  }
187  else if (source == "AverageOfMeasures") {
188  m_pointData->set_apriorisurfpointsource(
189  ControlNetFileProtoV0001_PBControlPoint::AverageOfMeasures);
190  }
191  else if (source == "Reference") {
192  m_pointData->set_apriorisurfpointsource(
193  ControlNetFileProtoV0001_PBControlPoint::Reference);
194  }
195  else if (source == "Basemap") {
196  m_pointData->set_apriorisurfpointsource(ControlNetFileProtoV0001_PBControlPoint::Basemap);
197  }
198  else if (source == "BundleSolution") {
199  m_pointData->set_apriorisurfpointsource(
200  ControlNetFileProtoV0001_PBControlPoint::BundleSolution);
201  }
202  else {
203  QString msg = "Invalid AprioriLatLonSource [" + source + "]";
204  throw IException(IException::User, msg, _FILEINFO_);
205  }
206  }
207 
208  if (pointObject.hasKeyword("AprioriRadiusSource")) {
209  QString source = pointObject["AprioriRadiusSource"][0];
210 
211  if (source == "None") {
212  m_pointData->set_aprioriradiussource(ControlNetFileProtoV0001_PBControlPoint::None);
213  }
214  else if (source == "User") {
215  m_pointData->set_aprioriradiussource(ControlNetFileProtoV0001_PBControlPoint::User);
216  }
217  else if (source == "AverageOfMeasures") {
218  m_pointData->set_aprioriradiussource(
219  ControlNetFileProtoV0001_PBControlPoint::AverageOfMeasures);
220  }
221  else if (source == "Ellipsoid") {
222  m_pointData->set_aprioriradiussource(ControlNetFileProtoV0001_PBControlPoint::Ellipsoid);
223  }
224  else if (source == "DEM") {
225  m_pointData->set_aprioriradiussource(ControlNetFileProtoV0001_PBControlPoint::DEM);
226  }
227  else if (source == "BundleSolution") {
228  m_pointData->set_aprioriradiussource(
229  ControlNetFileProtoV0001_PBControlPoint::BundleSolution);
230  }
231  else {
232  QString msg = "Invalid AprioriRadiusSource, [" + source + "]";
233  throw IException(IException::User, msg, _FILEINFO_);
234  }
235  }
236 
237  // Copy the covariance matrices
238  // Sometimes they are not stored in version 1 Pvls so we compute them from the
239  // surface point sigmas using the local radius to convert to/from angular units.
240 
241  // Add the Apriori Covariance Matrix
242  if ( pointObject.hasKeyword("AprioriCovarianceMatrix") ) {
243  PvlKeyword &matrix = pointObject["AprioriCovarianceMatrix"];
244 
245  m_pointData->add_aprioricovar(toDouble(matrix[0]));
246  m_pointData->add_aprioricovar(toDouble(matrix[1]));
247  m_pointData->add_aprioricovar(toDouble(matrix[2]));
248  m_pointData->add_aprioricovar(toDouble(matrix[3]));
249  m_pointData->add_aprioricovar(toDouble(matrix[4]));
250  m_pointData->add_aprioricovar(toDouble(matrix[5]));
251 
252  m_pointData->set_latitudeconstrained(true);
253  m_pointData->set_longitudeconstrained(true);
254  m_pointData->set_radiusconstrained(true);
255  }
256  else if ( pointObject.hasKeyword("AprioriSigmaLatitude")
257  || pointObject.hasKeyword("AprioriSigmaLongitude")
258  || pointObject.hasKeyword("AprioriSigmaRadius") ) {
259  // There may be missing or negative apriori sigmas so default to 10,000
260  double sigmaLat = 10000.0;
261  double sigmaLon = 10000.0;
262  double sigmaRad = 10000.0;
263 
264  if ( pointObject.hasKeyword("AprioriSigmaLatitude") ) {
265  if (toDouble(pointObject["AprioriSigmaLatitude"][0]) > 0
266  && toDouble(pointObject["AprioriSigmaLatitude"][0]) < sigmaLat) {
267  sigmaLat = toDouble(pointObject["AprioriSigmaLatitude"][0]);
268  }
269  m_pointData->set_latitudeconstrained(true);
270  }
271 
272  if ( pointObject.hasKeyword("AprioriSigmaLongitude") ) {
273  if (toDouble(pointObject["AprioriSigmaLongitude"][0]) > 0
274  && toDouble(pointObject["AprioriSigmaLongitude"][0]) < sigmaLon) {
275  sigmaLon = toDouble(pointObject["AprioriSigmaLongitude"][0]);
276  }
277  m_pointData->set_longitudeconstrained(true);
278  }
279 
280  if ( pointObject.hasKeyword("AprioriSigmaRadius") ) {
281  if (toDouble(pointObject["AprioriSigmaRadius"][0]) > 0
282  && toDouble(pointObject["AprioriSigmaRadius"][0]) < sigmaRad) {
283  sigmaRad = toDouble(pointObject["AprioriSigmaRadius"][0]);
284  }
285  m_pointData->set_radiusconstrained(true);
286  }
287 
288  SurfacePoint aprioriPoint;
289  aprioriPoint.SetRectangular( Displacement(m_pointData->apriorix(), Displacement::Meters),
292  aprioriPoint.SetSphericalSigmasDistance( Distance(sigmaLat, Distance::Meters),
293  Distance(sigmaLon, Distance::Meters),
294  Distance(sigmaRad, Distance::Meters) );
295  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(0, 0) );
296  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(0, 1) );
297  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(0, 2) );
298  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(1, 1) );
299  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(1, 2) );
300  m_pointData->add_aprioricovar( aprioriPoint.GetRectangularMatrix()(2, 2) );
301  }
302 
303  // Add the Adjusted (Apost) Covariance Matrix
304  if ( pointObject.hasKeyword("ApostCovarianceMatrix") ) {
305  PvlKeyword &matrix = pointObject["ApostCovarianceMatrix"];
306 
307  m_pointData->add_adjustedcovar(toDouble(matrix[0]));
308  m_pointData->add_adjustedcovar(toDouble(matrix[1]));
309  m_pointData->add_adjustedcovar(toDouble(matrix[2]));
310  m_pointData->add_adjustedcovar(toDouble(matrix[3]));
311  m_pointData->add_adjustedcovar(toDouble(matrix[4]));
312  m_pointData->add_adjustedcovar(toDouble(matrix[5]));
313 
314  m_pointData->set_latitudeconstrained(true);
315  m_pointData->set_longitudeconstrained(true);
316  m_pointData->set_radiusconstrained(true);
317  }
318  else if ( pointObject.hasKeyword("AdjustedSigmaLatitude")
319  || pointObject.hasKeyword("AdjustedSigmaLongitude")
320  || pointObject.hasKeyword("AdjustedSigmaRadius") ) {
321  // There may be missing or negative adjusted sigmas so default to 10,000
322  double sigmaLat = 10000.0;
323  double sigmaLon = 10000.0;
324  double sigmaRad = 10000.0;
325 
326  if ( pointObject.hasKeyword("AdjustedSigmaLatitude") ) {
327  if (toDouble(pointObject["AdjustedSigmaLatitude"][0]) > 0
328  && toDouble(pointObject["AdjustedSigmaLatitude"][0]) < sigmaLat) {
329  sigmaLat = toDouble(pointObject["AdjustedSigmaLatitude"][0]);
330  }
331  }
332 
333  if ( pointObject.hasKeyword("AdjustedSigmaLongitude") ) {
334  if (toDouble(pointObject["AdjustedSigmaLongitude"][0]) > 0
335  && toDouble(pointObject["AdjustedSigmaLongitude"][0]) < sigmaLon) {
336  sigmaLon = toDouble(pointObject["AdjustedSigmaLongitude"][0]);
337  }
338  }
339 
340  if ( pointObject.hasKeyword("AdjustedSigmaRadius") ) {
341  if (toDouble(pointObject["AdjustedSigmaRadius"][0]) > 0
342  && toDouble(pointObject["AdjustedSigmaRadius"][0]) < sigmaRad) {
343  sigmaRad = toDouble(pointObject["AdjustedSigmaRadius"][0]);
344  }
345  }
346 
347  SurfacePoint adjustedPoint;
348  adjustedPoint.SetRectangular( Displacement(m_pointData->adjustedx(), Displacement::Meters),
351  adjustedPoint.SetSphericalSigmasDistance( Distance(sigmaLat, Distance::Meters),
352  Distance(sigmaLon, Distance::Meters),
353  Distance(sigmaRad, Distance::Meters) );
354  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(0, 0) );
355  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(0, 1) );
356  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(0, 2) );
357  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(1, 1) );
358  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(1, 2) );
359  m_pointData->add_adjustedcovar( adjustedPoint.GetRectangularMatrix()(2, 2) );
360  }
361 
362  // Process Measures
363  for (int groupIndex = 0; groupIndex < pointObject.groups(); groupIndex ++) {
364  PvlGroup &group = pointObject.group(groupIndex);
365  ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure measure;
366 
367  // Copy strings, booleans, and doubles
368  copy(group, "SerialNumber",
369  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_serialnumber);
370  copy(group, "ChooserName",
371  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_choosername);
372  copy(group, "DateTime",
373  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_datetime);
374  copy(group, "Diameter",
375  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_diameter);
376  copy(group, "EditLock",
377  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_editlock);
378  copy(group, "Ignore",
379  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_ignore);
380  copy(group, "JigsawRejected",
381  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_jigsawrejected);
382  copy(group, "AprioriSample",
383  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_apriorisample);
384  copy(group, "AprioriLine",
385  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_aprioriline);
386  copy(group, "SampleSigma",
387  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_samplesigma);
388  copy(group, "LineSigma",
389  measure, &ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::set_linesigma);
390 
391  // The sample, line, sample residual, and line residual are nested in another structure
392  // inside the measure, so they cannot be copied with the conenience methods.
393  if (group.hasKeyword("Sample")) {
394  // The sample may not be a numeric value
395  // in this case set it to 0 and ignore the measure
396  double value;
397  try {
398  value = toDouble(group["Sample"][0]);
399  }
400  catch (...) {
401  value = 0;
402  measure.set_ignore(true);
403  }
404  measure.mutable_measurement()->set_sample(value);
405  group.deleteKeyword("Sample");
406  }
407  if (group.hasKeyword("Line")) {
408  // The line may not be a numeric value
409  // in this case set it to 0 and ignore the measure
410  double value;
411  try {
412  value = toDouble(group["Line"][0]);
413  }
414  catch (...) {
415  value = 0;
416  measure.set_ignore(true);
417  }
418  measure.mutable_measurement()->set_line(value);
419  group.deleteKeyword("Line");
420  }
421 
422  // Some old networks use ErrorSample and ErrorLine,
423  // others use SampleResidual and LineResidual so check for both
424  if (group.hasKeyword("ErrorSample")) {
425  double value = toDouble(group["ErrorSample"][0]);
426  measure.mutable_measurement()->set_sampleresidual(value);
427  group.deleteKeyword("ErrorSample");
428  }
429  if (group.hasKeyword("ErrorLine")) {
430  double value = toDouble(group["ErrorLine"][0]);
431  measure.mutable_measurement()->set_lineresidual(value);
432  group.deleteKeyword("ErrorLine");
433  }
434 
435  if (group.hasKeyword("SampleResidual")) {
436  double value = toDouble(group["SampleResidual"][0]);
437  measure.mutable_measurement()->set_sampleresidual(value);
438  group.deleteKeyword("SampleResidual");
439  }
440 
441  if (group.hasKeyword("LineResidual")) {
442  double value = toDouble(group["LineResidual"][0]);
443  measure.mutable_measurement()->set_lineresidual(value);
444  group.deleteKeyword("LineResidual");
445  }
446 
447  if (group.hasKeyword("Reference")) {
448  if (group["Reference"][0].toLower() == "true") {
449  m_pointData->set_referenceindex(groupIndex);
450  }
451  group.deleteKeyword("Reference");
452  }
453 
454  // Copy the measure type
455  if (group.hasKeyword("MeasureType")) {
456  QString type = group["MeasureType"][0].toLower();
457  if (type == "estimated"
458  || type == "unmeasured"
459  || type == "candidate") {
460  measure.set_type(ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::Candidate);
461  }
462  else if (type == "manual") {
463  measure.set_type(ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::Manual);
464  }
465  else if (type == "automatic"
466  || type == "validatedmanual"
467  || type == "automaticpixel") {
468  measure.set_type(ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::RegisteredPixel);
469  }
470  else if (type == "validatedautomatic"
471  || type == "automaticsubpixel") {
472  measure.set_type(ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::RegisteredSubPixel);
473  }
474  else {
476  "Unknown measure type [" + type + "]",
477  _FILEINFO_);
478  }
479  group.deleteKeyword("MeasureType");
480  }
481 
482  // Clean up the remaining keywords
483  for (int cmKeyIndex = 0; cmKeyIndex < group.keywords(); cmKeyIndex++) {
484  if (group[cmKeyIndex][0] == ""
485  || group[cmKeyIndex].name() == "ZScore"
486  || group[cmKeyIndex].name() == "ErrorMagnitude") {
487  group.deleteKeyword(cmKeyIndex);
488  cmKeyIndex--;
489  }
490  }
491 
492  // Create the log data for the measure
493  ControlNetLogDataProtoV0001_Point_Measure measureLogData;
494 
495  for (int keyIndex = 0; keyIndex < group.keywords(); keyIndex++) {
496  PvlKeyword dataKeyword = group[keyIndex];
497  QString name = dataKeyword.name();
498  int dataType = 0;
499  double value = 0.0;
500 
501  if (name == "Obsolete_Eccentricity") {
502  dataType = 1;
503  }
504  else if (name == "GoodnessOfFit") {
505  dataType = 2;
506  }
507  else if (name == "MinimumPixelZScore") {
508  dataType = 3;
509  }
510  else if (name == "MaximumPixelZScore") {
511  dataType = 4;
512  }
513  else if (name == "PixelShift") {
514  dataType = 5;
515  }
516  else if (name == "WholePixelCorrelation") {
517  dataType = 6;
518  }
519  else if (name == "SubPixelCorrelation") {
520  dataType = 7;
521  }
522  else if (name == "Obsolete_AverageResidual") {
523  dataType = 8;
524  }
525  else {
526  QString msg = "Invalid control measure log data name [" + name + "]";
527  throw IException(IException::Programmer, msg, _FILEINFO_);
528  }
529 
530  try {
531  value = toDouble(dataKeyword[0]);
532  }
533  catch (IException &e) {
534  QString msg = "Invalid control measure log data value [" + dataKeyword[0] + "]";
535  throw IException(e, IException::Io, msg, _FILEINFO_);
536  }
537 
538  ControlNetLogDataProtoV0001_Point_Measure_DataEntry logEntry;
539  logEntry.set_datatype(dataType);
540  logEntry.set_datavalue(value);
541  *measureLogData.add_loggedmeasuredata() = logEntry;
542  }
543 
544  // Store the measure and its log data
545  *m_pointData->add_measures() = measure;
546  *m_logData->add_measures() = measureLogData;
547  }
548 
549  if (!m_pointData->IsInitialized()) {
550  QString msg = "There is missing required information in the control "
551  "points or measures";
552  throw IException(IException::Io, msg, _FILEINFO_);
553  }
554 
555  }
556 
557 
565  return m_pointData;
566  }
567 
568 
576  return m_logData;
577  }
578 
579 
595  QString keyName,
597  void (ControlNetFileProtoV0001_PBControlPoint::*setter)(bool)) {
598 
599  if (!container.hasKeyword(keyName)) {
600  return;
601  }
602 
603  QString value = container[keyName][0];
604  container.deleteKeyword(keyName);
605  value = value.toLower();
606 
607  if (value == "true" || value == "yes") {
608  (point.data()->*setter)(true);
609  }
610  }
611 
612 
628  QString keyName,
630  void (ControlNetFileProtoV0001_PBControlPoint::*setter)(double)) {
631 
632  if (!container.hasKeyword(keyName)) {
633  return;
634  }
635 
636  double value = toDouble(container[keyName][0]);
637  container.deleteKeyword(keyName);
638  (point.data()->*setter)(value);
639  }
640 
641 
657  QString keyName,
659  void (ControlNetFileProtoV0001_PBControlPoint::*setter)(const std::string&)) {
660 
661  if (!container.hasKeyword(keyName)) {
662  return;
663  }
664 
665  QString value = container[keyName][0];
666  container.deleteKeyword(keyName);
667  (point.data()->*setter)(value.toLatin1().data());
668  }
669 
670 
686  QString keyName,
687  ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure &measure,
688  void (ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::*setter)(bool)) {
689 
690  if (!container.hasKeyword(keyName)) {
691  return;
692  }
693 
694  QString value = container[keyName][0];
695  container.deleteKeyword(keyName);
696  value = value.toLower();
697 
698  if (value == "true" || value == "yes") {
699  (measure.*setter)(true);
700  }
701  }
702 
703 
719  QString keyName,
720  ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure &measure,
721  void (ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::*setter)(double)) {
722 
723  if (!container.hasKeyword(keyName)) {
724  return;
725  }
726 
727  double value = Isis::Null;
728  if ( container.hasKeyword(keyName) ) {
729  value = toDouble(container[keyName][0]);
730  container.deleteKeyword(keyName);
731 
732  }
733 
734  (measure.*setter)(value);
735  }
736 
737 
753  QString keyName,
754  ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure &measure,
755  void (ControlNetFileProtoV0001_PBControlPoint_PBControlMeasure::*setter)
756  (const std::string &)) {
757 
758  if (!container.hasKeyword(keyName)) {
759  return;
760  }
761 
762 
763  QString value = container[keyName][0];
764  container.deleteKeyword(keyName);
765  (measure.*setter)(value.toLatin1().data());
766  }
767 }
Isis::ControlPointV0001::copy
void copy(PvlContainer &container, QString keyName, QSharedPointer< ControlNetFileProtoV0001_PBControlPoint > point, void(ControlNetFileProtoV0001_PBControlPoint::*setter)(bool))
This convenience method takes a boolean value from a PvlKeyword and copies it into a version 1 protob...
Definition: ControlPointV0001.cpp:594
Isis::Angle::Degrees
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:56
Isis::ControlPointV0001::logData
QSharedPointer< ControlNetLogDataProtoV0001_Point > logData()
Access the protobuf log data for the control measures in the point.
Definition: ControlPointV0001.cpp:575
Isis::PvlKeyword::name
QString name() const
Returns the keyword name.
Definition: PvlKeyword.h:98
Isis::SurfacePoint::SetRectangular
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.
Definition: SurfacePoint.cpp:283
Isis::PvlObject::group
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:452
Isis::IException::Io
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:155
Isis::ControlPointV0001::m_logData
QSharedPointer< ControlNetLogDataProtoV0001_Point > m_logData
Protobuf container that holds log data for the control measures in the point.
Definition: ControlPointV0001.h:120
Isis::PvlObject
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:61
Isis::Displacement::Meters
@ Meters
The distance is being specified in meters.
Definition: Displacement.h:40
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::ControlPointV0001::pointData
QSharedPointer< ControlNetFileProtoV0001_PBControlPoint > pointData()
Access the protobuf control point data.
Definition: ControlPointV0001.cpp:564
Isis::PvlObject::groups
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:75
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
QSharedPointer< ControlNetFileProtoV0001_PBControlPoint >
Isis::ControlPointV0001::ControlPointV0001
ControlPointV0001()
Default constructor.
Isis::Distance
Distance measurement, usually in meters.
Definition: Distance.h:34
Isis::Longitude
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:40
Isis::Displacement
Displacement is a signed length, usually in meters.
Definition: Displacement.h:31
Isis::Distance::Meters
@ Meters
The distance is being specified in meters.
Definition: Distance.h:43
Isis::Displacement::meters
double meters() const
Get the displacement in meters.
Definition: Displacement.cpp:73
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PvlObject::hasKeyword
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Definition: PvlObject.cpp:236
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::PvlContainer::deleteKeyword
void deleteKeyword(const QString &name)
Remove a specified keyword.
Definition: PvlContainer.cpp:97
Isis::ControlPointV0001::m_pointData
QSharedPointer< ControlNetFileProtoV0001_PBControlPoint > m_pointData
Protobuf container that holds information used to create a control point.
Definition: ControlPointV0001.h:118
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
std
Namespace for the standard library.
Isis::PvlContainer::keywords
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:86
Isis::SurfacePoint::SetSphericalSigmasDistance
void SetSphericalSigmasDistance(const Distance &latSigma, const Distance &lonSigma, const Distance &radiusSigma)
Set the spherical sigmas (in Distance units) into the spherical variance/covariance matrix.
Definition: SurfacePoint.cpp:617
Isis::PvlContainer
Contains more than one keyword-value pair.
Definition: PvlContainer.h:49
Isis::SurfacePoint
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:132
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126