Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified CMakeLists.txt
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified README.md
100644 → 100755
Empty file.
Empty file modified conf/settings-default.toml
100644 → 100755
Empty file.
Empty file modified src/CMakeLists.txt
100644 → 100755
Empty file.
87 changes: 67 additions & 20 deletions src/services/geo_bon_catalog.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<std::string> &ebv_entity_path) const;
// const std::vector<std::string> &ebv_entity_path) const;
const std::string &ebv_entity_path) const;

private:
struct EbvClass {
Expand Down Expand Up @@ -76,6 +77,8 @@ class GeoBonCatalogService : public HTTPService {

template<class T>
static auto toJsonArray(const std::vector<T> &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)
Expand All @@ -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") {
Expand All @@ -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");
}
Expand All @@ -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<std::string>("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<std::string>("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<std::string> 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);
}
Expand All @@ -137,15 +179,15 @@ void GeoBonCatalogService::classes() const {
for (const auto &dataset : web_service_json["data"]) {
std::vector<std::string> 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) {
ebv_names.push_back(ebvName.asString());
}

datasets.append(GeoBonCatalogService::EbvClass{
.name = dataset.get("ebvClass", "").asString(),
.name = dataset.get("ebv_class", "").asString(),
.ebv_names = ebv_names,
}.to_json());
}
Expand All @@ -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<std::string>("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<std::string>("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());
}
Expand All @@ -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();

Expand All @@ -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,
Expand All @@ -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<std::string> &ebv_entity_path) const {
// const std::vector<std::string> &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));
}
Expand Down
56 changes: 45 additions & 11 deletions src/util/netcdf_parser.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include "netcdf_parser.h"
#include <gdal/ogr_spatialref.h>
#include <util/stringsplit.h>

auto attribute_to_string(const H5::Attribute &attribute) -> std::string {
std::string buffer;
Expand Down Expand Up @@ -279,26 +280,59 @@ std::ostream &operator<<(std::ostream &os, const NetCdfParser::NetCdfValue &valu
return os;
}

auto NetCdfParser::unit_range(const std::vector<std::string> &entity_path) const -> std::array<double, 2> {
auto NetCdfParser::unit_range(const std::string &entity_path) const -> std::array<double, 2> {
const std::string value_range_identifier = "value_range";
const std::vector<std::string> 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<double> 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<double> 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<double> 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<double> 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`
Expand Down
4 changes: 2 additions & 2 deletions src/util/netcdf_parser.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,7 +87,7 @@ class NetCdfParser {

auto time_info() const -> NetCdfTimeInfo;

auto unit_range(const std::vector<std::string> &dataset_path) const -> std::array<double, 2>;
auto unit_range(const std::string &dataset_path) const -> std::array<double, 2>;

protected:
static auto time_points_as_unix(double time_start,
Expand Down
Empty file modified test/CMakeLists.txt
100644 → 100755
Empty file.
Binary file removed test/data/48/netcdf/cSAR_idiv_v1.nc
Binary file not shown.
Empty file modified test/data/test.nc
100644 → 100755
Empty file.
Empty file modified test/unittests/init.cpp
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions test/unittests/netcdf_parser.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -81,7 +81,7 @@ TEST(NetCdfParser, cSAR) { // NOLINT(cert-err58-cpp)
"EPSG:4326"
);

const auto unit_range = parser.unit_range(std::vector<std::string>{"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);
Expand Down
Empty file modified test/unittests/netcdf_tests.cpp
100644 → 100755
Empty file.
Empty file modified test/unittests/util.h
100644 → 100755
Empty file.