Skip to content

Commit

Permalink
Merge pull request #10 from acpaquette/gdaljson
Browse files Browse the repository at this point in the history
gdal json pvl parsing
  • Loading branch information
acpaquette authored May 20, 2024
2 parents 293f058 + cca6d4c commit 3a9c187
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 19 deletions.
77 changes: 76 additions & 1 deletion isis/src/base/objs/Pvl/Pvl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ find files of those names at the top level of this repository. **/
#include <locale>
#include <fstream>
#include <sstream>
#include <cctype>

#include <filesystem>
#include <random>
#include <gdal_priv.h>
#include <nlohmann/json.hpp>

#include "FileName.h"
#include "IException.h"
#include "Message.h"
#include "PvlTokenizer.h"
#include "PvlFormat.h"

namespace fs = std::filesystem;
using json = nlohmann::json;

using namespace std;
namespace Isis {
//! Constructs an empty Pvl object.
Expand All @@ -32,8 +41,74 @@ namespace Isis {
* @param file The file containing the pvl formatted information
*/
Pvl::Pvl(const QString &file) : Isis::PvlObject("Root") {
// This function specifically reads from GDAL-style JSON metadata.
function<PvlObject(PvlObject&, json)> read_object = [&](PvlObject &pvlobj, json jdata) -> PvlObject {
for(auto &[key, value] : jdata.items()) {
string name = key;
if(value.contains("_type")) {
string type = value.at("_type");
value.erase("_type");
if (value.contains("_container_name")) {
name = value["_container_name"];
value.erase("_container_name");
}

if(type == "object") {
PvlObject nestedObj(QString::fromStdString(name));
pvlobj.addObject(read_object(nestedObj, value));
}
if(type == "group") {
// parse keys
PvlGroup group(QString::fromStdString(name));
for(auto &[pvlkeyword, pvlvalue] : value.items()) {
PvlKeyword keyword;
keyword.setName(QString::fromStdString(pvlkeyword));
if (pvlvalue.is_array())
keyword.addJsonArrayValue(pvlvalue);
else
keyword.setJsonValue(pvlvalue);
group.addKeyword(keyword);
}
pvlobj.addGroup(group);
} // end of group
} // end of _type search

// not a group or object, must be a keyword
else if (key != "_type" && key != "_filename") {
PvlKeyword keyword;
keyword.setName(QString::fromStdString(key));
if (value.is_array())
keyword.setJsonArrayValue(value);
else
keyword.setJsonValue(value);

pvlobj.addKeyword(keyword);
}
}
return pvlobj;
};


init();
read(file);
// try to read as a geodataset
try{
GDALAllRegister();
const GDALAccess eAccess = GA_ReadOnly;
GDALDataset *dataset = GDALDataset::FromHandle(GDALOpen( file.toStdString().c_str(), eAccess ));

char** metadata = dataset->GetMetadata("json:ISIS3");
json jsonlabel = json::parse(metadata[0]);
if (jsonlabel.contains("_name")) {
QString name = QString::fromStdString(jsonlabel["name"].get<string>());
this->setName(name);
}

read_object(*this, jsonlabel);

} catch (exception &e) {
cout << "failed : " << e.what() << endl;
read(file);
}
}


Expand Down
90 changes: 74 additions & 16 deletions isis/src/base/objs/PvlKeyword/PvlKeyword.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,9 @@ namespace Isis {
*
* @see addJsonValue()
*/
void PvlKeyword::setJsonValue(json jsonobj, QString unit)
{
void PvlKeyword::setJsonValue(json jsonobj) {
clear();
addJsonValue(jsonobj, unit);
addJsonValue(jsonobj);
}

/**
Expand Down Expand Up @@ -299,31 +298,90 @@ namespace Isis {
*
* @throws Isis::iException::Unknown - jsonobj cannot be an array of values
*/
void PvlKeyword::addJsonValue(json jsonobj, QString unit) {
void PvlKeyword::addJsonValue(json jsonobj) {
QString value;
if (jsonobj.is_array()) {
QString unit = "";
json jvalue = jsonobj;
if (jsonobj.contains("unit")) {
unit = QString::fromStdString(jsonobj["unit"].get<string>());
jvalue = jsonobj["value"];
}

if (jvalue.is_array()) {
QString msg = "Unable to convert " + name() + " with nested json array value into PvlKeyword";
throw IException(IException::Unknown, msg, _FILEINFO_);
}
else if (jsonobj.is_number())
{
value = QString::number(jsonobj.get<double>(), 'g', 16);
else if (jvalue.is_number()) {
value = QString::number(jvalue.get<double>(), 'g', 16);
}
else if (jsonobj.is_boolean())
{
value = QString(jsonobj.get<bool>() ? "true" : "false");
else if (jvalue.is_boolean()) {
value = QString(jvalue.get<bool>() ? "true" : "false");
}
else if (jsonobj.is_null())
{
else if (jvalue.is_null()) {
value = QString("Null");
}
else
{
value = QString::fromStdString(jsonobj);
else {
value = QString::fromStdString(jvalue);
}
addValue(value, unit);
}

/**
* Adds multiple items from a json array.
*
* If no current value exists, this method sets the given json value.
* Otherwise, it retains any current values and adds the json value
* given to the array of values for this PvlKeyword object using addValue.
* Defaults to unit = "" (empty QString).
*
* @param jsonobj New jsonobj to be parsed and assigned.
* @param unit Units of measurement corresponding to the value.
*
* @see setJsonValue()
* @see addValue()
*
* @throws Isis::iException::Unknown - jsonobj must be a json array
*/
void PvlKeyword::addJsonArrayValue(json jsonobj) {
if(!jsonobj.is_array()) {
QString msg = "Unable to convert to a json array:\n" + QString::fromStdString(jsonobj.dump());
throw IException(IException::Unknown, msg, _FILEINFO_);
}

for(auto ar = jsonobj.begin(); ar!=jsonobj.end(); ar++) {
try {
addJsonValue(*ar);
}
catch (IException &e) {
QString msg = "While attempting to parse " + name() + " the following occured";
throw IException(e, IException::Unknown, msg, _FILEINFO_);
}
}
}


/**
* sets multiple items from a json array.
*
* If no current value exists, this method sets the given json value.
* Otherwise, it retains any current values and adds the json value
* given to the array of values for this PvlKeyword object using addValue.
* Defaults to unit = "" (empty QString).
*
* @param jsonobj New jsonobj to be parsed and assigned.
* @param unit Units of measurement corresponding to the value.
*
* @see setJsonValue()
* @see addValue()
*
* @throws Isis::iException::Unknown - jsonobj must be a json array
*/
void PvlKeyword::setJsonArrayValue(json jsonobj) {
clear();
addJsonArrayValue(jsonobj);
}


/**
* Adds a value.
*
Expand Down
7 changes: 5 additions & 2 deletions isis/src/base/objs/PvlKeyword/PvlKeyword.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,18 @@ namespace Isis {
};

void setValue(QString value, QString unit = "");
void setJsonValue(nlohmann::json jsonobj, QString unit = "");
void setJsonValue(nlohmann::json jsonobj);
void setJsonArrayValue(nlohmann::json jsonobj);


void setUnits(QString units);
void setUnits(QString value, QString units);

PvlKeyword &operator=(QString value);

void addValue(QString value, QString unit = "");
void addJsonValue(nlohmann::json jsonobj, QString unit = "");
void addJsonValue(nlohmann::json jsonobj);
void addJsonArrayValue(nlohmann::json jsonobj);

PvlKeyword &operator+=(QString value);

Expand Down

0 comments on commit 3a9c187

Please sign in to comment.