diff --git a/isis/src/base/objs/FileName/FileName.cpp b/isis/src/base/objs/FileName/FileName.cpp index 425e0801a5af08f81bd93a3e6e4e6c10e21632f4..0ef719ced72f6b2edcfa22fada8efd3bfc6ecd9e 100644 --- a/isis/src/base/objs/FileName/FileName.cpp +++ b/isis/src/base/objs/FileName/FileName.cpp @@ -447,6 +447,9 @@ namespace Isis { * @return Boolean */ bool FileName::fileExists() const { + if (toString().contains((QString)"https://")) { + return true; + } return QFileInfo(expanded()).exists(); } diff --git a/isis/src/base/objs/Pvl/Pvl.cpp b/isis/src/base/objs/Pvl/Pvl.cpp index 1c6240509303098d37e4bb79bcd0c0c3050731fe..f5664e6821eb0d27c0433650f6289fa215b6d055 100644 --- a/isis/src/base/objs/Pvl/Pvl.cpp +++ b/isis/src/base/objs/Pvl/Pvl.cpp @@ -11,6 +11,12 @@ 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" @@ -18,6 +24,9 @@ find files of those names at the top level of this repository. **/ #include "PvlTokenizer.h" #include "PvlFormat.h" +namespace fs = std::filesystem; +using json = nlohmann::json; + using namespace std; namespace Isis { //! Constructs an empty Pvl object. @@ -32,8 +41,74 @@ namespace Isis { * @param file The file containing the pvl formatted information */ Pvl::Pvl(const QString &file) : Isis::PvlObject("Root") { + + 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); + } } diff --git a/isis/src/base/objs/PvlKeyword/PvlKeyword.cpp b/isis/src/base/objs/PvlKeyword/PvlKeyword.cpp index 0fa0aca35bf96376bd7c480f309f65c98a2f72f3..fadfd02d3cbf1648282a5ce3c95198456a4aad97 100644 --- a/isis/src/base/objs/PvlKeyword/PvlKeyword.cpp +++ b/isis/src/base/objs/PvlKeyword/PvlKeyword.cpp @@ -172,10 +172,9 @@ namespace Isis { * * @see addJsonValue() */ - void PvlKeyword::setJsonValue(json jsonobj, QString unit) - { + void PvlKeyword::setJsonValue(json jsonobj) { clear(); - addJsonValue(jsonobj, unit); + addJsonValue(jsonobj); } /** @@ -301,31 +300,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. * diff --git a/isis/src/base/objs/PvlKeyword/PvlKeyword.h b/isis/src/base/objs/PvlKeyword/PvlKeyword.h index ba9800c6a166f6011a2ffbf7ccfea956f64b500d..33772ed06d7c416e7befacd8b5378b55074f4e37 100644 --- a/isis/src/base/objs/PvlKeyword/PvlKeyword.h +++ b/isis/src/base/objs/PvlKeyword/PvlKeyword.h @@ -117,7 +117,9 @@ 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); @@ -125,7 +127,8 @@ namespace Isis { 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);