7 #include "ControlNetFile.h"
10 #include "ControlNetFileV0002.pb.h"
43 Pvl network(networkFileName.expanded());
45 if (network.hasObject(
"ProtoBuffer")) {
46 return ReadBinaryNetwork(network, networkFileName);
48 else if (network.hasObject(
"ControlNetwork")) {
49 return ReadPvlNetwork(network);
52 IString msg =
"Could not determine the control network file type";
57 IString msg =
"Reading the control network [" + networkFileName.name()
72 void ControlNetVersioner::Write(
const FileName &file,
107 int version =
toInt(network[
"Version"][0]);
109 while (version != LATEST_PVL_VERSION) {
110 int previousVersion = version;
114 ConvertVersion1ToVersion2(network);
118 ConvertVersion2ToVersion3(network);
122 ConvertVersion3ToVersion4(network);
126 IString msg =
"The Pvl file version [" +
IString(version) +
"] is not"
131 version =
toInt(network[
"Version"][0]);
133 if (version == previousVersion) {
134 IString msg =
"Cannot update from version [" +
IString(version) +
"] "
135 "to any other version";
140 return LatestPvlToBinary(network);
162 header.set_networkid(network.
findKeyword(
"NetworkId")[0].toLatin1().data());
163 header.set_targetname(network.
findKeyword(
"TargetName")[0].toLatin1().data());
164 header.set_created(network.
findKeyword(
"Created")[0].toLatin1().data());
165 header.set_lastmodified(network.
findKeyword(
"LastModified")[0].toLatin1().data());
166 header.set_description(network.
findKeyword(
"Description")[0].toLatin1().data());
167 header.set_username(network.
findKeyword(
"UserName")[0].toLatin1().data());
168 header.add_pointmessagesizes(0);
170 if (!header.IsInitialized()) {
171 IString msg =
"There is missing required information in the network "
178 for (
int objectIndex = 0; objectIndex < network.
objects(); objectIndex ++) {
182 Copy(
object,
"PointId",
183 point, &ControlPointFileEntryV0002::set_id);
184 Copy(
object,
"ChooserName",
185 point, &ControlPointFileEntryV0002::set_choosername);
186 Copy(
object,
"DateTime",
187 point, &ControlPointFileEntryV0002::set_datetime);
188 Copy(
object,
"AprioriXYZSourceFile",
189 point, &ControlPointFileEntryV0002::set_apriorisurfpointsourcefile);
190 Copy(
object,
"AprioriRadiusSourceFile",
191 point, &ControlPointFileEntryV0002::set_aprioriradiussourcefile);
192 Copy(
object,
"JigsawRejected",
193 point, &ControlPointFileEntryV0002::set_jigsawrejected);
194 Copy(
object,
"EditLock",
195 point, &ControlPointFileEntryV0002::set_editlock);
196 Copy(
object,
"Ignore",
197 point, &ControlPointFileEntryV0002::set_ignore);
198 Copy(
object,
"AprioriX",
199 point, &ControlPointFileEntryV0002::set_apriorix);
200 Copy(
object,
"AprioriY",
201 point, &ControlPointFileEntryV0002::set_aprioriy);
202 Copy(
object,
"AprioriZ",
203 point, &ControlPointFileEntryV0002::set_aprioriz);
204 Copy(
object,
"AdjustedX",
205 point, &ControlPointFileEntryV0002::set_adjustedx);
206 Copy(
object,
"AdjustedY",
207 point, &ControlPointFileEntryV0002::set_adjustedy);
208 Copy(
object,
"AdjustedZ",
209 point, &ControlPointFileEntryV0002::set_adjustedz);
210 Copy(
object,
"LatitudeConstrained",
211 point, &ControlPointFileEntryV0002::set_latitudeconstrained);
212 Copy(
object,
"LongitudeConstrained",
213 point, &ControlPointFileEntryV0002::set_longitudeconstrained);
214 Copy(
object,
"RadiusConstrained",
215 point, &ControlPointFileEntryV0002::set_radiusconstrained);
217 if (
object[
"PointType"][0] ==
"Fixed")
218 point.set_type(ControlPointFileEntryV0002::Fixed);
219 else if (
object[
"PointType"][0] ==
"Constrained")
220 point.set_type(ControlPointFileEntryV0002::Constrained);
222 point.set_type(ControlPointFileEntryV0002::Free);
224 if (
object.hasKeyword(
"AprioriXYZSource")) {
225 IString source =
object[
"AprioriXYZSource"][0];
227 if (source ==
"None") {
228 point.set_apriorisurfpointsource(ControlPointFileEntryV0002::None);
230 else if (source ==
"User") {
231 point.set_apriorisurfpointsource(ControlPointFileEntryV0002::User);
233 else if (source ==
"AverageOfMeasures") {
234 point.set_apriorisurfpointsource(
235 ControlPointFileEntryV0002::AverageOfMeasures);
237 else if (source ==
"Reference") {
238 point.set_apriorisurfpointsource(
239 ControlPointFileEntryV0002::Reference);
241 else if (source ==
"Basemap") {
242 point.set_apriorisurfpointsource(
243 ControlPointFileEntryV0002::Basemap);
245 else if (source ==
"BundleSolution") {
246 point.set_apriorisurfpointsource(
247 ControlPointFileEntryV0002::BundleSolution);
250 IString msg =
"Invalid AprioriXYZSource [" + source +
"]";
255 if (
object.hasKeyword(
"AprioriRadiusSource")) {
256 IString source =
object[
"AprioriRadiusSource"][0];
258 if (source ==
"None") {
259 point.set_aprioriradiussource(ControlPointFileEntryV0002::None);
261 else if (source ==
"User") {
262 point.set_aprioriradiussource(ControlPointFileEntryV0002::User);
264 else if (source ==
"AverageOfMeasures") {
265 point.set_aprioriradiussource(ControlPointFileEntryV0002::AverageOfMeasures);
267 else if (source ==
"Ellipsoid") {
268 point.set_aprioriradiussource(ControlPointFileEntryV0002::Ellipsoid);
270 else if (source ==
"DEM") {
271 point.set_aprioriradiussource(ControlPointFileEntryV0002::DEM);
273 else if (source ==
"BundleSolution") {
274 point.set_aprioriradiussource(ControlPointFileEntryV0002::BundleSolution);
277 std::string msg =
"Invalid AprioriRadiusSource, [" + source +
"]";
282 if (
object.hasKeyword(
"AprioriCovarianceMatrix")) {
283 PvlKeyword &matrix =
object[
"AprioriCovarianceMatrix"];
285 point.add_aprioricovar(
toDouble(matrix[0]));
286 point.add_aprioricovar(
toDouble(matrix[1]));
287 point.add_aprioricovar(
toDouble(matrix[2]));
288 point.add_aprioricovar(
toDouble(matrix[3]));
289 point.add_aprioricovar(
toDouble(matrix[4]));
290 point.add_aprioricovar(
toDouble(matrix[5]));
293 if (
object.hasKeyword(
"AdjustedCovarianceMatrix")) {
294 PvlKeyword &matrix =
object[
"AdjustedCovarianceMatrix"];
296 point.add_adjustedcovar(
toDouble(matrix[0]));
297 point.add_adjustedcovar(
toDouble(matrix[1]));
298 point.add_adjustedcovar(
toDouble(matrix[2]));
299 point.add_adjustedcovar(
toDouble(matrix[3]));
300 point.add_adjustedcovar(
toDouble(matrix[4]));
301 point.add_adjustedcovar(
toDouble(matrix[5]));
305 for (
int groupIndex = 0; groupIndex <
object.groups(); groupIndex ++) {
306 PvlGroup &group =
object.group(groupIndex);
309 Copy(group,
"SerialNumber",
310 measure, &ControlPointFileEntryV0002::Measure::set_serialnumber);
311 Copy(group,
"ChooserName",
312 measure, &ControlPointFileEntryV0002::Measure::set_choosername);
313 Copy(group,
"Sample",
314 measure, &ControlPointFileEntryV0002::Measure::set_sample);
316 measure, &ControlPointFileEntryV0002::Measure::set_line);
317 Copy(group,
"SampleResidual",
318 measure, &ControlPointFileEntryV0002::Measure::set_sampleresidual);
319 Copy(group,
"LineResidual",
320 measure, &ControlPointFileEntryV0002::Measure::set_lineresidual);
321 Copy(group,
"DateTime",
322 measure, &ControlPointFileEntryV0002::Measure::set_datetime);
323 Copy(group,
"Diameter",
324 measure, &ControlPointFileEntryV0002::Measure::set_diameter);
325 Copy(group,
"EditLock",
326 measure, &ControlPointFileEntryV0002::Measure::set_editlock);
327 Copy(group,
"Ignore",
328 measure, &ControlPointFileEntryV0002::Measure::set_ignore);
329 Copy(group,
"JigsawRejected",
330 measure, &ControlPointFileEntryV0002::Measure::set_jigsawrejected);
331 Copy(group,
"AprioriSample",
332 measure, &ControlPointFileEntryV0002::Measure::set_apriorisample);
333 Copy(group,
"AprioriLine",
334 measure, &ControlPointFileEntryV0002::Measure::set_aprioriline);
335 Copy(group,
"SampleSigma",
336 measure, &ControlPointFileEntryV0002::Measure::set_samplesigma);
337 Copy(group,
"LineSigma",
338 measure, &ControlPointFileEntryV0002::Measure::set_linesigma);
341 if (group[
"Reference"][0].toLower() ==
"true")
342 point.set_referenceindex(groupIndex);
347 QString type = group[
"MeasureType"][0].toLower();
348 if (type ==
"candidate")
349 measure.set_type(ControlPointFileEntryV0002::Measure::Candidate);
350 else if (type ==
"manual")
351 measure.set_type(ControlPointFileEntryV0002::Measure::Manual);
352 else if (type ==
"registeredpixel")
353 measure.set_type(ControlPointFileEntryV0002::Measure::RegisteredPixel);
354 else if (type ==
"registeredsubpixel")
355 measure.set_type(ControlPointFileEntryV0002::Measure::RegisteredSubPixel);
358 "Unknown measure type [" + type +
"]",
362 for (
int key = 0; key < group.
keywords(); key++) {
365 IString msg =
"Unhandled or duplicate keywords in control measure ["
366 + group[key].
name() +
"]";
374 *point.add_measures() = measure;
377 if (!point.IsInitialized()) {
378 IString msg =
"There is missing required information in the control "
379 "points or measures";
383 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(
PvlObject &network) {
463 network[
"Version"] =
"2";
466 NaifStatus::CheckErrors();
468 if (QString(network[
"TargetName"]).startsWith(
"MRO/")) {
469 network[
"TargetName"] =
"Mars";
474 radii = Target::radiiGroup(network[
"TargetName"][0]);
478 NaifStatus::CheckErrors();
483 QString msg =
"Unable to get convert ControlNet Version 1 to Version 2.";
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"];
605 if (cp.
hasKeyword(
"AdjustedSigmaLongitude")) {
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);
623 Distance(sigmaLon, Distance::Meters),
624 Distance(sigmaRad, Distance::Meters));
626 PvlKeyword adjustedCovarMatrix(
"AdjustedCovarianceMatrix");
627 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 0));
628 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 1));
629 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(0, 2));
630 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 1));
631 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(1, 2));
632 adjustedCovarMatrix +=
toString(tmp.GetRectangularMatrix()(2, 2));
634 cp += adjustedCovarMatrix;
638 cp[
"ApostCovarianceMatrix"].setName(
"AdjustedCovarianceMatrix");
642 cp +=
PvlKeyword(
"LatitudeConstrained",
"True");
644 cp +=
PvlKeyword(
"LatitudeConstrained",
"False");
649 cp +=
PvlKeyword(
"LongitudeConstrained",
"True");
651 cp +=
PvlKeyword(
"LongitudeConstrained",
"False");
656 cp +=
PvlKeyword(
"RadiusConstrained",
"True");
658 cp +=
PvlKeyword(
"RadiusConstrained",
"False");
662 for (
int cpKeyIndex = 0; cpKeyIndex < cp.
keywords(); cpKeyIndex ++) {
663 if (cp[cpKeyIndex][0] ==
"") {
668 for (
int cmIndex = 0; cmIndex < cp.
groups(); cmIndex ++) {
673 QString type = cm[
"MeasureType"][0].toLower();
675 if (type ==
"estimated" || type ==
"unmeasured") {
676 if (type ==
"unmeasured") {
677 bool hasSampleLine =
false;
682 hasSampleLine =
true;
687 if (!hasSampleLine) {
694 cm[
"MeasureType"] =
"Candidate";
696 else if (type ==
"automatic" ||
697 type ==
"validatedmanual" ||
698 type ==
"automaticpixel") {
699 cm[
"MeasureType"] =
"RegisteredPixel";
701 else if (type ==
"validatedautomatic" || type ==
"automaticsubpixel") {
702 cm[
"MeasureType"] =
"RegisteredSubPixel";
707 cm[
"ErrorSample"].setName(
"SampleResidual");
710 cm[
"ErrorLine"].setName(
"LineResidual");
714 toDouble(cm[
"SampleResidual"][0]) == 0.0)
718 toDouble(cm[
"LineResidual"][0]) == 0.0)
732 for (
int cmKeyIndex = 0; cmKeyIndex < cm.
keywords(); cmKeyIndex ++) {
733 if (cm[cmKeyIndex][0] ==
"") {
749 void ControlNetVersioner::ConvertVersion2ToVersion3(
PvlObject &network) {
751 network[
"Version"] =
"3";
753 for (
int cpIndex = 0; cpIndex < network.
objects(); cpIndex ++) {
756 if (cp.
hasKeyword(
"AprioriCovarianceMatrix") ||
758 cp[
"PointType"] =
"Constrained";
770 void ControlNetVersioner::ConvertVersion3ToVersion4(
PvlObject &network) {
772 network[
"Version"] =
"4";
774 for (
int cpIndex = 0; cpIndex < network.
objects(); cpIndex ++) {
777 if (cp[
"PointType"][0] ==
"Ground") cp[
"PointType"] =
"Fixed";
778 if (cp[
"PointType"][0] ==
"Tie") cp[
"PointType"] =
"Free";
804 QString value = container[keyName][0];
806 value = value.toLower();
808 if (value ==
"true" || value ==
"yes")
809 (point.*setter)(
true);
834 double value =
toDouble(container[keyName][0]);
836 (point.*setter)(value);
861 IString value = container[keyName][0];
863 (point.*setter)(value);
888 QString value = container[keyName][0];
890 value = value.toLower();
892 if (value ==
"true" || value ==
"yes")
893 (measure.*setter)(
true);
918 double value =
toDouble(container[keyName][0]);
920 (measure.*setter)(value);
941 (
const std::string &)) {
946 IString value = container[keyName][0];
948 (measure.*set)(value);
This class defines a body-fixed surface point.
PvlObject & object(const int index)
Return the object at the specified index.
Handle Binary Control Network Files version 1.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Contains more than one keyword-value pair.
File name manipulation and expansion.
double meters() const
Get the displacement in meters.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
virtual Pvl toPvl() const
Converts binary control net version 2 to pvl version 3.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
int toInt(const QString &string)
Global function to convert from a string to an integer.
Statistical and similar ControlMeasure associated information.
This class is designed to encapsulate the concept of a Latitude.
ControlNetFileHeaderV0002 & GetNetworkHeader()
Get the control network level information - things like NetworkID, TargetName, etc...
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Generic Binary Control Net File Representation.
Distance measurement, usually in meters.
ControlPointFileEntryV0002_Measure_MeasureLogData ToProtocolBuffer() const
This converts the log data to a protocol buffer object.
void SetRadii(const Distance &majorRadius, const Distance &minorRadius, const Distance &polarRadius)
Reset the radii of the surface body of the surface point.
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 ...
This class is designed to encapsulate the concept of a Longitude.
QList< ControlPointFileEntryV0002 > & GetNetworkPoints()
Get the control point data along with the log data.
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
int objects() const
Returns the number of objects.
A single keyword-value pair.
virtual void Read(const Pvl &header, const FileName &file)=0
This reads the binary file into memory.
Container for cube-like labels.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
bool IsValid() const
This tests if the log data is complete and valid.
int groups() const
Returns the number of groups contained.
PvlGroup & group(const int index)
Return the group at the specified index.
virtual void Write(const FileName &file) const
This writes the binary file that is in memory to disk.
Displacement is a signed length, usually in meters.
Adds specific functionality to C++ strings.
Handle Binary Control Network Files version 2.
void SetSphericalSigmasDistance(const Distance &latSigma, const Distance &lonSigma, const Distance &radiusSigma)
Set the spherical sigmas (in meters) into the spherical variance/covariance matrix.
void write(const QString &file)
Opens and writes PVL information to a file and handles the end of line sequence.
Contains Pvl Groups and Pvl Objects.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString name() const
Returns the container name.
virtual Pvl toPvl() const =0
Convert the binary representation to Pvl (any pvl version).
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.
void deleteKeyword(const QString &name)
Remove a specified keyword.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.