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
25using namespace std;
26
27namespace Isis {
28
36 QSharedPointer<ControlNetFileProtoV0001_PBControlPoint> pointData,
37 QSharedPointer<ControlNetLogDataProtoV0001_Point> logData)
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;
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
564 QSharedPointer<ControlNetFileProtoV0001_PBControlPoint> ControlPointV0001::pointData() {
565 return m_pointData;
566 }
567
568
575 QSharedPointer<ControlNetLogDataProtoV0001_Point> ControlPointV0001::logData() {
576 return m_logData;
577 }
578
579
595 QString keyName,
596 QSharedPointer<ControlNetFileProtoV0001_PBControlPoint> point,
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,
629 QSharedPointer<ControlNetFileProtoV0001_PBControlPoint> point,
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,
658 QSharedPointer<ControlNetFileProtoV0001_PBControlPoint> point,
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}
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition Angle.h:56
QSharedPointer< ControlNetLogDataProtoV0001_Point > m_logData
Protobuf container that holds log data for the control measures in the point.
QSharedPointer< ControlNetFileProtoV0001_PBControlPoint > m_pointData
Protobuf container that holds information used to create a control point.
ControlPointV0001()
Default constructor.
QSharedPointer< ControlNetLogDataProtoV0001_Point > logData()
Access the protobuf log data for the control measures in the point.
QSharedPointer< ControlNetFileProtoV0001_PBControlPoint > pointData()
Access the protobuf control point data.
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...
Displacement is a signed length, usually in meters.
@ Meters
The distance is being specified in meters.
Distance measurement, usually in meters.
Definition Distance.h:34
@ Meters
The distance is being specified in meters.
Definition Distance.h:43
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
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
This class is designed to encapsulate the concept of a Latitude.
Definition Latitude.h:51
This class is designed to encapsulate the concept of a Longitude.
Definition Longitude.h:40
Contains more than one keyword-value pair.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
QString name() const
Returns the container name.
void deleteKeyword(const QString &name)
Remove a specified keyword.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
A single keyword-value pair.
Definition PvlKeyword.h:87
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
This class defines a body-fixed surface point.
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
const double Null
Value for an Isis Null pixel.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149
Namespace for the standard library.