7 #include "ControlNetFile.h"
10 #include "ControlNetFileV0002.pb.h"
42 Pvl network(networkFileName.expanded());
44 if(network.hasObject(
"ProtoBuffer")) {
45 return ReadBinaryNetwork(network, networkFileName);
47 else if(network.hasObject(
"ControlNetwork")) {
48 return ReadPvlNetwork(network);
51 IString msg =
"Could not determine the control network file type";
56 IString msg =
"Reading the control network [" + networkFileName.name()
71 void ControlNetVersioner::Write(
const FileName &file,
104 int version =
toInt(network[
"Version"][0]);
106 while(version != LATEST_PVL_VERSION) {
107 int previousVersion = version;
111 ConvertVersion1ToVersion2(network);
115 ConvertVersion2ToVersion3(network);
119 ConvertVersion3ToVersion4(network);
123 IString msg =
"The Pvl file version [" +
IString(version) +
"] is not"
128 version =
toInt(network[
"Version"][0]);
130 if(version == previousVersion) {
131 IString msg =
"Cannot update from version [" +
IString(version) +
"] "
132 "to any other version";
137 return LatestPvlToBinary(network);
159 header.set_networkid(network.
findKeyword(
"NetworkId")[0].toAscii().data());
160 header.set_targetname(network.
findKeyword(
"TargetName")[0].toAscii().data());
161 header.set_created(network.
findKeyword(
"Created")[0].toAscii().data());
162 header.set_lastmodified(network.
findKeyword(
"LastModified")[0].toAscii().data());
163 header.set_description(network.
findKeyword(
"Description")[0].toAscii().data());
164 header.set_username(network.
findKeyword(
"UserName")[0].toAscii().data());
165 header.add_pointmessagesizes(0);
167 if(!header.IsInitialized()) {
168 IString msg =
"There is missing required information in the network "
175 for(
int objectIndex = 0; objectIndex < network.
objects(); objectIndex ++) {
179 Copy(
object,
"PointId",
180 point, &ControlPointFileEntryV0002::set_id);
181 Copy(
object,
"ChooserName",
182 point, &ControlPointFileEntryV0002::set_choosername);
183 Copy(
object,
"DateTime",
184 point, &ControlPointFileEntryV0002::set_datetime);
185 Copy(
object,
"AprioriXYZSourceFile",
186 point, &ControlPointFileEntryV0002::set_apriorisurfpointsourcefile);
187 Copy(
object,
"AprioriRadiusSourceFile",
188 point, &ControlPointFileEntryV0002::set_aprioriradiussourcefile);
189 Copy(
object,
"JigsawRejected",
190 point, &ControlPointFileEntryV0002::set_jigsawrejected);
191 Copy(
object,
"EditLock",
192 point, &ControlPointFileEntryV0002::set_editlock);
193 Copy(
object,
"Ignore",
194 point, &ControlPointFileEntryV0002::set_ignore);
195 Copy(
object,
"AprioriX",
196 point, &ControlPointFileEntryV0002::set_apriorix);
197 Copy(
object,
"AprioriY",
198 point, &ControlPointFileEntryV0002::set_aprioriy);
199 Copy(
object,
"AprioriZ",
200 point, &ControlPointFileEntryV0002::set_aprioriz);
201 Copy(
object,
"AdjustedX",
202 point, &ControlPointFileEntryV0002::set_adjustedx);
203 Copy(
object,
"AdjustedY",
204 point, &ControlPointFileEntryV0002::set_adjustedy);
205 Copy(
object,
"AdjustedZ",
206 point, &ControlPointFileEntryV0002::set_adjustedz);
207 Copy(
object,
"LatitudeConstrained",
208 point, &ControlPointFileEntryV0002::set_latitudeconstrained);
209 Copy(
object,
"LongitudeConstrained",
210 point, &ControlPointFileEntryV0002::set_longitudeconstrained);
211 Copy(
object,
"RadiusConstrained",
212 point, &ControlPointFileEntryV0002::set_radiusconstrained);
214 if (
object[
"PointType"][0] ==
"Fixed")
215 point.set_type(ControlPointFileEntryV0002::Fixed);
216 else if (
object[
"PointType"][0] ==
"Constrained")
217 point.set_type(ControlPointFileEntryV0002::Constrained);
219 point.set_type(ControlPointFileEntryV0002::Free);
221 if (
object.hasKeyword(
"AprioriXYZSource")) {
222 IString source =
object[
"AprioriXYZSource"][0];
224 if (source ==
"None") {
225 point.set_apriorisurfpointsource(ControlPointFileEntryV0002::None);
227 else if (source ==
"User") {
228 point.set_apriorisurfpointsource(ControlPointFileEntryV0002::User);
230 else if (source ==
"AverageOfMeasures") {
231 point.set_apriorisurfpointsource(
232 ControlPointFileEntryV0002::AverageOfMeasures);
234 else if (source ==
"Reference") {
235 point.set_apriorisurfpointsource(
236 ControlPointFileEntryV0002::Reference);
238 else if (source ==
"Basemap") {
239 point.set_apriorisurfpointsource(
240 ControlPointFileEntryV0002::Basemap);
242 else if (source ==
"BundleSolution") {
243 point.set_apriorisurfpointsource(
244 ControlPointFileEntryV0002::BundleSolution);
247 IString msg =
"Invalid AprioriXYZSource [" + source +
"]";
252 if (
object.hasKeyword(
"AprioriRadiusSource")) {
253 IString source =
object[
"AprioriRadiusSource"][0];
255 if (source ==
"None") {
256 point.set_aprioriradiussource(ControlPointFileEntryV0002::None);
258 else if (source ==
"User") {
259 point.set_aprioriradiussource(ControlPointFileEntryV0002::User);
261 else if (source ==
"AverageOfMeasures") {
262 point.set_aprioriradiussource(
263 ControlPointFileEntryV0002::AverageOfMeasures);
265 else if (source ==
"Ellipsoid") {
266 point.set_aprioriradiussource(ControlPointFileEntryV0002::Ellipsoid);
268 else if (source ==
"DEM") {
269 point.set_aprioriradiussource(ControlPointFileEntryV0002::DEM);
271 else if (source ==
"BundleSolution") {
272 point.set_aprioriradiussource(
273 ControlPointFileEntryV0002::BundleSolution);
276 std::string msg =
"Invalid AprioriRadiusSource, [" + source +
"]";
281 if (
object.hasKeyword(
"AprioriCovarianceMatrix")) {
282 PvlKeyword &matrix =
object[
"AprioriCovarianceMatrix"];
284 point.add_aprioricovar(
toDouble(matrix[0]));
285 point.add_aprioricovar(
toDouble(matrix[1]));
286 point.add_aprioricovar(
toDouble(matrix[2]));
287 point.add_aprioricovar(
toDouble(matrix[3]));
288 point.add_aprioricovar(
toDouble(matrix[4]));
289 point.add_aprioricovar(
toDouble(matrix[5]));
292 if(
object.hasKeyword(
"AdjustedCovarianceMatrix")) {
293 PvlKeyword &matrix =
object[
"AdjustedCovarianceMatrix"];
295 point.add_adjustedcovar(
toDouble(matrix[0]));
296 point.add_adjustedcovar(
toDouble(matrix[1]));
297 point.add_adjustedcovar(
toDouble(matrix[2]));
298 point.add_adjustedcovar(
toDouble(matrix[3]));
299 point.add_adjustedcovar(
toDouble(matrix[4]));
300 point.add_adjustedcovar(
toDouble(matrix[5]));
304 for (
int groupIndex = 0; groupIndex <
object.groups(); groupIndex ++) {
305 PvlGroup &group =
object.group(groupIndex);
308 Copy(group,
"SerialNumber",
309 measure, &ControlPointFileEntryV0002::Measure::set_serialnumber);
310 Copy(group,
"ChooserName",
311 measure, &ControlPointFileEntryV0002::Measure::set_choosername);
312 Copy(group,
"Sample",
313 measure, &ControlPointFileEntryV0002::Measure::set_sample);
315 measure, &ControlPointFileEntryV0002::Measure::set_line);
316 Copy(group,
"SampleResidual",
317 measure, &ControlPointFileEntryV0002::Measure::set_sampleresidual);
318 Copy(group,
"LineResidual",
319 measure, &ControlPointFileEntryV0002::Measure::set_lineresidual);
320 Copy(group,
"DateTime",
321 measure, &ControlPointFileEntryV0002::Measure::set_datetime);
322 Copy(group,
"Diameter",
323 measure, &ControlPointFileEntryV0002::Measure::set_diameter);
324 Copy(group,
"EditLock",
325 measure, &ControlPointFileEntryV0002::Measure::set_editlock);
326 Copy(group,
"Ignore",
327 measure, &ControlPointFileEntryV0002::Measure::set_ignore);
328 Copy(group,
"JigsawRejected",
329 measure, &ControlPointFileEntryV0002::Measure::set_jigsawrejected);
330 Copy(group,
"AprioriSample",
331 measure, &ControlPointFileEntryV0002::Measure::set_apriorisample);
332 Copy(group,
"AprioriLine",
333 measure, &ControlPointFileEntryV0002::Measure::set_aprioriline);
334 Copy(group,
"SampleSigma",
335 measure, &ControlPointFileEntryV0002::Measure::set_samplesigma);
336 Copy(group,
"LineSigma",
337 measure, &ControlPointFileEntryV0002::Measure::set_linesigma);
340 if(group[
"Reference"][0].toLower() ==
"true")
341 point.set_referenceindex(groupIndex);
346 QString type = group[
"MeasureType"][0].toLower();
347 if(type ==
"candidate")
348 measure.set_type(ControlPointFileEntryV0002::Measure::Candidate);
349 else if(type ==
"manual")
350 measure.set_type(ControlPointFileEntryV0002::Measure::Manual);
351 else if(type ==
"registeredpixel")
353 ControlPointFileEntryV0002::Measure::RegisteredPixel);
354 else if(type ==
"registeredsubpixel")
356 ControlPointFileEntryV0002::Measure::RegisteredSubPixel);
359 "Unknown measure type [" + type +
"]",
363 for(
int key = 0; key < group.
keywords(); key++) {
366 IString msg =
"Unhandled or duplicate keywords in control measure ["
367 + group[key].
name() +
"]";
375 *point.add_measures() = measure;
378 if(!point.IsInitialized()) {
379 IString msg =
"There is missing required information in the control "
380 "points or measures";
384 points.append(point);
408 version =
toInt(netInfo[
"Version"][0]);
422 IString msg =
"The binary file version [" +
IString(version) +
"] is "
428 cnetFile->
Read(header, filename);
430 if(version != LATEST_BINARY_VERSION) {
436 return ReadPvlNetwork(pvl);
461 void ControlNetVersioner::ConvertVersion1ToVersion2(
463 network[
"Version"] =
"2";
466 NaifStatus::CheckErrors();
468 if (QString(network[
"TargetName"]).startsWith(
"MRO/")) {
469 network[
"TargetName"] =
"Mars";
474 radii = TProjection::TargetRadii(network[
"TargetName"]);
478 NaifStatus::CheckErrors();
483 QString msg =
"The target name is not recognized";
487 Distance equatorialRadius(radii[
"EquatorialRadius"], Distance::Meters);
488 Distance polarRadius(radii[
"PolarRadius"], Distance::Meters);
490 for(
int cpIndex = 0; cpIndex < network.
objects(); cpIndex ++) {
493 if(cp.
hasKeyword(
"Held") && cp[
"Held"][0] ==
"True")
494 cp[
"PointType"] =
"Ground";
497 cp[
"AprioriLatLonSource"].setName(
"AprioriXYZSource");
500 cp[
"AprioriLatLonSourceFile"].setName(
"AprioriXYZSourceFile");
531 cp[
"X"].setName(
"AdjustedX");
534 cp[
"Y"].setName(
"AdjustedY");
537 cp[
"Z"].setName(
"AdjustedZ");
542 double sigmaLat = 10000.0;
543 double sigmaLon = 10000.0;
544 double sigmaRad = 10000.0;
547 if(
toDouble(cp[
"AprioriSigmaLatitude"][0]) > 0 &&
548 toDouble(cp[
"AprioriSigmaLatitude"][0]) < sigmaLat)
549 sigmaLat = cp[
"AprioriSigmaLatitude"];
551 cp +=
PvlKeyword(
"LatitudeConstrained",
"True");
555 if(
toDouble(cp[
"AprioriSigmaLongitude"][0]) > 0 &&
556 toDouble(cp[
"AprioriSigmaLongitude"][0]) < sigmaLon)
557 sigmaLon = cp[
"AprioriSigmaLongitude"];
559 cp +=
PvlKeyword(
"LongitudeConstrained",
"True");
563 if(
toDouble(cp[
"AprioriSigmaRadius"][0]) > 0 &&
564 toDouble(cp[
"AprioriSigmaRadius"][0]) < sigmaRad)
565 sigmaRad = cp[
"AprioriSigmaRadius"];
567 cp +=
PvlKeyword(
"RadiusConstrained",
"True");
571 tmp.
SetRadii(equatorialRadius, equatorialRadius, polarRadius);
577 Distance(sigmaLat, Distance::Meters),
578 Distance(sigmaLon, Distance::Meters),
579 Distance(sigmaRad, Distance::Meters));
581 PvlKeyword aprioriCovarMatrix(
"AprioriCovarianceMatrix");
582 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 0));
583 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 1));
584 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 2));
585 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 1));
586 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 2));
587 aprioriCovarMatrix +=
toString(tmp.GetRectangularMatrix()(2, 2));
589 cp += aprioriCovarMatrix;
595 double sigmaLat = 10000.0;
596 double sigmaLon = 10000.0;
597 double sigmaRad = 10000.0;
600 if(
toDouble(cp[
"AdjustedSigmaLatitude"][0]) > 0 &&
601 toDouble(cp[
"AdjustedSigmaLatitude"][0]) < sigmaLat)
602 sigmaLat = cp[
"AdjustedSigmaLatitude"];
606 if(
toDouble(cp[
"AdjustedSigmaLongitude"][0]) > 0 &&
607 toDouble(cp[
"AdjustedSigmaLongitude"][0]) < sigmaLon)
608 sigmaLon = cp[
"AdjustedSigmaLongitude"];
612 if(
toDouble(cp[
"AdjustedSigmaRadius"][0]) > 0 &&
613 toDouble(cp[
"AdjustedSigmaRadius"][0]) < sigmaRad)
614 sigmaRad = cp[
"AdjustedSigmaRadius"];
618 tmp.
SetRadii(equatorialRadius, equatorialRadius, polarRadius);
624 Distance(sigmaLat, Distance::Meters),
625 Distance(sigmaLon, Distance::Meters),
626 Distance(sigmaRad, Distance::Meters));
628 PvlKeyword adjustedCovarMatrix(
"AdjustedCovarianceMatrix");
629 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 0));
630 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 1));
631 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 2));
632 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 1));
633 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 2));
634 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(2, 2));
636 cp += adjustedCovarMatrix;
640 cp[
"ApostCovarianceMatrix"].setName(
"AdjustedCovarianceMatrix");
644 cp +=
PvlKeyword(
"LatitudeConstrained",
"True");
646 cp +=
PvlKeyword(
"LatitudeConstrained",
"False");
651 cp +=
PvlKeyword(
"LongitudeConstrained",
"True");
653 cp +=
PvlKeyword(
"LongitudeConstrained",
"False");
658 cp +=
PvlKeyword(
"RadiusConstrained",
"True");
660 cp +=
PvlKeyword(
"RadiusConstrained",
"False");
664 for(
int cpKeyIndex = 0; cpKeyIndex < cp.
keywords(); cpKeyIndex ++) {
665 if(cp[cpKeyIndex][0] ==
"") {
670 for(
int cmIndex = 0; cmIndex < cp.
groups(); cmIndex ++) {
675 QString type = cm[
"MeasureType"][0].toLower();
677 if(type ==
"estimated" || type ==
"unmeasured") {
678 if (type ==
"unmeasured") {
679 bool hasSampleLine =
false;
684 hasSampleLine =
true;
689 if (!hasSampleLine) {
696 cm[
"MeasureType"] =
"Candidate";
698 else if(type ==
"automatic" || type ==
"validatedmanual" ||
699 type ==
"automaticpixel") {
700 cm[
"MeasureType"] =
"RegisteredPixel";
702 else if(type ==
"validatedautomatic" ||
703 type ==
"automaticsubpixel") {
704 cm[
"MeasureType"] =
"RegisteredSubPixel";
709 cm[
"ErrorSample"].setName(
"SampleResidual");
712 cm[
"ErrorLine"].setName(
"LineResidual");
716 toDouble(cm[
"SampleResidual"][0]) == 0.0)
720 toDouble(cm[
"LineResidual"][0]) == 0.0)
734 for(
int cmKeyIndex = 0; cmKeyIndex < cm.
keywords(); cmKeyIndex ++) {
735 if(cm[cmKeyIndex][0] ==
"") {
752 void ControlNetVersioner::ConvertVersion2ToVersion3(
754 network[
"Version"] =
"3";
756 for(
int cpIndex = 0; cpIndex < network.
objects(); cpIndex ++) {
759 if(cp.
hasKeyword(
"AprioriCovarianceMatrix") ||
761 cp[
"PointType"] =
"Constrained";
773 void ControlNetVersioner::ConvertVersion3ToVersion4(
775 network[
"Version"] =
"4";
777 for (
int cpIndex = 0; cpIndex < network.
objects(); cpIndex ++) {
780 if (cp[
"PointType"][0] ==
"Ground") cp[
"PointType"] =
"Fixed";
781 if (cp[
"PointType"][0] ==
"Tie") cp[
"PointType"] =
"Free";
805 QString value = container[keyName][0];
807 value = value.toLower();
808 if(value ==
"true" || value ==
"yes")
809 (point.*setter)(
true);
832 double value =
toDouble(container[keyName][0]);
834 (point.*setter)(value);
857 IString value = container[keyName][0];
859 (point.*setter)(value);
876 void ControlNetVersioner::Copy(
PvlContainer &container, QString keyName,
882 QString value = container[keyName][0];
884 value = value.toLower();
885 if(value ==
"true" || value ==
"yes")
886 (measure.*setter)(
true);
903 void ControlNetVersioner::Copy(
PvlContainer &container, QString keyName,
909 double value =
toDouble(container[keyName][0]);
911 (measure.*setter)(value);
928 void ControlNetVersioner::Copy(
PvlContainer &container, QString keyName,
934 IString value = container[keyName][0];
936 (measure.*
set)(value);