6#include <QJsonDocument>
10#include <QMapIterator>
11#include <QSharedPointer>
17#include "CameraFactory.h"
18#include "ControlNet.h"
21#include "IException.h"
26#include "SerialNumberList.h"
27#include "SurfacePoint.h"
29using namespace boost::numeric::ublas;
38 m_numSimultaneousMeasures = 0;
39 m_numAsynchronousMeasures = 0;
62 QString msg =
"Point " + pointId +
" is not in the lidar data.";
63 throw IException(IException::Programmer, msg, _FILEINFO_);
89 std::sort(pointlist.begin(), pointlist.end(),
112 return m_numSimultaneousMeasures;
121 return m_numAsynchronousMeasures;
131 return m_numSimultaneousMeasures + m_numAsynchronousMeasures;
150 QMapIterator< QString, Isis::Camera *> it(
p_cameraMap);
151 while (it.hasNext()) {
153 QString serialNumber = it.key();
164 QHashIterator< QString, QSharedPointer<LidarControlPoint> > p(
m_points);
165 while (p.hasNext()) {
170 for (
int m = 0; m < serialNums.size(); m++) {
177 IString msg =
"Lidar Control point [" + curPoint->GetId() +
179 "] does not have a cube in the ISIS control net with a matching serial number";
180 throw IException(IException::User, msg, _FILEINFO_);
186 if (!curMeasure->IsIgnored()) {
215 if (progress != NULL) {
216 progress->
SetText(
"Setting input images...");
221 for (
int i = 0; i < list.
size(); i++) {
223 QString filename = list.
fileName(i);
224 Cube cube(filename,
"r");
233 catch (IException &e) {
234 QString msg =
"Unable to create camera for cube file ";
236 throw IException(e, IException::Unknown, msg, _FILEINFO_);
239 if (progress != NULL)
244 QHashIterator< QString, QSharedPointer<LidarControlPoint> > p(
m_points);
245 while (p.hasNext()) {
250 for (
int m = 0; m < serialNums.size(); m++) {
261 IString msg =
"Control point [" + curPoint->GetId() +
263 "] does not have a cube with a matching serial number";
264 throw IException(IException::User, msg, _FILEINFO_);
282 QFile loadFile(lidarDataFile.expanded());
284 if (!loadFile.open(QIODevice::ReadOnly)) {
285 QString msg(
"Could not open " + loadFile.fileName());
286 throw IException(IException::User, msg, _FILEINFO_);
290 QByteArray saveData = loadFile.readAll();
291 QCborValue loadData(saveData);
292 QJsonDocument loadDoc(QJsonDocument::fromJson(loadData.toByteArray()));
294 int totalMeasures = 0;
297 QJsonObject lidarDataObject = loadDoc.object();
298 if (lidarDataObject.contains(
"points") && lidarDataObject[
"points"].isArray()) {
300 QJsonArray pointArray = lidarDataObject[
"points"].toArray();
301 for (
int pointIndex = 0; pointIndex < pointArray.size(); pointIndex++) {
303 QJsonObject pointObject = pointArray[pointIndex].toObject();
306 if (pointObject.contains(
"id") && pointObject[
"id"].isString()) {
307 id = pointObject[
"id"].toString();
311 if (pointObject.contains(
"range") && pointObject[
"range"].isDouble()) {
312 range = pointObject[
"range"].toDouble();
315 double sigmaRange = 0.0;
316 if (pointObject.contains(
"sigmaRange") && pointObject[
"sigmaRange"].isDouble()) {
317 sigmaRange = pointObject[
"sigmaRange"].toDouble();
321 if (pointObject.contains(
"time") && pointObject[
"time"].isDouble()) {
322 time = pointObject[
"time"].toDouble();
325 double latitude = 0.0;
326 if (pointObject.contains(
"latitude") && pointObject[
"latitude"].isDouble()) {
327 latitude = pointObject[
"latitude"].toDouble();
330 double longitude = 0.0;
331 if (pointObject.contains(
"longitude") && pointObject[
"longitude"].isDouble()) {
332 longitude = pointObject[
"longitude"].toDouble();
336 if (pointObject.contains(
"radius") && pointObject[
"radius"].isDouble()) {
337 radius = pointObject[
"radius"].toDouble();
343 lcp->setTime(
iTime(time));
344 lcp->setRange(range);
345 lcp->setSigmaRange(sigmaRange);
347 if (pointObject.contains(
"aprioriMatrix") &&
348 pointObject[
"aprioriMatrix"].isArray()) {
349 QJsonArray aprioriMatrixArray = pointObject[
"aprioriMatrix"].toArray();
350 boost::numeric::ublas::symmetric_matrix<double, upper> aprioriMatrix(3);
351 aprioriMatrix.clear();
352 aprioriMatrix(0, 0) = aprioriMatrixArray[0].toDouble();
353 aprioriMatrix(0, 1) = aprioriMatrix(1, 0) = aprioriMatrixArray[1].toDouble();
354 aprioriMatrix(0, 2) = aprioriMatrix(2, 0) = aprioriMatrixArray[2].toDouble();
355 aprioriMatrix(1, 1) = aprioriMatrixArray[3].toDouble();
356 aprioriMatrix(1, 2) = aprioriMatrix(2, 1) = aprioriMatrixArray[4].toDouble();
357 aprioriMatrix(2, 2) = aprioriMatrixArray[5].toDouble();
372 if (pointObject.contains(
"adjustedLatitude") &&
373 pointObject[
"adjustedLatitude"].isDouble() &&
374 pointObject.contains(
"adjustedLongitude") &&
375 pointObject[
"adjustedLongitude"].isDouble() &&
376 pointObject.contains(
"adjustedRadius") &&
377 pointObject[
"adjustedRadius"].isDouble()) {
379 double adjustedLatitude = 0.0;
380 adjustedLatitude = pointObject[
"adjustedLatitude"].toDouble();
382 double adjustedLongitude = 0.0;
383 adjustedLongitude = pointObject[
"adjustedLongitude"].toDouble();
385 double adjustedRadius = 0.0;
386 adjustedRadius = pointObject[
"radius"].toDouble();
388 if (pointObject.contains(
"adjustedMatrix") &&
389 pointObject[
"adjustedMatrix"].isArray()) {
390 QJsonArray adjustedMatrixArray = pointObject[
"adjustedMatrix"].toArray();
391 boost::numeric::ublas::symmetric_matrix<double, upper> adjustedMatrix(3);
392 adjustedMatrix.clear();
393 adjustedMatrix(0, 0) = adjustedMatrixArray[0].toDouble();
394 adjustedMatrix(0, 1) = adjustedMatrix(1, 0) = adjustedMatrixArray[1].toDouble();
395 adjustedMatrix(0, 2) = adjustedMatrix(2, 0) = adjustedMatrixArray[2].toDouble();
396 adjustedMatrix(1, 1) = adjustedMatrixArray[3].toDouble();
397 adjustedMatrix(1, 2) = adjustedMatrix(2, 1) = adjustedMatrixArray[4].toDouble();
398 adjustedMatrix(2, 2) = adjustedMatrixArray[5].toDouble();
413 if (pointObject.contains(
"simultaneousImages") &&
414 pointObject[
"simultaneousImages"].isArray()) {
415 QJsonArray simultaneousArray =
416 pointObject[
"simultaneousImages"].toArray();
418 for (
int simIndex = 0; simIndex < simultaneousArray.size(); simIndex ++) {
421 newSerial = simultaneousArray[simIndex].toString();
422 lcp->addSimultaneous(newSerial);
423 m_numSimultaneousMeasures++;
428 if (pointObject.contains(
"measures") && pointObject[
"measures"].isArray()) {
429 QJsonArray measureArray = pointObject[
"measures"].toArray();
430 for (
int measureIndex = 0; measureIndex < measureArray.size(); measureIndex++) {
432 QJsonObject measureObject = measureArray[measureIndex].toObject();
435 if (measureObject.contains(
"line") && measureObject[
"line"].toDouble()) {
436 line = measureObject[
"line"].toDouble();
440 if (measureObject.contains(
"sample") && measureObject[
"sample"].toDouble()) {
441 sample = measureObject[
"sample"].toDouble();
444 QString serialNumber;
445 if (measureObject.contains(
"serialNumber") && measureObject[
"serialNumber"].isString()) {
446 serialNumber = measureObject[
"serialNumber"].toString();
470 m_numAsynchronousMeasures = totalMeasures - m_numSimultaneousMeasures;
489 if (format ==
Json) {
490 outputFile = outputFile.setExtension(
"json");
492 else if (format ==
Test) {
495 outputFile = outputFile.setExtension(
"json");
499 outputFile = outputFile.setExtension(
"dat");
501 QFile saveFile(outputFile.expanded());
503 if (!saveFile.open(QIODevice::WriteOnly)) {
504 QString msg(
"Could not open " + saveFile.fileName());
505 throw IException(IException::User, msg, _FILEINFO_);
509 QJsonObject lidarDataObject;
510 QJsonArray pointArray;
514 QJsonObject pointObject;
515 pointObject[
"id"] = lcp->GetId();
516 pointObject[
"range"] = lcp->range();
517 pointObject[
"sigmaRange"] = lcp->sigmaRange();
518 pointObject[
"time"] = lcp->time().Et();
521 SurfacePoint aprioriSurfacePoint = lcp->GetAprioriSurfacePoint();
522 if (aprioriSurfacePoint.Valid()) {
528 symmetric_matrix<double, upper> aprioriMatrix = aprioriSurfacePoint.GetSphericalMatrix();
529 QJsonArray aprioriMatrixArray;
530 aprioriMatrixArray += aprioriMatrix(0, 0);
531 aprioriMatrixArray += aprioriMatrix(0, 1);
532 aprioriMatrixArray += aprioriMatrix(0, 2);
533 aprioriMatrixArray += aprioriMatrix(1, 1);
534 aprioriMatrixArray += aprioriMatrix(1, 2);
535 aprioriMatrixArray += aprioriMatrix(2, 2);
538 if ( aprioriMatrix(0, 0) != 0.0
539 || aprioriMatrix(0, 1) != 0.0
540 || aprioriMatrix(0, 2) != 0.0
541 || aprioriMatrix(1, 1) != 0.0
542 || aprioriMatrix(1, 2) != 0.0
543 || aprioriMatrix(2, 2) != 0.0 ) {
544 pointObject[
"aprioriMatrix"] = aprioriMatrixArray;
549 SurfacePoint adjustedSurfacePoint = lcp->GetAdjustedSurfacePoint();
550 if (adjustedSurfacePoint.Valid()) {
551 pointObject[
"adjustedLatitude"] =
553 pointObject[
"adjustedLongitude"] =
558 symmetric_matrix<double, upper> adjustedMatrix = adjustedSurfacePoint.GetSphericalMatrix();
559 QJsonArray adjustedMatrixArray;
560 adjustedMatrixArray += adjustedMatrix(0, 0);
561 adjustedMatrixArray += adjustedMatrix(0, 1);
562 adjustedMatrixArray += adjustedMatrix(0, 2);
563 adjustedMatrixArray += adjustedMatrix(1, 1);
564 adjustedMatrixArray += adjustedMatrix(1, 2);
565 adjustedMatrixArray += adjustedMatrix(2, 2);
568 if ( adjustedMatrix(0, 0) != 0.0
569 || adjustedMatrix(0, 1) != 0.0
570 || adjustedMatrix(0, 2) != 0.0
571 || adjustedMatrix(1, 1) != 0.0
572 || adjustedMatrix(1, 2) != 0.0
573 || adjustedMatrix(2, 2) != 0.0 ) {
574 pointObject[
"adjustedMatrix"] = adjustedMatrixArray;
579 QJsonArray simultaneousArray;
580 foreach (QString sn, lcp->snSimultaneous()) {
581 simultaneousArray.append(sn);
583 pointObject[
"simultaneousImages"] = simultaneousArray;
585 QJsonArray measureArray;
589 QJsonObject measureObject;
590 measureObject[
"line"] = measure->GetLine();
591 measureObject[
"sample"] = measure->GetSample();
594 measureArray.append(measureObject);
598 pointObject[
"measures"] = measureArray;
600 pointArray.append(pointObject);
604 lidarDataObject[
"points"] = pointArray;
607 QJsonDocument lidarDataDoc(lidarDataObject);
608 if (format ==
Json || format ==
Test) {
609 saveFile.write(lidarDataDoc.toJson());
612 QCborValue json(lidarDataDoc.toJson());
613 saveFile.write(json.toByteArray());
668 if (!measure->IsIgnored()) {
669 validMeasures.append(measure);
673 return validMeasures;
683 IString msg =
"Cube Serial Number [" + serialNumber +
"] not found in "
685 throw IException(IException::Programmer, msg, _FILEINFO_);
689 foreach(QSharedPointer <LidarControlPoint>
point,
m_points) {
690 if (
point->HasSerialNumber(serialNumber)) {
691 measures.append(
point->GetMeasure(serialNumber));
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
Status SetCamera(Isis::Camera *camera)
Set pointer to camera associated with a measure.
Isis::Camera * Camera(int index)
Returns the camera list from the given image number.
@ Constrained
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
IO Handler for Isis Cubes.
Distance measurement, usually in meters.
double kilometers() const
Get the distance in kilometers.
@ Kilometers
The distance is being specified in kilometers.
This class is designed to encapsulate the concept of a Latitude.
double planetocentric(Angle::Units units=Angle::Radians) const
Get the latitude in the planetocentric (universal) coordinate system.
A lidar control ControlPoint.
QSharedPointer< LidarControlPoint > point(QString pointId) const
Gets a single LidarDataPoint by ID.
QVector< Isis::Camera * > p_cameraList
vector of image# to camera
int numberLidarPoints()
Returns number of Lidar data points.
bool ValidateSerialNumber(QString serialNumber) const
Does a check to ensure that the given serial number is contained within the network.
QList< ControlMeasure * > GetValidMeasuresInCube(QString serialNumber)
Get all the valid measures pertaining to a given cube serial number.
Format
Enumerates the file formats for serializing the LidarData class.
@ Test
Serializes to an ordered JSON .json file for comparing to truth data.
@ Json
Serializes to a JSON .json file.
void SetImages(SerialNumberList &list, Progress *progress=0)
Creates the ControlNet's image camera's based on the list of Serial Numbers.
LidarData()
Default constructor.
void read(FileName)
Unserialize LidarData.
QMap< QString, Isis::Camera * > p_cameraMap
camera
QList< QSharedPointer< LidarControlPoint > > points(bool sort=false) const
Gets the list of Lidar data points optionally sorted .
void write(FileName, Format)
Serializes LidarData.
int numberMeasures()
Returns total number of lidar measures.
int numberSimultaneousMeasures()
Returns number of simultaneous lidar measures.
QMap< QString, int > p_cameraRejectedMeasuresMap
#rejected measures
void insert(QSharedPointer< LidarControlPoint > point)
Adds a LidarControlPoint to the LidarData.
int GetNumberOfValidMeasuresInImage(const QString &serialNumber)
Return the number of measures in image specified by serialNumber.
QMap< QString, int > p_cameraValidMeasuresMap
#measures
QList< ControlMeasure * > GetMeasuresInCube(QString serialNumber)
Get all the measures pertaining to a given cube serial number.
QHash< QString, QSharedPointer< LidarControlPoint > > m_points
hash of LidarControlPoints
int numberAsynchronousMeasures()
Returns number of non-simultaneous lidar measures.
int GetNumberOfJigsawRejectedMeasuresInImage(const QString &serialNumber)
Return the number of jigsaw rejected measures in image specified by serialNumber.
This class is designed to encapsulate the concept of a Longitude.
double positiveEast(Angle::Units units=Angle::Radians) const
Get the longitude in the PositiveEast coordinate system.
Program progress reporter.
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
void CheckStatus()
Checks and updates the status.
Serial Number list generator.
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
int size() const
How many serial number / filename combos are in the list.
QString fileName(const QString &sn)
Return a filename given a serial number.
This class defines a body-fixed surface point.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Distance GetLocalRadius() const
Return the radius of the surface point.
Parse and return pieces of a time string.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
QSharedPointer< LidarControlPoint > LidarControlPointQsp
Definition for a shared pointer to a LidarControlPoint.