diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/conf/settings-default.toml b/conf/settings-default.toml old mode 100644 new mode 100755 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/src/services/geo_bon_catalog.cpp b/src/services/geo_bon_catalog.cpp old mode 100644 new mode 100755 index 2994ad5..bafe228 --- a/src/services/geo_bon_catalog.cpp +++ b/src/services/geo_bon_catalog.cpp @@ -25,7 +25,7 @@ class GeoBonCatalogService : public HTTPService { void run() override; /// Load and return an ID specified EBV dataset from the catalog - void dataset(const std::string &id) const; + void dataset(UserDB::User &user, const std::string &id) const; /// Load and return all EBV classes from the catalog void classes() const; @@ -45,7 +45,8 @@ class GeoBonCatalogService : public HTTPService { /// Extract and return meta data for loading the dataset void data_loading_info(UserDB::User &user, const std::string &ebv_file, - const std::vector &ebv_entity_path) const; + // const std::vector &ebv_entity_path) const; + const std::string &ebv_entity_path) const; private: struct EbvClass { @@ -76,6 +77,8 @@ class GeoBonCatalogService : public HTTPService { template static auto toJsonArray(const std::vector &vector) -> Json::Value; + + static auto subgroups_json(const NetCdfParser &net_cdf_parser) -> Json::Value; }; REGISTER_HTTP_SERVICE(GeoBonCatalogService, "geo_bon_catalog"); // NOLINT(cert-err58-cpp) @@ -88,7 +91,7 @@ void GeoBonCatalogService::run() { const std::string &request = params.get("request"); if (request == "dataset") { - this->dataset(params.get("id")); + this->dataset(session->getUser(), params.get("id")); } else if (request == "classes") { this->classes(); } else if (request == "datasets") { @@ -103,7 +106,8 @@ void GeoBonCatalogService::run() { } else if (request == "data_loading_info") { this->data_loading_info(session->getUser(), params.get("ebv_path"), - split(params.get("ebv_entity_path"), '/')); + // split(params.get("ebv_entity_path"), '/')); + params.get("ebv_entity_path")); } else { // FALLBACK response.sendFailureJSON("GeoBonCatalogService: Invalid request"); } @@ -113,16 +117,54 @@ void GeoBonCatalogService::run() { } } -void GeoBonCatalogService::dataset(const std::string &id) const { //Development - iDiv - Thomas Bauer +void GeoBonCatalogService::dataset(UserDB::User &user, const std::string &id) const { + // Dataset info + const auto web_service_json = requestJsonFromUrl(combinePaths( Configuration::get("ebv.webservice_endpoint"), - concat("datasets/id/", boost::algorithm::replace_all_copy(id, " ", "%20")) + concat("datasets/", boost::algorithm::replace_all_copy(id, " ", "%20")) )); - const auto dataset = web_service_json.get("data", Json::Value(Json::objectValue)); + const auto dataset = web_service_json.get("data", Json::Value(Json::objectValue))[0]; + + const std::string dataset_path = combinePaths( + Configuration::get("ebv.path"), + dataset.get("dataset", "").get("pathname", "").asString() + ); + GeoBonCatalogService::addUserPermissions(user, dataset_path); + + // Subgroups + + NetCdfParser net_cdf_parser(dataset_path); + auto subgroups = subgroups_json(net_cdf_parser); + + // Add values to each subgroup + + std::vector ebv_group_path; + + Json::Value subgroups_array (Json::arrayValue); + for (auto &subgroup : subgroups) { + const auto ebv_subgroup = subgroup["name"].asString(); + + bool first_value_in_subgroup = true; + + Json::Value values(Json::arrayValue); + for (const auto &subgroup_value : net_cdf_parser.ebv_subgroup_values(ebv_subgroup, ebv_group_path)) { + if (first_value_in_subgroup) { + ebv_group_path.push_back(subgroup_value.name); + first_value_in_subgroup = false; + } + + values.append(subgroup_value.to_json()); + } + + subgroup["values"] = values; + subgroups_array.append(subgroup); + } Json::Value result(Json::objectValue); result["dataset"] = dataset; + result["subgroups_and_values"] = subgroups_array; response.sendSuccessJSON(result); } @@ -137,7 +179,7 @@ void GeoBonCatalogService::classes() const { for (const auto &dataset : web_service_json["data"]) { std::vector ebv_names; - const auto ebv_names_json = dataset.get("ebvName", Json::Value(Json::arrayValue)); + const auto ebv_names_json = dataset.get("ebv_name", Json::Value(Json::arrayValue)); ebv_names.reserve(ebv_names.size()); for (const auto &ebvName : ebv_names_json) { @@ -145,7 +187,7 @@ void GeoBonCatalogService::classes() const { } datasets.append(GeoBonCatalogService::EbvClass{ - .name = dataset.get("ebvClass", "").asString(), + .name = dataset.get("ebv_class", "").asString(), .ebv_names = ebv_names, }.to_json()); } @@ -159,24 +201,24 @@ void GeoBonCatalogService::classes() const { void GeoBonCatalogService::datasets(UserDB::User &user, const std::string &ebv_name) const { const auto web_service_json = requestJsonFromUrl(combinePaths( Configuration::get("ebv.webservice_endpoint"), - concat("datasets/ebvName/", boost::algorithm::replace_all_copy(ebv_name, " ", "%20")) + concat("datasets/filter?ebvName=", boost::algorithm::replace_all_copy(ebv_name, " ", "+")) )); Json::Value datasets(Json::arrayValue); for (const auto &dataset : web_service_json["data"]) { const std::string dataset_path = combinePaths( Configuration::get("ebv.path"), - dataset.get("pathNameDataset", "").asString() + dataset.get("dataset", "").get("pathname", "").asString() ); GeoBonCatalogService::addUserPermissions(user, dataset_path); datasets.append(GeoBonCatalogService::Dataset{ .id = dataset.get("id", "").asString(), - .name = dataset.get("name", "").asString(), - .author = dataset.get("author", "").asString(), - .description = dataset.get("description", "").asString(), - .license = dataset.get("License", "").asString(), + .name = dataset.get("title", "").asString(), + .author = dataset.get("creator", "").get("creator_name", "").asString(), + .description = dataset.get("summary", "").asString(), + .license = dataset.get("license", "").asString(), .dataset_path = dataset_path, }.to_json()); } @@ -194,6 +236,13 @@ void GeoBonCatalogService::subgroups(UserDB::User &user, const std::string &ebv_ NetCdfParser net_cdf_parser(ebv_file); + Json::Value result(Json::objectValue); + result["subgroups"] = subgroups_json(net_cdf_parser); + + response.sendSuccessJSON(result); +} + +auto GeoBonCatalogService::subgroups_json(const NetCdfParser &net_cdf_parser) -> Json::Value { const auto subgroup_names = net_cdf_parser.ebv_subgroups(); const auto subgroup_descriptions = net_cdf_parser.ebv_subgroup_descriptions(); @@ -209,10 +258,7 @@ void GeoBonCatalogService::subgroups(UserDB::User &user, const std::string &ebv_ subgroups_json.append(subgroup_json); } - Json::Value result(Json::objectValue); - result["subgroups"] = subgroups_json; - - response.sendSuccessJSON(result); + return subgroups_json; } void GeoBonCatalogService::subgroup_values(UserDB::User &user, @@ -238,7 +284,8 @@ void GeoBonCatalogService::subgroup_values(UserDB::User &user, void GeoBonCatalogService::data_loading_info(UserDB::User &user, const std::string &ebv_file, - const std::vector &ebv_entity_path) const { + // const std::vector &ebv_entity_path) const { + const std::string &ebv_entity_path) const { if (!hasUserPermissions(user, ebv_file)) { throw GeoBonCatalogServiceException(concat("GeoBonCatalogServiceException: Missing access rights for ", ebv_file)); } diff --git a/src/util/netcdf_parser.cpp b/src/util/netcdf_parser.cpp old mode 100644 new mode 100755 index c219409..b823887 --- a/src/util/netcdf_parser.cpp +++ b/src/util/netcdf_parser.cpp @@ -7,6 +7,7 @@ #include #include "netcdf_parser.h" #include +#include auto attribute_to_string(const H5::Attribute &attribute) -> std::string { std::string buffer; @@ -279,26 +280,59 @@ std::ostream &operator<<(std::ostream &os, const NetCdfParser::NetCdfValue &valu return os; } -auto NetCdfParser::unit_range(const std::vector &entity_path) const -> std::array { +auto NetCdfParser::unit_range(const std::string &entity_path) const -> std::array { const std::string value_range_identifier = "value_range"; + const std::vector entity_path_split = split(entity_path, '/'); - H5::Group group = file.openGroup("/"); // open root group - for (const auto &group_name : entity_path) { - if (group.attrExists(value_range_identifier)) { - H5::Attribute value_range = group.openAttribute(value_range_identifier); - std::vector range = attribute_to_casted_double_vector(value_range); + const auto enti = file.openDataSet(entity_path); + if (enti.attrExists(value_range_identifier)) { + H5::Attribute value_range = enti.openAttribute(value_range_identifier); - if (range.size() != 2) { - throw NetCdfParserException(concat("Attribute `value_range` must contain 2 element, but contains ", range.size())); - } + std::vector range = attribute_to_casted_double_vector(value_range); - return {range[0], range[1]}; + if (range.size() != 2) { + throw NetCdfParserException(concat("Attribute `value_range` must contain 2 element, but contains ", range.size())); } - group = group.openGroup(group_name); + return {range[0], range[1]}; + } + else { + H5::Group group = file.openGroup("/"); // open root group + for (const auto &group_name : entity_path_split) { + if (group.attrExists(value_range_identifier)) { + H5::Attribute value_range = group.openAttribute(value_range_identifier); + std::vector range = attribute_to_casted_double_vector(value_range); + + if (range.size() != 2) { + throw NetCdfParserException(concat("Attribute `value_range` must contain 2 element, but contains ", range.size())); + } + + return {range[0], range[1]}; + } + + group = group.openGroup(group_name); + } } return {0., 1.}; // default if nothing is found + + // H5::Group group = file.openGroup("/"); // open root group + // for (const auto &group_name : entity_path) { + // if (group.attrExists(value_range_identifier)) { + // H5::Attribute value_range = group.openAttribute(value_range_identifier); + // std::vector range = attribute_to_casted_double_vector(value_range); + + // if (range.size() != 2) { + // throw NetCdfParserException(concat("Attribute `value_range` must contain 2 element, but contains ", range.size())); + // } + + // return {range[0], range[1]}; + // } + + // group = group.openGroup(group_name); + // } + + // return {0., 1.}; // default if nothing is found } /// Reads `to.capacity()` number of values from the attribute, casts it and pastes it to `to` diff --git a/src/util/netcdf_parser.h b/src/util/netcdf_parser.h old mode 100644 new mode 100755 index 3697946..524964f --- a/src/util/netcdf_parser.h +++ b/src/util/netcdf_parser.h @@ -35,7 +35,7 @@ class NetCdfParser { auto crs_wkt() const -> std::string; auto crs_as_code() const -> std::string; - + auto ebv_class() const -> std::string; auto ebv_name() const -> std::string; @@ -87,7 +87,7 @@ class NetCdfParser { auto time_info() const -> NetCdfTimeInfo; - auto unit_range(const std::vector &dataset_path) const -> std::array; + auto unit_range(const std::string &dataset_path) const -> std::array; protected: static auto time_points_as_unix(double time_start, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/test/data/48/netcdf/cSAR_idiv_v1.nc b/test/data/48/netcdf/cSAR_idiv_v1.nc deleted file mode 100644 index 2da80be..0000000 Binary files a/test/data/48/netcdf/cSAR_idiv_v1.nc and /dev/null differ diff --git a/test/data/test.nc b/test/data/test.nc old mode 100644 new mode 100755 diff --git a/test/unittests/init.cpp b/test/unittests/init.cpp old mode 100644 new mode 100755 diff --git a/test/unittests/netcdf_parser.cpp b/test/unittests/netcdf_parser.cpp old mode 100644 new mode 100755 index 0fa4c3f..0b06f66 --- a/test/unittests/netcdf_parser.cpp +++ b/test/unittests/netcdf_parser.cpp @@ -4,7 +4,7 @@ #include "util.h" TEST(NetCdfParser, cSAR) { // NOLINT(cert-err58-cpp) - NetCdfParser parser(test_util::get_data_dir() + "48/netcdf/cSAR_idiv_v1.nc"); + NetCdfParser parser(test_util::get_data_dir() + "1/netcdf/cSAR_idiv_v1.nc"); EXPECT_EQ(parser.ebv_class(), "Community composition"); EXPECT_EQ(parser.ebv_name(), "Species diversity"); @@ -81,7 +81,7 @@ TEST(NetCdfParser, cSAR) { // NOLINT(cert-err58-cpp) "EPSG:4326" ); - const auto unit_range = parser.unit_range(std::vector{"past", "mean", "0"}); + const auto unit_range = parser.unit_range(std::string{"past/mean/0"}); ASSERT_EQ(unit_range.size(), 2); EXPECT_DOUBLE_EQ(unit_range[0], -31.24603271484375); EXPECT_DOUBLE_EQ(unit_range[1], 31.14495849609375); diff --git a/test/unittests/netcdf_tests.cpp b/test/unittests/netcdf_tests.cpp old mode 100644 new mode 100755 diff --git a/test/unittests/util.h b/test/unittests/util.h old mode 100644 new mode 100755