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;
61 QSharedPointer<LidarControlPoint>
point =
m_points.value(pointId, 0);
63 QString msg =
"Point " + pointId +
" is not in the lidar data.";
89 QList< QSharedPointer<LidarControlPoint> > pointlist =
points();
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() +
179 "], measure [" + curMeasure->GetCubeSerialNumber() +
180 "] does not have a cube in the ISIS control net with a matching serial number";
184 curMeasure->SetCamera(cam);
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() +
263 "], measure [" + curMeasure->GetCubeSerialNumber() +
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();
341 QSharedPointer<LidarControlPoint> lcp =
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();
460 measure->SetCoordinate(sample, line);
461 measure->SetCubeSerialNumber(serialNumber);
471 m_numAsynchronousMeasures = totalMeasures - m_numSimultaneousMeasures;
490 if (format ==
Json) {
491 outputFile = outputFile.setExtension(
"json");
493 else if (format ==
Test) {
496 outputFile = outputFile.setExtension(
"json");
500 outputFile = outputFile.setExtension(
"dat");
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;
513 foreach (QSharedPointer<LidarControlPoint> lcp,
points(sort)) {
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();
593 measureObject[
"serialNumber"] = measure->GetCubeSerialNumber();
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());
663 QList< ControlMeasure * > validMeasures;
669 if (!measure->IsIgnored()) {
670 validMeasures.append(measure);
674 return validMeasures;
684 IString msg =
"Cube Serial Number [" + serialNumber +
"] not found in "
689 QList< ControlMeasure * > measures;
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.
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
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.
@ 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.