6#include <QJsonDocument>
10#include <QMapIterator>
12#include <QSharedPointer>
18#include "CameraFactory.h"
19#include "ControlNet.h"
22#include "IException.h"
27#include "SerialNumberList.h"
28#include "SurfacePoint.h"
30using namespace boost::numeric::ublas;
39 m_numSimultaneousMeasures = 0;
40 m_numAsynchronousMeasures = 0;
63 QString msg =
"Point " + pointId +
" is not in the lidar data.";
90 std::sort(pointlist.begin(), pointlist.end(),
113 return m_numSimultaneousMeasures;
122 return m_numAsynchronousMeasures;
132 return m_numSimultaneousMeasures + m_numAsynchronousMeasures;
151 QMapIterator< QString, Isis::Camera *> it(
p_cameraMap);
152 while (it.hasNext()) {
154 QString serialNumber = it.key();
165 QHashIterator< QString, QSharedPointer<LidarControlPoint> > p(
m_points);
166 while (p.hasNext()) {
171 for (
int m = 0; m < serialNums.size(); m++) {
178 IString msg =
"Lidar Control point [" + curPoint->GetId() +
180 "] does not have a cube in the ISIS control net with a matching serial number";
187 if (!curMeasure->IsIgnored()) {
216 if (progress != NULL) {
217 progress->
SetText(
"Setting input images...");
222 for (
int i = 0; i < list.
size(); i++) {
224 QString filename = list.
fileName(i);
225 Cube cube(filename,
"r");
235 QString msg =
"Unable to create camera for cube file ";
240 if (progress != NULL)
245 QHashIterator< QString, QSharedPointer<LidarControlPoint> > p(
m_points);
246 while (p.hasNext()) {
251 for (
int m = 0; m < serialNums.size(); m++) {
262 IString msg =
"Control point [" + curPoint->GetId() +
264 "] does not have a cube with a matching serial number";
283 QFile loadFile(lidarDataFile.
expanded());
285 if (!loadFile.open(QIODevice::ReadOnly)) {
286 QString msg(
"Could not open " + loadFile.fileName());
291 QByteArray saveData = loadFile.readAll();
292 QCborValue loadData(saveData);
293 QJsonDocument loadDoc(QJsonDocument::fromJson(loadData.toByteArray()));
295 int totalMeasures = 0;
298 QJsonObject lidarDataObject = loadDoc.object();
299 if (lidarDataObject.contains(
"points") && lidarDataObject[
"points"].isArray()) {
301 QJsonArray pointArray = lidarDataObject[
"points"].toArray();
302 for (
int pointIndex = 0; pointIndex < pointArray.size(); pointIndex++) {
304 QJsonObject pointObject = pointArray[pointIndex].toObject();
307 if (pointObject.contains(
"id") && pointObject[
"id"].isString()) {
308 id = pointObject[
"id"].toString();
312 if (pointObject.contains(
"range") && pointObject[
"range"].isDouble()) {
313 range = pointObject[
"range"].toDouble();
316 double sigmaRange = 0.0;
317 if (pointObject.contains(
"sigmaRange") && pointObject[
"sigmaRange"].isDouble()) {
318 sigmaRange = pointObject[
"sigmaRange"].toDouble();
322 if (pointObject.contains(
"time") && pointObject[
"time"].isDouble()) {
323 time = pointObject[
"time"].toDouble();
326 double latitude = 0.0;
327 if (pointObject.contains(
"latitude") && pointObject[
"latitude"].isDouble()) {
328 latitude = pointObject[
"latitude"].toDouble();
331 double longitude = 0.0;
332 if (pointObject.contains(
"longitude") && pointObject[
"longitude"].isDouble()) {
333 longitude = pointObject[
"longitude"].toDouble();
337 if (pointObject.contains(
"radius") && pointObject[
"radius"].isDouble()) {
338 radius = pointObject[
"radius"].toDouble();
344 lcp->setTime(
iTime(time));
345 lcp->setRange(range);
346 lcp->setSigmaRange(sigmaRange);
348 if (pointObject.contains(
"aprioriMatrix") &&
349 pointObject[
"aprioriMatrix"].isArray()) {
350 QJsonArray aprioriMatrixArray = pointObject[
"aprioriMatrix"].toArray();
351 boost::numeric::ublas::symmetric_matrix<double, upper> aprioriMatrix(3);
352 aprioriMatrix.clear();
353 aprioriMatrix(0, 0) = aprioriMatrixArray[0].toDouble();
354 aprioriMatrix(0, 1) = aprioriMatrix(1, 0) = aprioriMatrixArray[1].toDouble();
355 aprioriMatrix(0, 2) = aprioriMatrix(2, 0) = aprioriMatrixArray[2].toDouble();
356 aprioriMatrix(1, 1) = aprioriMatrixArray[3].toDouble();
357 aprioriMatrix(1, 2) = aprioriMatrix(2, 1) = aprioriMatrixArray[4].toDouble();
358 aprioriMatrix(2, 2) = aprioriMatrixArray[5].toDouble();
373 if (pointObject.contains(
"adjustedLatitude") &&
374 pointObject[
"adjustedLatitude"].isDouble() &&
375 pointObject.contains(
"adjustedLongitude") &&
376 pointObject[
"adjustedLongitude"].isDouble() &&
377 pointObject.contains(
"adjustedRadius") &&
378 pointObject[
"adjustedRadius"].isDouble()) {
380 double adjustedLatitude = 0.0;
381 adjustedLatitude = pointObject[
"adjustedLatitude"].toDouble();
383 double adjustedLongitude = 0.0;
384 adjustedLongitude = pointObject[
"adjustedLongitude"].toDouble();
386 double adjustedRadius = 0.0;
387 adjustedRadius = pointObject[
"radius"].toDouble();
389 if (pointObject.contains(
"adjustedMatrix") &&
390 pointObject[
"adjustedMatrix"].isArray()) {
391 QJsonArray adjustedMatrixArray = pointObject[
"adjustedMatrix"].toArray();
392 boost::numeric::ublas::symmetric_matrix<double, upper> adjustedMatrix(3);
393 adjustedMatrix.clear();
394 adjustedMatrix(0, 0) = adjustedMatrixArray[0].toDouble();
395 adjustedMatrix(0, 1) = adjustedMatrix(1, 0) = adjustedMatrixArray[1].toDouble();
396 adjustedMatrix(0, 2) = adjustedMatrix(2, 0) = adjustedMatrixArray[2].toDouble();
397 adjustedMatrix(1, 1) = adjustedMatrixArray[3].toDouble();
398 adjustedMatrix(1, 2) = adjustedMatrix(2, 1) = adjustedMatrixArray[4].toDouble();
399 adjustedMatrix(2, 2) = adjustedMatrixArray[5].toDouble();
414 if (pointObject.contains(
"simultaneousImages") &&
415 pointObject[
"simultaneousImages"].isArray()) {
416 QJsonArray simultaneousArray =
417 pointObject[
"simultaneousImages"].toArray();
419 for (
int simIndex = 0; simIndex < simultaneousArray.size(); simIndex ++) {
422 newSerial = simultaneousArray[simIndex].toString();
423 lcp->addSimultaneous(newSerial);
424 m_numSimultaneousMeasures++;
429 if (pointObject.contains(
"measures") && pointObject[
"measures"].isArray()) {
430 QJsonArray measureArray = pointObject[
"measures"].toArray();
431 for (
int measureIndex = 0; measureIndex < measureArray.size(); measureIndex++) {
433 QJsonObject measureObject = measureArray[measureIndex].toObject();
436 if (measureObject.contains(
"line") && measureObject[
"line"].toDouble()) {
437 line = measureObject[
"line"].toDouble();
441 if (measureObject.contains(
"sample") && measureObject[
"sample"].toDouble()) {
442 sample = measureObject[
"sample"].toDouble();
445 QString serialNumber;
446 if (measureObject.contains(
"serialNumber") && measureObject[
"serialNumber"].isString()) {
447 serialNumber = measureObject[
"serialNumber"].toString();
471 m_numAsynchronousMeasures = totalMeasures - m_numSimultaneousMeasures;
490 if (format ==
Json) {
493 else if (format ==
Test) {
502 QFile saveFile(outputFile.
expanded());
504 if (!saveFile.open(QIODevice::WriteOnly)) {
505 QString msg(
"Could not open " + saveFile.fileName());
510 QJsonObject lidarDataObject;
511 QJsonArray pointArray;
515 QJsonObject pointObject;
516 pointObject[
"id"] = lcp->GetId();
517 pointObject[
"range"] = lcp->range();
518 pointObject[
"sigmaRange"] = lcp->sigmaRange();
519 pointObject[
"time"] = lcp->time().Et();
522 SurfacePoint aprioriSurfacePoint = lcp->GetAprioriSurfacePoint();
523 if (aprioriSurfacePoint.Valid()) {
529 symmetric_matrix<double, upper> aprioriMatrix = aprioriSurfacePoint.GetSphericalMatrix();
530 QJsonArray aprioriMatrixArray;
531 aprioriMatrixArray += aprioriMatrix(0, 0);
532 aprioriMatrixArray += aprioriMatrix(0, 1);
533 aprioriMatrixArray += aprioriMatrix(0, 2);
534 aprioriMatrixArray += aprioriMatrix(1, 1);
535 aprioriMatrixArray += aprioriMatrix(1, 2);
536 aprioriMatrixArray += aprioriMatrix(2, 2);
539 if ( aprioriMatrix(0, 0) != 0.0
540 || aprioriMatrix(0, 1) != 0.0
541 || aprioriMatrix(0, 2) != 0.0
542 || aprioriMatrix(1, 1) != 0.0
543 || aprioriMatrix(1, 2) != 0.0
544 || aprioriMatrix(2, 2) != 0.0 ) {
545 pointObject[
"aprioriMatrix"] = aprioriMatrixArray;
550 SurfacePoint adjustedSurfacePoint = lcp->GetAdjustedSurfacePoint();
551 if (adjustedSurfacePoint.Valid()) {
552 pointObject[
"adjustedLatitude"] =
554 pointObject[
"adjustedLongitude"] =
559 symmetric_matrix<double, upper> adjustedMatrix = adjustedSurfacePoint.GetSphericalMatrix();
560 QJsonArray adjustedMatrixArray;
561 adjustedMatrixArray += adjustedMatrix(0, 0);
562 adjustedMatrixArray += adjustedMatrix(0, 1);
563 adjustedMatrixArray += adjustedMatrix(0, 2);
564 adjustedMatrixArray += adjustedMatrix(1, 1);
565 adjustedMatrixArray += adjustedMatrix(1, 2);
566 adjustedMatrixArray += adjustedMatrix(2, 2);
569 if ( adjustedMatrix(0, 0) != 0.0
570 || adjustedMatrix(0, 1) != 0.0
571 || adjustedMatrix(0, 2) != 0.0
572 || adjustedMatrix(1, 1) != 0.0
573 || adjustedMatrix(1, 2) != 0.0
574 || adjustedMatrix(2, 2) != 0.0 ) {
575 pointObject[
"adjustedMatrix"] = adjustedMatrixArray;
580 QJsonArray simultaneousArray;
581 foreach (QString sn, lcp->snSimultaneous()) {
582 simultaneousArray.append(sn);
584 pointObject[
"simultaneousImages"] = simultaneousArray;
586 QJsonArray measureArray;
590 QJsonObject measureObject;
591 measureObject[
"line"] = measure->GetLine();
592 measureObject[
"sample"] = measure->GetSample();
595 measureArray.append(measureObject);
599 pointObject[
"measures"] = measureArray;
601 pointArray.append(pointObject);
605 lidarDataObject[
"points"] = pointArray;
608 QJsonDocument lidarDataDoc(lidarDataObject);
609 if (format ==
Json || format ==
Test) {
610 saveFile.write(lidarDataDoc.toJson());
613 QCborValue json(lidarDataDoc.toJson());
614 saveFile.write(json.toByteArray());
669 if (!measure->IsIgnored()) {
670 validMeasures.append(measure);
674 return validMeasures;
684 IString msg =
"Cube Serial Number [" + serialNumber +
"] not found in "
690 foreach(QSharedPointer <LidarControlPoint>
point,
m_points) {
691 if (
point->HasSerialNumber(serialNumber)) {
692 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.
File name manipulation and expansion.
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
@ Unknown
A type of error that cannot be classified as any of the other error types.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
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.