5 #include <google/protobuf/io/zero_copy_stream_impl.h>
6 #include <google/protobuf/io/coded_stream.h>
7 #include <boost/numeric/ublas/symmetric.hpp>
8 #include <boost/numeric/ublas/io.hpp>
14 #include "ControlNetFileV0002.pb.h"
24 using namespace google::protobuf;
25 using namespace google::protobuf::io;
26 using boost::numeric::ublas::symmetric_matrix;
27 using boost::numeric::ublas::upper;
31 ControlNetFileV0002::ControlNetFileV0002() {
32 p_networkHeader =
new ControlNetFileHeaderV0002;
37 ControlNetFileV0002::~ControlNetFileV0002() {
38 delete p_networkHeader;
39 delete p_controlPoints;
52 void ControlNetFileV0002::Read(
const Pvl &header,
const FileName &file) {
56 BigInt headerStartPos = protoBufferCore[
"HeaderStartByte"];
57 BigInt headerLength = protoBufferCore[
"HeaderBytes"];
59 fstream input(file.expanded().toAscii().data(), ios::in | ios::binary);
60 if (!input.is_open()) {
61 IString msg =
"Failed to open control network file" + file.name();
65 input.seekg(headerStartPos, ios::beg);
66 streampos filePos = input.tellg();
67 IstreamInputStream headerInStream(&input);
68 CodedInputStream headerCodedInStream(&headerInStream);
70 headerCodedInStream.SetTotalBytesLimit(1024 * 1024 * 512,
75 filePos += headerLength;
76 int oldLimit = headerCodedInStream.PushLimit(headerLength);
77 if (!p_networkHeader->ParseFromCodedStream(&headerCodedInStream)) {
78 IString msg =
"Failed to read input control net file [" +
82 headerCodedInStream.PopLimit(oldLimit);
89 IstreamInputStream *pointInStream = NULL;
90 CodedInputStream *pointCodedInStream = NULL;
92 for(
int cp = 0; cp < p_networkHeader->pointmessagesizes_size(); cp ++) {
93 if(cp % 50000 == 0 && pointCodedInStream && pointInStream) {
94 delete pointCodedInStream;
95 pointCodedInStream = NULL;
101 if(pointInStream == NULL) {
103 input.open(file.expanded().toAscii().data(), ios::in | ios::binary);
104 input.seekg(filePos, ios::beg);
106 pointInStream =
new IstreamInputStream(&input);
107 pointCodedInStream =
new CodedInputStream(pointInStream);
109 pointCodedInStream->SetTotalBytesLimit(1024 * 1024 * 512,
113 int size = p_networkHeader->pointmessagesizes(cp);
114 oldLimit = pointCodedInStream->PushLimit(size);
118 newPoint.ParseFromCodedStream(pointCodedInStream);
120 if (newPoint.type() == ControlPointFileEntryV0002::obsolete_Tie ||
121 newPoint.type() == ControlPointFileEntryV0002::obsolete_Ground) {
122 if (newPoint.aprioricovar_size())
123 newPoint.set_type(ControlPointFileEntryV0002::Constrained);
126 p_controlPoints->append(newPoint);
127 pointCodedInStream->PopLimit(oldLimit);
130 if(pointCodedInStream) {
131 delete pointCodedInStream;
132 pointCodedInStream = NULL;
136 delete pointInStream;
137 pointInStream = NULL;
141 string msg =
"Cannot understand binary PB file";
146 void ControlNetFileV0002::Write(
const FileName &file)
const {
148 p_networkHeader->clear_pointmessagesizes();
149 BigInt pointsSize = 0;
150 BigInt numMeasures = 0;
151 for(
int cpIndex = 0; cpIndex < p_controlPoints->size(); cpIndex ++) {
152 numMeasures += p_controlPoints->at(cpIndex).measures_size();
153 int size = p_controlPoints->at(cpIndex).ByteSize();
155 p_networkHeader->add_pointmessagesizes(size);
158 streampos coreHeaderSize = p_networkHeader->ByteSize();
160 const int labelBytes = 65536;
161 fstream output(file.expanded().toAscii().data(),
162 ios::out | ios::trunc | ios::binary);
164 char *blankLabel =
new char[labelBytes];
165 memset(blankLabel, 0, labelBytes);
166 output.write(blankLabel, labelBytes);
167 delete [] blankLabel;
169 streampos startCoreHeaderPos = output.tellp();
171 if (!p_networkHeader->SerializeToOstream(&output)) {
172 IString msg =
"Failed to write output control network file [" +
177 streampos curPosition = startCoreHeaderPos + coreHeaderSize;
178 for(
int cpIndex = 0; cpIndex < p_controlPoints->size(); cpIndex ++) {
179 if(!p_controlPoints->at(cpIndex).IsInitialized()) {
180 IString msg =
"Failed to write output control network file [" +
181 file.name() +
"] because control points are missing required "
186 if(!p_controlPoints->at(cpIndex).SerializeToOstream(&output)) {
187 IString msg =
"Failed to write output control network file [" +
188 file.name() +
"] while attempting to write control points";
192 curPosition += p_controlPoints->at(cpIndex).ByteSize();
200 toString((BigInt) startCoreHeaderPos)));
203 toString((BigInt) ( startCoreHeaderPos + coreHeaderSize))));
208 PvlGroup netInfo(
"ControlNetworkInfo");
209 netInfo.addComment(
"This group is for informational purposes only");
210 netInfo +=
PvlKeyword(
"NetworkId", p_networkHeader->networkid().c_str());
211 netInfo +=
PvlKeyword(
"TargetName", p_networkHeader->targetname().c_str());
212 netInfo +=
PvlKeyword(
"UserName", p_networkHeader->username().c_str());
213 netInfo +=
PvlKeyword(
"Created", p_networkHeader->created().c_str());
214 netInfo +=
PvlKeyword(
"LastModified", p_networkHeader->lastmodified().c_str());
215 netInfo +=
PvlKeyword(
"Description", p_networkHeader->description().c_str());
223 output.seekp(0, ios::beg);
246 Pvl ControlNetFileV0002::toPvl()
const {
251 network +=
PvlKeyword(
"NetworkId", p_networkHeader->networkid().c_str());
252 network +=
PvlKeyword(
"TargetName", p_networkHeader->targetname().c_str());
253 network +=
PvlKeyword(
"UserName", p_networkHeader->username().c_str());
254 network +=
PvlKeyword(
"Created", p_networkHeader->created().c_str());
255 network +=
PvlKeyword(
"LastModified", p_networkHeader->lastmodified().c_str());
256 network +=
PvlKeyword(
"Description", p_networkHeader->description().c_str());
263 QString target = (QString)network.findKeyword(
"TargetName",Pvl::Traverse);
266 NaifStatus::CheckErrors();
267 pvlRadii = TProjection::TargetRadii(target);
270 IString msg =
"The target name, " + target +
", is not recognized.";
276 foreach(binaryPoint, *p_controlPoints) {
279 if(binaryPoint.type() == ControlPointFileEntryV0002::Fixed)
281 else if(binaryPoint.type() == ControlPointFileEntryV0002::Constrained)
282 pvlPoint +=
PvlKeyword(
"PointType",
"Constrained");
286 pvlPoint +=
PvlKeyword(
"PointId", binaryPoint.id().c_str());
287 pvlPoint +=
PvlKeyword(
"ChooserName", binaryPoint.choosername().c_str());
288 pvlPoint +=
PvlKeyword(
"DateTime", binaryPoint.datetime().c_str());
290 if (binaryPoint.editlock()) {
294 if (binaryPoint.ignore()) {
298 switch (binaryPoint.apriorisurfpointsource()) {
299 case ControlPointFileEntryV0002::None:
301 case ControlPointFileEntryV0002::User:
302 pvlPoint +=
PvlKeyword(
"AprioriXYZSource",
"User");
304 case ControlPointFileEntryV0002::AverageOfMeasures:
305 pvlPoint +=
PvlKeyword(
"AprioriXYZSource",
"AverageOfMeasures");
307 case ControlPointFileEntryV0002::Reference:
308 pvlPoint +=
PvlKeyword(
"AprioriXYZSource",
"Reference");
310 case ControlPointFileEntryV0002::Basemap:
311 pvlPoint +=
PvlKeyword(
"AprioriXYZSource",
"Basemap");
313 case ControlPointFileEntryV0002::BundleSolution:
314 pvlPoint +=
PvlKeyword(
"AprioriXYZSource",
"BundleSolution");
316 case ControlPointFileEntryV0002::Ellipsoid:
317 case ControlPointFileEntryV0002::DEM:
321 if (binaryPoint.has_apriorisurfpointsourcefile())
322 pvlPoint +=
PvlKeyword(
"AprioriXYZSourceFile",
323 binaryPoint.apriorisurfpointsourcefile().c_str());
325 switch (binaryPoint.aprioriradiussource()) {
326 case ControlPointFileEntryV0002::None:
328 case ControlPointFileEntryV0002::User:
329 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"User");
331 case ControlPointFileEntryV0002::AverageOfMeasures:
332 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"AverageOfMeasures");
334 case ControlPointFileEntryV0002::Reference:
335 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"Reference");
337 case ControlPointFileEntryV0002::Basemap:
338 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"Basemap");
340 case ControlPointFileEntryV0002::BundleSolution:
341 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"BundleSolution");
343 case ControlPointFileEntryV0002::Ellipsoid:
344 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"Ellipsoid");
346 case ControlPointFileEntryV0002::DEM:
347 pvlPoint +=
PvlKeyword(
"AprioriRadiusSource",
"DEM");
351 if (binaryPoint.has_aprioriradiussourcefile())
352 pvlPoint +=
PvlKeyword(
"AprioriRadiusSourceFile",
353 binaryPoint.aprioriradiussourcefile().c_str());
355 if(binaryPoint.has_apriorix()) {
363 Displacement(binaryPoint.apriorix(),Displacement::Meters),
364 Displacement(binaryPoint.aprioriy(),Displacement::Meters),
365 Displacement(binaryPoint.aprioriz(),Displacement::Meters));
366 pvlPoint.findKeyword(
"AprioriX").
addComment(
"AprioriLatitude = " +
369 pvlPoint.findKeyword(
"AprioriY").
addComment(
"AprioriLongitude = " +
372 pvlPoint.findKeyword(
"AprioriZ").
addComment(
"AprioriRadius = " +
376 if(binaryPoint.aprioricovar_size()) {
378 matrix +=
toString(binaryPoint.aprioricovar(0));
379 matrix +=
toString(binaryPoint.aprioricovar(1));
380 matrix +=
toString(binaryPoint.aprioricovar(2));
381 matrix +=
toString(binaryPoint.aprioricovar(3));
382 matrix +=
toString(binaryPoint.aprioricovar(4));
383 matrix +=
toString(binaryPoint.aprioricovar(5));
386 if (pvlRadii.
hasKeyword(
"EquatorialRadius")) {
388 Distance(pvlRadii[
"EquatorialRadius"],Distance::Meters),
389 Distance(pvlRadii[
"EquatorialRadius"],Distance::Meters),
390 Distance(pvlRadii[
"PolarRadius"],Distance::Meters));
391 symmetric_matrix<double, upper> covar;
394 covar(0, 0) = binaryPoint.aprioricovar(0);
395 covar(0, 1) = binaryPoint.aprioricovar(1);
396 covar(0, 2) = binaryPoint.aprioricovar(2);
397 covar(1, 1) = binaryPoint.aprioricovar(3);
398 covar(1, 2) = binaryPoint.aprioricovar(4);
399 covar(2, 2) = binaryPoint.aprioricovar(5);
401 QString sigmas =
"AprioriLatitudeSigma = " +
403 " <meters> AprioriLongitudeSigma = " +
405 " <meters> AprioriRadiusSigma = " +
408 pvlPoint.findKeyword(
"AprioriCovarianceMatrix").addComment(sigmas);
413 if(binaryPoint.latitudeconstrained())
414 pvlPoint +=
PvlKeyword(
"LatitudeConstrained",
"True");
416 if(binaryPoint.longitudeconstrained())
417 pvlPoint +=
PvlKeyword(
"LongitudeConstrained",
"True");
419 if(binaryPoint.radiusconstrained())
420 pvlPoint +=
PvlKeyword(
"RadiusConstrained",
"True");
422 if(binaryPoint.has_adjustedx()) {
430 Displacement(binaryPoint.adjustedx(),Displacement::Meters),
431 Displacement(binaryPoint.adjustedy(),Displacement::Meters),
432 Displacement(binaryPoint.adjustedz(),Displacement::Meters));
433 pvlPoint.findKeyword(
"AdjustedX").
addComment(
"AdjustedLatitude = " +
436 pvlPoint.findKeyword(
"AdjustedY").
addComment(
"AdjustedLongitude = " +
439 pvlPoint.findKeyword(
"AdjustedZ").
addComment(
"AdjustedRadius = " +
443 if(binaryPoint.adjustedcovar_size()) {
444 PvlKeyword matrix(
"AdjustedCovarianceMatrix");
445 matrix +=
toString(binaryPoint.adjustedcovar(0));
446 matrix +=
toString(binaryPoint.adjustedcovar(1));
447 matrix +=
toString(binaryPoint.adjustedcovar(2));
448 matrix +=
toString(binaryPoint.adjustedcovar(3));
449 matrix +=
toString(binaryPoint.adjustedcovar(4));
450 matrix +=
toString(binaryPoint.adjustedcovar(5));
453 if (pvlRadii.
hasKeyword(
"EquatorialRadius")) {
455 Distance(pvlRadii[
"EquatorialRadius"],Distance::Meters),
456 Distance(pvlRadii[
"EquatorialRadius"],Distance::Meters),
457 Distance(pvlRadii[
"PolarRadius"],Distance::Meters));
458 symmetric_matrix<double, upper> covar;
461 covar(0, 0) = binaryPoint.adjustedcovar(0);
462 covar(0, 1) = binaryPoint.adjustedcovar(1);
463 covar(0, 2) = binaryPoint.adjustedcovar(2);
464 covar(1, 1) = binaryPoint.adjustedcovar(3);
465 covar(1, 2) = binaryPoint.adjustedcovar(4);
466 covar(2, 2) = binaryPoint.adjustedcovar(5);
468 QString sigmas =
"AdjustedLatitudeSigma = " +
470 " <meters> AdjustedLongitudeSigma = " +
472 " <meters> AdjustedRadiusSigma = " +
475 pvlPoint.findKeyword(
"AdjustedCovarianceMatrix").addComment(sigmas);
480 for (
int j = 0; j < binaryPoint.measures_size(); j++) {
481 PvlGroup pvlMeasure(
"ControlMeasure");
483 binaryMeasure = binaryPoint.measures(j);
484 pvlMeasure +=
PvlKeyword(
"SerialNumber", binaryMeasure.serialnumber().c_str());
486 switch(binaryMeasure.type()) {
487 case ControlPointFileEntryV0002_Measure_MeasureType_Candidate:
488 pvlMeasure +=
PvlKeyword(
"MeasureType",
"Candidate");
490 case ControlPointFileEntryV0002_Measure_MeasureType_Manual:
491 pvlMeasure +=
PvlKeyword(
"MeasureType",
"Manual");
493 case ControlPointFileEntryV0002_Measure_MeasureType_RegisteredPixel:
494 pvlMeasure +=
PvlKeyword(
"MeasureType",
"RegisteredPixel");
496 case ControlPointFileEntryV0002_Measure_MeasureType_RegisteredSubPixel:
497 pvlMeasure +=
PvlKeyword(
"MeasureType",
"RegisteredSubPixel");
501 if(binaryMeasure.has_choosername())
502 pvlMeasure +=
PvlKeyword(
"ChooserName", binaryMeasure.choosername().c_str());
504 if(binaryMeasure.has_datetime())
505 pvlMeasure +=
PvlKeyword(
"DateTime", binaryMeasure.datetime().c_str());
507 if(binaryMeasure.editlock())
510 if(binaryMeasure.ignore())
513 if(binaryMeasure.has_sample())
516 if(binaryMeasure.has_line())
519 if (binaryMeasure.has_diameter())
522 if (binaryMeasure.has_apriorisample())
525 if (binaryMeasure.has_aprioriline())
528 if (binaryMeasure.has_samplesigma())
532 if (binaryMeasure.has_samplesigma())
536 if(binaryMeasure.has_sampleresidual())
540 if(binaryMeasure.has_lineresidual())
544 if(binaryMeasure.has_jigsawrejected()) {
548 for(
int logEntry = 0;
549 logEntry < binaryMeasure.log_size();
552 binaryMeasure.log(logEntry);
558 if(binaryPoint.has_referenceindex() &&
559 binaryPoint.referenceindex() == j)
560 pvlMeasure +=
PvlKeyword(
"Reference",
"True");
562 pvlPoint.addGroup(pvlMeasure);
565 network.addObject(pvlPoint);