From 1a260633a267c6e20c94ccb7bd749b9c2f558e92 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 2 Sep 2024 16:56:15 +0200 Subject: [PATCH 01/50] Converting projection list to json --- adagucserverEC/CDBAdapter.h | 5 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 65 ++++++++++++++++++++++++- adagucserverEC/CDBAdapterPostgreSQL.h | 2 + adagucserverEC/CDBAdapterSQLLite.cpp | 3 ++ adagucserverEC/CDBAdapterSQLLite.h | 2 + adagucserverEC/CMakeLists.txt | 2 + adagucserverEC/CXMLGen.cpp | 12 +++++ 7 files changed, 88 insertions(+), 3 deletions(-) diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index 11bfa2070..89d3a7bc5 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -16,7 +16,7 @@ class CDBAdapter { public: CDBAdapter() {} - virtual ~CDBAdapter(){}; + virtual ~CDBAdapter() {}; class GeoOptions { public: @@ -96,6 +96,9 @@ class CDBAdapter { /** First use setFile as many times as you whish, second use addFilesToDataBase to make it final*/ virtual int addFilesToDataBase() = 0; + + virtual int storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob) = 0; + virtual CT::string getLayerMetadata(const char *layertable, const char *metadataitem) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 9cf79c6ad..1e0a2e15b 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -423,7 +423,7 @@ CDBStore::Store *CDBAdapterPostgreSQL::getFilesAndIndicesForDimensions(CDataSour CT::string whereStatement; CT::string *requestedDimVals = requestedDimMap[m.first]; - for (int i = 0; i < requestedDimVals->count; ++i) { + for (size_t i = 0; i < requestedDimVals->count; ++i) { if (requestedDimVals[i].equals("*")) continue; if (i != 0) { @@ -713,7 +713,7 @@ std::map CDBAdapterPostgreSQL::getTableNamesForPathFilterAn } // Found all tablenames for requested dimensions in lookup table - int found = tableDimStore->size(); + size_t found = tableDimStore->size(); delete tableDimStore; if (found == mapping.size()) { #ifdef MEASURETIME @@ -1083,3 +1083,64 @@ int CDBAdapterPostgreSQL::addFilesToDataBase() { #endif return 0; } + +int CDBAdapterPostgreSQL::storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob) { +#ifdef MEASURETIME + StopWatch_Stop(">CDBAdapterPostgreSQL::storeLayerMetadata"); +#endif + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + return -1; + } + + CT::string query; + CT::string tableColumns("id varchar (255) PRIMARY KEY, blob JSONB"); + + int status = dataBaseConnection->checkTable(layertable, tableColumns.c_str()); + if (status == 1) { + CDBError("\nFAIL: Table autoconfigure_dimensions could not be created: %s", tableColumns.c_str()); + throw(__LINE__); + } + + query.print("INSERT INTO %s values (E'%s', E'%s') ON CONFLICT (id) DO UPDATE SET blob = excluded.blob;", layertable, metadataitem, metadatablob); + status = dataBaseConnection->query(query.c_str()); + if (status != 0) { + CDBError("Unable to insert records: \"%s\"", query.c_str()); + throw(__LINE__); + } +#ifdef MEASURETIME + StopWatch_Stop("CDBAdapterPostgreSQL::getLayerMetadata"); +#endif + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + CDBError("No database connection"); + throw(__LINE__); + } + + CT::string query; + query.print("SELECT blob from %s wgere ud = '%s';", layertable, metadataitem); + auto store = dataBaseConnection->queryToStore(query.c_str()); + if (store == nullptr) { + CDBError("Unable query: \"%s\"", query.c_str()); + throw(__LINE__); + } + if (store->size() == 0) { + CDBError("No results \"%s\"", query.c_str()); + throw(__LINE__); + } + + CT::string result = store->getRecord(0)->get("blob")->c_str(); + CDBDebug(store->getRecord(0)->get("blob")->c_str()); + +#ifdef MEASURETIME + StopWatch_Stop(" +#include "utils/tojsonandback.h" // #define CXMLGEN_DEBUG // #define MEASURE_TIME const char *CFile::className = "CFile"; @@ -348,6 +350,16 @@ int CXMLGen::getProjectionInformationForLayer(WMSLayer *myWMSLayer) { myProjection->dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[3]; } + try { + CT::string tableName = + CDBFactory::getDBAdapter(srvParam->cfg) + ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), "metadata", myWMSLayer->dataSource); + + std::string projSettingsAsJsonString = convertProjectionListToJsonString(myWMSLayer->projectionList); + CDBFactory::getDBAdapter(srvParam->cfg)->storeLayerMetadata(tableName, "projected_extents", projSettingsAsJsonString.c_str()); + } catch (int e) { + } + return 0; } From 9152b17f0857be5df53005a22d9cc8dd8d9a2c75 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 3 Sep 2024 08:36:10 +0200 Subject: [PATCH 02/50] Store and retrieve is working for layer boundingboxes --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 6 ++-- adagucserverEC/CXMLGen.cpp | 21 ++++++----- adagucserverEC/utils/tojsonandback.cpp | 48 +++++++++++++++++++++++++ adagucserverEC/utils/tojsonandback.h | 4 +++ 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 69e8e8902..35112e98f 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -423,7 +423,7 @@ CDBStore::Store *CDBAdapterPostgreSQL::getFilesAndIndicesForDimensions(CDataSour CT::string whereStatement; std::vector requestedDimVals = requestedDimMap[m.first]; - for (int i = 0; i < requestedDimVals.size(); ++i) { + for (size_t i = 0; i < requestedDimVals.size(); ++i) { if (requestedDimVals[i].equals("*")) continue; if (i != 0) { @@ -1122,7 +1122,7 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *layertable, const } CT::string query; - query.print("SELECT blob from %s wgere ud = '%s';", layertable, metadataitem); + query.print("SELECT blob from %s where id = '%s';", layertable, metadataitem); auto store = dataBaseConnection->queryToStore(query.c_str()); if (store == nullptr) { CDBError("Unable query: \"%s\"", query.c_str()); @@ -1134,7 +1134,7 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *layertable, const } CT::string result = store->getRecord(0)->get("blob")->c_str(); - CDBDebug(store->getRecord(0)->get("blob")->c_str()); + // CDBDebug(store->getRecord(0)->get("blob")->c_str()); #ifdef MEASURETIME StopWatch_Stop("dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[3]; } - try { - CT::string tableName = - CDBFactory::getDBAdapter(srvParam->cfg) - ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), "metadata", myWMSLayer->dataSource); - - std::string projSettingsAsJsonString = convertProjectionListToJsonString(myWMSLayer->projectionList); - CDBFactory::getDBAdapter(srvParam->cfg)->storeLayerMetadata(tableName, "projected_extents", projSettingsAsJsonString.c_str()); - } catch (int e) { - } + // if (storeProjectionList(myWMSLayer) != 0) { + // CDBWarning("Unable to store projection list"); + // } return 0; } @@ -452,6 +454,7 @@ int CXMLGen::getDimsForLayer(WMSLayer *myWMSLayer) { StopWatch_Stop("Get the first 100 values from the database, and determine whether the time resolution is continous or multivalue."); #endif + CDBDebug("MPPPPPP"); // Get the first 100 values from the database, and determine whether the time resolution is continous or multivalue. CDBStore::Store *store = CDBFactory::getDBAdapter(srvParam->cfg)->getUniqueValuesOrderedByValue(pszDimName, 100, true, tableName.c_str()); bool dataHasBeenFoundInStore = false; diff --git a/adagucserverEC/utils/tojsonandback.cpp b/adagucserverEC/utils/tojsonandback.cpp index 52390bffa..a5487a5af 100644 --- a/adagucserverEC/utils/tojsonandback.cpp +++ b/adagucserverEC/utils/tojsonandback.cpp @@ -1,6 +1,7 @@ #include "./tojsonandback.h" #include +#include std::string convertProjectionListToJsonString(std::vector projectionList) { json projsettings; @@ -10,4 +11,51 @@ std::string convertProjectionListToJsonString(std::vectordataSource->srvParams->cfg) + ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), "metadata", myWMSLayer->dataSource); + + std::string projSettingsAsJsonString = convertProjectionListToJsonString(myWMSLayer->projectionList); + + CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->storeLayerMetadata(tableName, "projected_extents", projSettingsAsJsonString.c_str()); + } catch (int e) { + return e; + } + return 0; +} + +int getProjectionList(WMSLayer *myWMSLayer) { + if (myWMSLayer->projectionList.size() != 0) { + return 1; + } + try { + CT::string tableName = + CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg) + ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), "metadata", myWMSLayer->dataSource); + + CT::string projInfo = CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->getLayerMetadata(tableName, "projected_extents"); + + json a; + auto c = a.parse(projInfo.c_str()); + + for (auto d : c.items()) { + auto bboxArray = d.value(); + + WMSLayer::Projection *projection = new WMSLayer::Projection(); + myWMSLayer->projectionList.push_back(projection); + projection->name = d.key().c_str(); + bboxArray[0].get_to((projection->dfBBOX[0])); + bboxArray[1].get_to((projection->dfBBOX[1])); + bboxArray[2].get_to((projection->dfBBOX[2])); + bboxArray[3].get_to((projection->dfBBOX[3])); + } + + } catch (int e) { + return e; + } + return 0; } \ No newline at end of file diff --git a/adagucserverEC/utils/tojsonandback.h b/adagucserverEC/utils/tojsonandback.h index 4bcde4d24..76177daf5 100644 --- a/adagucserverEC/utils/tojsonandback.h +++ b/adagucserverEC/utils/tojsonandback.h @@ -7,4 +7,8 @@ std::string convertProjectionListToJsonString(std::vector projectionList); +int storeProjectionList(WMSLayer *layer); + +int getProjectionList(WMSLayer *layer); + #endif \ No newline at end of file From be6d15b5c63979f6d418574084cc5772389d65f3 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 3 Sep 2024 08:39:09 +0200 Subject: [PATCH 03/50] Renamed files --- adagucserverEC/CMakeLists.txt | 4 ++-- adagucserverEC/CXMLGen.cpp | 2 +- .../utils/{tojsonandback.cpp => LayerMetadataStore.cpp} | 2 +- .../utils/{tojsonandback.h => LayerMetadataStore.h} | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename adagucserverEC/utils/{tojsonandback.cpp => LayerMetadataStore.cpp} (98%) rename adagucserverEC/utils/{tojsonandback.h => LayerMetadataStore.h} (77%) diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index ce8bdd12f..ba6e5545f 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -68,8 +68,8 @@ add_library( CDBFileScannerCleanFiles.cpp CDFObjectStore.cpp CDFObjectStore.h - utils/tojsonandback.h - utils/tojsonandback.cpp + utils/LayerMetadataStore.h + utils/LayerMetadataStore.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.h CDataPostProcessors/CDataPostProcessor_CDPDBZtoRR.cpp diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 1b1396a14..30920676e 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -30,7 +30,7 @@ #include "CDBFactory.h" #include "LayerTypeLiveUpdate/LayerTypeLiveUpdate.h" #include -#include "utils/tojsonandback.h" +#include "utils/LayerMetadataStore.h" // #define CXMLGEN_DEBUG // #define MEASURE_TIME const char *CFile::className = "CFile"; diff --git a/adagucserverEC/utils/tojsonandback.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp similarity index 98% rename from adagucserverEC/utils/tojsonandback.cpp rename to adagucserverEC/utils/LayerMetadataStore.cpp index a5487a5af..e35b821e1 100644 --- a/adagucserverEC/utils/tojsonandback.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -1,4 +1,4 @@ -#include "./tojsonandback.h" +#include "./LayerMetadataStore.h" #include #include diff --git a/adagucserverEC/utils/tojsonandback.h b/adagucserverEC/utils/LayerMetadataStore.h similarity index 77% rename from adagucserverEC/utils/tojsonandback.h rename to adagucserverEC/utils/LayerMetadataStore.h index 76177daf5..d1d9b1894 100644 --- a/adagucserverEC/utils/tojsonandback.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -1,5 +1,5 @@ -#ifndef TOJSONANDBACK_H -#define TOJSONANDBACK_H +#ifndef LAYER_METADATA_STORE_UTILS_H +#define LAYER_METADATA_STORE_UTILS_H #include #include From caa8ab764918190fe40f334bdf3a80e98fe58253 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 4 Sep 2024 13:11:16 +0200 Subject: [PATCH 04/50] Refactored CXMLGen --- CCDFDataModel/CCDFVariable.h | 24 +- adagucserverEC/CAutoConfigure.cpp | 9 +- adagucserverEC/CDBAdapter.h | 4 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 57 +- adagucserverEC/CDBAdapterPostgreSQL.h | 6 +- adagucserverEC/CDBAdapterSQLLite.cpp | 9 +- adagucserverEC/CDBAdapterSQLLite.h | 4 +- .../CDataPostProcessor_Operator.cpp | 4 +- adagucserverEC/CDataReader.cpp | 13 +- adagucserverEC/CDataSource.cpp | 14 +- adagucserverEC/CDataSource.h | 2 + adagucserverEC/CMakeLists.txt | 5 + adagucserverEC/CRequest.cpp | 7 +- adagucserverEC/CXMLGen.cpp | 1093 ++--------------- adagucserverEC/CXMLGen.h | 137 +-- adagucserverEC/Definitions.h | 6 - .../LayerTypeLiveUpdate.cpp | 8 +- adagucserverEC/Types/LayerMetadataType.cpp | 20 + adagucserverEC/Types/LayerMetadataType.h | 54 + adagucserverEC/utils/CXMLTemplates.h | 264 ++++ adagucserverEC/utils/LayerMetadataStore.cpp | 225 +++- adagucserverEC/utils/LayerMetadataStore.h | 18 +- adagucserverEC/utils/XMLGenUtils.cpp | 739 +++++++++++ adagucserverEC/utils/XMLGenUtils.h | 13 + .../WCS_1.0.0_GetCapabilities_Header.dat | 63 - .../WMS_1.0.0_GetCapabilities_Header.dat | 51 - .../WMS_1.1.1_GetCapabilities_Header.dat | 85 -- .../WMS_1.3.0_GetCapabilities_Header.dat | 59 - ...taPostProcessor_SubstractLevels_GetMap.png | Bin 661 -> 661 bytes ...ities_KMDS_PointNetCDF_pointstylepoint.xml | 60 +- ...MSGetCapabilities_multidimnc_autostyle.xml | 4 +- ...pabilities_multidimncdataset_autostyle.xml | 4 +- ...bilities_timeseries_path_netcdf_5dims_seq1 | 4 +- ...bilities_timeseries_path_netcdf_5dims_seq2 | 4 +- ...ties_timeseries_tailpath_netcdf_5dims_seq1 | 4 +- ...series_tailpath_netcdf_5dims_seq1_and_seq2 | 6 +- ...est_WMSGetCapabilities_timeseries_twofiles | 4 +- ...ties_timeseries_tailpath_netcdf_5dims_seq1 | 4 +- ...series_tailpath_netcdf_5dims_seq1_and_seq2 | 4 +- ...est_WMSGetCapabilities_timeseries_twofiles | 4 +- 40 files changed, 1590 insertions(+), 1505 deletions(-) create mode 100644 adagucserverEC/Types/LayerMetadataType.cpp create mode 100644 adagucserverEC/Types/LayerMetadataType.h create mode 100644 adagucserverEC/utils/CXMLTemplates.h create mode 100644 adagucserverEC/utils/XMLGenUtils.cpp create mode 100644 adagucserverEC/utils/XMLGenUtils.h delete mode 100644 data/XMLTemplates/WCS_1.0.0_GetCapabilities_Header.dat delete mode 100644 data/XMLTemplates/WMS_1.0.0_GetCapabilities_Header.dat delete mode 100644 data/XMLTemplates/WMS_1.1.1_GetCapabilities_Header.dat delete mode 100644 data/XMLTemplates/WMS_1.3.0_GetCapabilities_Header.dat diff --git a/CCDFDataModel/CCDFVariable.h b/CCDFDataModel/CCDFVariable.h index 86997a2e3..660e91231 100644 --- a/CCDFDataModel/CCDFVariable.h +++ b/CCDFDataModel/CCDFVariable.h @@ -291,21 +291,29 @@ namespace CDF { void setSize(size_t size) { currentSize = size; } size_t getSize() { return currentSize; } - Attribute *getAttribute(const char *name) const { + bool hasAttribute(const char *name) const { for (size_t j = 0; j < attributes.size(); j++) { if (attributes[j]->name.equals(name)) { - return attributes[j]; + return true; } } - throw(CDF_E_ATTNOTFOUND); - return NULL; + return false; + } + + Attribute *getAttribute(const char *name) const { + Attribute *a = getAttributeNE(name); + if (a == nullptr) { + throw(CDF_E_ATTNOTFOUND); + } + return a; } Attribute *getAttributeNE(const char *name) const { - try { - return getAttribute(name); - } catch (int e) { - return NULL; + for (size_t j = 0; j < attributes.size(); j++) { + if (attributes[j]->name.equals(name)) { + return attributes[j]; + } } + return nullptr; } /** diff --git a/adagucserverEC/CAutoConfigure.cpp b/adagucserverEC/CAutoConfigure.cpp index c69e59399..cd245a449 100644 --- a/adagucserverEC/CAutoConfigure.cpp +++ b/adagucserverEC/CAutoConfigure.cpp @@ -484,10 +484,11 @@ int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { return 0; } - CT::string foundFileName; - - /* Use the file specified as header file */ - foundFileName = dataSource->headerFileName.c_str(); + CT::string foundFileName = dataSource->getFileName(); + if (foundFileName.empty()) { + /* Use the file specified as header file */ + foundFileName = dataSource->headerFileName.c_str(); + } if (foundFileName.empty()) { /* Try to get a file from DB */ diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index 89d3a7bc5..f4bf3d9f7 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -97,8 +97,8 @@ class CDBAdapter { /** First use setFile as many times as you whish, second use addFilesToDataBase to make it final*/ virtual int addFilesToDataBase() = 0; - virtual int storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob) = 0; - virtual CT::string getLayerMetadata(const char *layertable, const char *metadataitem) = 0; + virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; + virtual CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 35112e98f..c9326ea2e 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1081,7 +1081,7 @@ int CDBAdapterPostgreSQL::addFilesToDataBase() { return 0; } -int CDBAdapterPostgreSQL::storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob) { +int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadataBlob) { #ifdef MEASURETIME StopWatch_Stop(">CDBAdapterPostgreSQL::storeLayerMetadata"); #endif @@ -1091,15 +1091,16 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *layertable, const char } CT::string query; - CT::string tableColumns("id varchar (255) PRIMARY KEY, blob JSONB"); + CT::string tableColumns("datasetname varchar (255) ,layername varchar (255), metadatakey varchar (255), blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); - int status = dataBaseConnection->checkTable(layertable, tableColumns.c_str()); + int status = dataBaseConnection->checkTable("metadata", tableColumns.c_str()); if (status == 1) { CDBError("\nFAIL: Table autoconfigure_dimensions could not be created: %s", tableColumns.c_str()); throw(__LINE__); } - query.print("INSERT INTO %s values (E'%s', E'%s') ON CONFLICT (id) DO UPDATE SET blob = excluded.blob;", layertable, metadataitem, metadatablob); + query.print("INSERT INTO metadata values (E'%s',E'%s', E'%s', E'%s') ON CONFLICT (datasetname, layername, metadatakey) DO UPDATE SET blob = excluded.blob;", datasetName, layerName, metadataKey, + metadataBlob); status = dataBaseConnection->query(query.c_str()); if (status != 0) { CDBError("Unable to insert records: \"%s\"", query.c_str()); @@ -1111,33 +1112,45 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *layertable, const char return 0; } -CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *layertable, const char *metadataitem) { +CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) { #ifdef MEASURETIME StopWatch_Stop(">CDBAdapterPostgreSQL::getLayerMetadata"); #endif - CPGSQLDB *dataBaseConnection = getDataBaseConnection(); - if (dataBaseConnection == NULL) { - CDBError("No database connection"); - throw(__LINE__); - } - CT::string query; - query.print("SELECT blob from %s where id = '%s';", layertable, metadataitem); - auto store = dataBaseConnection->queryToStore(query.c_str()); - if (store == nullptr) { - CDBError("Unable query: \"%s\"", query.c_str()); - throw(__LINE__); - } - if (store->size() == 0) { - CDBError("No results \"%s\"", query.c_str()); - throw(__LINE__); + if (this->layerMetaDataStore == nullptr) { + CDBDebug("Need to query layer metadata for %s/%s/%s", datasetName, layerName, metadataKey); + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + CDBError("No database connection"); + throw(__LINE__); + } + + CT::string query; + query.print("SELECT layername, metadatakey, blob from metadata where datasetname = '%s';", datasetName); + this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); + if (layerMetaDataStore == nullptr) { + CDBDebug("Unable query: \"%s\"", query.c_str()); + throw(__LINE__); + } + if (layerMetaDataStore->size() == 0) { + CDBDebug("No results \"%s\"", query.c_str()); + throw(__LINE__); + } + } else { + // CDBDebug("Re-using layer metadata"); } - CT::string result = store->getRecord(0)->get("blob")->c_str(); + auto records = layerMetaDataStore->getRecords(); + for (auto record : records) { + if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { + return record->get("blob"); + } + } // CDBDebug(store->getRecord(0)->get("blob")->c_str()); #ifdef MEASURETIME StopWatch_Stop("> fileListPerTable; int createDimTableOfType(const char *dimname, const char *tablename, int type); + CDBStore::Store *layerMetaDataStore = nullptr; + public: CDBAdapterPostgreSQL(); ~CDBAdapterPostgreSQL(); @@ -87,6 +89,6 @@ class CDBAdapterPostgreSQL : public CDBAdapter { int setFileString(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int setFileTimeStamp(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int addFilesToDataBase(); - int storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob); - CT::string getLayerMetadata(const char *layertable, const char *metadataitem); + int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); + CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; diff --git a/adagucserverEC/CDBAdapterSQLLite.cpp b/adagucserverEC/CDBAdapterSQLLite.cpp index 4776ed242..e8b2a8cf6 100644 --- a/adagucserverEC/CDBAdapterSQLLite.cpp +++ b/adagucserverEC/CDBAdapterSQLLite.cpp @@ -694,11 +694,6 @@ CDBStore::Store *CDBAdapterSQLLite::getFilesAndIndicesForDimensions(CDataSource int CDBAdapterSQLLite::autoUpdateAndScanDimensionTables(CDataSource *dataSource) { CServerParams *srvParams = dataSource->srvParams; - ; - // if(srvParams->isAutoLocalFileResourceEnabled()==false){ - // CDBDebug("Auto update is not available"); - // return 0; - // } CServerConfig::XMLE_Layer *cfgLayer = dataSource->cfgLayer; CSQLLiteDB *dataBaseConnection = getDataBaseConnection(); if (dataBaseConnection == NULL) { @@ -1310,7 +1305,7 @@ CDBStore::Store *CDBAdapterSQLLite::getFilesForIndices(CDataSource *dataSource, return store; } -int CDBAdapterSQLLite::storeLayerMetadata(const char *, const char *, const char *) { return 0; } -CT::string CDBAdapterSQLLite::getLayerMetadata(const char *, const char *) { return "nullptr"; } +int CDBAdapterSQLLite::storeLayerMetadata(const char *, const char *, const char *, const char *) { return 0; } +CT::string CDBAdapterSQLLite::getLayerMetadata(const char *, const char *, const char *) { return ""; } #endif diff --git a/adagucserverEC/CDBAdapterSQLLite.h b/adagucserverEC/CDBAdapterSQLLite.h index 6f2b5febb..c410e1dc0 100644 --- a/adagucserverEC/CDBAdapterSQLLite.h +++ b/adagucserverEC/CDBAdapterSQLLite.h @@ -119,7 +119,7 @@ class CDBAdapterSQLLite : public CDBAdapter { int setFileString(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int setFileTimeStamp(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int addFilesToDataBase(); - int storeLayerMetadata(const char *layertable, const char *metadataitem, const char *metadatablob); - CT::string getLayerMetadata(const char *layertable, const char *metadataitem); + int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); + CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; #endif diff --git a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_Operator.cpp b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_Operator.cpp index 89da86b91..5ebf00b76 100644 --- a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_Operator.cpp +++ b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_Operator.cpp @@ -64,8 +64,8 @@ int CDPPOperator::execute(CServerConfig::XMLE_DataPostProc *proc, CDataSource *d newDataObject->cdfVariable->setAttributeText("units", proc->attr.units); } - short attrData[3]; - attrData[0] = -1; + double attrData[1]; + attrData[0] = 0; newDataObject->cdfVariable->setAttribute("_FillValue", newDataObject->cdfVariable->getType(), attrData, 1); newDataObject->cdfVariable->setCustomReader(CDF::Variable::CustomMemoryReaderInstance); diff --git a/adagucserverEC/CDataReader.cpp b/adagucserverEC/CDataReader.cpp index 7189287c2..c30cf6b49 100755 --- a/adagucserverEC/CDataReader.cpp +++ b/adagucserverEC/CDataReader.cpp @@ -421,7 +421,6 @@ int CDataReader::parseDimensions(CDataSource *dataSource, int mode, int x, int y #ifdef CDATAREADER_DEBUG CDBDebug("Number of dimensions = %d", dataSource->dNetCDFNumDims); #endif - // Determine the X and Y dimensions and variables. determineXAndYDimIndices(dataSource, dataSourceVar); if (!determineXandYVars(dataSource, dataSourceVar, cdfObject)) { @@ -847,15 +846,10 @@ int CDataReader::open(CDataSource *dataSource, int mode, int x, int y, int *grid if (x != -1 && y != -1) { singleCellMode = true; } - CT::string dataSourceFilename; dataSourceFilename.copy(dataSource->getFileName()); - - // CCache cache; - // CT::string cacheFilename; - // pthread_mutex_lock(&CDataReader_open_lock); CStyleConfiguration *styleConfiguration = dataSource->getStyle(); - // pthread_mutex_unlock(&CDataReader_open_lock); + // Use autoscale of legendcolors when the legendscale factor has been set to zero. if (styleConfiguration != NULL) { if (dataSource->stretchMinMaxDone == false) { @@ -867,7 +861,6 @@ int CDataReader::open(CDataSource *dataSource, int mode, int x, int y, int *grid } CDFObject *cdfObject = NULL; - #ifdef CDATAREADER_DEBUG CDBDebug("Working on [%s] with mode %d and (%d,%d)", dataSourceFilename.c_str(), mode, x, y); @@ -876,11 +869,9 @@ int CDataReader::open(CDataSource *dataSource, int mode, int x, int y, int *grid CDBDebug("Working on [%s]", dataSourceFilename.c_str()); } #endif - if (mode == CNETCDFREADER_MODE_OPEN_DIMENSIONS || mode == CNETCDFREADER_MODE_OPEN_HEADER) { cdfObject = CDFObjectStore::getCDFObjectStore()->getCDFObjectHeader(dataSource, dataSource->srvParams, dataSourceFilename.c_str(), enableObjectCache); } - if (mode == CNETCDFREADER_MODE_OPEN_ALL || mode == CNETCDFREADER_MODE_GET_METADATA || mode == CNETCDFREADER_MODE_OPEN_EXTENT) { cdfObject = CDFObjectStore::getCDFObjectStore()->getCDFObject(dataSource, dataSourceFilename.c_str(), enableObjectCache); } @@ -888,7 +879,6 @@ int CDataReader::open(CDataSource *dataSource, int mode, int x, int y, int *grid CDBError("Unable to get CDFObject from store"); return 1; } - if (dataSource->attachCDFObject(cdfObject) != 0) { CDBError("Unable to attach CDFObject"); return 1; @@ -914,7 +904,6 @@ int CDataReader::open(CDataSource *dataSource, int mode, int x, int y, int *grid #ifdef MEASURETIME StopWatch_Stop("parseDimensions done"); #endif - if (dataSource->useLonTransformation != -1 && gridExtent == NULL) { for (size_t varNr = 0; varNr < dataSource->getNumDataObjects(); varNr++) { Proc::swapPixelsAtLocation(dataSource, dataSource->getDataObject(varNr)->cdfVariable, 0); diff --git a/adagucserverEC/CDataSource.cpp b/adagucserverEC/CDataSource.cpp index cb61b1d70..5b61a2057 100644 --- a/adagucserverEC/CDataSource.cpp +++ b/adagucserverEC/CDataSource.cpp @@ -433,13 +433,6 @@ void CDataSource::addStep(const char *fileName, CCDFDims *dims) { if (dims != NULL) { timeStep->dims.copy(dims); } - // for(size_t j=0;jVariable.size();j++){ - // DataObject *newDataObject = new DataObject(); - // newDataObject->variableName.copy(cfgLayer->Variable[j]->value.c_str()); - // - // getDataObjectsVector()->push_back(newDataObject); - // - // } } const char *CDataSource::getFileName() { @@ -860,6 +853,7 @@ CT::PointerList *CDataSource::getStyleListForDataSource(C #ifdef CDATASOURCE_DEBUG CDBDebug("getStyleListForDataSource %s", dataSource->layerName.c_str()); #endif + CT::PointerList *styleConfigurationList = new CT::PointerList(); CServerConfig::XMLE_Configuration *serverCFG = dataSource->cfg; @@ -869,13 +863,11 @@ CT::PointerList *CDataSource::getStyleListForDataSource(C // Auto configure styles, if no legends or styles are defined if (dataSource->cfgLayer->Styles.size() == 0 && dataSource->cfgLayer->Legend.size() == 0) { - renderMethods = getRenderMethodListForDataSource(dataSource, NULL); if (renderMethods->size() > 0) { CAutoConfigure::autoConfigureStyles(dataSource); } } - delete renderMethods; renderMethods = NULL; @@ -1453,4 +1445,6 @@ int CDataSource::readVariableDataForCDFDims(CDF::Variable *variableToRead, CDFTy } } return variableToRead->readData(dataTypeToReturnData, start, count, stride, true); -} \ No newline at end of file +} + +std::string CDataSource::getDataSetName() { return std::string(this->srvParams->datasetLocation.c_str()); } \ No newline at end of file diff --git a/adagucserverEC/CDataSource.h b/adagucserverEC/CDataSource.h index c25a4a56b..d9b6589f3 100644 --- a/adagucserverEC/CDataSource.h +++ b/adagucserverEC/CDataSource.h @@ -373,6 +373,8 @@ class CDataSource { * @return 0 on succes, 1 on failure */ int readVariableDataForCDFDims(CDF::Variable *variableToRead, CDFType dataTypeToReturnData); + + std::string getDataSetName(); }; #endif diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index ba6e5545f..dba90e803 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -70,6 +70,11 @@ add_library( CDFObjectStore.h utils/LayerMetadataStore.h utils/LayerMetadataStore.cpp + utils/XMLGenUtils.h + utils/XMLGenUtils.cpp + utils/CXMLTemplates.h + Types/LayerMetadataType.h + Types/LayerMetadataType.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.h CDataPostProcessors/CDataPostProcessor_CDPDBZtoRR.cpp diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index 4e615e4f0..991765f66 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -143,6 +143,7 @@ int CRequest::setConfigFile(const char *pszConfigFile) { value0Cap.toUpperCaseSelf(); if (value0Cap.equals("DATASET")) { if (srvParam->datasetLocation.empty()) { + srvParam->datasetLocation.copy(values[1].c_str()); status = CAutoResource::configureDataset(srvParam, false); if (status != 0) { @@ -700,12 +701,6 @@ int CRequest::getDocFromDocCache(CSimpleStore *simpleStore, CT::string *docName, int CRequest::generateOGCGetCapabilities(CT::string *XMLdocument) { CXMLGen XMLGen; - // Set WMSLayers: - srvParam->WMSLayers = new CT::string[srvParam->cfg->Layer.size()]; - for (size_t j = 0; j < srvParam->cfg->Layer.size(); j++) { - srvParam->makeUniqueLayerName(&srvParam->WMSLayers[j], srvParam->cfg->Layer[j]); - srvParam->WMSLayers[j].count = srvParam->cfg->Layer.size(); - } return XMLGen.OGCGetCapabilities(srvParam, XMLdocument); } diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 30920676e..060253425 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -31,15 +31,15 @@ #include "LayerTypeLiveUpdate/LayerTypeLiveUpdate.h" #include #include "utils/LayerMetadataStore.h" +#include "utils/XMLGenUtils.h" +#include "utils/CXMLTemplates.h" + // #define CXMLGEN_DEBUG // #define MEASURE_TIME -const char *CFile::className = "CFile"; const char *CXMLGen::className = "CXMLGen"; int CXMLGen::WCSDescribeCoverage(CServerParams *srvParam, CT::string *XMLDocument) { return OGCGetCapabilities(srvParam, XMLDocument); } -bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) <= 0; } - const WMSLayer *getFirstLayerWithoutError(std::vector *myWMSLayerList) { if (myWMSLayerList->size() == 0) { return nullptr; @@ -53,788 +53,12 @@ const WMSLayer *getFirstLayerWithoutError(std::vector *myWMSLayerLis return (*myWMSLayerList)[0]; } -void addErrorInXMLForMisconfiguredLayer(CT::string *XMLDoc, WMSLayer *layer) { XMLDoc->printconcat("\n\n", layer->name.c_str()); } - -int CXMLGen::getFileNameForLayer(WMSLayer *myWMSLayer) { -#ifdef CXMLGEN_DEBUG - CDBDebug("getFileNameForLayer"); -#endif - - /**********************************************/ - /* Read the file to obtain BBOX parameters */ - /**********************************************/ - - // Create a new datasource and set configuration for it - if (myWMSLayer->dataSource == NULL) { - myWMSLayer->dataSource = new CDataSource(); - if (myWMSLayer->dataSource->setCFGLayer(srvParam, srvParam->configObj->Configuration[0], myWMSLayer->layer, myWMSLayer->name.c_str(), -1) != 0) { - return 1; - } - } - - int status; - - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { - if (myWMSLayer->dataSource->cfgLayer->Dimension.size() == 0) { - - myWMSLayer->fileName.copy(myWMSLayer->dataSource->cfgLayer->FilePath[0]->value.c_str()); - if (CAutoConfigure::autoConfigureDimensions(myWMSLayer->dataSource) != 0) { - CDBError("Unable to autoconfigure dimensions"); - return 1; - } - } - - bool dataBaseDimension = true; - - /* A dimension where the default value is set to filetimedate should not be queried from the db */ - if (myWMSLayer->layer->Dimension.size() == 1 && myWMSLayer->layer->Dimension[0]->attr.defaultV.equals("filetimedate")) { - dataBaseDimension = false; - } - - // Check if any dimension is given: - if (dataBaseDimension == false || (myWMSLayer->layer->Dimension.size() == 0) || (myWMSLayer->layer->Dimension.size() == 1 && myWMSLayer->layer->Dimension[0]->attr.name.equals("none"))) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Layer %s has no dimensions", myWMSLayer->dataSource->layerName.c_str()); -#endif - // If not, just return the filename - std::vector fileList; - try { - fileList = CDBFileScanner::searchFileNames(myWMSLayer->dataSource->cfgLayer->FilePath[0]->value.c_str(), myWMSLayer->dataSource->cfgLayer->FilePath[0]->attr.filter, NULL); - } catch (int linenr) { - }; - if (fileList.size() == 1) { - myWMSLayer->fileName.copy(fileList[0].c_str()); - } else { - myWMSLayer->fileName.copy(myWMSLayer->layer->FilePath[0]->value.c_str()); - } - return 0; - } - - status = CDBFactory::getDBAdapter(srvParam->cfg)->autoUpdateAndScanDimensionTables(myWMSLayer->dataSource); - if (status != 0) { - CDBError("Unable to checkDimTables"); - return 1; - } - - // Find the first occuring filename. - CT::string tableName; - CT::string dimName(myWMSLayer->layer->Dimension[0]->attr.name.c_str()); - try { - tableName = - CDBFactory::getDBAdapter(srvParam->cfg) - ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str(), myWMSLayer->dataSource); - } catch (int e) { - CDBError("Unable to create tableName from '%s' '%s' '%s'", myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str()); - return 1; - } - - bool databaseError = false; - - CDBStore::Store *values = CDBFactory::getDBAdapter(srvParam->cfg)->getUniqueValuesOrderedByValue("path", 1, false, tableName.c_str()); - - if (values == NULL) { - CDBError("No files found for %s ", myWMSLayer->dataSource->layerName.c_str()); - databaseError = true; - } - if (databaseError == false) { - if (values->getSize() > 0) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Query succeeded: Filename = %s", values->getRecord(0)->get(0)->c_str()); -#endif - myWMSLayer->fileName.copy(values->getRecord(0)->get(0)); - } else { - // The file is not in the database, probably an error during the database scan has been detected earlier. - // Ignore the file for now too - CDBError("Query for '%s' not succeeded", myWMSLayer->layer->FilePath[0]->value.c_str()); - databaseError = true; - } - delete values; - } - -#ifdef CXMLGEN_DEBUG - CDBDebug("/Database"); -#endif - if (databaseError) { - return 1; - } - } - // If this layer is a file type layer (not a database type layer) TODO type file is deprecated... - if (myWMSLayer->layer->attr.type.equals("file")) { - CDBWarning("Type 'file' is deprecated"); - CT::string pathFileName(""); - if (myWMSLayer->fileName.c_str()[0] != '/') { - pathFileName.copy(srvParam->cfg->Path[0]->attr.value.c_str()); - pathFileName.concat("/"); - } - pathFileName.concat(&myWMSLayer->fileName); - myWMSLayer->fileName.copy(pathFileName.c_str(), pathFileName.length()); - } - - return 0; -} - -/** - * - * - */ -int CXMLGen::getDataSourceForLayer(WMSLayer *myWMSLayer) { -#ifdef CXMLGEN_DEBUG - CDBDebug("getDataSourceForLayer"); -#endif - - // Get abstract for layer - if (myWMSLayer->dataSource->cfgLayer->Abstract.size() > 0) { - const char *v = myWMSLayer->dataSource->cfgLayer->Abstract[0]->value.c_str(); - if (v != NULL) { - myWMSLayer->abstract.copy(v); - } - } - // Is this a cascaded WMS server? - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Cascaded layer"); -#endif - if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { - myWMSLayer->title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); - } else { - myWMSLayer->title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); - } - return 0; - } - // This a liveupdate layer - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Live update layer"); -#endif - return layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(myWMSLayer); - } - if (myWMSLayer->fileName.empty()) { - CDBError("No file name specified for layer %s", myWMSLayer->dataSource->layerName.c_str()); - return 1; - } - - // Is this a local file based WMS server? - if (myWMSLayer->dataSource->dLayerType != CConfigReaderLayerTypeCascaded) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Database layer"); -#endif - CDataReader reader; - // CNETCDFREADER_MODE_OPEN_DIMENSIONS - int status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); - if (status != 0) { - CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); - return 1; - } - // Get a nice name for this layer (if not configured) - if (myWMSLayer->dataSource->cfgLayer->Title.size() == 0) { - // By default title is the same as the name of the layer. - myWMSLayer->title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); - // Try to get longname: - // reader.cdfObject-> - - try { - CT::string attributeValue; - myWMSLayer->dataSource->getDataObject(0)->cdfVariable->getAttribute("long_name")->getDataAsString(&attributeValue); - myWMSLayer->title.copy(attributeValue.c_str()); - myWMSLayer->title.printconcat(" (%s)", myWMSLayer->dataSource->getDataObject(0)->cdfVariable->name.c_str()); - } catch (int e) { - CT::string errorMessage; - CDF::getErrorMessage(&errorMessage, e); -#ifdef CXMLGEN_DEBUG - CDBDebug("No long_name: %s (%d)", errorMessage.c_str(), e); -#endif - try { - CT::string attributeValue; - myWMSLayer->dataSource->getDataObject(0)->cdfVariable->getAttribute("standard_name")->getDataAsString(&attributeValue); - // CDBDebug("attributeValue %s",attributeValue.c_str()); - myWMSLayer->title.copy(attributeValue.c_str()); - } catch (int e) { - CT::string errorMessage; - CDF::getErrorMessage(&errorMessage, e); -#ifdef CXMLGEN_DEBUG - CDBDebug("No standard_name: %s (%d)", errorMessage.c_str(), e); -#endif - } - } - } else { - myWMSLayer->title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); - } - - return 0; - } - CDBWarning("Unknown layer type"); - return 0; -} - -int CXMLGen::getProjectionInformationForLayer(WMSLayer *myWMSLayer) { -#ifdef CXMLGEN_DEBUG - CDBDebug("getProjectionInformationForLayer"); -#endif - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded) { - if (myWMSLayer->dataSource->cfgLayer->LatLonBox.size() == 0) { - return 0; - } - } - - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { - if (myWMSLayer->dataSource->cfgLayer->LatLonBox.size() == 0) { - return 0; - } - } - - // if (getProjectionList(myWMSLayer) != 0) { - // CDBWarning("Unable to get projection list"); - - // } else { - // CDBDebug("Proj information fetched!"); - // return 0; - // } - - CGeoParams geo; - - int status; - for (size_t p = 0; p < srvParam->cfg->Projection.size(); p++) { - geo.CRS.copy(srvParam->cfg->Projection[p]->attr.id.c_str()); - -#ifdef MEASURETIME - StopWatch_Stop("start initreproj %s", geo.CRS.c_str()); -#endif - CImageWarper warper; - status = warper.initreproj(myWMSLayer->dataSource, &geo, &srvParam->cfg->Projection); - -#ifdef MEASURETIME - StopWatch_Stop("finished initreproj"); -#endif - -#ifdef CXMLGEN_DEBUG - if (status != 0) { - warper.closereproj(); - CDBDebug("Unable to initialize projection "); - } -#endif - if (status != 0) { - warper.closereproj(); - return 1; - } - - // Find the max extent of the image - WMSLayer::Projection *myProjection = new WMSLayer::Projection(); - myWMSLayer->projectionList.push_back(myProjection); - - // Set the projection string - myProjection->name.copy(srvParam->cfg->Projection[p]->attr.id.c_str()); - - // Calculate the extent for this projection - -#ifdef MEASURETIME - StopWatch_Stop("start findExtent"); -#endif - - warper.findExtent(myWMSLayer->dataSource, myProjection->dfBBOX); - -#ifdef MEASURETIME - StopWatch_Stop("finished findExtent"); -#endif - -#ifdef CXMLGEN_DEBUG - CDBDebug("PROJ=%s\tBBOX=(%f,%f,%f,%f)", myProjection->name.c_str(), myProjection->dfBBOX[0], myProjection->dfBBOX[1], myProjection->dfBBOX[2], myProjection->dfBBOX[3]); -#endif - // Calculate the latlonBBOX - if (srvParam->cfg->Projection[p]->attr.id.equals("EPSG:4326")) { - for (int k = 0; k < 4; k++) myWMSLayer->dfLatLonBBOX[k] = myProjection->dfBBOX[k]; - } - - warper.closereproj(); - } - - // Add the layers native projection as well - if (!myWMSLayer->dataSource->nativeEPSG.empty()) { - WMSLayer::Projection *myProjection = new WMSLayer::Projection(); - myWMSLayer->projectionList.push_back(myProjection); - myProjection->name.copy(myWMSLayer->dataSource->nativeEPSG.c_str()); - myProjection->dfBBOX[0] = myWMSLayer->dataSource->dfBBOX[0]; - myProjection->dfBBOX[3] = myWMSLayer->dataSource->dfBBOX[1]; - myProjection->dfBBOX[2] = myWMSLayer->dataSource->dfBBOX[2]; - myProjection->dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[3]; - } - - // if (storeProjectionList(myWMSLayer) != 0) { - // CDBWarning("Unable to store projection list"); - // } - - return 0; -} - -int CXMLGen::getDimsForLayer(WMSLayer *myWMSLayer) { -#ifdef CXMLGEN_DEBUG - CDBDebug("getDimsForLayer"); -#endif - char szMaxTime[32]; - char szMinTime[32]; - // char szInterval[32]; - // int hastimedomain = 0; - - // Dimensions - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { - /* if(myWMSLayer->dataSource->cfgLayer->Dimension.size()!=0){ - #ifdef CXMLGEN_DEBUG - CDBDebug("Check"); - #endif - //Check if all dimensions are configured properly by the user (X and Y are never configured by the user, so +2) - if(myWMSLayer->dataSource->cfgLayer->Dimension.size()+2!=myWMSLayer->dataSource->getDataObject(0)->cdfVariable->dimensionlinks.size()){ - CDBError("Warning: Dimensions for layer %s are not configured properly! (configured: %d!=variable: - %d)",myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()+2,myWMSLayer->dataSource->cfgLayer->Dimension.size(),myWMSLayer->dataSource->getDataObject(0)->cdfVariable->dimensionlinks.size()); - } - }*/ -#ifdef CXMLGEN_DEBUG - CDBDebug("Start looping dimensions"); - CDBDebug("Number of dimensions is %d", myWMSLayer->dataSource->cfgLayer->Dimension.size()); -#endif - /* Auto configure dimensions */ - for (size_t i = 0; i < myWMSLayer->dataSource->cfgLayer->Dimension.size(); i++) { - - /* This dimension is a filetimedate type, its values come from the modification date of the file */ - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.equals("filetimedate")) { - CT::string fileDate = CDirReader::getFileDate(myWMSLayer->layer->FilePath[0]->value.c_str()); - WMSLayer::Dim *dim = new WMSLayer::Dim(); - myWMSLayer->dimList.push_back(dim); - dim->name.copy("time"); - dim->units.copy("ISO8601"); - dim->values.copy(fileDate.c_str()); - dim->defaultValue.copy(fileDate.c_str()); - dim->hasMultipleValues = true; - break; - } -#ifdef CXMLGEN_DEBUG - CDBDebug("%d = %s / %s", i, myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(), myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); -#endif - if (i == 0 && myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.equals("none")) break; - // Shorthand dimName - const char *pszDimName = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); - - // Create a new dim to store in the layer - WMSLayer::Dim *dim = new WMSLayer::Dim(); - myWMSLayer->dimList.push_back(dim); - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); - // Get the tablename - CT::string tableName; - try { - tableName = CDBFactory::getDBAdapter(srvParam->cfg) - ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName, myWMSLayer->dataSource); - } catch (int e) { - CDBError("Unable to create tableName from '%s' '%s' '%s'", myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName); - return 1; - } - - bool hasMultipleValues = false; - bool isTimeDim = false; - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { - hasMultipleValues = true; - - /* Automatically scan the time dimension, two types are avaible, start/stop/resolution and individual values */ - // TODO try to detect automatically the time resolution of the layer. - CT::string varName = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); - // CDBDebug("VarName = [%s]",varName.c_str()); - int ind = varName.indexOf("time"); - if (ind >= 0) { - // CDBDebug("VarName = [%s] and this is a time dim at %d!",varName.c_str(),ind); - CT::string units; - isTimeDim = true; - try { - myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")->getAttribute("units")->getDataAsString(&units); - - } catch (int e) { - } - if (units.length() > 0) { -#ifdef CXMLGEN_DEBUG - CDBDebug("Time dimension units = %s", units.c_str()); -#endif - -#ifdef MEASURETIME - StopWatch_Stop("Get the first 100 values from the database, and determine whether the time resolution is continous or multivalue."); -#endif - - CDBDebug("MPPPPPP"); - // Get the first 100 values from the database, and determine whether the time resolution is continous or multivalue. - CDBStore::Store *store = CDBFactory::getDBAdapter(srvParam->cfg)->getUniqueValuesOrderedByValue(pszDimName, 100, true, tableName.c_str()); - bool dataHasBeenFoundInStore = false; - if (store != NULL) { - if (store->size() != 0) { - dataHasBeenFoundInStore = true; - tm tms[store->size()]; - - try { - - for (size_t j = 0; j < store->size(); j++) { - store->getRecord(j)->get("time")->setChar(10, 'T'); - const char *isotime = store->getRecord(j)->get("time")->c_str(); -#ifdef CXMLGEN_DEBUG - // CDBDebug("isotime = %s",isotime); -#endif - CT::string year, month, day, hour, minute, second; - year.copy(isotime + 0, 4); - tms[j].tm_year = year.toInt() - 1900; - month.copy(isotime + 5, 2); - tms[j].tm_mon = month.toInt() - 1; - day.copy(isotime + 8, 2); - tms[j].tm_mday = day.toInt(); - hour.copy(isotime + 11, 2); - tms[j].tm_hour = hour.toInt(); - minute.copy(isotime + 14, 2); - tms[j].tm_min = minute.toInt(); - second.copy(isotime + 17, 2); - tms[j].tm_sec = second.toInt(); - } - size_t nrTimes = store->size() - 1; - bool isConst = true; - if (store->size() < 4) { - isConst = false; - } - try { - CTime *time = CTime::GetCTimeInstance(myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")); - if (time == nullptr) { - CDBDebug(CTIME_GETINSTANCE_ERROR_MESSAGE); - return 1; - } - if (time->getMode() != 0) { - isConst = false; - } - } catch (int e) { - } - - CT::string iso8601timeRes = "P"; - CT::string yearPart = ""; - if (tms[1].tm_year - tms[0].tm_year != 0) { - if (tms[1].tm_year - tms[0].tm_year == (tms[nrTimes < 10 ? nrTimes : 10].tm_year - tms[0].tm_year) / double(nrTimes < 10 ? nrTimes : 10)) { - yearPart.printconcat("%dY", abs(tms[1].tm_year - tms[0].tm_year)); - } else { - isConst = false; -#ifdef CXMLGEN_DEBUG - CDBDebug("year is irregular"); -#endif - } - } - if (tms[1].tm_mon - tms[0].tm_mon != 0) { - if (tms[1].tm_mon - tms[0].tm_mon == (tms[nrTimes < 10 ? nrTimes : 10].tm_mon - tms[0].tm_mon) / double(nrTimes < 10 ? nrTimes : 10)) - yearPart.printconcat("%dM", abs(tms[1].tm_mon - tms[0].tm_mon)); - else { - isConst = false; -#ifdef CXMLGEN_DEBUG - CDBDebug("month is irregular"); -#endif - } - } - - if (tms[1].tm_mday - tms[0].tm_mday != 0) { - if (tms[1].tm_mday - tms[0].tm_mday == (tms[nrTimes < 10 ? nrTimes : 10].tm_mday - tms[0].tm_mday) / double(nrTimes < 10 ? nrTimes : 10)) - yearPart.printconcat("%dD", abs(tms[1].tm_mday - tms[0].tm_mday)); - else { - isConst = false; -#ifdef CXMLGEN_DEBUG - CDBDebug("day irregular"); - for (size_t j = 0; j < nrTimes; j++) { - CDBDebug("Day %d = %d", j, tms[j].tm_mday); - } -#endif - } - } - - CT::string hourPart = ""; - if (tms[1].tm_hour - tms[0].tm_hour != 0) { - hourPart.printconcat("%dH", abs(tms[1].tm_hour - tms[0].tm_hour)); - } - if (tms[1].tm_min - tms[0].tm_min != 0) { - hourPart.printconcat("%dM", abs(tms[1].tm_min - tms[0].tm_min)); - } - if (tms[1].tm_sec - tms[0].tm_sec != 0) { - hourPart.printconcat("%dS", abs(tms[1].tm_sec - tms[0].tm_sec)); - } - - int sd = (tms[1].tm_hour * 3600 + tms[1].tm_min * 60 + tms[1].tm_sec) - (tms[0].tm_hour * 3600 + tms[0].tm_min * 60 + tms[0].tm_sec); - for (size_t j = 2; j < store->size() && isConst; j++) { - int d = (tms[j].tm_hour * 3600 + tms[j].tm_min * 60 + tms[j].tm_sec) - (tms[j - 1].tm_hour * 3600 + tms[j - 1].tm_min * 60 + tms[j - 1].tm_sec); - if (d > 0) { - if (sd != d) { - isConst = false; -#ifdef CXMLGEN_DEBUG - CDBDebug("hour/min/sec is irregular %d ", j); -#endif - } - } - } - - // Check whether we found a time resolution - if (isConst == false) { - hasMultipleValues = true; -#ifdef CXMLGEN_DEBUG - CDBDebug("Not a continous time dimension, multipleValues required"); -#endif - } else { -#ifdef CXMLGEN_DEBUG - CDBDebug("Continous time dimension, Time resolution needs to be calculated"); -#endif - hasMultipleValues = false; - } - - if (isConst) { - if (yearPart.length() > 0) { - iso8601timeRes.concat(&yearPart); - } - if (hourPart.length() > 0) { - iso8601timeRes.concat("T"); - iso8601timeRes.concat(&hourPart); - } -#ifdef CXMLGEN_DEBUG - CDBDebug("Calculated a timeresolution of %s", iso8601timeRes.c_str()); -#endif - myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.copy(iso8601timeRes.c_str()); - myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.copy("ISO8601"); - } - } catch (int e) { - } - } - delete store; - store = NULL; - } - if (dataHasBeenFoundInStore == false) { - CDBDebug("No data available in database for dimension %s", pszDimName); - } - } - } - } - CDBStore::Store *values = NULL; - // This is a multival dim, defined as val1,val2,val3,val4,val5,etc... - if (hasMultipleValues == true) { - // Get all dimension values from the db - if (isTimeDim) { - values = CDBFactory::getDBAdapter(srvParam->cfg)->getUniqueValuesOrderedByValue(pszDimName, 0, true, tableName.c_str()); - } else { - // query.print("select distinct %s,dim%s from %s order by dim%s,%s",pszDimName,pszDimName,tableName.c_str(),pszDimName,pszDimName); - values = CDBFactory::getDBAdapter(srvParam->cfg)->getUniqueValuesOrderedByIndex(pszDimName, 0, true, tableName.c_str()); - } - - if (values == NULL) { - CDBError("Query failed"); - return 1; - } - - if (values->getSize() > 0) { - // if(srvParam->requestType==REQUEST_WMS_GETCAPABILITIES) - { - - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); - - // Try to get units from the variable - dim->units.copy("NA"); - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { - CT::string units; - try { - myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable(dim->name.c_str())->getAttribute("units")->getDataAsString(&units); - dim->units.copy(&units); - } catch (int e) { - } - } - - dim->hasMultipleValues = 1; - if (isTimeDim == true) { - dim->units.copy("ISO8601"); - for (size_t j = 0; j < values->getSize(); j++) { - // 2011-01-01T22:00:01Z - // 01234567890123456789 - values->getRecord(j)->get(0)->setChar(10, 'T'); - if (values->getRecord(j)->get(0)->length() == 19) { - values->getRecord(j)->get(0)->printconcat("Z"); - } - } - dim->units.copy("ISO8601"); - } - - if (!myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { - // Units are configured in the configuration file. - dim->units.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); - } - - const char *pszDefaultV = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); - CT::string defaultV; - if (pszDefaultV != NULL) defaultV = pszDefaultV; - - if (defaultV.length() == 0 || defaultV.equals("max", 3)) { - dim->defaultValue.copy(values->getRecord(values->getSize() - 1)->get(0)->c_str()); - } else if (defaultV.equals("min", 3)) { - dim->defaultValue.copy(values->getRecord(0)->get(0)->c_str()); - } else { - dim->defaultValue.copy(&defaultV); - } - - dim->values.copy(values->getRecord(0)->get(0)); - for (size_t j = 1; j < values->getSize(); j++) { - dim->values.printconcat(",%s", values->getRecord(j)->get(0)->c_str()); - } - } - } - delete values; - } - - // This is an interval defined as start/stop/resolution - if (hasMultipleValues == false) { - // Retrieve the max dimension value - CDBStore::Store *values = CDBFactory::getDBAdapter(srvParam->cfg)->getMax(pszDimName, tableName.c_str()); - if (values == NULL) { - CDBError("Query failed"); - return 1; - } - if (values->getSize() > 0) { - snprintf(szMaxTime, 31, "%s", values->getRecord(0)->get(0)->c_str()); - szMaxTime[10] = 'T'; - } - delete values; - // Retrieve the minimum dimension value - values = CDBFactory::getDBAdapter(srvParam->cfg)->getMin(pszDimName, tableName.c_str()); - if (values == NULL) { - CDBError("Query failed"); - return 1; - } - if (values->getSize() > 0) { - snprintf(szMinTime, 31, "%s", values->getRecord(0)->get(0)->c_str()); - szMinTime[10] = 'T'; - } - delete values; - - // Retrieve all values for time position - // if(srvParam->serviceType==SERVICE_WCS){ - - /* - query.print("select %s from %s",dimName,tableName.c_str()); - values = DB.query_select(query.c_str(),0); - if(values == NULL){CDBError("Query failed");DB.close();return 1;} - if(values->count>0){ - if(TimePositions!=NULL){ - delete[] TimePositions; - TimePositions=NULL; - } - TimePositions=new CT::string[values->count]; - char szTemp[32]; - for(size_t l=0;lcount;l++){ - snprintf(szTemp,31,"%s",values[l].c_str());szTemp[10]='T'; - TimePositions[l].copy(szTemp); - TimePositions[l].count=values[l].count; - } - } - delete[] values;*/ - - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { - // TODO - CDBError("Dimension interval '%d' not defined", i); - return 1; - } - // strncpy(szInterval,myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(),32);szInterval[31]='\0'; - const char *pszInterval = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(); - // hastimedomain = 1; - // if(srvParam->requestType==REQUEST_WMS_GETCAPABILITIES) - { - CT::string dimUnits("ISO8601"); - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty() == false) { - dimUnits.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); - } - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); - dim->units.copy(dimUnits.c_str()); - dim->hasMultipleValues = 0; - // myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str() - const char *pszDefaultV = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); - CT::string defaultV; - if (pszDefaultV != NULL) defaultV = pszDefaultV; - if (defaultV.length() == 0 || defaultV.equals("max", 3)) { - dim->defaultValue.copy(szMaxTime); - } else if (defaultV.equals("min", 3)) { - dim->defaultValue.copy(szMinTime); - } else { - dim->defaultValue.copy(&defaultV); - } - if (dim->defaultValue.length() == 19) { - dim->defaultValue.concat("Z"); - } - - CT::string minTime = szMinTime; - if (minTime.equals(szMaxTime)) { - dim->values.print("%s", szMinTime); - } else { - dim->values.print("%s/%s/%s", szMinTime, szMaxTime, pszInterval); - } - } - } - - // Check for forced values - if (!myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue.empty()) { - dim->values = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; - dim->defaultValue = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; - dim->hasMultipleValues = false; - } - - // Check if it should be hidden - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.hidden == true) { - dim->hidden = true; - } - } - } - - return 0; -} - -int CXMLGen::getStylesForLayer(WMSLayer *myWMSLayer) { - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded) { - return 0; - } - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { - return 0; - } - - CT::PointerList *styleList = myWMSLayer->dataSource->getStyleListForDataSource(myWMSLayer->dataSource); - - if (styleList == NULL) return 1; - // for(size_t j=0;jsize();j++){ - // CImageDataWriter::getStyleConfigurationByName(styleList->get(j)->c_str(),myWMSLayer->dataSource); - // - // if(myWMSLayer->dataSource->styleConfiguration->hasError){ - // CDBError("Style %s has an error",styleList->get(j)->c_str()); - // } - // - // WMSLayer::Style *style = new WMSLayer::Style(); - // style->name.copy(styleList->get(j)); - // if(myWMSLayer->dataSource->styleConfiguration->styleTitle.length()>0){ - // style->title.copy(myWMSLayer->dataSource->styleConfiguration->styleTitle.c_str()); - // }else{ - // style->title.copy(styleList->get(j)); - // } - // style->abstract.copy(myWMSLayer->dataSource->styleConfiguration->styleAbstract.c_str()); - // myWMSLayer->styleList.push_back(style); - // - // - // } - // - - for (size_t j = 0; j < styleList->size(); j++) { - - WMSLayer::Style *style = new WMSLayer::Style(); - style->name.copy(styleList->get(j)->styleCompositionName.c_str()); - style->title.copy(styleList->get(j)->styleTitle.c_str()); - style->abstract.copy(styleList->get(j)->styleAbstract.c_str()); - - myWMSLayer->styleList.push_back(style); - } - - delete styleList; - - return 0; -} +void addErrorInXMLForMisconfiguredLayer(CT::string *XMLDoc, WMSLayer *layer) { XMLDoc->printconcat("\n\n", layer->layerMetadata.name.c_str()); } int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { - CFile header; CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); - int status = header.open(srvParam->cfg->Path[0]->attr.value.c_str(), WMS_1_0_0_HEADERFILE); - if (status != 0) return 1; - - XMLDoc->copy(header.data); + XMLDoc->copy(WMS_1_0_0_GetCapabilities_Header); XMLDoc->replaceSelf("[SERVICETITLE]", srvParam->cfg->WMS[0]->Title[0]->value.c_str()); XMLDoc->replaceSelf("[SERVICEABSTRACT]", srvParam->cfg->WMS[0]->Abstract[0]->value.c_str()); XMLDoc->replaceSelf("[GLOBALLAYERTITLE]", srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); @@ -842,8 +66,8 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorreplaceSelf("[SERVICEINFO]", serviceInfo.c_str()); const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); if (firstWMLayer != nullptr) { - for (size_t p = 0; p < firstWMLayer->projectionList.size(); p++) { - WMSLayer::Projection *proj = firstWMLayer->projectionList[p]; + for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; XMLDoc->concat(""); XMLDoc->concat(&proj->name); XMLDoc->concat("\n"); @@ -855,27 +79,28 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorhasError == 0) { - XMLDoc->printconcat("\n", layer->isQuerable); + XMLDoc->printconcat("\n", layer->layerMetadata.isQueryable); XMLDoc->concat(""); - XMLDoc->concat(&layer->name); + XMLDoc->concat(&layer->layerMetadata.name); XMLDoc->concat("\n"); - CT::string layerTitle = layer->title; + CT::string layerTitle = layer->layerMetadata.title; layerTitle.encodeXMLSelf(); XMLDoc->concat(""); XMLDoc->concat(&layerTitle); XMLDoc->concat("\n"); XMLDoc->concat(""); - for (size_t p = 0; p < layer->projectionList.size(); p++) { - WMSLayer::Projection *proj = layer->projectionList[p]; + for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; XMLDoc->concat(&proj->name); - if (p + 1 < layer->projectionList.size()) XMLDoc->concat(" "); + if (p + 1 < layer->layerMetadata.projectionList.size()) XMLDoc->concat(" "); } XMLDoc->concat("\n"); - XMLDoc->printconcat("\n", layer->dfLatLonBBOX[0], layer->dfLatLonBBOX[1], layer->dfLatLonBBOX[2], layer->dfLatLonBBOX[3]); + XMLDoc->printconcat("\n", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[1], + layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[3]); // Dims - for (size_t d = 0; d < layer->dimList.size(); d++) { - WMSLayer::Dim *dim = layer->dimList[d]; + for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { + LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; if (dim->hidden) continue; XMLDoc->printconcat("\n", dim->name.c_str(), dim->units.c_str()); XMLDoc->printconcat("", dim->name.c_str(), dim->defaultValue.c_str(), 1); @@ -884,7 +109,7 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorconcat("\n"); } else { - CDBError("Skipping layer %s", layer->name.c_str()); + CDBError("Skipping layer %s", layer->layerMetadata.name.c_str()); } } } @@ -893,13 +118,9 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { - CFile header; CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); - int status = header.open(srvParam->cfg->Path[0]->attr.value.c_str(), WMS_1_1_1_HEADERFILE); - if (status != 0) return 1; - - XMLDoc->copy(header.data); + XMLDoc->copy(WMS_1_1_1_GetCapabilities_Header); XMLDoc->replaceSelf("[SERVICETITLE]", srvParam->cfg->WMS[0]->Title[0]->value.c_str()); XMLDoc->replaceSelf("[SERVICEABSTRACT]", srvParam->cfg->WMS[0]->Abstract[0]->value.c_str()); XMLDoc->replaceSelf("[GLOBALLAYERTITLE]", srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); @@ -907,8 +128,8 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorreplaceSelf("[SERVICEINFO]", serviceInfo.c_str()); const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); if (firstWMLayer != nullptr) { - for (size_t p = 0; p < firstWMLayer->projectionList.size(); p++) { - WMSLayer::Projection *proj = firstWMLayer->projectionList[p]; + for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; XMLDoc->concat(""); XMLDoc->concat(&proj->name); XMLDoc->concat("\n"); @@ -919,7 +140,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { WMSLayer *layer = (*myWMSLayerList)[lnr]; std::string key = ""; - if (layer->group.length() > 0) key = layer->group.c_str(); + if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; for (j = 0; j < groupKeys.size(); j++) { if (groupKeys[j] == key) break; @@ -991,24 +212,24 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { WMSLayer *layer = (*myWMSLayerList)[lnr]; - if (layer->group.equals(groupKeys[groupIndex])) { + if (layer->layerMetadata.group.equals(groupKeys[groupIndex])) { // CDBError("layer %d %s",groupDepth,layer->name.c_str()); if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } if (layer->hasError == 0) { - XMLDoc->printconcat("\n", layer->isQuerable, layer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded ? 1 : 0); + XMLDoc->printconcat("\n", layer->layerMetadata.isQueryable, layer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded ? 1 : 0); XMLDoc->concat(""); - XMLDoc->concat(&layer->name); + XMLDoc->concat(&layer->layerMetadata.name); XMLDoc->concat("\n"); - CT::string layerTitle = layer->title; + CT::string layerTitle = layer->layerMetadata.title; layerTitle.encodeXMLSelf(); XMLDoc->concat(""); XMLDoc->concat(&layerTitle); XMLDoc->concat("\n"); - for (size_t p = 0; p < layer->projectionList.size(); p++) { - WMSLayer::Projection *proj = layer->projectionList[p]; + for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; XMLDoc->concat(""); XMLDoc->concat(&proj->name); XMLDoc->concat("\n"); @@ -1016,11 +237,11 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectordfBBOX[3]); } - XMLDoc->printconcat("\n", layer->dfLatLonBBOX[0], layer->dfLatLonBBOX[1], layer->dfLatLonBBOX[2], - layer->dfLatLonBBOX[3]); + XMLDoc->printconcat("\n", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[1], + layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[3]); // Dims - for (size_t d = 0; d < layer->dimList.size(); d++) { - WMSLayer::Dim *dim = layer->dimList[d]; + for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { + LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; if (dim->hidden) continue; XMLDoc->printconcat("\n", dim->name.c_str(), dim->units.c_str()); XMLDoc->printconcat("", dim->name.c_str(), dim->defaultValue.c_str(), 1); @@ -1029,8 +250,8 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorstyleList.size(); s++) { - WMSLayer::Style *style = layer->styleList[s]; + for (size_t s = 0; s < layer->layerMetadata.styleList.size(); s++) { + LayerMetadataStyle *style = layer->layerMetadata.styleList[s]; XMLDoc->concat(" "); } @@ -1059,7 +280,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorconcat(" \n"); XMLDoc->concat("\n"); } else { - CDBError("Skipping layer %s", layer->name.c_str()); + CDBError("Skipping layer %s", layer->layerMetadata.name.c_str()); } } } @@ -1075,13 +296,9 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { - CFile header; CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); - int status = header.open(srvParam->cfg->Path[0]->attr.value.c_str(), WMS_1_3_0_HEADERFILE); - if (status != 0) return 1; - - XMLDoc->copy(header.data); + XMLDoc->copy(WMS_1_3_0_GetCapabilities_Header); XMLDoc->replaceSelf("[SERVICETITLE]", srvParam->cfg->WMS[0]->Title[0]->value.c_str()); XMLDoc->replaceSelf("[SERVICEABSTRACT]", srvParam->cfg->WMS[0]->Abstract[0]->value.c_str()); // XMLDoc->replaceSelf("[GLOBALLAYERTITLE]",srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); @@ -1254,16 +471,16 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorprojectionList.size(); p++) { - WMSLayer::Projection *proj = firstWMLayer->projectionList[p]; + for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; if (!proj->name.empty()) { XMLDoc->concat(""); XMLDoc->concat(&proj->name); XMLDoc->concat("\n"); } } - for (size_t p = 0; p < firstWMLayer->projectionList.size(); p++) { - WMSLayer::Projection *proj = firstWMLayer->projectionList[p]; + for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; if (!proj->name.empty()) { if (srvParam->checkBBOXXYOrder(proj->name.c_str()) == true) { XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[1], proj->dfBBOX[0], proj->dfBBOX[3], proj->dfBBOX[2]); @@ -1289,7 +506,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { WMSLayer *layer = (*myWMSLayerList)[lnr]; std::string key = ""; - if (layer->group.length() > 0) key = layer->group.c_str(); + if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; for (j = 0; j < groupKeys.size(); j++) { if (groupKeys[j] == key) break; @@ -1368,7 +585,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorgroup.c_str(), groupKeys[groupIndex].c_str()); #endif - if (layer->group.equals(groupKeys[groupIndex])) { + if (layer->layerMetadata.group.equals(groupKeys[groupIndex])) { #ifdef CXMLGEN_DEBUG CDBDebug("layer %d %s", groupDepth, layer->name.c_str()); #endif @@ -1377,20 +594,20 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorhasError == 0) { - XMLDoc->printconcat("\n", layer->isQuerable, layer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded ? 1 : 0); + XMLDoc->printconcat("\n", layer->layerMetadata.isQueryable, layer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded ? 1 : 0); XMLDoc->concat(""); - XMLDoc->concat(&layer->name); + XMLDoc->concat(&layer->layerMetadata.name); XMLDoc->concat("\n"); - CT::string layerTitle = layer->title; + CT::string layerTitle = layer->layerMetadata.title; layerTitle.encodeXMLSelf(); XMLDoc->concat(""); XMLDoc->concat(&layerTitle); XMLDoc->concat("\n"); // TODO - if (layer->abstract.length() > 0) { + if (layer->layerMetadata.abstract.length() > 0) { XMLDoc->concat(""); - XMLDoc->concat(layer->abstract.encodeXML().c_str()); + XMLDoc->concat(layer->layerMetadata.abstract.encodeXML().c_str()); XMLDoc->concat("\n"); } #ifdef ENABLE_INSPIRE @@ -1414,10 +631,10 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector%f\n" " %f\n" "", - layer->dfLatLonBBOX[0], layer->dfLatLonBBOX[2], layer->dfLatLonBBOX[1], layer->dfLatLonBBOX[3]); + layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[3]); - for (size_t p = 0; p < layer->projectionList.size(); p++) { - WMSLayer::Projection *proj = layer->projectionList[p]; + for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; if (srvParam->checkBBOXXYOrder(proj->name.c_str()) == true) { XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[1], proj->dfBBOX[0], proj->dfBBOX[3], @@ -1443,8 +660,8 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectordimList.size(); d++) { - WMSLayer::Dim *dim = layer->dimList[d]; + for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { + LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; if (dim->hidden) continue; if (dim->name.indexOf("time") != -1) { XMLDoc->printconcat("", dim->name.c_str(), dim->units.c_str(), @@ -1474,12 +691,12 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorprintconcat(" \n", authorityName.c_str(), authorityOnlineResource.c_str()); // XMLDoc->printconcat(" %s\n",identifierAuthority.c_str(),identifierId.c_str()); - XMLDoc->printconcat(" %s\n", identifierAuthority.c_str(), layer->name.c_str()); + XMLDoc->printconcat(" %s\n", identifierAuthority.c_str(), layer->layerMetadata.name.c_str()); } // Styles - for (size_t s = 0; s < layer->styleList.size(); s++) { - WMSLayer::Style *style = layer->styleList[s]; + for (size_t s = 0; s < layer->layerMetadata.styleList.size(); s++) { + LayerMetadataStyle *style = layer->layerMetadata.styleList[s]; XMLDoc->concat(" "); } XMLDoc->concat("\n"); } else { - CDBError("Skipping layer %s", layer->name.c_str()); + CDBError("Skipping layer %s", layer->layerMetadata.name.c_str()); } } } @@ -1514,13 +731,10 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { - CFile header; CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WCS&"); - int status = header.open(srvParam->cfg->Path[0]->attr.value.c_str(), WCS_1_0_HEADERFILE); - if (status != 0) return 1; - XMLDoc->copy(header.data); + XMLDoc->copy(WCS_1_0_0_GetCapabilities_Header); if (srvParam->cfg->WCS[0]->Title.size() == 0) { CDBError("No title defined for WCS"); return 1; @@ -1549,12 +763,12 @@ int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorhasError == 0) { XMLDoc->printconcat("\n"); XMLDoc->concat(""); - XMLDoc->concat(&layer->name); + XMLDoc->concat(&layer->layerMetadata.name); XMLDoc->concat("\n"); XMLDoc->concat(""); - XMLDoc->concat(&layer->name); + XMLDoc->concat(&layer->layerMetadata.name); XMLDoc->concat("\n"); - CT::string layerTitle = layer->title; + CT::string layerTitle = layer->layerMetadata.title; layerTitle.encodeXMLSelf(); XMLDoc->concat("\n"); } else { - CDBError("Skipping layer %s", layer->name.c_str()); + CDBError("Skipping layer %s", layer->layerMetadata.name.c_str()); } } } @@ -1592,7 +806,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorWMSLayers->count; layerIndex++) { for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { WMSLayer *layer = (*myWMSLayerList)[lnr]; - if (layer->name.equals(&srvParam->WMSLayers[layerIndex])) { + if (layer->layerMetadata.name.equals(&srvParam->WMSLayers[layerIndex])) { if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } @@ -1600,8 +814,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectordimList.size(); d++) { - WMSLayer::Dim *dim = layer->dimList[d]; + for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { + LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; // if(dim->hasMultipleValues==0){ if (dim->units.equals("ISO8601")) { timeDimIndex = d; @@ -1610,24 +824,24 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorrequestType == REQUEST_WCS_DESCRIBECOVERAGE) { // XMLDoc->print("\n"); - CT::string layerTitle = layer->title; + CT::string layerTitle = layer->layerMetadata.title; layerTitle.encodeXMLSelf(); XMLDoc->printconcat(" \n" " %s\n" " %s\n" " \n", - layer->name.c_str(), layer->name.c_str(), layerTitle.c_str()); + layer->layerMetadata.name.c_str(), layer->layerMetadata.name.c_str(), layerTitle.c_str()); if (layer->dataSource->dataObjects.size() > 0) { XMLDoc->printconcat(" %s\n", layer->dataSource->dataObjects[0]->getUnits().c_str()); } XMLDoc->printconcat(" \n" " %f %f\n" " %f %f\n", - layer->dfLatLonBBOX[0], layer->dfLatLonBBOX[1], layer->dfLatLonBBOX[2], layer->dfLatLonBBOX[3]); + layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[3]); if (timeDimIndex >= 0) { // For information about this, visit http://www.galdosinc.com/archives/151 - CT::string *timeDimSplit = layer->dimList[timeDimIndex]->values.splitToArray("/"); + CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex]->values.splitToArray("/"); if (timeDimSplit->count == 3) { XMLDoc->concat(" \n"); XMLDoc->printconcat(" %s\n", timeDimSplit[0].c_str()); @@ -1640,8 +854,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorconcat(" \n" " \n" " \n"); - for (size_t p = 0; p < layer->projectionList.size(); p++) { - WMSLayer::Projection *proj = layer->projectionList[p]; + for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; CT::string encodedProjString(proj->name.c_str()); // encodedProjString.encodeURLSelf(); @@ -1682,8 +896,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector= 0) { XMLDoc->concat(" \n"); - if (layer->dimList[timeDimIndex]->hasMultipleValues == 0) { - CT::string *timeDimSplit = layer->dimList[timeDimIndex]->values.splitToArray("/"); + if (layer->layerMetadata.dimList[timeDimIndex]->hasMultipleValues == 0) { + CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex]->values.splitToArray("/"); if (timeDimSplit->count == 3) { XMLDoc->concat(" \n"); XMLDoc->printconcat(" %s\n", timeDimSplit[0].c_str()); @@ -1694,7 +908,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectordimList[timeDimIndex]->values.splitToArray(","); + CT::string *positions = layer->layerMetadata.dimList[timeDimIndex]->values.splitToArray(","); for (size_t p = 0; p < positions->count; p++) { XMLDoc->printconcat(" %s\n", (positions[p]).c_str()); } @@ -1721,8 +935,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorconcat(" \n"); - for (size_t p = 0; p < layer->projectionList.size(); p++) { - WMSLayer::Projection *proj = firstWMLayer->projectionList[p]; + for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { + LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; CT::string encodedProjString(proj->name.c_str()); XMLDoc->printconcat(" %s\n", encodedProjString.c_str()); @@ -1766,119 +980,60 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen if (srvParam->cfg->Layer[j]->attr.type.equals("autoscan")) { continue; } - bool hideLayer = false; - if (srvParam->cfg->Layer[j]->attr.hidden.equals("true")) hideLayer = true; - - if (hideLayer == false) { - // For web: URL encoding is necessary - // layerUniqueName.encodeURLSelf(); - - CT::string layerGroup = ""; - if (srvParam->cfg->Layer[j]->Group.size() > 0) { - if (srvParam->cfg->Layer[j]->Group[0]->attr.value.empty() == false) { - layerGroup.copy(srvParam->cfg->Layer[j]->Group[0]->attr.value.c_str()); - } - } - // Create a new layer and push it in the list - WMSLayer *myWMSLayer = new WMSLayer(); - myWMSLayerList.push_back(myWMSLayer); - CT::string layerUniqueName; - if (srvParam->makeUniqueLayerName(&layerUniqueName, srvParam->cfg->Layer[j]) != 0) myWMSLayer->hasError = true; - - bool foundWMSLayer = false; - for (size_t i = 0; i < srvParam->WMSLayers->count; i++) { - if (srvParam->WMSLayers[i].equals(&layerUniqueName)) { - foundWMSLayer = true; - break; - } - } - if (foundWMSLayer == false) { - // WMS layer is not in the list, so we can skip it already - myWMSLayer->hasError = true; - } - - if (myWMSLayer->hasError == false) { - - myWMSLayer->name.copy(&layerUniqueName); - - myWMSLayer->group.copy(&layerGroup); - // Set the configuration layer for this layer, as easy reference - myWMSLayer->layer = srvParam->cfg->Layer[j]; - - // Check if this layer is querable - int datasetRestriction = CServerParams::checkDataRestriction(); - if ((datasetRestriction & ALLOW_GFI)) { - myWMSLayer->isQuerable = 1; - } - - // Get a default file name for this layer to obtain some information - status = getFileNameForLayer(myWMSLayer); - if (status != 0) myWMSLayer->hasError = 1; - if (myWMSLayer->hasError == false) { - // Try to open the file, and make a datasource for the layer - myWMSLayer->dataSource->addStep(myWMSLayer->fileName.c_str(), NULL); + if (srvParam->cfg->Layer[j]->attr.hidden.equals("true")) { + continue; + } + // Create a new layer and push it in the list + WMSLayer *myWMSLayer = new WMSLayer(); + myWMSLayerList.push_back(myWMSLayer); - if (myWMSLayer->hasError == false) { - status = getDataSourceForLayer(myWMSLayer); - if (status != 0) myWMSLayer->hasError = 1; - } + // Set the configuration layer for this layer, as easy reference + myWMSLayer->layer = srvParam->cfg->Layer[j]; - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { - myWMSLayer->isQuerable = 0; - if (srvParam->serviceType == SERVICE_WCS) { - myWMSLayer->hasError = true; - } - } - // Generate a common projection list information - if (myWMSLayer->hasError == false) { -#ifdef MEASURETIME - StopWatch_Stop("start getProjectionInformationForLayer"); -#endif - - status = getProjectionInformationForLayer(myWMSLayer); -#ifdef MEASURETIME - StopWatch_Stop("finished getProjectionInformationForLayer"); -#endif + // Make the layer name + CT::string layerUniqueName; + if (srvParam->makeUniqueLayerName(&layerUniqueName, srvParam->cfg->Layer[j]) != 0) { + myWMSLayer->hasError = true; + continue; + } + myWMSLayer->layerMetadata.name.copy(&layerUniqueName); - if (status != 0) myWMSLayer->hasError = 1; - } + // Make the group + CT::string layerGroup = ""; + if (srvParam->cfg->Layer[j]->Group.size() > 0) { + if (srvParam->cfg->Layer[j]->Group[0]->attr.value.empty() == false) { + layerGroup.copy(srvParam->cfg->Layer[j]->Group[0]->attr.value.c_str()); + } + } + myWMSLayer->layerMetadata.group.copy(&layerGroup); - // Get the dimensions and its extents for this layer - if (myWMSLayer->hasError == false) { -#ifdef MEASURETIME - StopWatch_Stop("Start getDimsForLayer"); -#endif + // Check if this layer is querable + int datasetRestriction = CServerParams::checkDataRestriction(); + if ((datasetRestriction & ALLOW_GFI)) { + myWMSLayer->layerMetadata.isQueryable = 1; + } - status = getDimsForLayer(myWMSLayer); - if (status != 0) myWMSLayer->hasError = 1; -#ifdef MEASURETIME - StopWatch_Stop("Finished getDimsForLayer"); -#endif - } + // Assign a datasource + if (myWMSLayer->dataSource == NULL) { + myWMSLayer->dataSource = new CDataSource(); + if (myWMSLayer->dataSource->setCFGLayer(srvParam, srvParam->configObj->Configuration[0], myWMSLayer->layer, myWMSLayer->layerMetadata.name.c_str(), -1) != 0) { + return 1; + } + } - // Auto configure styles - if (myWMSLayer->hasError == false) { - if (myWMSLayer->dataSource->cfgLayer->Styles.size() == 0) { - if (myWMSLayer->dataSource->dLayerType != CConfigReaderLayerTypeCascaded && myWMSLayer->dataSource->dLayerType != CConfigReaderLayerTypeLiveUpdate) { -#ifdef CXMLGEN_DEBUG - CDBDebug("cfgLayer->attr.type %d", myWMSLayer->dataSource->dLayerType); -#endif - status = CAutoConfigure::autoConfigureStyles(myWMSLayer->dataSource); - if (status != 0) { - myWMSLayer->hasError = 1; - CDBError("Unable to autoconfigure styles for layer %s", layerUniqueName.c_str()); - } - // Get the defined styles for this layer - } - } - } + // Get Abstract + if (myWMSLayer->dataSource->cfgLayer->Abstract.size() > 0) { + myWMSLayer->layerMetadata.abstract = myWMSLayer->dataSource->cfgLayer->Abstract[0]->value; + } - // Get the defined styles for this layer - status = getStylesForLayer(myWMSLayer); - if (status != 0) myWMSLayer->hasError = 1; - } - } + // Fill in Layer title, with fallback to Name (later this can be set based on metadata or info from the file) + if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { + myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); + } else { + myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); } + + populateMyWMSLayerStruct(myWMSLayer); } #ifdef CXMLGEN_DEBUG diff --git a/adagucserverEC/CXMLGen.h b/adagucserverEC/CXMLGen.h index 678e8148a..61a563809 100644 --- a/adagucserverEC/CXMLGen.h +++ b/adagucserverEC/CXMLGen.h @@ -40,160 +40,25 @@ #include "CRequest.h" #include "CDebugger.h" #include "CStyleConfiguration.h" +#include "./Types/LayerMetadataType.h" #define CXMLGEN_FATAL_ERROR_OCCURED 1 #define CXML_NON_FATAL_ERRORS_OCCURED 100 -class WMSLayer { -public: - class Dim { - public: - CT::string name; - CT::string units; - CT::string values; - CT::string defaultValue; - int hasMultipleValues; - bool hidden = false; - }; - class Projection { - public: - CT::string name; - double dfBBOX[4]; - }; - class Style { - public: - CT::string name; - CT::string title; - CT::string abstract; - }; - WMSLayer() { - isQuerable = 0; - hasError = 0; - dataSource = NULL; - dfLatLonBBOX[0] = -180; - dfLatLonBBOX[1] = -90; - dfLatLonBBOX[2] = 180; - dfLatLonBBOX[3] = 90; - abstract = ""; - } - ~WMSLayer() { - delete dataSource; - dataSource = NULL; - for (size_t j = 0; j < projectionList.size(); j++) { - delete projectionList[j]; - projectionList[j] = NULL; - } - for (size_t j = 0; j < dimList.size(); j++) { - delete dimList[j]; - dimList[j] = NULL; - } - for (size_t j = 0; j < styleList.size(); j++) { - delete styleList[j]; - styleList[j] = NULL; - } - } - CServerConfig::XMLE_Layer *layer; - CT::string name, title, group, abstract, fileName; - int isQuerable, hasError; - CDataSource *dataSource; - std::vector projectionList; - std::vector dimList; - std::vector + +height +stationshoogte [m] +stationshoogte [m] + + -68.275833 + 7.149322 + 12.130000 + 55.399166 + + + + + + + + + + + + + + + + + + dd windrichting [graden] diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml index a9bb574ed..e9ee872ea 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.23.0, of Jul 9 2024 12:13:41 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -102,7 +102,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml index 826d6343a..a18e46ace 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 index 6b3286576..c1897beff 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 index 74beb35f4..e0b10fd81 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index 6b3286576..c1897beff 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index c923c0c30..e0b10fd81 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,11 +15,11 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 - + no conditions apply None @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles index 74beb35f4..e0b10fd81 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index 9a22324d3..0aaa4199b 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index 51d105d3c..2eb51242e 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles index 51d105d3c..2eb51242e 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 @@ -98,7 +98,7 @@ data -data +data (data) -180.494446 179.505554 From be61a63f8564e251a83cc05d72548fa6d674d001 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 4 Sep 2024 13:18:36 +0200 Subject: [PATCH 05/50] Reduced loggings --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 4 ++++ adagucserverEC/utils/LayerMetadataStore.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index c9326ea2e..16fee6914 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1118,7 +1118,9 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const #endif if (this->layerMetaDataStore == nullptr) { +#ifdef CDBAdapterPostgreSQL_DEBUG CDBDebug("Need to query layer metadata for %s/%s/%s", datasetName, layerName, metadataKey); +#endif CPGSQLDB *dataBaseConnection = getDataBaseConnection(); if (dataBaseConnection == NULL) { CDBError("No database connection"); @@ -1129,7 +1131,9 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const query.print("SELECT layername, metadatakey, blob from metadata where datasetname = '%s';", datasetName); this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); if (layerMetaDataStore == nullptr) { +#ifdef CDBAdapterPostgreSQL_DEBUG CDBDebug("Unable query: \"%s\"", query.c_str()); +#endif throw(__LINE__); } if (layerMetaDataStore->size() == 0) { diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 024f17132..04a43b862 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -120,7 +120,7 @@ int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { bboxArray[3].get_to((projection->dfBBOX[3])); } } catch (int e) { - CDBError("loadLayerProjectionAndExtentListFromMetadataDb %d", e); + // CDBError("loadLayerProjectionAndExtentListFromMetadataDb %d", e); return e; } return 0; @@ -172,7 +172,7 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { } } catch (int e) { - CDBError("loadLayerStyleListFromMetadataDb %d", e); + // CDBError("loadLayerStyleListFromMetadataDb %d", e); return e; } return 0; @@ -227,7 +227,7 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { } } catch (int e) { - CDBDebug("loadLayerDimensionListFromMetadataDb %d", e); + // CDBDebug("loadLayerDimensionListFromMetadataDb %d", e); return e; } return 0; From 8cc797e840fe4dad9118175667f53ca84557a34e Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 5 Sep 2024 10:53:57 +0200 Subject: [PATCH 06/50] Refactored CXMLGen --- adagucserverEC/CDBFileScanner.cpp | 2 +- .../CDataPostProcessor_IncludeLayer.cpp | 3 +- .../CDataPostProcessor_WFP.cpp | 3 +- adagucserverEC/CDataSource.cpp | 3 +- adagucserverEC/CMakeLists.txt | 2 + adagucserverEC/COpenDAPHandler.cpp | 3 +- adagucserverEC/CRequest.cpp | 7 +-- adagucserverEC/CSLD.cpp | 3 +- adagucserverEC/CServerParams.cpp | 40 ---------------- adagucserverEC/CServerParams.h | 7 --- adagucserverEC/CXMLGen.cpp | 48 +------------------ adagucserverEC/Types/LayerMetadataType.cpp | 3 ++ adagucserverEC/Types/LayerMetadataType.h | 1 + adagucserverEC/utils/LayerUtils.cpp | 30 ++++++++++++ adagucserverEC/utils/LayerUtils.h | 14 ++++++ adagucserverEC/utils/XMLGenUtils.cpp | 44 +++++++++++++++++ hclasses/CDirReader.cpp | 2 +- ...est_WMSGetCapabilities_timeseries_twofiles | 2 +- 18 files changed, 113 insertions(+), 104 deletions(-) create mode 100644 adagucserverEC/utils/LayerUtils.cpp create mode 100644 adagucserverEC/utils/LayerUtils.h diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 1ae23a10b..c33f578b5 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -1101,7 +1101,7 @@ std::vector CDBFileScanner::searchFileNames(const char *path, CT::s if (expr.empty() == false) { // dataSource->cfgLayer->FilePath[0]->attr.filter.c_str() fileFilterExpr.copy(&expr); } - CDBDebug("Reading directory %s with filter %s", filePath.c_str(), fileFilterExpr.c_str()); + // CDBDebug("Reading directory %s with filter %s", filePath.c_str(), fileFilterExpr.c_str()); CDirReader *dirReader = CCachedDirReader::getDirReader(filePath.c_str(), fileFilterExpr.c_str()); dirReader->listDirRecursive(filePath.c_str(), fileFilterExpr.c_str()); diff --git a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_IncludeLayer.cpp b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_IncludeLayer.cpp index 330e39fae..4da0d76aa 100644 --- a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_IncludeLayer.cpp +++ b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_IncludeLayer.cpp @@ -1,6 +1,7 @@ #include #include "CDataPostProcessor_IncludeLayer.h" #include "CRequest.h" +#include /************************/ /*CDPPIncludeLayer */ /************************/ @@ -20,7 +21,7 @@ CDataSource *CDPPIncludeLayer::getDataSource(CServerConfig::XMLE_DataPostProc *p size_t additionalLayerNo = 0; for (size_t j = 0; j < dataSource->srvParams->cfg->Layer.size(); j++) { CT::string layerName; - dataSource->srvParams->makeUniqueLayerName(&layerName, dataSource->srvParams->cfg->Layer[j]); + makeUniqueLayerName(&layerName, dataSource->srvParams->cfg->Layer[j]); // CDBDebug("comparing for additionallayer %s==%s", additionalLayerName.c_str(), layerName.c_str()); if (additionalLayerName.equals(layerName)) { additionalLayerNo = j; diff --git a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_WFP.cpp b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_WFP.cpp index 186b98eca..bac7dc5d5 100644 --- a/adagucserverEC/CDataPostProcessors/CDataPostProcessor_WFP.cpp +++ b/adagucserverEC/CDataPostProcessors/CDataPostProcessor_WFP.cpp @@ -1,6 +1,7 @@ #include "CDataPostProcessor_WFP.h" #include "CRequest.h" #include "CGenericDataWarper.h" +#include /************************/ /* CDPPWFP */ @@ -25,7 +26,7 @@ CDataSource *CDPPWFP::getDataSource(CDataSource *dataSource, CT::string baseLaye size_t additionalLayerNo = 0; for (size_t j = 0; j < dataSource->srvParams->cfg->Layer.size(); j++) { CT::string layerName; - dataSource->srvParams->makeUniqueLayerName(&layerName, dataSource->srvParams->cfg->Layer[j]); + makeUniqueLayerName(&layerName, dataSource->srvParams->cfg->Layer[j]); if (baseLayerName.equals(layerName)) { additionalLayerNo = j; break; diff --git a/adagucserverEC/CDataSource.cpp b/adagucserverEC/CDataSource.cpp index 5b61a2057..974e1e0ab 100644 --- a/adagucserverEC/CDataSource.cpp +++ b/adagucserverEC/CDataSource.cpp @@ -26,6 +26,7 @@ #include "CDataSource.h" #include "CDBFileScanner.h" #include "CConvertGeoJSON.h" +#include "utils/LayerUtils.h" const char *CDataSource::className = "CDataSource"; // #define CDATASOURCE_DEBUG @@ -368,7 +369,7 @@ int CDataSource::setCFGLayer(CServerParams *_srvParams, CServerConfig::XMLE_Conf // Set the layername CT::string layerUniqueName; if (_layerName == NULL) { - if (srvParams->makeUniqueLayerName(&layerUniqueName, cfgLayer) != 0) layerUniqueName = "undefined"; + if (makeUniqueLayerName(&layerUniqueName, cfgLayer) != 0) layerUniqueName = "undefined"; _layerName = layerUniqueName.c_str(); } diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index dba90e803..a133293ba 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -73,6 +73,8 @@ add_library( utils/XMLGenUtils.h utils/XMLGenUtils.cpp utils/CXMLTemplates.h + utils/LayerUtils.h + utils/LayerUtils.cpp Types/LayerMetadataType.h Types/LayerMetadataType.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp diff --git a/adagucserverEC/COpenDAPHandler.cpp b/adagucserverEC/COpenDAPHandler.cpp index ff8717558..537735db5 100644 --- a/adagucserverEC/COpenDAPHandler.cpp +++ b/adagucserverEC/COpenDAPHandler.cpp @@ -2,6 +2,7 @@ #include "CRequest.h" #include "CDBFactory.h" #include "CAutoResource.h" +#include "utils/LayerUtils.h" const char *COpenDAPHandler::className = "COpenDAPHandler"; // References: http://opendap.org/pdf/ESE-RFC-004v1.2.pdf @@ -580,7 +581,7 @@ int COpenDAPHandler::handleOpenDAPRequest(const char *path, const char *_query, if (srvParam->cfg->Layer[layerNo]->attr.type.equals("database")) { CT::string intLayerName; - srvParam->makeUniqueLayerName(&intLayerName, srvParam->cfg->Layer[layerNo]); + makeUniqueLayerName(&intLayerName, srvParam->cfg->Layer[layerNo]); if (layerName.length() == 0) { layerName = intLayerName; } diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index 991765f66..540df9c61 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -41,6 +41,7 @@ #include "LayerTypeLiveUpdate/LayerTypeLiveUpdate.h" #include #include "Definitions.h" +#include "utils/LayerUtils.h" const char *CRequest::className = "CRequest"; int CRequest::CGI = 0; @@ -1580,7 +1581,7 @@ int CRequest::process_all_layers() { srvParam->requestType = REQUEST_WCS_DESCRIBECOVERAGE; srvParam->WMSLayers = new CT::string[srvParam->cfg->Layer.size()]; for (size_t j = 0; j < srvParam->cfg->Layer.size(); j++) { - srvParam->makeUniqueLayerName(&srvParam->WMSLayers[j], srvParam->cfg->Layer[j]); + makeUniqueLayerName(&srvParam->WMSLayers[j], srvParam->cfg->Layer[j]); srvParam->WMSLayers[j].count = srvParam->cfg->Layer.size(); } } else { @@ -1602,7 +1603,7 @@ int CRequest::process_all_layers() { size_t layerNo = 0; for (layerNo = 0; layerNo < srvParam->cfg->Layer.size(); layerNo++) { - srvParam->makeUniqueLayerName(&layerName, srvParam->cfg->Layer[layerNo]); + makeUniqueLayerName(&layerName, srvParam->cfg->Layer[layerNo]); // CDBError("comparing (%d) %s==%s",j,layerName.c_str(),srvParam->WMSLayers[j].c_str()); if (layerName.equals(srvParam->WMSLayers[j].c_str())) { CDataSource *dataSource = new CDataSource(); @@ -1630,7 +1631,7 @@ int CRequest::process_all_layers() { size_t additionalLayerNo = 0; for (additionalLayerNo = 0; additionalLayerNo < srvParam->cfg->Layer.size(); additionalLayerNo++) { CT::string additional; - srvParam->makeUniqueLayerName(&additional, srvParam->cfg->Layer[additionalLayerNo]); + makeUniqueLayerName(&additional, srvParam->cfg->Layer[additionalLayerNo]); // CDBDebug("comparing for additionallayer %s==%s", additionalLayerName.c_str(), additional.c_str()); if (additionalLayerName.equals(additional)) { // CDBDebug("Found additionalLayer [%s]", additional.c_str()); diff --git a/adagucserverEC/CSLD.cpp b/adagucserverEC/CSLD.cpp index d5539321f..76c06471c 100644 --- a/adagucserverEC/CSLD.cpp +++ b/adagucserverEC/CSLD.cpp @@ -4,6 +4,7 @@ #include "CSLD.h" #include "../hclasses/CXMLParser.h" #include "../hclasses/CHTTPTools.h" +#include "utils/LayerUtils.h" const char *CSLD::className = "CSLD"; @@ -62,7 +63,7 @@ int CSLD::processSLDUrl(CT::string sldUrl) { // Generate unique layer name for layer in Server Config CT::string layerUniqueName; - if (this->serverParams->makeUniqueLayerName(&layerUniqueName, this->serverConfig->Layer[j]) != 0) { + if (makeUniqueLayerName(&layerUniqueName, this->serverConfig->Layer[j]) != 0) { CDBError("Unable to compose layer name"); return 1; } diff --git a/adagucserverEC/CServerParams.cpp b/adagucserverEC/CServerParams.cpp index 1615991ce..ebd535b34 100644 --- a/adagucserverEC/CServerParams.cpp +++ b/adagucserverEC/CServerParams.cpp @@ -211,46 +211,6 @@ void CServerParams::makeCorrectTableName(CT::string *tableName, CT::string *dimN void CServerParams::showWCSNotEnabledErrorMessage() { CDBError("WCS is not enabled because GDAL was not compiled into the server. "); } -int CServerParams::makeUniqueLayerName(CT::string *layerName, CServerConfig::XMLE_Layer *cfgLayer) { - /* - if(cfgLayer->Variable.size()!=0){ - _layerName=cfgLayer->Variable[0]->value.c_str(); -}*/ - - layerName->copy(""); - if (cfgLayer->Group.size() == 1) { - if (cfgLayer->Group[0]->attr.value.empty() == false) { - layerName->copy(cfgLayer->Group[0]->attr.value.c_str()); - layerName->concat("/"); - } - } - if (cfgLayer->Name.size() == 0) { - CServerConfig::XMLE_Name *name = new CServerConfig::XMLE_Name(); - cfgLayer->Name.push_back(name); - if (cfgLayer->Variable.size() == 0) { - name->value.copy("undefined_variable"); - } else { - name->value.copy(cfgLayer->Variable[0]->value.c_str()); - } - } - - if (!cfgLayer->Name[0]->attr.force.equals("true")) { - layerName->concat(cfgLayer->Name[0]->value.c_str()); - // layerName->replaceSelf(".","_");//TODO CHECK WHY? - layerName->replaceSelf(" ", "_"); - } else { - layerName->copy(cfgLayer->Name[0]->value.c_str()); - } - - /*if(cfgLayer->Title.size()==0){ - CServerConfig::XMLE_Title *title=new CServerConfig::XMLE_Title(); - cfgLayer->Title.push_back(title); - title->value.copy(cfgLayer->Name[0]->value.c_str()); - } */ - - return 0; -} - int CServerParams::makeLayerGroupName(CT::string *groupName, CServerConfig::XMLE_Layer *cfgLayer) { /* if(cfgLayer->Variable.size()!=0){ diff --git a/adagucserverEC/CServerParams.h b/adagucserverEC/CServerParams.h index f0b7d0b1a..eed3ffdd2 100644 --- a/adagucserverEC/CServerParams.h +++ b/adagucserverEC/CServerParams.h @@ -146,13 +146,6 @@ class CServerParams { */ ~CServerParams(); - /** - * Function which generates a unique layername from the Layer's configuration - * @param layerName the returned name - * @param cfgLayer the configuration object of the corresponding layer - */ - int makeUniqueLayerName(CT::string *layerName, CServerConfig::XMLE_Layer *cfgLayer); - /** * Function which generates a group name from the Layer's configuration * @param groupName the returned name diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 060253425..f1f5564cf 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -33,6 +33,7 @@ #include "utils/LayerMetadataStore.h" #include "utils/XMLGenUtils.h" #include "utils/CXMLTemplates.h" +#include "utils/LayerUtils.h" // #define CXMLGEN_DEBUG // #define MEASURE_TIME @@ -986,53 +987,8 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen // Create a new layer and push it in the list WMSLayer *myWMSLayer = new WMSLayer(); myWMSLayerList.push_back(myWMSLayer); - - // Set the configuration layer for this layer, as easy reference myWMSLayer->layer = srvParam->cfg->Layer[j]; - - // Make the layer name - CT::string layerUniqueName; - if (srvParam->makeUniqueLayerName(&layerUniqueName, srvParam->cfg->Layer[j]) != 0) { - myWMSLayer->hasError = true; - continue; - } - myWMSLayer->layerMetadata.name.copy(&layerUniqueName); - - // Make the group - CT::string layerGroup = ""; - if (srvParam->cfg->Layer[j]->Group.size() > 0) { - if (srvParam->cfg->Layer[j]->Group[0]->attr.value.empty() == false) { - layerGroup.copy(srvParam->cfg->Layer[j]->Group[0]->attr.value.c_str()); - } - } - myWMSLayer->layerMetadata.group.copy(&layerGroup); - - // Check if this layer is querable - int datasetRestriction = CServerParams::checkDataRestriction(); - if ((datasetRestriction & ALLOW_GFI)) { - myWMSLayer->layerMetadata.isQueryable = 1; - } - - // Assign a datasource - if (myWMSLayer->dataSource == NULL) { - myWMSLayer->dataSource = new CDataSource(); - if (myWMSLayer->dataSource->setCFGLayer(srvParam, srvParam->configObj->Configuration[0], myWMSLayer->layer, myWMSLayer->layerMetadata.name.c_str(), -1) != 0) { - return 1; - } - } - - // Get Abstract - if (myWMSLayer->dataSource->cfgLayer->Abstract.size() > 0) { - myWMSLayer->layerMetadata.abstract = myWMSLayer->dataSource->cfgLayer->Abstract[0]->value; - } - - // Fill in Layer title, with fallback to Name (later this can be set based on metadata or info from the file) - if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); - } else { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); - } - + myWMSLayer->srvParams = srvParam; populateMyWMSLayerStruct(myWMSLayer); } diff --git a/adagucserverEC/Types/LayerMetadataType.cpp b/adagucserverEC/Types/LayerMetadataType.cpp index e05970694..bfa531105 100644 --- a/adagucserverEC/Types/LayerMetadataType.cpp +++ b/adagucserverEC/Types/LayerMetadataType.cpp @@ -11,10 +11,13 @@ WMSLayer::~WMSLayer() { for (size_t j = 0; j < layerMetadata.projectionList.size(); j++) { delete layerMetadata.projectionList[j]; } + layerMetadata.projectionList.clear(); for (size_t j = 0; j < layerMetadata.dimList.size(); j++) { delete layerMetadata.dimList[j]; } + layerMetadata.dimList.clear(); for (size_t j = 0; j < layerMetadata.styleList.size(); j++) { delete layerMetadata.styleList[j]; } + layerMetadata.styleList.clear(); } diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index 0be6ebd52..d27ba589d 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -44,6 +44,7 @@ class WMSLayer { // TODO: Would be nice to get rid of these in this class CServerConfig::XMLE_Layer *layer; CDataSource *dataSource; + CServerParams *srvParams; CT::string fileName; int hasError; diff --git a/adagucserverEC/utils/LayerUtils.cpp b/adagucserverEC/utils/LayerUtils.cpp new file mode 100644 index 000000000..3936eaacd --- /dev/null +++ b/adagucserverEC/utils/LayerUtils.cpp @@ -0,0 +1,30 @@ +#include "LayerUtils.h" + +int makeUniqueLayerName(CT::string *layerName, CServerConfig::XMLE_Layer *cfgLayer) { + + layerName->copy(""); + if (cfgLayer->Group.size() == 1) { + if (cfgLayer->Group[0]->attr.value.empty() == false) { + layerName->copy(cfgLayer->Group[0]->attr.value.c_str()); + layerName->concat("/"); + } + } + if (cfgLayer->Name.size() == 0) { + CServerConfig::XMLE_Name *name = new CServerConfig::XMLE_Name(); + cfgLayer->Name.push_back(name); + if (cfgLayer->Variable.size() == 0) { + name->value.copy("undefined_variable"); + } else { + name->value.copy(cfgLayer->Variable[0]->value.c_str()); + } + } + + if (!cfgLayer->Name[0]->attr.force.equals("true")) { + layerName->concat(cfgLayer->Name[0]->value.c_str()); + layerName->replaceSelf(" ", "_"); + } else { + layerName->copy(cfgLayer->Name[0]->value.c_str()); + } + + return 0; +} diff --git a/adagucserverEC/utils/LayerUtils.h b/adagucserverEC/utils/LayerUtils.h new file mode 100644 index 000000000..4a8df81b0 --- /dev/null +++ b/adagucserverEC/utils/LayerUtils.h @@ -0,0 +1,14 @@ +#include +#include + +#ifndef LAYERUTILS_H +#define LAYERUTILS_H + +/** + * Function which generates a unique layername from the Layer's configuration + * @param layerName the returned name + * @param cfgLayer the configuration object of the corresponding layer + */ +int makeUniqueLayerName(CT::string *layerName, CServerConfig::XMLE_Layer *cfgLayer); + +#endif \ No newline at end of file diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 49bd1a731..ec2deec95 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -4,8 +4,52 @@ #include #include #include +#include "LayerUtils.h" int populateMyWMSLayerStruct(WMSLayer *myWMSLayer) { + // Make the layer name + CT::string layerUniqueName; + if (makeUniqueLayerName(&layerUniqueName, myWMSLayer->layer) != 0) { + myWMSLayer->hasError = true; + return 1; + } + myWMSLayer->layerMetadata.name.copy(&layerUniqueName); + + // Create and datasource + if (myWMSLayer->dataSource == NULL) { + myWMSLayer->dataSource = new CDataSource(); + if (myWMSLayer->dataSource->setCFGLayer(myWMSLayer->srvParams, myWMSLayer->srvParams->configObj->Configuration[0], myWMSLayer->layer, myWMSLayer->layerMetadata.name.c_str(), -1) != 0) { + return 1; + } + } + + // Make the group + CT::string layerGroup = ""; + if (myWMSLayer->layer->Group.size() > 0) { + if (myWMSLayer->layer->Group[0]->attr.value.empty() == false) { + layerGroup.copy(myWMSLayer->layer->Group[0]->attr.value.c_str()); + } + } + myWMSLayer->layerMetadata.group.copy(&layerGroup); + + // Check if this layer is querable + int datasetRestriction = CServerParams::checkDataRestriction(); + if ((datasetRestriction & ALLOW_GFI)) { + myWMSLayer->layerMetadata.isQueryable = 1; + } + + // Get Abstract + if (myWMSLayer->dataSource->cfgLayer->Abstract.size() > 0) { + myWMSLayer->layerMetadata.abstract = myWMSLayer->dataSource->cfgLayer->Abstract[0]->value; + } + + // Fill in Layer title, with fallback to Name (later this can be set based on metadata or info from the file) + if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { + myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); + } else { + myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); + } + // Get a default file name for this layer to obtain some information int status = getFileNameForLayer(myWMSLayer); if (status != 0) { diff --git a/hclasses/CDirReader.cpp b/hclasses/CDirReader.cpp index cfcb0616a..a26a9e371 100644 --- a/hclasses/CDirReader.cpp +++ b/hclasses/CDirReader.cpp @@ -95,7 +95,7 @@ int CDirReader::listDirRecursive(const char *directory, const char *ext_filter) return 1; } else { /* Already done */ - CDBDebug("Using cached results for [%s]", directory); + // CDBDebug("Using cached results for [%s]", directory); return 0; } } diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles index e0b10fd81..e1bc5ca51 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 10:44:15 From cffe53dfee51886a7f8880e19740aab77f4ab45e Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 5 Sep 2024 15:44:40 +0200 Subject: [PATCH 07/50] Commit before fixing tests --- adagucserverEC/CDBFileScanner.cpp | 7 ++++- adagucserverEC/CXMLGen.cpp | 2 +- adagucserverEC/Types/LayerMetadataType.cpp | 2 -- adagucserverEC/Types/LayerMetadataType.h | 1 + adagucserverEC/utils/LayerMetadataStore.cpp | 29 +++++++++++++++++++ adagucserverEC/utils/LayerMetadataStore.h | 1 + adagucserverEC/utils/XMLGenUtils.cpp | 31 ++++++++++++++++----- adagucserverEC/utils/XMLGenUtils.h | 5 +++- 8 files changed, 66 insertions(+), 12 deletions(-) diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index c33f578b5..988ea299a 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -31,6 +31,7 @@ #include "CNetCDFDataWriter.h" #include "CCreateTiles.h" #include +#include "utils/LayerMetadataStore.h" const char *CDBFileScanner::className = "CDBFileScanner"; std::vector CDBFileScanner::tableNamesDone; // #define CDBFILESCANNER_DEBUG @@ -820,7 +821,7 @@ int CDBFileScanner::DBLoopFiles(CDataSource *dataSource, int removeNonExistingFi // delete cdfObject;cdfObject=NULL; // cdfObject=CDFObjectStore::getCDFObjectStore()->deleteCDFObject(&cdfObject); } catch (int linenr) { - CDBError("Exception in DBLoopFiles at line %d"); + CDBError("Exception in DBLoopFiles at line %d", linenr); CDBError(" *** SKIPPING FILE %s ***", (*fileList)[j].c_str()); // Close cdfObject. this is only needed if an exception occurs, otherwise it does nothing... // delete cdfObject;cdfObject=NULL; @@ -1052,6 +1053,10 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: } } + if (scanFlags & CDBFILESCANNER_UPDATEDB) { + updateMetaDataTable(dataSource); + } + CDBDebug(" ==> *** Finished update layer [%s] ***", dataSource->cfgLayer->Name[0]->value.c_str()); return 0; } diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index f1f5564cf..f86378f75 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -989,7 +989,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen myWMSLayerList.push_back(myWMSLayer); myWMSLayer->layer = srvParam->cfg->Layer[j]; myWMSLayer->srvParams = srvParam; - populateMyWMSLayerStruct(myWMSLayer); + populateMyWMSLayerStruct(myWMSLayer, true); } #ifdef CXMLGEN_DEBUG diff --git a/adagucserverEC/Types/LayerMetadataType.cpp b/adagucserverEC/Types/LayerMetadataType.cpp index bfa531105..5bcbdc8f2 100644 --- a/adagucserverEC/Types/LayerMetadataType.cpp +++ b/adagucserverEC/Types/LayerMetadataType.cpp @@ -6,8 +6,6 @@ WMSLayer::WMSLayer() { } WMSLayer::~WMSLayer() { - delete dataSource; - dataSource = NULL; for (size_t j = 0; j < layerMetadata.projectionList.size(); j++) { delete layerMetadata.projectionList[j]; } diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index d27ba589d..e30bb3883 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -46,6 +46,7 @@ class WMSLayer { CDataSource *dataSource; CServerParams *srvParams; CT::string fileName; + bool readFromDb = false; int hasError; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 04a43b862..c8adb8d9a 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -2,6 +2,7 @@ #include #include +#include "XMLGenUtils.h" int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer) { storeLayerMetadataStructIntoMetadataDb(myWMSLayer); @@ -60,6 +61,9 @@ int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { } int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { + if (!myWMSLayer->readFromDb) { + return 1; + } try { CT::string layerMetadataAsJson = getLayerMetadataFromDb(myWMSLayer, "layermetadata"); if (layerMetadataAsJson.empty()) { @@ -98,6 +102,9 @@ int storeLayerProjectionAndExtentListIntoMetadataDb(WMSLayer *myWMSLayer) { } int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { + if (!myWMSLayer->readFromDb) { + return 1; + } if (myWMSLayer->layerMetadata.projectionList.size() != 0) { CDBError("myWMSLayer->layerMetadata.projectionList is not empty"); return 1; @@ -146,6 +153,9 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { return 0; } + if (!myWMSLayer->readFromDb) { + return 1; + } if (myWMSLayer->layerMetadata.styleList.size() != 0) { CDBError("myWMSLayer->layerMetadata.styleList is not empty"); @@ -179,6 +189,7 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { } int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { + CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; for (auto dimension : myWMSLayer->layerMetadata.dimList) { @@ -199,6 +210,9 @@ int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { } int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { + if (!myWMSLayer->readFromDb) { + return 1; + } if (myWMSLayer->layerMetadata.dimList.size() != 0) { CDBError("myWMSLayer->layerMetadata.dimList is not empty"); return 1; @@ -232,3 +246,18 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { } return 0; } + +int updateMetaDataTable(CDataSource *dataSource) { + // return 0; + if (dataSource->srvParams->datasetLocation.empty()) { + return 0; + } + WMSLayer *myWMSLayer = new WMSLayer(); + myWMSLayer->layer = dataSource->cfgLayer; + myWMSLayer->srvParams = dataSource->srvParams; + myWMSLayer->dataSource = dataSource; + populateMyWMSLayerStruct(myWMSLayer, false); + storeMyWMSLayerIntoMetadataDb(myWMSLayer); + delete myWMSLayer; + return 0; +} \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index 9c7e66b3e..052151cb7 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -23,4 +23,5 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *layer); int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer); int loadLayerStyleListFromMetadataDb(WMSLayer *layer); +int updateMetaDataTable(CDataSource *dataSource); #endif \ No newline at end of file diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index ec2deec95..725bbd1c2 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -6,7 +6,8 @@ #include #include "LayerUtils.h" -int populateMyWMSLayerStruct(WMSLayer *myWMSLayer) { +int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { + myWMSLayer->readFromDb = readFromDB; // Make the layer name CT::string layerUniqueName; if (makeUniqueLayerName(&layerUniqueName, myWMSLayer->layer) != 0) { @@ -56,29 +57,39 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer) { myWMSLayer->hasError = 1; return 1; } - myWMSLayer->dataSource->addStep(myWMSLayer->fileName.c_str(), NULL); + if (myWMSLayer->dataSource->timeSteps.size() == 0) { + myWMSLayer->dataSource->addStep(myWMSLayer->fileName.c_str(), NULL); + } // CDBDebug("Filename for layer is %s / %s", myWMSLayer->fileName.c_str(), myWMSLayer->dataSource->getFileName()); - status = getTitleForLayer(myWMSLayer); - if (status != 0) { + // CDBDebug("getTitleForLayer"); + if (getTitleForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; return 1; } + + // CDBDebug("getDimsForLayer"); if (getDimsForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; return 1; } + // CDBDebug("getProjectionInformationForLayer"); if (getProjectionInformationForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; return 1; } + + // CDBDebug("getStylesForLayer"); if (getStylesForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; return 1; } + std::sort(myWMSLayer->layerMetadata.projectionList.begin(), myWMSLayer->layerMetadata.projectionList.end(), compareProjection); + std::sort(myWMSLayer->layerMetadata.dimList.begin(), myWMSLayer->layerMetadata.dimList.end(), compareDim); + std::sort(myWMSLayer->layerMetadata.styleList.begin(), myWMSLayer->layerMetadata.styleList.end(), compareStyle); return 0; } @@ -94,7 +105,7 @@ int getDimsForLayer(WMSLayer *myWMSLayer) { // Dimensions if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { if (loadLayerDimensionListFromMetadataDb(myWMSLayer) == 0) { - // CDBDebug("LayerMetadata: dimensionList information fetched!"); + CDBDebug("LayerMetadata: dimensionList information fetched!"); return 0; } @@ -510,8 +521,10 @@ int getProjectionInformationForLayer(WMSLayer *myWMSLayer) { } if (loadLayerProjectionAndExtentListFromMetadataDb(myWMSLayer) == 0) { - // CDBDebug("LayerMetadata: Proj information fetched!"); - return 0; + if (loadLayerMetadataStructFromMetadataDb(myWMSLayer) == 0) { + // CDBDebug("LayerMetadata: Proj information fetched!"); + return 0; + } } CGeoParams geo; @@ -642,6 +655,10 @@ int getStylesForLayer(WMSLayer *myWMSLayer) { bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) <= 0; } +bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } +bool compareDim(const LayerMetadataDim *p1, const LayerMetadataDim *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } +bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } + int getTitleForLayer(WMSLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getTitleForLayer"); diff --git a/adagucserverEC/utils/XMLGenUtils.h b/adagucserverEC/utils/XMLGenUtils.h index 3db9ffd90..ee5c4fa43 100644 --- a/adagucserverEC/utils/XMLGenUtils.h +++ b/adagucserverEC/utils/XMLGenUtils.h @@ -7,7 +7,10 @@ int getProjectionInformationForLayer(WMSLayer *myWMSLayer); int getDimsForLayer(WMSLayer *myWMSLayer); int getStylesForLayer(WMSLayer *myWMSLayer); bool compareStringCase(const std::string &s1, const std::string &s2); -int populateMyWMSLayerStruct(WMSLayer *myWMSLayer); +bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2); +bool compareDim(const LayerMetadataDim *p1, const LayerMetadataDim *p2); +bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2); +int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDb); int getTitleForLayer(WMSLayer *myWMSLayer); int getFileNameForLayer(WMSLayer *myWMSLayer); #endif \ No newline at end of file From a1d8ec3183147f8c0e718d3aa95323bab248212e Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 5 Sep 2024 16:11:14 +0200 Subject: [PATCH 08/50] Tests without store do work --- adagucserverEC/utils/XMLGenUtils.cpp | 4 +- ..._reference_timesupport_GetCapabilities.xml | 96 +- ...cessor_SubstractLevels_GetCapabilities.xml | 100 +-- .../test_GeoJSON_time_GetCapabilities.xml | 52 +- .../test_WCSDescribeCoverage_testdatanc.xml | 234 ++--- .../test_WCSGetCapabilities_testdatanc | 15 +- .../testWMSGetCapabilities_quantizehigh.xml | 52 +- .../testWMSGetCapabilities_quantizelow.xml | 52 +- .../testWMSGetCapabilities_quantizeround.xml | 52 +- ...eDBPathFileInSubfoldersGetCapabilities.xml | 52 +- ...test_WMSGetCapabilities_DimensionUnits.xml | 56 +- ...ities_KMDS_PointNetCDF_pointstylepoint.xml | 828 +++++++++--------- ...MSGetCapabilities_multidimnc_autostyle.xml | 62 +- ...pabilities_multidimncdataset_autostyle.xml | 62 +- ...n_existing_dataset_misconfigured_layer.xml | 60 +- .../test_WMSGetCapabilities_testdatanc | 60 +- ...MSGetCapabilities_testdatanc_autostyle.xml | 60 +- ...bilities_timeseries_path_netcdf_5dims_seq1 | 62 +- ...bilities_timeseries_path_netcdf_5dims_seq2 | 62 +- ...ties_timeseries_tailpath_netcdf_5dims_seq1 | 62 +- ...series_tailpath_netcdf_5dims_seq1_and_seq2 | 62 +- ...est_WMSGetCapabilities_timeseries_twofiles | 62 +- ...tlon_nextdimensionstep_getcapabilities.xml | 56 +- ...tlon_nextdimensionstep_getcapabilities.xml | 56 +- .../TestWMS/test_WMSGetMap_Report_nounits | 2 +- ...ties_timeseries_tailpath_netcdf_5dims_seq1 | 62 +- ...series_tailpath_netcdf_5dims_seq1_and_seq2 | 62 +- ...est_WMSGetCapabilities_timeseries_twofiles | 62 +- .../test_WMSGetMap_testdatanc_NOSLDURL.xml | 2 +- ..._WMSGetCapabilities_TimeHeightProfiles.xml | 54 +- ...bilities_timeheightprofiles_as_dataset.xml | 56 +- .../test_WMSGetCapabilities_testdatanc.xml | 60 +- .../test_WMSGetCapabilities_VolScan.xml | 194 ++-- 33 files changed, 1436 insertions(+), 1437 deletions(-) diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 725bbd1c2..a9071e594 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -656,8 +656,8 @@ int getStylesForLayer(WMSLayer *myWMSLayer) { bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) <= 0; } bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } -bool compareDim(const LayerMetadataDim *p1, const LayerMetadataDim *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } -bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } +bool compareDim(const LayerMetadataDim *p2, const LayerMetadataDim *p1) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } +bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2) { return strcmp(p2->name.c_str(), p1->name.c_str()) <= 0; } int getTitleForLayer(WMSLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG diff --git a/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml b/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml index 22fc6d9fb..93dda7fce 100644 --- a/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml +++ b/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.testCSVReader_reference_time +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - wind Wind @@ -102,26 +102,26 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - -2018-12-04T12:00:00Z,2018-12-04T12:05:00Z 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z,2018-12-04T12:10:00Z - +2018-12-04T12:00:00Z,2018-12-04T12:05:00Z + index Index @@ -130,25 +130,25 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - -2018-12-04T12:00:00Z,2018-12-04T12:05:00Z 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z,2018-12-04T12:10:00Z +2018-12-04T12:00:00Z,2018-12-04T12:05:00Z name @@ -158,25 +158,25 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - -2018-12-04T12:00:00Z,2018-12-04T12:05:00Z 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z,2018-12-04T12:10:00Z +2018-12-04T12:00:00Z,2018-12-04T12:05:00Z diff --git a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml index 23484e182..ce75c0068 100644 --- a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml +++ b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.tests.datapostproc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - output Data at height 2000 minus data at height 8000 @@ -104,27 +104,27 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 - + RAD_NL25_PCP_CM Precipitation Radar NL @@ -133,23 +133,23 @@ 10.856452 48.895303 55.973600 - + + + + + + + + - - - - - - - + - 2021-06-22T20:00:00Z @@ -161,25 +161,25 @@ 32.676474 37.353267 65.888228 - + + + + + + + + + - - - - - - - + - - - + diff --git a/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml b/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml index fca9b7376..852fac8b0 100644 --- a/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml +++ b/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.testGeoJSONReader_time +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - features Features @@ -102,23 +102,23 @@ 30.937500 43.580391 50.064192 - + + + + + + + + - - - - - - - + - 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z,2018-12-04T12:10:00Z diff --git a/tests/expectedoutputs/TestWCS/test_WCSDescribeCoverage_testdatanc.xml b/tests/expectedoutputs/TestWCS/test_WCSDescribeCoverage_testdatanc.xml index c91bb3dc1..c4485c4ef 100644 --- a/tests/expectedoutputs/TestWCS/test_WCSDescribeCoverage_testdatanc.xml +++ b/tests/expectedoutputs/TestWCS/test_WCSDescribeCoverage_testdatanc.xml @@ -18,6 +18,30 @@ + + -68.275833 12.130000 + 7.149322 55.399166 + + + -9906758.676129 1341055.638469 + 951836.432640 8605856.308089 + + + -11426227.343341 1341612.511753 + 382800.244818 9034799.679759 + + + -8805606.109966 -4164572.069133 + 372143.463211 3233625.747402 + + + -13588402.263697 1423498.626368 + -747816.881762 12453122.100930 + + + -7498001.230434 -8223848.076474 + 3272454.133168 535002.459267 + -3942117.046146 -9975996.132113 7877215.337643 -2369697.552660 @@ -34,6 +58,10 @@ -7600430.977505 1360506.839359 795858.888223 7439724.721958 + + -9555333.229813 -10285561.445145 + 1280134.942825 -1473840.584239 + -68.275833 12.130000 7.149322 55.399166 @@ -42,26 +70,6 @@ -68.275833 12.130000 7.149322 55.399166 - - -68.275833 12.130000 - 7.149322 55.399166 - - - -9906758.676129 1341055.638469 - 951836.432640 8605856.308089 - - - -11426227.343341 1341612.511753 - 382800.244818 9034799.679759 - - - -8805606.109966 -4164572.069133 - 372143.463211 3233625.747402 - - - -6748084.942175 1495513.911739 - 706607.743114 6426594.553880 - -2000000.000000 -2000000.000000 10000000.000000 8500000.000000 @@ -70,22 +78,14 @@ -6408021.286199 1297326.829390 670998.883042 5878649.483190 - - -7498001.230434 -8223848.076474 - 3272454.133168 535002.459267 - - - -9555333.229813 -10285561.445145 - 1280134.942825 -1473840.584239 + + -6748084.942175 1495513.911739 + 706607.743114 6426594.553880 -7600430.977505 1360506.839359 795858.888223 7439724.721958 - - -13588402.263697 1423498.626368 - -747816.881762 12453122.100930 - @@ -122,23 +122,23 @@ + CRS:84 + EPSG:25831 + EPSG:25832 + EPSG:28992 + EPSG:3067 + EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 + EPSG:40000 EPSG:4258 EPSG:4326 - CRS:84 - EPSG:25831 - EPSG:25832 - EPSG:28992 - EPSG:7399 EPSG:50001 EPSG:54030 - EPSG:32661 - EPSG:40000 + EPSG:7399 EPSG:900913 - EPSG:3067 @@ -165,6 +165,30 @@ + + -68.275833 12.130000 + 7.149322 55.399166 + + + -9906758.676129 1341055.638469 + 951836.432640 8605856.308089 + + + -11426227.343341 1341612.511753 + 382800.244818 9034799.679759 + + + -8805606.109966 -4164572.069133 + 372143.463211 3233625.747402 + + + -13588402.263697 1423498.626368 + -747816.881762 12453122.100930 + + + -7498001.230434 -8223848.076474 + 3272454.133168 535002.459267 + -3942117.046146 -9975996.132113 7877215.337643 -2369697.552660 @@ -181,6 +205,10 @@ -7600430.977505 1360506.839359 795858.888223 7439724.721958 + + -9555333.229813 -10285561.445145 + 1280134.942825 -1473840.584239 + -68.275833 12.130000 7.149322 55.399166 @@ -189,26 +217,6 @@ -68.275833 12.130000 7.149322 55.399166 - - -68.275833 12.130000 - 7.149322 55.399166 - - - -9906758.676129 1341055.638469 - 951836.432640 8605856.308089 - - - -11426227.343341 1341612.511753 - 382800.244818 9034799.679759 - - - -8805606.109966 -4164572.069133 - 372143.463211 3233625.747402 - - - -6748084.942175 1495513.911739 - 706607.743114 6426594.553880 - -2000000.000000 -2000000.000000 10000000.000000 8500000.000000 @@ -217,22 +225,14 @@ -6408021.286199 1297326.829390 670998.883042 5878649.483190 - - -7498001.230434 -8223848.076474 - 3272454.133168 535002.459267 - - - -9555333.229813 -10285561.445145 - 1280134.942825 -1473840.584239 + + -6748084.942175 1495513.911739 + 706607.743114 6426594.553880 -7600430.977505 1360506.839359 795858.888223 7439724.721958 - - -13588402.263697 1423498.626368 - -747816.881762 12453122.100930 - @@ -269,23 +269,23 @@ + CRS:84 + EPSG:25831 + EPSG:25832 + EPSG:28992 + EPSG:3067 + EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 + EPSG:40000 EPSG:4258 EPSG:4326 - CRS:84 - EPSG:25831 - EPSG:25832 - EPSG:28992 - EPSG:7399 EPSG:50001 EPSG:54030 - EPSG:32661 - EPSG:40000 + EPSG:7399 EPSG:900913 - EPSG:3067 @@ -312,6 +312,30 @@ + + -68.275833 12.130000 + 7.149322 55.399166 + + + -9906758.676129 1341055.638469 + 951836.432640 8605856.308089 + + + -11426227.343341 1341612.511753 + 382800.244818 9034799.679759 + + + -8805606.109966 -4164572.069133 + 372143.463211 3233625.747402 + + + -13588402.263697 1423498.626368 + -747816.881762 12453122.100930 + + + -7498001.230434 -8223848.076474 + 3272454.133168 535002.459267 + -3942117.046146 -9975996.132113 7877215.337643 -2369697.552660 @@ -328,6 +352,10 @@ -7600430.977505 1360506.839359 795858.888223 7439724.721958 + + -9555333.229813 -10285561.445145 + 1280134.942825 -1473840.584239 + -68.275833 12.130000 7.149322 55.399166 @@ -336,26 +364,6 @@ -68.275833 12.130000 7.149322 55.399166 - - -68.275833 12.130000 - 7.149322 55.399166 - - - -9906758.676129 1341055.638469 - 951836.432640 8605856.308089 - - - -11426227.343341 1341612.511753 - 382800.244818 9034799.679759 - - - -8805606.109966 -4164572.069133 - 372143.463211 3233625.747402 - - - -6748084.942175 1495513.911739 - 706607.743114 6426594.553880 - -2000000.000000 -2000000.000000 10000000.000000 8500000.000000 @@ -364,22 +372,14 @@ -6408021.286199 1297326.829390 670998.883042 5878649.483190 - - -7498001.230434 -8223848.076474 - 3272454.133168 535002.459267 - - - -9555333.229813 -10285561.445145 - 1280134.942825 -1473840.584239 + + -6748084.942175 1495513.911739 + 706607.743114 6426594.553880 -7600430.977505 1360506.839359 795858.888223 7439724.721958 - - -13588402.263697 1423498.626368 - -747816.881762 12453122.100930 - @@ -416,23 +416,23 @@ + CRS:84 + EPSG:25831 + EPSG:25832 + EPSG:28992 + EPSG:3067 + EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 + EPSG:40000 EPSG:4258 EPSG:4326 - CRS:84 - EPSG:25831 - EPSG:25832 - EPSG:28992 - EPSG:7399 EPSG:50001 EPSG:54030 - EPSG:32661 - EPSG:40000 + EPSG:7399 EPSG:900913 - EPSG:3067 diff --git a/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc b/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc index c061dc34e..62bac775f 100644 --- a/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc +++ b/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc @@ -1,17 +1,17 @@ ADAGUC_AUTO_WCS_AutoResource testdata.nc ADAGUC_AUTO_WCS_AutoResource testdata.nc - ADAGUCServer version 2.5.13, of Sep 1 2021 15:34:53 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 NONE NONE @@ -60,8 +60,7 @@ application/vnd.ogc.se_xml - - + testdata testdata diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml index 935cc6f36..0dfad5ee2 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.tests.quantizehigh +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - wind Wind @@ -102,23 +102,23 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - 2018-12-04T12:10:00Z/2018-12-04T13:00:00Z/PT10M diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml index 4925c4050..498ad7954 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.tests.quantizelow +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - wind Wind @@ -102,23 +102,23 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - 2018-12-04T12:00:00Z,2018-12-04T12:10:00Z,2018-12-04T12:20:00Z,2018-12-04T12:40:00Z diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml index d23596997..466d78933 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.tests.quantizeround +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - wind Wind @@ -102,23 +102,23 @@ 0.250000 47.099998 49.099998 - + + + + + + + + - - - - - - - + - 2018-12-04T12:00:00Z/2018-12-04T12:40:00Z/PT10M diff --git a/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml index e0e198f45..f169e8483 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,41 +60,41 @@ WMS of adaguc.testScanPathSubfolder +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 PROJ4:%2Bproj%3Dstere%20%2Blat_0%3D90%20%2Blon_0%3D0%20%2Blat_ts%3D60%20%2Ba%3D6378%2E14%20%2Bb%3D6356%2E75%20%2Bx_0%3D0%20y_0%3D0 + + + + + + + - - - - - - - + - RAD_NL25_PCP_CM @@ -104,23 +104,23 @@ 10.856452 48.895303 55.973600 - + + + + + + + + - - - - - - - + - 2021-06-22T20:00:00Z diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml index 548f9701e..636838685 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,41 +60,41 @@ WMS of adaguc.tests.311-getcapabilities-dimension-units +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs + + + + + + + - - - - - - - + - wind-speed-of-gust-hagl @@ -104,28 +104,28 @@ 1.050000 48.950000 49.650000 - + + + + + + + + - - - - - - - + - 2023-10-26T05:00:00Z -10 2023-10-26T00:00:00Z - +10 + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml index f297fb09d..d05b4c72c 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of adaguc.testKMDS_PointNetCDF +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - stationname stationsnaam @@ -103,23 +103,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - height @@ -130,23 +130,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - dd @@ -157,23 +157,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -185,23 +185,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -213,25 +213,25 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z - + gff windstoten [m/s] @@ -241,23 +241,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -269,23 +269,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -297,23 +297,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -325,23 +325,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -353,23 +353,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -381,23 +381,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -409,23 +409,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -437,23 +437,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -465,23 +465,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -493,23 +493,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -521,23 +521,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -549,23 +549,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -577,23 +577,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -605,23 +605,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -633,23 +633,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -661,23 +661,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -689,23 +689,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -717,23 +717,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -745,23 +745,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -773,23 +773,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -801,23 +801,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -829,23 +829,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -857,23 +857,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -885,23 +885,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -913,23 +913,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -941,23 +941,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -969,23 +969,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -997,23 +997,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1025,23 +1025,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1053,23 +1053,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1081,23 +1081,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1109,23 +1109,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1137,23 +1137,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1165,23 +1165,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1193,23 +1193,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1221,23 +1221,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1249,23 +1249,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z @@ -1277,23 +1277,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z/2020-12-20T12:40:00Z/PT5M @@ -1307,23 +1307,23 @@ 7.149322 12.130000 55.399166 - + + + + + + + + - - - - - - - + - 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml index e9ee872ea..b8f8c8b26 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of AutoResource nc_5D_20170101000000-20170101001000.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - @@ -108,28 +108,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml index a18e46ace..3d1fc33c2 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.testmultidimautostyle +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml index 0c7e5ff6e..a0e1d90e6 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.23.0, of Jul 9 2024 12:13:41 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.tests.datasetwithmisconfiguredlayer +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:28992 + + + + + + + + - - - - - - - + - - testdata Testdata (testdata) @@ -104,25 +104,25 @@ 32.676474 37.353267 65.888228 - + + + + + + + + + - - - - - - - + - - - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc index a827d01ec..359b92f93 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.21.2, of May 24 2024 11:28:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of AutoResource testdata.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:28992 + + + + + + + + - - - - - - - + - - testdata Testdata (testdata) @@ -104,25 +104,25 @@ 32.676474 37.353267 65.888228 - + + + + + + + + + - - - - - - - + - - - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml index 9b40d877b..bdaeb8dd5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.23.0, of Jul 9 2024 12:13:41 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of AutoResource testdata.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:28992 + + + + + + + + - - - - - - - + - - @@ -108,25 +108,25 @@ 32.676474 37.353267 65.888228 - + + + + + + + + + - - - - - - - + - - - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 index c1897beff..5b875a623 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ Root Layer Title +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 index e0b10fd81..7d265dfd5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ Root Layer Title +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index c1897beff..5b875a623 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ Root Layer Title +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index e0b10fd81..7d265dfd5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ Root Layer Title +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles index e1bc5ca51..7d265dfd5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 10:44:15 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ Root Layer Title +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml index cf7638e46..064464824 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.15.0, of Feb 2 2024 11:40:13 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of AutoResource example_file_irregular_1Dlat1Dlon_grid.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - data_var_1 data_var_1 (data_var_1) @@ -102,26 +102,26 @@ 12.000000 48.000000 56.000000 - + + + + + + + + - - - - - - - + - -0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 2017-01-01T00:10:00Z,2017-01-01T00:11:00Z - +0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml index 3aa6b8c1c..559bd420b 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.15.1, of Feb 2 2024 15:50:33 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of AutoResource example_file_irregular_2Dlat2Dlon_grid.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - data_var_1 data_var_1 (data_var_1) @@ -102,26 +102,26 @@ 14.878220 50.047555 68.959048 - + + + + + + + + - - - - - - - + - -0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 2017-01-01T00:10:00Z,2017-01-01T00:11:00Z - +0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetMap_Report_nounits b/tests/expectedoutputs/TestWMS/test_WMSGetMap_Report_nounits index 4ec143a22..7b3167478 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetMap_Report_nounits +++ b/tests/expectedoutputs/TestWMS/test_WMSGetMap_Report_nounits @@ -4,7 +4,7 @@ Content-Type:text/xml No time units found for variable time; - Exception in DBLoopFiles at line -1232049787; + Exception in DBLoopFiles at line 611; *** SKIPPING FILE /home/plieger/code/github/KNMI/adaguc-server/data/datasets/test/testdata_report_nounits.nc ***; Invalid dimensions values: No data available for layer sow_a1; WMS GetMap Request failed; diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index 0aaa4199b..00f4f3915 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.testtimeseriescached +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z - + diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index 2eb51242e..03b236df6 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.testtimeseriescached +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles index 2eb51242e..03b236df6 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 4 2024 12:10:25 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.testtimeseriescached +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 +EPSG:4326 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:4326 + + + + + + + + - - - - - - - + - - data data (data) @@ -104,28 +104,28 @@ 179.505554 -90.488892 89.511108 - + + + + + + + + + - - - - - - - + - - +2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 -2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M - + diff --git a/tests/expectedoutputs/TestWMSSLD/test_WMSGetMap_testdatanc_NOSLDURL.xml b/tests/expectedoutputs/TestWMSSLD/test_WMSGetMap_testdatanc_NOSLDURL.xml index 81ff2237d..0fe988b28 100644 --- a/tests/expectedoutputs/TestWMSSLD/test_WMSGetMap_testdatanc_NOSLDURL.xml +++ b/tests/expectedoutputs/TestWMSSLD/test_WMSGetMap_testdatanc_NOSLDURL.xml @@ -1 +1 @@ -SLD parameter value needs to be a url pointed to a .xml file \ No newline at end of file +Unable to read configuration file. diff --git a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml index a0c27f990..51d3dabfe 100644 --- a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml +++ b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.14.0, of Dec 15 2023 15:44:55 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of CHM15k Nimbus +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - beta_raw normalized range corrected signal @@ -104,25 +104,25 @@ with P_raw = sum(P_raw_hr) * range_gate_hr / range_gate (beta_raw) 4.095820 50.941341 51.941341 - + + + + + + + + - - - - - - - + - 2023-12-02T06:40:00Z - + diff --git a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml index 242f468e9..95cadacf3 100644 --- a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml +++ b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.14.1, of Dec 18 2023 11:19:06 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of adaguc.tests.timeheightprofiles -GFI:TIME_ELEVATION +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 - +GFI:TIME_ELEVATION + + + + + + + - - - - - - - + - + beta_raw ceilonet 06310 eprofile @@ -104,24 +104,24 @@ 4.095820 50.941341 51.941341 - + + + + + + + - - - - - - - + - + 2023-12-02T06:40:00Z diff --git a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml index 90a58a962..359b92f93 100644 --- a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml +++ b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,42 +60,42 @@ WMS of AutoResource testdata.nc +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 -EPSG:28992 + + + + + + + + - - - - - - - + - - testdata Testdata (testdata) @@ -104,25 +104,25 @@ 32.676474 37.353267 65.888228 - + + + + + + + + + - - - - - - - + - - - + diff --git a/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml b/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml index 941e87d45..e5b3255a6 100644 --- a/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml +++ b/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.13.7, of Nov 1 2023 11:45:57 + ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 @@ -60,40 +60,40 @@ WMS of AutoResource RAD_NL62_VOL_NA_202106181850.h5 +CRS:84 +EPSG:25831 +EPSG:25832 +EPSG:28992 +EPSG:3067 +EPSG:32661 EPSG:3411 EPSG:3412 EPSG:3575 EPSG:3857 +EPSG:40000 EPSG:4258 EPSG:4326 -CRS:84 -EPSG:25831 -EPSG:25832 -EPSG:28992 -EPSG:7399 EPSG:50001 EPSG:54030 -EPSG:32661 -EPSG:40000 +EPSG:7399 EPSG:900913 -EPSG:3067 + + + + + + + - - - - - - - + - KDP KDP (KDP) @@ -102,26 +102,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + PhiDP PhiDP (PhiDP) @@ -130,26 +130,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + RhoHV RhoHV (RhoHV) @@ -158,26 +158,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + V V (V) @@ -186,26 +186,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + W W (W) @@ -214,26 +214,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + Z Z (Z) @@ -242,26 +242,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + Zv Zv (Zv) @@ -270,26 +270,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + ZDR ZDR (ZDR) @@ -298,26 +298,26 @@ 10.000000 48.000000 58.000000 - + + + + + + + + - - - - - - - + - 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + From 79d71d58f4b51fb8a6debbb02c38a8212224de9c Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 5 Sep 2024 17:21:18 +0200 Subject: [PATCH 09/50] Tests succeed --- adagucserverEC/utils/XMLGenUtils.cpp | 11 +++++++++++ ...aPostProcessor_SubstractLevels_GetCapabilities.xml | 4 ---- .../test_WMSGetCapabilities_multidimnc_autostyle.xml | 3 --- ...WMSGetCapabilities_multidimncdataset_autostyle.xml | 3 --- ..._error_on_existing_dataset_misconfigured_layer.xml | 3 --- .../TestWMS/test_WMSGetCapabilities_testdatanc | 3 --- .../test_WMSGetCapabilities_testdatanc_autostyle.xml | 3 --- ...SGetCapabilities_timeseries_path_netcdf_5dims_seq1 | 3 --- ...SGetCapabilities_timeseries_path_netcdf_5dims_seq2 | 3 --- ...Capabilities_timeseries_tailpath_netcdf_5dims_seq1 | 3 --- ...ies_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 | 3 --- .../test_WMSGetCapabilities_timeseries_twofiles | 3 --- ...Capabilities_timeseries_tailpath_netcdf_5dims_seq1 | 3 --- ...ies_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 | 3 --- .../test_WMSGetCapabilities_timeseries_twofiles | 3 --- .../test_WMSGetCapabilities_testdatanc.xml | 3 --- 16 files changed, 11 insertions(+), 46 deletions(-) diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index a9071e594..4d3cab6c9 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -87,9 +87,20 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { return 1; } + std::map map; + + for (auto p : myWMSLayer->layerMetadata.projectionList) { + map[p->name.c_str()] = p; + } + myWMSLayer->layerMetadata.projectionList.clear(); + for (auto p : map) { + myWMSLayer->layerMetadata.projectionList.push_back(p.second); + } + std::sort(myWMSLayer->layerMetadata.projectionList.begin(), myWMSLayer->layerMetadata.projectionList.end(), compareProjection); std::sort(myWMSLayer->layerMetadata.dimList.begin(), myWMSLayer->layerMetadata.dimList.end(), compareDim); std::sort(myWMSLayer->layerMetadata.styleList.begin(), myWMSLayer->layerMetadata.styleList.end(), compareStyle); + return 0; } diff --git a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml index ce75c0068..e717fe979 100644 --- a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml +++ b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - @@ -164,7 +161,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml index b8f8c8b26..10a1fe138 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -121,7 +119,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml index 3d1fc33c2..da9c081a5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml index a0e1d90e6..bc1dc16e5 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml @@ -64,7 +64,6 @@ EPSG:25831 EPSG:25832 EPSG:28992 -EPSG:28992 EPSG:3067 EPSG:32661 EPSG:3411 @@ -81,7 +80,6 @@ - @@ -107,7 +105,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc index 359b92f93..cd363004d 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc @@ -64,7 +64,6 @@ EPSG:25831 EPSG:25832 EPSG:28992 -EPSG:28992 EPSG:3067 EPSG:32661 EPSG:3411 @@ -81,7 +80,6 @@ - @@ -107,7 +105,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml index bdaeb8dd5..552f58f54 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml @@ -64,7 +64,6 @@ EPSG:25831 EPSG:25832 EPSG:28992 -EPSG:28992 EPSG:3067 EPSG:32661 EPSG:3411 @@ -81,7 +80,6 @@ - @@ -111,7 +109,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 index 5b875a623..c45fcca26 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 index 7d265dfd5..e5262ef07 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index 5b875a623..c45fcca26 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index 7d265dfd5..e5262ef07 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles index 7d265dfd5..e5262ef07 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index 00f4f3915..a2abb0793 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index 03b236df6..637d1ad7e 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles index 03b236df6..637d1ad7e 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles @@ -73,7 +73,6 @@ EPSG:40000 EPSG:4258 EPSG:4326 -EPSG:4326 EPSG:50001 EPSG:54030 EPSG:7399 @@ -91,7 +90,6 @@ - @@ -117,7 +115,6 @@ - diff --git a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml index 359b92f93..cd363004d 100644 --- a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml +++ b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml @@ -64,7 +64,6 @@ EPSG:25831 EPSG:25832 EPSG:28992 -EPSG:28992 EPSG:3067 EPSG:32661 EPSG:3411 @@ -81,7 +80,6 @@ - @@ -107,7 +105,6 @@ - From da373cc20239f805abe9bd38d202d846e52920f3 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 6 Sep 2024 09:57:11 +0200 Subject: [PATCH 10/50] Stylelist is ordered as before --- adagucserverEC/utils/LayerMetadataStore.cpp | 10 +++++----- adagucserverEC/utils/XMLGenUtils.cpp | 9 ++++----- ...V_reference_timesupport_GetCapabilities.xml | 4 ++-- ...ocessor_SubstractLevels_GetCapabilities.xml | 6 +++--- .../test_GeoJSON_time_GetCapabilities.xml | 2 +- .../TestWCS/test_WCSGetCapabilities_testdatanc | 2 +- .../testWMSGetCapabilities_quantizehigh.xml | 2 +- .../testWMSGetCapabilities_quantizelow.xml | 2 +- .../testWMSGetCapabilities_quantizeround.xml | 2 +- ...teDBPathFileInSubfoldersGetCapabilities.xml | 2 +- .../test_WMSGetCapabilities_DimensionUnits.xml | 4 ++-- ...lities_KMDS_PointNetCDF_pointstylepoint.xml | 4 ++-- ...WMSGetCapabilities_multidimnc_autostyle.xml | 4 ++-- ...apabilities_multidimncdataset_autostyle.xml | 4 ++-- ...on_existing_dataset_misconfigured_layer.xml | 4 ++-- .../TestWMS/test_WMSGetCapabilities_testdatanc | 4 ++-- ...WMSGetCapabilities_testdatanc_autostyle.xml | 4 ++-- ...abilities_timeseries_path_netcdf_5dims_seq1 | 4 ++-- ...abilities_timeseries_path_netcdf_5dims_seq2 | 4 ++-- ...ities_timeseries_tailpath_netcdf_5dims_seq1 | 4 ++-- ...eseries_tailpath_netcdf_5dims_seq1_and_seq2 | 4 ++-- ...test_WMSGetCapabilities_timeseries_twofiles | 4 ++-- ...atlon_nextdimensionstep_getcapabilities.xml | 4 ++-- ...atlon_nextdimensionstep_getcapabilities.xml | 4 ++-- ...ities_timeseries_tailpath_netcdf_5dims_seq1 | 4 ++-- ...eseries_tailpath_netcdf_5dims_seq1_and_seq2 | 4 ++-- ...test_WMSGetCapabilities_timeseries_twofiles | 4 ++-- ...t_WMSGetCapabilities_TimeHeightProfiles.xml | 4 ++-- ...abilities_timeheightprofiles_as_dataset.xml | 2 +- .../test_WMSGetCapabilities_testdatanc.xml | 4 ++-- .../test_WMSGetCapabilities_VolScan.xml | 18 +++++++++--------- 31 files changed, 68 insertions(+), 69 deletions(-) diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index c8adb8d9a..bf29a55f1 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -140,7 +140,8 @@ int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer) { json item; item["abstract"] = style->abstract.c_str(); item["title"] = style->title.c_str(); - styleListJson[style->name.c_str()] = item; + item["name"] = style->name.c_str(); + styleListJson.push_back(item); } storeLayerMetadataInDb(myWMSLayer, "stylelist", styleListJson.dump()); } catch (int e) { @@ -171,12 +172,11 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { json a; auto c = a.parse(styleListAsJson.c_str()); - for (auto d : c.items()) { - auto styleProperties = d.value(); - + for (auto styleJson : c.items()) { + auto styleProperties = styleJson.value(); LayerMetadataStyle *style = new LayerMetadataStyle(); myWMSLayer->layerMetadata.styleList.push_back(style); - style->name = d.key().c_str(); + style->name = styleProperties["name"].get().c_str(); style->abstract = styleProperties["abstract"].get().c_str(); style->title = styleProperties["title"].get().c_str(); } diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 4d3cab6c9..388edebb3 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -87,19 +87,18 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { return 1; } - std::map map; - + std::map projectionMap; + // Make a unique list of projections for (auto p : myWMSLayer->layerMetadata.projectionList) { - map[p->name.c_str()] = p; + projectionMap[p->name.c_str()] = p; } myWMSLayer->layerMetadata.projectionList.clear(); - for (auto p : map) { + for (auto p : projectionMap) { myWMSLayer->layerMetadata.projectionList.push_back(p.second); } std::sort(myWMSLayer->layerMetadata.projectionList.begin(), myWMSLayer->layerMetadata.projectionList.end(), compareProjection); std::sort(myWMSLayer->layerMetadata.dimList.begin(), myWMSLayer->layerMetadata.dimList.end(), compareDim); - std::sort(myWMSLayer->layerMetadata.styleList.begin(), myWMSLayer->layerMetadata.styleList.end(), compareStyle); return 0; } diff --git a/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml b/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml index 93dda7fce..f87330b2d 100644 --- a/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml +++ b/tests/expectedoutputs/TestCSV/test_CSV_reference_timesupport_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -121,7 +121,7 @@ 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z,2018-12-04T12:10:00Z 2018-12-04T12:00:00Z,2018-12-04T12:05:00Z - + index Index diff --git a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml index e717fe979..bc63631be 100644 --- a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml +++ b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -121,7 +121,7 @@ 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 - + RAD_NL25_PCP_CM Precipitation Radar NL @@ -175,7 +175,7 @@ - + diff --git a/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml b/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml index 852fac8b0..dee1dbdf5 100644 --- a/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml +++ b/tests/expectedoutputs/TestGeoJSON/test_GeoJSON_time_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc b/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc index 62bac775f..8dd6b5097 100644 --- a/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc +++ b/tests/expectedoutputs/TestWCS/test_WCSGetCapabilities_testdatanc @@ -11,7 +11,7 @@ ADAGUC_AUTO_WCS_AutoResource testdata.nc ADAGUC_AUTO_WCS_AutoResource testdata.nc - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 NONE NONE diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml index 0dfad5ee2..d7eac1e62 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizehigh.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml index 498ad7954..ee01e12cb 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizelow.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml index 466d78933..9d1313854 100644 --- a/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml +++ b/tests/expectedoutputs/TestWMS/testWMSGetCapabilities_quantizeround.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml index f169e8483..e5f44bbfd 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSCMDUpdateDBPathFileInSubfoldersGetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml index 636838685..08591ef6f 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_DimensionUnits.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -125,7 +125,7 @@ 2023-10-26T05:00:00Z 2023-10-26T00:00:00Z 10 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml index d05b4c72c..ec94e9a50 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -231,7 +231,7 @@ 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z - + gff windstoten [m/s] diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml index 10a1fe138..046f659cc 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimnc_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -126,7 +126,7 @@ 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml index da9c081a5..ea7de9dce 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_multidimncdataset_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml index bc1dc16e5..35e667c95 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_no_error_on_existing_dataset_misconfigured_layer.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -119,7 +119,7 @@ - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc index cd363004d..108f30c44 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -119,7 +119,7 @@ - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml index 552f58f54..e82212dfa 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_testdatanc_autostyle.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -123,7 +123,7 @@ - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 index c45fcca26..531a205f0 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 index e5262ef07..ec94f7e58 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_path_netcdf_5dims_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index c45fcca26..531a205f0 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index e5262ef07..ec94f7e58 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles index e5262ef07..ec94f7e58 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml index 064464824..b4395479d 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_1Dimensional_latlon_nextdimensionstep_getcapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -121,7 +121,7 @@ 2017-01-01T00:10:00Z,2017-01-01T00:11:00Z 0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 - + diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml index 559bd420b..b6b5c9027 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetMap_IrregularGrid_2Dimensional_latlon_nextdimensionstep_getcapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -121,7 +121,7 @@ 2017-01-01T00:10:00Z,2017-01-01T00:11:00Z 0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 - + diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 index a2abb0793..638c2a235 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z,2017-01-01T00:05:00Z,2017-01-01T00:10:00Z member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 index 637d1ad7e..aade83f8a 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_tailpath_netcdf_5dims_seq1_and_seq2 @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles index 637d1ad7e..aade83f8a 100644 --- a/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles +++ b/tests/expectedoutputs/TestWMSDocumentCache/test_WMSGetCapabilities_timeseries_twofiles @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ 2017-01-01T00:00:00Z/2017-01-01T00:25:00Z/PT5M member6,member5,member4,member3,member2,member1 1000,2000,3000,4000,5000,6000,7000,8000,9000 - + diff --git a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml index 51d3dabfe..ad18800b8 100644 --- a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml +++ b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_WMSGetCapabilities_TimeHeightProfiles.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -122,7 +122,7 @@ with P_raw = sum(P_raw_hr) * range_gate_hr / range_gate (beta_raw) 2023-12-02T06:40:00Z - + diff --git a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml index 95cadacf3..398d9e378 100644 --- a/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml +++ b/tests/expectedoutputs/TestWMSTimeHeightProfiles/test_wmsgetcapabilities_timeheightprofiles_as_dataset.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 diff --git a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml index cd363004d..108f30c44 100644 --- a/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml +++ b/tests/expectedoutputs/TestWMSTimeSeries/test_WMSGetCapabilities_testdatanc.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -119,7 +119,7 @@ - + diff --git a/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml b/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml index e5b3255a6..a9becf451 100644 --- a/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml +++ b/tests/expectedoutputs/TestWMSVolScan/test_WMSGetCapabilities_VolScan.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 5 2024 15:34:21 + ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 @@ -121,7 +121,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + PhiDP PhiDP (PhiDP) @@ -149,7 +149,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + RhoHV RhoHV (RhoHV) @@ -177,7 +177,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + V V (V) @@ -205,7 +205,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + W W (W) @@ -233,7 +233,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + Z Z (Z) @@ -261,7 +261,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + Zv Zv (Zv) @@ -289,7 +289,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + ZDR ZDR (ZDR) @@ -317,7 +317,7 @@ 2021-06-18T18:50:00Z 0.3,0.3l,0.8,1.2,2,2.8,4,6,8 - + From 38319b789fafd5a3371ac6042d0e64e6c40e4c28 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 6 Sep 2024 10:16:34 +0200 Subject: [PATCH 11/50] enablemetadatacache can be enabled/disabled via the settings --- adagucserverEC/CServerConfig_CPPXSD.h | 7 +++++-- adagucserverEC/CServerParams.cpp | 11 +++++++++++ adagucserverEC/CServerParams.h | 2 ++ adagucserverEC/utils/LayerMetadataStore.cpp | 2 +- adagucserverEC/utils/XMLGenUtils.cpp | 4 ++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/adagucserverEC/CServerConfig_CPPXSD.h b/adagucserverEC/CServerConfig_CPPXSD.h index e0f51837b..18936c30d 100644 --- a/adagucserverEC/CServerConfig_CPPXSD.h +++ b/adagucserverEC/CServerConfig_CPPXSD.h @@ -1300,10 +1300,13 @@ class CServerConfig : public CXMLSerializerInterface { public: class Cattr { public: - CT::string enablecleanupsystem, cleanupsystemlimit, cache_age_cacheableresources, cache_age_volatileresources; + CT::string enablemetadatacache, enablecleanupsystem, cleanupsystemlimit, cache_age_cacheableresources, cache_age_volatileresources; } attr; void addAttribute(const char *attrname, const char *attrvalue) { - if (equals("enablecleanupsystem", attrname)) { + if (equals("enablemetadatacache", attrname)) { + attr.enablemetadatacache.copy(attrvalue); + return; + } else if (equals("enablecleanupsystem", attrname)) { attr.enablecleanupsystem.copy(attrvalue); return; } else if (equals("cleanupsystemlimit", attrname)) { diff --git a/adagucserverEC/CServerParams.cpp b/adagucserverEC/CServerParams.cpp index ebd535b34..d50958de0 100644 --- a/adagucserverEC/CServerParams.cpp +++ b/adagucserverEC/CServerParams.cpp @@ -684,4 +684,15 @@ std::tuple CServerParams::getLegendFont() { } return std::make_tuple(legendFontSize, legendfontLocation); +} + +bool CServerParams::useMetadataTable() { + size_t numSettings = this->cfg->Settings.size(); + if (numSettings > 0 && this->cfg->Settings[numSettings - 1]) { + auto settings = this->cfg->Settings[numSettings - 1]; + if (!settings->attr.enablemetadatacache.equalsIgnoreCase("true")) { + return false; + } + } + return true; } \ No newline at end of file diff --git a/adagucserverEC/CServerParams.h b/adagucserverEC/CServerParams.h index eed3ffdd2..5fcb49166 100644 --- a/adagucserverEC/CServerParams.h +++ b/adagucserverEC/CServerParams.h @@ -331,6 +331,8 @@ class CServerParams { * Returns the fontsize in px for legend */ std::tuple getLegendFont(); + + bool useMetadataTable(); }; #endif diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index bf29a55f1..587a3df39 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -248,7 +248,7 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { } int updateMetaDataTable(CDataSource *dataSource) { - // return 0; + if (dataSource->srvParams->datasetLocation.empty()) { return 0; } diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 388edebb3..d7cb84bea 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -8,6 +8,10 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { myWMSLayer->readFromDb = readFromDB; + if (!myWMSLayer->srvParams->useMetadataTable()) { + myWMSLayer->readFromDb = false; + } + // Make the layer name CT::string layerUniqueName; if (makeUniqueLayerName(&layerUniqueName, myWMSLayer->layer) != 0) { From 8d2afaeac8ca85a7dd748c6e41c01907b5cb9251 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 6 Sep 2024 10:48:59 +0200 Subject: [PATCH 12/50] Metadatatable enabled by default --- adagucserverEC/CRequest.cpp | 4 ++-- adagucserverEC/CServerParams.cpp | 2 +- adagucserverEC/utils/XMLGenUtils.cpp | 2 +- python/python_fastapi_server/routers/edr_utils.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index 540df9c61..2c2086e1c 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -756,7 +756,7 @@ int CRequest::generateOGCDescribeCoverage(CT::string *XMLdocument) { } int CRequest::process_wms_getcap_request() { - CDBDebug("WMS GETCAPABILITIES"); + CDBDebug("WMS GETCAPABILITIES [%s]", srvParam->datasetLocation.c_str()); CT::string XMLdocument; if (srvParam->enableDocumentCache == true) { @@ -802,7 +802,7 @@ int CRequest::process_wms_getcap_request() { } int CRequest::process_wms_getreferencetimes_request() { - CDBDebug("WMS GETREFERENCETIMES"); + CDBDebug("WMS GETREFERENCETIMES [%s]", srvParam->datasetLocation.c_str()); return process_all_layers(); } diff --git a/adagucserverEC/CServerParams.cpp b/adagucserverEC/CServerParams.cpp index d50958de0..4c74c5166 100644 --- a/adagucserverEC/CServerParams.cpp +++ b/adagucserverEC/CServerParams.cpp @@ -690,7 +690,7 @@ bool CServerParams::useMetadataTable() { size_t numSettings = this->cfg->Settings.size(); if (numSettings > 0 && this->cfg->Settings[numSettings - 1]) { auto settings = this->cfg->Settings[numSettings - 1]; - if (!settings->attr.enablemetadatacache.equalsIgnoreCase("true")) { + if (settings->attr.enablemetadatacache.equalsIgnoreCase("false")) { return false; } } diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index d7cb84bea..c2b2e3b5e 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -119,7 +119,7 @@ int getDimsForLayer(WMSLayer *myWMSLayer) { // Dimensions if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { if (loadLayerDimensionListFromMetadataDb(myWMSLayer) == 0) { - CDBDebug("LayerMetadata: dimensionList information fetched!"); + // CDBDebug("LayerMetadata: dimensionList information fetched!"); return 0; } diff --git a/python/python_fastapi_server/routers/edr_utils.py b/python/python_fastapi_server/routers/edr_utils.py index 7b709875c..1f77219b1 100644 --- a/python/python_fastapi_server/routers/edr_utils.py +++ b/python/python_fastapi_server/routers/edr_utils.py @@ -562,8 +562,8 @@ def get_params_for_collection( ) else: param_metadata = get_param_metadata(param_id, edr_collection) - logger.info(param_id) - logger.info(param_metadata["wms_layer_name"]) + # logger.info(param_id) + # logger.info(param_metadata["wms_layer_name"]) param = Parameter( id=param_metadata["wms_layer_name"], observedProperty=ObservedProperty( From 91e24831d55c26792e3a940efa808b93401103fe Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 6 Sep 2024 13:21:08 +0200 Subject: [PATCH 13/50] Update on conflict is working based on the defaultValue of the time dimension --- Dockerfile | 2 +- NEWS.md | 4 ++++ adagucserverEC/CDBAdapter.h | 2 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 14 ++++++++++---- adagucserverEC/CDBAdapterPostgreSQL.h | 2 +- adagucserverEC/CDBAdapterSQLLite.cpp | 2 +- adagucserverEC/CDBAdapterSQLLite.h | 2 +- adagucserverEC/Definitions.h | 2 +- adagucserverEC/utils/LayerMetadataStore.cpp | 13 ++++++++++++- .../datasets/adaguc.testGeoJSONReader_time.xml | 1 + 10 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2030ae901..72e79ded8 100755 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ USER root LABEL maintainer="adaguc@knmi.nl" # Version should be same as in Definitions.h -LABEL version="2.27.0" +LABEL version="2.28.0" # Try to update image packages RUN apt-get -q -y update \ diff --git a/NEWS.md b/NEWS.md index 6f027f05b..493173c93 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +**Version 2.28.0 2024-09-62** +- Metadata for layer items like the projections, dimensions and styles can now be stored in a metadatatable + + **Version 2.27.0 2024-09-02** - PostgreSQL query from `getFilesAndIndicesForDimensions` has been rewritten, which fixes https://github.com/KNMI/adaguc-server/issues/341. - Optimized existing PostgreSQL queries and reduced number of PostgreSQL queries in general. This results in better performance, the benchmark tool runs 9% faster. diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index f4bf3d9f7..bb745133a 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -97,7 +97,7 @@ class CDBAdapter { /** First use setFile as many times as you whish, second use addFilesToDataBase to make it final*/ virtual int addFilesToDataBase() = 0; - virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; + virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob, const char *updateTime) = 0; virtual CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) = 0; }; diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 16fee6914..99cf3d7e8 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1081,7 +1081,7 @@ int CDBAdapterPostgreSQL::addFilesToDataBase() { return 0; } -int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadataBlob) { +int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadataBlob, const char *updateTime) { #ifdef MEASURETIME StopWatch_Stop(">CDBAdapterPostgreSQL::storeLayerMetadata"); #endif @@ -1091,7 +1091,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char } CT::string query; - CT::string tableColumns("datasetname varchar (255) ,layername varchar (255), metadatakey varchar (255), blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); + CT::string tableColumns("datasetname varchar (255) ,layername varchar (255), metadatakey varchar (255), updatetime varchar (255), blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); int status = dataBaseConnection->checkTable("metadata", tableColumns.c_str()); if (status == 1) { @@ -1099,8 +1099,14 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char throw(__LINE__); } - query.print("INSERT INTO metadata values (E'%s',E'%s', E'%s', E'%s') ON CONFLICT (datasetname, layername, metadatakey) DO UPDATE SET blob = excluded.blob;", datasetName, layerName, metadataKey, - metadataBlob); + query.print("INSERT INTO metadata values (E'%s',E'%s', E'%s', E'%s', E'%s') " + "ON CONFLICT (datasetname, layername, metadatakey) " + "DO UPDATE SET blob = excluded.blob, updatetime = excluded.updatetime " + "WHERE excluded.updatetime > (select updatetime from metadata where datasetname = '%s' and layername = '%s' and metadatakey = '%s');", + datasetName, layerName, metadataKey, updateTime, metadataBlob, datasetName, layerName, metadataKey); + + // query.print("INSERT INTO metadata values (E'%s',E'%s', E'%s', E'%s', E'%s') ON CONFLICT (datasetname, layername, metadatakey, updatetime) DO UPDATE SET blob = excluded.blob;", datasetName, + // layerName, metadataKey, updateTime, metadataBlob); status = dataBaseConnection->query(query.c_str()); if (status != 0) { CDBError("Unable to insert records: \"%s\"", query.c_str()); diff --git a/adagucserverEC/CDBAdapterPostgreSQL.h b/adagucserverEC/CDBAdapterPostgreSQL.h index e07e0b521..7da5f74b2 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.h +++ b/adagucserverEC/CDBAdapterPostgreSQL.h @@ -89,6 +89,6 @@ class CDBAdapterPostgreSQL : public CDBAdapter { int setFileString(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int setFileTimeStamp(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int addFilesToDataBase(); - int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); + int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob, const char *updateTime); CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; diff --git a/adagucserverEC/CDBAdapterSQLLite.cpp b/adagucserverEC/CDBAdapterSQLLite.cpp index e8b2a8cf6..e42f50e23 100644 --- a/adagucserverEC/CDBAdapterSQLLite.cpp +++ b/adagucserverEC/CDBAdapterSQLLite.cpp @@ -1305,7 +1305,7 @@ CDBStore::Store *CDBAdapterSQLLite::getFilesForIndices(CDataSource *dataSource, return store; } -int CDBAdapterSQLLite::storeLayerMetadata(const char *, const char *, const char *, const char *) { return 0; } +int CDBAdapterSQLLite::storeLayerMetadata(const char *, const char *, const char *, const char *, const char *) { return 0; } CT::string CDBAdapterSQLLite::getLayerMetadata(const char *, const char *, const char *) { return ""; } #endif diff --git a/adagucserverEC/CDBAdapterSQLLite.h b/adagucserverEC/CDBAdapterSQLLite.h index c410e1dc0..71eb62a32 100644 --- a/adagucserverEC/CDBAdapterSQLLite.h +++ b/adagucserverEC/CDBAdapterSQLLite.h @@ -119,7 +119,7 @@ class CDBAdapterSQLLite : public CDBAdapter { int setFileString(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int setFileTimeStamp(const char *tablename, const char *file, const char *dimvalue, int dimindex, const char *filedate, GeoOptions *geoOptions); int addFilesToDataBase(); - int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); + int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob, const char *updateTime); CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; #endif diff --git a/adagucserverEC/Definitions.h b/adagucserverEC/Definitions.h index ddc2ee29e..041475aa1 100755 --- a/adagucserverEC/Definitions.h +++ b/adagucserverEC/Definitions.h @@ -28,7 +28,7 @@ #ifndef Definitions_H #define Definitions_H -#define ADAGUCSERVER_VERSION "2.27.0" // Please also update in the Dockerfile to the same version +#define ADAGUCSERVER_VERSION "2.28.0" // Please also update in the Dockerfile to the same version // CConfigReaderLayerType #define CConfigReaderLayerTypeUnknown 0 diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 587a3df39..fe89bb580 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -39,10 +39,21 @@ int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::st return 1; } CT::string layerName = myWMSLayer->dataSource->getLayerName(); - return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->storeLayerMetadata(datasetName, layerName, metadataKey, metadataBlob.c_str()); + + CT::string updateTime = "now"; + // Try to find the defaultValue in the time dimension, used for updateTime in the metadata table + auto timeDimIt = find_if(myWMSLayer->layerMetadata.dimList.begin(), myWMSLayer->layerMetadata.dimList.end(), [](const LayerMetadataDim *obj) { return obj->name.equals("time"); }); + if (timeDimIt != myWMSLayer->layerMetadata.dimList.end()) { + auto timeDim = *timeDimIt; + updateTime = timeDim->defaultValue.c_str(); + } else { + updateTime = CTime::currentDateTime().c_str(); + } + return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->storeLayerMetadata(datasetName, layerName, metadataKey, metadataBlob.c_str(), updateTime.c_str()); } catch (int e) { return e; } + return 0; } int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { diff --git a/data/config/datasets/adaguc.testGeoJSONReader_time.xml b/data/config/datasets/adaguc.testGeoJSONReader_time.xml index f04be2561..d27a38e74 100644 --- a/data/config/datasets/adaguc.testGeoJSONReader_time.xml +++ b/data/config/datasets/adaguc.testGeoJSONReader_time.xml @@ -1,6 +1,7 @@ + "); } - if (layer->dataSource->cfgLayer->MetadataURL.size() > 0) { - CT::string layerMetaDataURL = firstWMLayer->dataSource->cfgLayer->MetadataURL[0]->value.c_str(); + if (layer->layer->MetadataURL.size() > 0) { + CT::string layerMetaDataURL = firstWMLayer->layer->MetadataURL[0]->value.c_str(); layerMetaDataURL.replaceSelf("&", "&"); XMLDoc->concat(" \n"); XMLDoc->concat(" text/xml\n"); @@ -623,7 +623,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorconcat(""); XMLDoc->concat(&layer->abstract);XMLDoc->concat("\n"); - /*if(layer->dataSource->cfgLayer->MetadataURL.size()>0){ + /*if(layer->layerMetadata.cfgLayer->MetadataURL.size()>0){ XMLDoc->concat(" precipitation_amount\n"); }*/ XMLDoc->printconcat("\n" @@ -646,8 +646,8 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectordataSource->cfgLayer->MetadataURL.size() > 0) { - CT::string layerMetaDataURL = firstWMLayer->dataSource->cfgLayer->MetadataURL[0]->value.c_str(); + if (firstWMLayer->layer->MetadataURL.size() > 0) { + CT::string layerMetaDataURL = firstWMLayer->layer->MetadataURL[0]->value.c_str(); layerMetaDataURL.replaceSelf("&", "&"); XMLDoc->concat(" \n"); XMLDoc->concat(" application/gml+xml; version=3.2\n"); @@ -832,8 +832,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector%s\n" " \n", layer->layerMetadata.name.c_str(), layer->layerMetadata.name.c_str(), layerTitle.c_str()); - if (layer->dataSource->dataObjects.size() > 0) { - XMLDoc->printconcat(" %s\n", layer->dataSource->dataObjects[0]->getUnits().c_str()); + if (layer->layerMetadata.variableList.size() > 0) { + XMLDoc->printconcat(" %s\n", layer->layerMetadata.variableList[0]->units.c_str()); } XMLDoc->printconcat(" \n" " %f %f\n" @@ -866,8 +866,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector\n", encodedProjString.c_str(), proj->dfBBOX[0], proj->dfBBOX[1], proj->dfBBOX[2], proj->dfBBOX[3]); } - int width = layer->dataSource->dWidth - 1; - int height = layer->dataSource->dHeight - 1; + int width = layer->layerMetadata.width - 1; + int height = layer->layerMetadata.height - 1; if (width <= 1) { width = 999; } @@ -891,9 +891,9 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector\n" " \n", width, height, - layer->dataSource->dfBBOX[0], //+layer->dataSource->dfCellSizeX/2, - layer->dataSource->dfBBOX[3], //+layer->dataSource->dfCellSizeY/2, - layer->dataSource->dfCellSizeX, layer->dataSource->dfCellSizeY); + layer->layerMetadata.dfBBOX[0], //+layer->layerMetadata.dfCellSizeX/2, + layer->layerMetadata.dfBBOX[3], //+layer->layerMetadata.dfCellSizeY/2, + layer->layerMetadata.cellsizeX, layer->layerMetadata.cellsizeY); if (timeDimIndex >= 0) { XMLDoc->concat(" \n"); @@ -943,7 +943,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorprintconcat(" %s\n", encodedProjString.c_str()); } - CT::string prettyCRS = layer->dataSource->nativeEPSG.c_str(); + CT::string prettyCRS = layer->layerMetadata.nativeEPSG.c_str(); XMLDoc->printconcat(" %s\n \n", prettyCRS.c_str()); XMLDoc->concat(" \n" diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index e30bb3883..b87fa49d0 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -25,15 +25,25 @@ struct LayerMetadataStyle { CT::string abstract; }; +struct LayerMetadataVariable { + CT::string units; +}; + struct LayerMetadata { + int width = -1; + int height = -1; + double cellsizeX = 0; + double cellsizeY = 0; double dfLatLonBBOX[4] = {-180, -90, 180, 90}; + double dfBBOX[4] = {-180, -90, 180, 90}; int isQueryable = 0; - CT::string name, title, group, abstract; + CT::string name, title, group, abstract, nativeEPSG; std::vector projectionList; std::vector dimList; std::vector styleList; + std::vector variableList; }; // TODO should rename this class diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index d6b2b3f4c..3f0264716 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -53,11 +53,28 @@ int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; layerMetadataItem["group"] = myWMSLayer->layerMetadata.group; layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; - layerMetadataItem["isQueryable"] = myWMSLayer->layerMetadata.isQueryable; + layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; + layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; layerMetadataItem["latlonboxleft"] = myWMSLayer->layerMetadata.dfLatLonBBOX[0]; layerMetadataItem["latlonboxright"] = myWMSLayer->layerMetadata.dfLatLonBBOX[1]; layerMetadataItem["latlonboxbottom"] = myWMSLayer->layerMetadata.dfLatLonBBOX[2]; layerMetadataItem["latlonboxtop"] = myWMSLayer->layerMetadata.dfLatLonBBOX[3]; + layerMetadataItem["bboxleft"] = myWMSLayer->layerMetadata.dfBBOX[0]; + layerMetadataItem["bboxright"] = myWMSLayer->layerMetadata.dfBBOX[1]; + layerMetadataItem["bboxbottom"] = myWMSLayer->layerMetadata.dfBBOX[2]; + layerMetadataItem["bboxtop"] = myWMSLayer->layerMetadata.dfBBOX[3]; + layerMetadataItem["width"] = myWMSLayer->layerMetadata.width; + layerMetadataItem["height"] = myWMSLayer->layerMetadata.height; + layerMetadataItem["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; + layerMetadataItem["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + json variables; + for (auto lv : myWMSLayer->layerMetadata.variableList) { + json variable; + variable["units"] = lv->units; + variables.push_back(variable); + } + layerMetadataItem["variables"] = variables; + storeLayerMetadataInDb(myWMSLayer, "layermetadata", layerMetadataItem.dump()); return 0; } @@ -77,11 +94,28 @@ int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { myWMSLayer->layerMetadata.title = i["title"].get().c_str(); myWMSLayer->layerMetadata.group = i["group"].get().c_str(); myWMSLayer->layerMetadata.abstract = i["abstract"].get().c_str(); - myWMSLayer->layerMetadata.isQueryable = i["isQueryable"].get(); + myWMSLayer->layerMetadata.isQueryable = i["isqueryable"].get(); + myWMSLayer->layerMetadata.nativeEPSG = i["nativeepsg"].get().c_str(); myWMSLayer->layerMetadata.dfLatLonBBOX[0] = i["latlonboxleft"].get(); myWMSLayer->layerMetadata.dfLatLonBBOX[1] = i["latlonboxright"].get(); myWMSLayer->layerMetadata.dfLatLonBBOX[2] = i["latlonboxbottom"].get(); myWMSLayer->layerMetadata.dfLatLonBBOX[3] = i["latlonboxtop"].get(); + myWMSLayer->layerMetadata.dfBBOX[0] = i["bboxleft"].get(); + myWMSLayer->layerMetadata.dfBBOX[1] = i["bboxright"].get(); + myWMSLayer->layerMetadata.dfBBOX[2] = i["bboxbottom"].get(); + myWMSLayer->layerMetadata.dfBBOX[3] = i["bboxtop"].get(); + myWMSLayer->layerMetadata.width = i["width"].get(); + myWMSLayer->layerMetadata.height = i["height"].get(); + myWMSLayer->layerMetadata.cellsizeX = i["cellsizex"].get(); + myWMSLayer->layerMetadata.cellsizeY = i["cellsizey"].get(); + auto c = i["variables"]; + for (auto styleJson : c.items()) { + auto variableProps = styleJson.value(); + LayerMetadataVariable *variable = new LayerMetadataVariable(); + myWMSLayer->layerMetadata.variableList.push_back(variable); + variable->units = variableProps["units"].get().c_str(); + } + } catch (json::exception &e) { return 1; } catch (int e) { diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index eee27dd7e..8ec681631 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -68,12 +68,35 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { myWMSLayer->dataSource->addStep(myWMSLayer->fileName.c_str(), NULL); } - CDBDebug("Filename for layer is %s / %s", myWMSLayer->fileName.c_str(), myWMSLayer->dataSource->getFileName()); - CDBDebug("getTitleForLayer"); if (getTitleForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; return 1; } + + CDataReader reader; + status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); + if (status != 0) { + CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); + return 1; + } + + myWMSLayer->layerMetadata.dfBBOX[0] = myWMSLayer->dataSource->dfBBOX[0]; + myWMSLayer->layerMetadata.dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[1]; + myWMSLayer->layerMetadata.dfBBOX[2] = myWMSLayer->dataSource->dfBBOX[2]; + myWMSLayer->layerMetadata.dfBBOX[3] = myWMSLayer->dataSource->dfBBOX[3]; + + myWMSLayer->layerMetadata.width = myWMSLayer->dataSource->dWidth; + myWMSLayer->layerMetadata.height = myWMSLayer->dataSource->dHeight; + myWMSLayer->layerMetadata.cellsizeX = myWMSLayer->dataSource->dfCellSizeX; + myWMSLayer->layerMetadata.cellsizeY = myWMSLayer->dataSource->dfCellSizeY; + myWMSLayer->layerMetadata.nativeEPSG = myWMSLayer->dataSource->nativeEPSG; + + auto v = myWMSLayer->dataSource->getDataObjectsVector(); + for (auto d : (*v)) { + LayerMetadataVariable *layerMetadataVariable = new LayerMetadataVariable(); + layerMetadataVariable->units = (d->getUnits()); + myWMSLayer->layerMetadata.variableList.push_back(layerMetadataVariable); + } } if (getDimsForLayer(myWMSLayer) != 0) { myWMSLayer->hasError = 1; diff --git a/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml b/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml index 902e06ae1..2a64156e1 100644 --- a/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml +++ b/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml @@ -521,9 +521,9 @@ {ADAGUC_PATH}/data/datasets/test/netcdfpointtimeseries/ - pr + rg neerslagintensiteit(neerslagmeter) [mm/uur] - pr + rg neerslagintensiteit(neerslagmeter) [mm/uur] precipitation diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml index ec94e9a50..89e3356d8 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 + ADAGUCServer version 2.28.0, of Sep 9 2024 15:36:04 @@ -709,7 +709,7 @@ 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z -pr +rg neerslagintensiteit(neerslagmeter) [mm/uur] neerslagintensiteit(neerslagmeter) [mm/uur] @@ -735,7 +735,7 @@ 2020-12-20T12:30:00Z,2020-12-20T12:40:00Z - + pg neerslagintensiteit(PWS) [mm/uur] From c719e01c91d8f85f8624870668dc582c87967f08 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 9 Sep 2024 15:58:42 +0200 Subject: [PATCH 16/50] Fixed tests --- adagucserverEC/CServerConfig_CPPXSD.h | 20 +++++++------- adagucserverEC/CXMLSerializerInterface.cpp | 9 ++++--- .../datasets/adaguc.testKMDS_PointNetCDF.xml | 4 +-- hclasses/CTString.cpp | 27 ++++++++++++++----- hclasses/CTString.h | 5 ++++ ...ities_KMDS_PointNetCDF_pointstylepoint.xml | 6 ++--- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/adagucserverEC/CServerConfig_CPPXSD.h b/adagucserverEC/CServerConfig_CPPXSD.h index 8b1dbd5ec..30ca99ad2 100644 --- a/adagucserverEC/CServerConfig_CPPXSD.h +++ b/adagucserverEC/CServerConfig_CPPXSD.h @@ -296,7 +296,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -641,7 +641,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -901,7 +901,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { @@ -1383,7 +1383,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -1452,7 +1452,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -1490,7 +1490,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -1545,7 +1545,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -1616,7 +1616,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; @@ -1866,7 +1866,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { @@ -2009,7 +2009,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimSelf(); + this->value.trimWhiteSpacesAndLinesSelf(); } if (rc == 1) { pt2Class = NULL; diff --git a/adagucserverEC/CXMLSerializerInterface.cpp b/adagucserverEC/CXMLSerializerInterface.cpp index d5bf9e065..07a774542 100644 --- a/adagucserverEC/CXMLSerializerInterface.cpp +++ b/adagucserverEC/CXMLSerializerInterface.cpp @@ -33,7 +33,10 @@ void CXMLObjectInterface::addElement(CXMLObjectInterface *baseClass, int rc, con CXMLSerializerInterface *base = (CXMLSerializerInterface *)baseClass; base->currentNode = (CXMLObjectInterface *)this; if (rc == 0) - if (value != NULL) this->value.copy(value); + if (value != NULL) { + this->value.copy(value); + this->value.trimWhiteSpacesAndLinesSelf(); + } } int parseInt(const char *pszValue) { @@ -131,6 +134,4 @@ int CXMLSerializerInterface::parseFile(const char *xmlFile) { return 0; } -bool CXMLSerializerInterface::equals(const char *val1, const char *val2) { - return strcmp(val1, val2) == 0; -} \ No newline at end of file +bool CXMLSerializerInterface::equals(const char *val1, const char *val2) { return strcmp(val1, val2) == 0; } \ No newline at end of file diff --git a/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml b/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml index 2a64156e1..344c53140 100644 --- a/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml +++ b/data/config/datasets/adaguc.testKMDS_PointNetCDF.xml @@ -706,9 +706,7 @@ ww actuele wawa weercode weercode - - time - + time {ADAGUC_PATH}/data/datasets/test/netcdfpointtimeseries/ diff --git a/hclasses/CTString.cpp b/hclasses/CTString.cpp index f77164490..a9d3561eb 100644 --- a/hclasses/CTString.cpp +++ b/hclasses/CTString.cpp @@ -469,6 +469,25 @@ namespace CT { substringSelf(s, e + 1); } + void string::trimWhiteSpacesAndLinesSelf() { + + int s = -1, e = privatelength; + const char *value = useStack ? stackValue : heapValue; + for (size_t j = 0; j < privatelength; j++) { + if (value[j] != ' ' || value[j] != 10 || value[j] != 13) { + s = j; + break; + } + } + for (size_t j = privatelength - 1; j > 0; j--) { + if (value[j] != ' ' || value[j] != 10 || value[j] != 13) { + e = j; + break; + } + } + substringSelf(s, e + 1); + } + int string::substringSelf(CT::string *string, size_t start, size_t end) { if (start >= string->privatelength || end - start <= 0) { copy(""); @@ -679,13 +698,9 @@ namespace CT { return fValue; } - int string::toInt() { - return atoi(c_str()); - } + int string::toInt() { return atoi(c_str()); } - long string::toLong() { - return atol(c_str()); - } + long string::toLong() { return atol(c_str()); } CT::string string::basename() { const char *last = rindex(this->c_str(), '/'); diff --git a/hclasses/CTString.h b/hclasses/CTString.h index 6a1b671ac..e08fedde7 100644 --- a/hclasses/CTString.h +++ b/hclasses/CTString.h @@ -355,6 +355,11 @@ namespace CT { */ void trimSelf(); + /** + * Removes spaces in this string + */ + void trimWhiteSpacesAndLinesSelf(); + /** * Returns a new string with removed spaces */ diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml index 89e3356d8..19f14f378 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.28.0, of Sep 9 2024 15:36:04 + ADAGUCServer version 2.28.0, of Sep 9 2024 15:50:41 @@ -1294,9 +1294,7 @@ -2020-12-20T12:30:00Z/2020-12-20T12:40:00Z/PT5M +2020-12-20T12:30:00Z/2020-12-20T12:40:00Z/PT5M ww-10 From eb6b6d4ed85fa7e842cf372b03f4d2627750946c Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 9 Sep 2024 16:14:45 +0200 Subject: [PATCH 17/50] Resolved comments --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index f3b55d5af..b3adeb197 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1150,6 +1150,9 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const auto records = layerMetaDataStore->getRecords(); for (auto record : records) { if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { +#ifdef MEASURETIME + StopWatch_Stop("get("blob"); } } From 50267308ead5f2bbfc187c28261bad60f83d49ee Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 9 Sep 2024 21:03:41 +0200 Subject: [PATCH 18/50] added call to obtain metadata --- adagucserverEC/CRequest.cpp | 57 +++++++-- adagucserverEC/utils/LayerMetadataStore.cpp | 132 +++++++++++++------- adagucserverEC/utils/LayerMetadataStore.h | 6 + 3 files changed, 143 insertions(+), 52 deletions(-) diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index 2c2086e1c..d1cb47d8c 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -42,6 +42,9 @@ #include #include "Definitions.h" #include "utils/LayerUtils.h" +#include "utils/XMLGenUtils.h" +#include "utils/LayerMetadataStore.h" +#include const char *CRequest::className = "CRequest"; int CRequest::CGI = 0; @@ -2279,16 +2282,52 @@ int CRequest::process_all_layers() { // WMS GetMetaData if (srvParam->requestType == REQUEST_WMS_GETMETADATA) { - printf("%s%c%c\n", "Content-Type:text/plain", 13, 10); - CDataReader reader; - status = reader.open(dataSources[j], CNETCDFREADER_MODE_OPEN_HEADER); - if (status != 0) { - CDBError("Could not open file: %s", dataSources[j]->getFileName()); - throw(__LINE__); + if (srvParam->Format.equals("application/json")) { + json result; + json dataset; + json layer; + + WMSLayer *myWMSLayer = new WMSLayer(); + myWMSLayer->readFromDb = true; + myWMSLayer->layer = dataSources[j]->cfgLayer; + myWMSLayer->srvParams = srvParam; + myWMSLayer->dataSource = dataSources[j]; + loadMyWMSLayerFromMetadataDb(myWMSLayer); + + json dimListJson, layerMetadataItem, projsettings, styleListJson; + + getDimensionListAsJson(myWMSLayer, dimListJson); + getLayerMetadataAsJson(myWMSLayer, layerMetadataItem); + getProjectionListAsJson(myWMSLayer, projsettings); + getStyleListMetadataAsJson(myWMSLayer, styleListJson); + CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; + if (datasetName.empty()) { + CDBDebug("Not a dataset"); + return 1; + } + CT::string layerName = myWMSLayer->dataSource->getLayerName(); + + layer["dims"] = dimListJson; + layer["layer"] = layerMetadataItem; + layer["projections"] = projsettings; + layer["styles"] = styleListJson; + dataset[layerName.c_str()] = layer; + result[datasetName.c_str()] = dataset; + printf("%s%c%c\n", "Content-Type:application/json", 13, 10); + printf("%s", result.dump().c_str()); + } else { + printf("%s%c%c\n", "Content-Type:text/plain", 13, 10); + CDataReader reader; + status = reader.open(dataSources[j], CNETCDFREADER_MODE_OPEN_HEADER); + if (status != 0) { + CDBError("Could not open file: %s", dataSources[j]->getFileName()); + throw(__LINE__); + } + CT::string dumpString = CDF::dump(dataSources[j]->getDataObject(0)->cdfObject); + printf("%s", dumpString.c_str()); + reader.close(); } - CT::string dumpString = CDF::dump(dataSources[j]->getDataObject(0)->cdfObject); - printf("%s", dumpString.c_str()); - reader.close(); + return 0; } if (srvParam->requestType == REQUEST_WMS_GETREFERENCETIMES) { diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 3f0264716..414db4635 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -4,6 +4,86 @@ #include #include "XMLGenUtils.h" +int getDimensionListAsJson(WMSLayer *myWMSLayer, json &dimListJson) { + try { + + for (auto dimension : myWMSLayer->layerMetadata.dimList) { + json item; + item["defaultValue"] = dimension->defaultValue.c_str(); + item["hasMultipleValues"] = dimension->hasMultipleValues; + item["hidden"] = dimension->hidden; + item["name"] = dimension->name.c_str(); + item["units"] = dimension->units.c_str(); + item["values"] = dimension->values.c_str(); + dimListJson[dimension->name.c_str()] = item; + } + } catch (json::exception &e) { + return 1; + } + return 0; +} + +int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { + try { + layerMetadataItem["name"] = myWMSLayer->layerMetadata.name; + layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; + layerMetadataItem["group"] = myWMSLayer->layerMetadata.group; + layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; + layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; + layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; + layerMetadataItem["latlonboxleft"] = myWMSLayer->layerMetadata.dfLatLonBBOX[0]; + layerMetadataItem["latlonboxright"] = myWMSLayer->layerMetadata.dfLatLonBBOX[1]; + layerMetadataItem["latlonboxbottom"] = myWMSLayer->layerMetadata.dfLatLonBBOX[2]; + layerMetadataItem["latlonboxtop"] = myWMSLayer->layerMetadata.dfLatLonBBOX[3]; + layerMetadataItem["bboxleft"] = myWMSLayer->layerMetadata.dfBBOX[0]; + layerMetadataItem["bboxright"] = myWMSLayer->layerMetadata.dfBBOX[1]; + layerMetadataItem["bboxbottom"] = myWMSLayer->layerMetadata.dfBBOX[2]; + layerMetadataItem["bboxtop"] = myWMSLayer->layerMetadata.dfBBOX[3]; + layerMetadataItem["width"] = myWMSLayer->layerMetadata.width; + layerMetadataItem["height"] = myWMSLayer->layerMetadata.height; + layerMetadataItem["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; + layerMetadataItem["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + json variables; + for (auto lv : myWMSLayer->layerMetadata.variableList) { + json variable; + variable["units"] = lv->units; + variables.push_back(variable); + } + layerMetadataItem["variables"] = variables; + + } catch (json::exception &e) { + return 1; + } + return 0; +} +int getProjectionListAsJson(WMSLayer *myWMSLayer, json &projsettings) { + try { + for (auto projection : myWMSLayer->layerMetadata.projectionList) { + json item = {projection->dfBBOX[0], projection->dfBBOX[1], projection->dfBBOX[2], projection->dfBBOX[3]}; + projsettings[projection->name.c_str()] = item; + } + } catch (json::exception &e) { + return 1; + } + return 0; +} + +int getStyleListMetadataAsJson(WMSLayer *myWMSLayer, json &styleListJson) { + try { + + for (auto style : myWMSLayer->layerMetadata.styleList) { + json item; + item["abstract"] = style->abstract.c_str(); + item["title"] = style->title.c_str(); + item["name"] = style->name.c_str(); + styleListJson.push_back(item); + } + } catch (json::exception &e) { + return 1; + } + return 0; +} + int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer) { storeLayerMetadataStructIntoMetadataDb(myWMSLayer); storeLayerDimensionListIntoMetadataDb(myWMSLayer); @@ -12,7 +92,6 @@ int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -// Not sure if this will be used int loadMyWMSLayerFromMetadataDb(WMSLayer *myWMSLayer) { loadLayerMetadataStructFromMetadataDb(myWMSLayer); loadLayerDimensionListFromMetadataDb(myWMSLayer); @@ -49,31 +128,10 @@ int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::st int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { json layerMetadataItem; - layerMetadataItem["name"] = myWMSLayer->layerMetadata.name; - layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; - layerMetadataItem["group"] = myWMSLayer->layerMetadata.group; - layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; - layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; - layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; - layerMetadataItem["latlonboxleft"] = myWMSLayer->layerMetadata.dfLatLonBBOX[0]; - layerMetadataItem["latlonboxright"] = myWMSLayer->layerMetadata.dfLatLonBBOX[1]; - layerMetadataItem["latlonboxbottom"] = myWMSLayer->layerMetadata.dfLatLonBBOX[2]; - layerMetadataItem["latlonboxtop"] = myWMSLayer->layerMetadata.dfLatLonBBOX[3]; - layerMetadataItem["bboxleft"] = myWMSLayer->layerMetadata.dfBBOX[0]; - layerMetadataItem["bboxright"] = myWMSLayer->layerMetadata.dfBBOX[1]; - layerMetadataItem["bboxbottom"] = myWMSLayer->layerMetadata.dfBBOX[2]; - layerMetadataItem["bboxtop"] = myWMSLayer->layerMetadata.dfBBOX[3]; - layerMetadataItem["width"] = myWMSLayer->layerMetadata.width; - layerMetadataItem["height"] = myWMSLayer->layerMetadata.height; - layerMetadataItem["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; - layerMetadataItem["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; - json variables; - for (auto lv : myWMSLayer->layerMetadata.variableList) { - json variable; - variable["units"] = lv->units; - variables.push_back(variable); + + if (getLayerMetadataAsJson(myWMSLayer, layerMetadataItem) != 0) { + return 1; } - layerMetadataItem["variables"] = variables; storeLayerMetadataInDb(myWMSLayer, "layermetadata", layerMetadataItem.dump()); return 0; @@ -128,9 +186,8 @@ int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { int storeLayerProjectionAndExtentListIntoMetadataDb(WMSLayer *myWMSLayer) { try { json projsettings; - for (auto projection : myWMSLayer->layerMetadata.projectionList) { - json item = {projection->dfBBOX[0], projection->dfBBOX[1], projection->dfBBOX[2], projection->dfBBOX[3]}; - projsettings[projection->name.c_str()] = item; + if (getProjectionListAsJson(myWMSLayer, projsettings) != 0) { + return 1; } storeLayerMetadataInDb(myWMSLayer, "projected_extents", projsettings.dump()); } catch (int e) { @@ -176,12 +233,8 @@ int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer) { try { json styleListJson; - for (auto style : myWMSLayer->layerMetadata.styleList) { - json item; - item["abstract"] = style->abstract.c_str(); - item["title"] = style->title.c_str(); - item["name"] = style->name.c_str(); - styleListJson.push_back(item); + if (getStyleListMetadataAsJson(myWMSLayer, styleListJson) != 0) { + return 1; } storeLayerMetadataInDb(myWMSLayer, "stylelist", styleListJson.dump()); } catch (int e) { @@ -234,15 +287,8 @@ int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; - for (auto dimension : myWMSLayer->layerMetadata.dimList) { - json item; - item["defaultValue"] = dimension->defaultValue.c_str(); - item["hasMultipleValues"] = dimension->hasMultipleValues; - item["hidden"] = dimension->hidden; - item["name"] = dimension->name.c_str(); - item["units"] = dimension->units.c_str(); - item["values"] = dimension->values.c_str(); - dimListJson[dimension->name.c_str()] = item; + if (getDimensionListAsJson(myWMSLayer, dimListJson) != 0) { + return 1; } storeLayerMetadataInDb(myWMSLayer, "dimensionlist", dimListJson.dump()); } catch (json::exception &e) { diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index 052151cb7..ed0cf97b2 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -4,6 +4,12 @@ #include #include #include "CXMLGen.h" +#include + +int getDimensionListAsJson(WMSLayer *myWMSLayer, json &dimListJson); +int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem); +int getProjectionListAsJson(WMSLayer *myWMSLayer, json &projsettings); +int getStyleListMetadataAsJson(WMSLayer *myWMSLayer, json &styleListJson); int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob); CT::string getLayerMetadataFromDb(WMSLayer *myWMSLayer, CT::string metadataKey); From 526bbe0bc0d3d0c413c515ca5264d9e5b5abd0d1 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 9 Sep 2024 21:18:59 +0200 Subject: [PATCH 19/50] Resolved comments --- hclasses/CTString.cpp | 4 ++-- ...st_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hclasses/CTString.cpp b/hclasses/CTString.cpp index a9d3561eb..b08a8563c 100644 --- a/hclasses/CTString.cpp +++ b/hclasses/CTString.cpp @@ -474,13 +474,13 @@ namespace CT { int s = -1, e = privatelength; const char *value = useStack ? stackValue : heapValue; for (size_t j = 0; j < privatelength; j++) { - if (value[j] != ' ' || value[j] != 10 || value[j] != 13) { + if (value[j] != ' ' && value[j] != '\n' && value[j] != '\r') { s = j; break; } } for (size_t j = privatelength - 1; j > 0; j--) { - if (value[j] != ' ' || value[j] != 10 || value[j] != 13) { + if (value[j] != ' ' && value[j] != '\n' && value[j] != '\r') { e = j; break; } diff --git a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml index 19f14f378..ea4d9d15d 100644 --- a/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml +++ b/tests/expectedoutputs/TestWMS/test_WMSGetCapabilities_KMDS_PointNetCDF_pointstylepoint.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.28.0, of Sep 9 2024 15:50:41 + ADAGUCServer version 2.28.0, of Sep 9 2024 21:05:01 @@ -206,7 +206,7 @@ ff_dd -windsnelheid [m/s] en windrichting [graden] +windsnelheid [m/s] en windrichting [graden] windsnelheid [m/s] en windrichting [graden] 10 min. gemiddelden -68.275833 From f51e22a9e1fdbbfeb69b75bdb38100d22d07160a Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 10 Sep 2024 08:17:59 +0200 Subject: [PATCH 20/50] Resolved comments --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index b3adeb197..3833e341e 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1092,9 +1092,9 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char CT::string tableColumns("datasetname varchar (255), layername varchar (255), metadatakey varchar (255), updatetime TIMESTAMPTZ, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); - int status = dataBaseConnection->checkTable("metadata", tableColumns.c_str()); + int status = dataBaseConnection->checkTable("layermetadata", tableColumns.c_str()); if (status == 1) { - CDBError("\nFAIL: Table metadata could not be created: %s", tableColumns.c_str()); + CDBError("\nFAIL: Table layermetadata could not be created: %s", tableColumns.c_str()); throw(__LINE__); } From f3e3b3b347a71e04410eb8c8e164ae761db1c121 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 10 Sep 2024 08:41:20 +0200 Subject: [PATCH 21/50] Moved json generation to another file --- adagucserverEC/CMakeLists.txt | 2 + adagucserverEC/CRequest.cpp | 33 ++-------- adagucserverEC/utils/LayerMetadataStore.cpp | 69 ++++++++++++-------- adagucserverEC/utils/LayerMetadataStore.h | 2 +- adagucserverEC/utils/LayerMetadataToJson.cpp | 36 ++++++++++ adagucserverEC/utils/LayerMetadataToJson.h | 8 +++ 6 files changed, 94 insertions(+), 56 deletions(-) create mode 100644 adagucserverEC/utils/LayerMetadataToJson.cpp create mode 100644 adagucserverEC/utils/LayerMetadataToJson.h diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index a133293ba..bebea3030 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -75,6 +75,8 @@ add_library( utils/CXMLTemplates.h utils/LayerUtils.h utils/LayerUtils.cpp + utils/LayerMetadataToJson.h + utils/LayerMetadataToJson.cpp Types/LayerMetadataType.h Types/LayerMetadataType.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index d1cb47d8c..ec1b967fb 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -45,6 +45,7 @@ #include "utils/XMLGenUtils.h" #include "utils/LayerMetadataStore.h" #include +#include "utils/LayerMetadataToJson.h" const char *CRequest::className = "CRequest"; int CRequest::CGI = 0; @@ -2283,36 +2284,10 @@ int CRequest::process_all_layers() { // WMS GetMetaData if (srvParam->requestType == REQUEST_WMS_GETMETADATA) { if (srvParam->Format.equals("application/json")) { + json result; - json dataset; - json layer; - - WMSLayer *myWMSLayer = new WMSLayer(); - myWMSLayer->readFromDb = true; - myWMSLayer->layer = dataSources[j]->cfgLayer; - myWMSLayer->srvParams = srvParam; - myWMSLayer->dataSource = dataSources[j]; - loadMyWMSLayerFromMetadataDb(myWMSLayer); - - json dimListJson, layerMetadataItem, projsettings, styleListJson; - - getDimensionListAsJson(myWMSLayer, dimListJson); - getLayerMetadataAsJson(myWMSLayer, layerMetadataItem); - getProjectionListAsJson(myWMSLayer, projsettings); - getStyleListMetadataAsJson(myWMSLayer, styleListJson); - CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; - if (datasetName.empty()) { - CDBDebug("Not a dataset"); - return 1; - } - CT::string layerName = myWMSLayer->dataSource->getLayerName(); - - layer["dims"] = dimListJson; - layer["layer"] = layerMetadataItem; - layer["projections"] = projsettings; - layer["styles"] = styleListJson; - dataset[layerName.c_str()] = layer; - result[datasetName.c_str()] = dataset; + getLayerMetadataAsJson(dataSources[j], result); + printf("%s%c%c\n", "Content-Type:application/json", 13, 10); printf("%s", result.dump().c_str()); } else { diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 414db4635..7f61e7196 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -18,12 +18,13 @@ int getDimensionListAsJson(WMSLayer *myWMSLayer, json &dimListJson) { dimListJson[dimension->name.c_str()] = item; } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } return 0; } -int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { +int getLayerBaseMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { try { layerMetadataItem["name"] = myWMSLayer->layerMetadata.name; layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; @@ -31,18 +32,24 @@ int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; - layerMetadataItem["latlonboxleft"] = myWMSLayer->layerMetadata.dfLatLonBBOX[0]; - layerMetadataItem["latlonboxright"] = myWMSLayer->layerMetadata.dfLatLonBBOX[1]; - layerMetadataItem["latlonboxbottom"] = myWMSLayer->layerMetadata.dfLatLonBBOX[2]; - layerMetadataItem["latlonboxtop"] = myWMSLayer->layerMetadata.dfLatLonBBOX[3]; - layerMetadataItem["bboxleft"] = myWMSLayer->layerMetadata.dfBBOX[0]; - layerMetadataItem["bboxright"] = myWMSLayer->layerMetadata.dfBBOX[1]; - layerMetadataItem["bboxbottom"] = myWMSLayer->layerMetadata.dfBBOX[2]; - layerMetadataItem["bboxtop"] = myWMSLayer->layerMetadata.dfBBOX[3]; - layerMetadataItem["width"] = myWMSLayer->layerMetadata.width; - layerMetadataItem["height"] = myWMSLayer->layerMetadata.height; - layerMetadataItem["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; - layerMetadataItem["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + json latlonbox; + for (size_t j = 0; j < 4; j++) { + latlonbox.push_back(myWMSLayer->layerMetadata.dfLatLonBBOX[j]); + } + layerMetadataItem["latlonbox"] = latlonbox; + + json gridspec; + json bbox; + for (size_t j = 0; j < 4; j++) { + bbox.push_back(myWMSLayer->layerMetadata.dfBBOX[j]); + } + gridspec["bbox"] = bbox; + gridspec["width"] = myWMSLayer->layerMetadata.width; + gridspec["height"] = myWMSLayer->layerMetadata.height; + gridspec["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; + gridspec["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + layerMetadataItem["gridspec"] = gridspec; + json variables; for (auto lv : myWMSLayer->layerMetadata.variableList) { json variable; @@ -52,6 +59,7 @@ int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { layerMetadataItem["variables"] = variables; } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } return 0; @@ -63,6 +71,7 @@ int getProjectionListAsJson(WMSLayer *myWMSLayer, json &projsettings) { projsettings[projection->name.c_str()] = item; } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } return 0; @@ -79,6 +88,7 @@ int getStyleListMetadataAsJson(WMSLayer *myWMSLayer, json &styleListJson) { styleListJson.push_back(item); } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } return 0; @@ -129,7 +139,7 @@ int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::st int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { json layerMetadataItem; - if (getLayerMetadataAsJson(myWMSLayer, layerMetadataItem) != 0) { + if (getLayerBaseMetadataAsJson(myWMSLayer, layerMetadataItem) != 0) { return 1; } @@ -154,18 +164,20 @@ int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { myWMSLayer->layerMetadata.abstract = i["abstract"].get().c_str(); myWMSLayer->layerMetadata.isQueryable = i["isqueryable"].get(); myWMSLayer->layerMetadata.nativeEPSG = i["nativeepsg"].get().c_str(); - myWMSLayer->layerMetadata.dfLatLonBBOX[0] = i["latlonboxleft"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[1] = i["latlonboxright"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[2] = i["latlonboxbottom"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[3] = i["latlonboxtop"].get(); - myWMSLayer->layerMetadata.dfBBOX[0] = i["bboxleft"].get(); - myWMSLayer->layerMetadata.dfBBOX[1] = i["bboxright"].get(); - myWMSLayer->layerMetadata.dfBBOX[2] = i["bboxbottom"].get(); - myWMSLayer->layerMetadata.dfBBOX[3] = i["bboxtop"].get(); - myWMSLayer->layerMetadata.width = i["width"].get(); - myWMSLayer->layerMetadata.height = i["height"].get(); - myWMSLayer->layerMetadata.cellsizeX = i["cellsizex"].get(); - myWMSLayer->layerMetadata.cellsizeY = i["cellsizey"].get(); + + json latlonbox = i["latlonbox"]; + for (size_t j = 0; j < 4; j += 1) { + latlonbox[j].get_to((myWMSLayer->layerMetadata.dfLatLonBBOX[j])); + } + json gridspec = i["gridspec"]; + json bbox = gridspec["bbox"]; + for (size_t j = 0; j < 4; j += 1) { + bbox[j].get_to((myWMSLayer->layerMetadata.dfBBOX[j])); + } + myWMSLayer->layerMetadata.width = gridspec["width"].get(); + myWMSLayer->layerMetadata.height = gridspec["height"].get(); + myWMSLayer->layerMetadata.cellsizeX = gridspec["cellsizex"].get(); + myWMSLayer->layerMetadata.cellsizeY = gridspec["cellsizey"].get(); auto c = i["variables"]; for (auto styleJson : c.items()) { auto variableProps = styleJson.value(); @@ -175,6 +187,7 @@ int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } catch (int e) { CDBError("loadLayerMetadataStructFromMetadataDb %d", e); @@ -222,6 +235,7 @@ int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { bboxArray[3].get_to((projection->dfBBOX[3])); } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerProjectionAndExtentListFromMetadataDb %d", e); @@ -275,6 +289,7 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerStyleListFromMetadataDb %d", e); @@ -292,6 +307,7 @@ int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { } storeLayerMetadataInDb(myWMSLayer, "dimensionlist", dimListJson.dump()); } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } catch (int e) { return e; @@ -330,6 +346,7 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { dimension->values = dimensionProperties["values"].get().c_str(); } } catch (json::exception &e) { + CDBError("Unable to build json structure"); return 1; } catch (int e) { return e; diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index ed0cf97b2..7a9719f60 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -7,7 +7,7 @@ #include int getDimensionListAsJson(WMSLayer *myWMSLayer, json &dimListJson); -int getLayerMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem); +int getLayerBaseMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem); int getProjectionListAsJson(WMSLayer *myWMSLayer, json &projsettings); int getStyleListMetadataAsJson(WMSLayer *myWMSLayer, json &styleListJson); diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp new file mode 100644 index 000000000..083a808f9 --- /dev/null +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -0,0 +1,36 @@ +#include "LayerMetadataToJson.h" +#include +#include "LayerMetadataStore.h" + +int getLayerMetadataAsJson(CDataSource *dataSource, json &result) { + json dataset; + json layer; + + WMSLayer *myWMSLayer = new WMSLayer(); + myWMSLayer->readFromDb = true; + myWMSLayer->layer = dataSource->cfgLayer; + myWMSLayer->srvParams = dataSource->srvParams; + myWMSLayer->dataSource = dataSource; + loadMyWMSLayerFromMetadataDb(myWMSLayer); + + json dimListJson, layerMetadataItem, projsettings, styleListJson; + + getDimensionListAsJson(myWMSLayer, dimListJson); + getLayerBaseMetadataAsJson(myWMSLayer, layerMetadataItem); + getProjectionListAsJson(myWMSLayer, projsettings); + getStyleListMetadataAsJson(myWMSLayer, styleListJson); + CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; + if (datasetName.empty()) { + CDBDebug("Not a dataset"); + return 1; + } + CT::string layerName = myWMSLayer->dataSource->getLayerName(); + + layer["dims"] = dimListJson; + layer["layer"] = layerMetadataItem; + layer["projections"] = projsettings; + layer["styles"] = styleListJson; + dataset[layerName.c_str()] = layer; + result[datasetName.c_str()] = dataset; + return 0; +} \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataToJson.h b/adagucserverEC/utils/LayerMetadataToJson.h new file mode 100644 index 000000000..78fc077bf --- /dev/null +++ b/adagucserverEC/utils/LayerMetadataToJson.h @@ -0,0 +1,8 @@ +#ifndef LAYERMETADATATOJSON_H +#define LAYERMETADATATOJSON_H +#include +#include + +int getLayerMetadataAsJson(CDataSource *dataSource, json &result); + +#endif \ No newline at end of file From cf262fd77bdd27e11a97fab4b7ad8a1c710375bc Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 10 Sep 2024 08:42:14 +0200 Subject: [PATCH 22/50] Resolved comments --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 3833e341e..726fcb1db 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1101,7 +1101,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char CT::string updateTime = CTime::currentDateTime().c_str(); updateTime.setSize(19); CT::string query; - query.print("INSERT INTO metadata values (E'%s',E'%s', E'%s', E'%s', E'%s') " + query.print("INSERT INTO layermetadata values (E'%s',E'%s', E'%s', E'%s', E'%s') " "ON CONFLICT (datasetname, layername, metadatakey) " "DO UPDATE SET blob = excluded.blob, updatetime = excluded.updatetime;", datasetName, layerName, metadataKey, updateTime.c_str(), metadataBlob); From e5fff4564c916d98a6205d09d2f8cd9469da4af6 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 10 Sep 2024 08:44:45 +0200 Subject: [PATCH 23/50] Resolved comments --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 726fcb1db..c25e4cf28 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1133,7 +1133,7 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const } CT::string query; - query.print("SELECT layername, metadatakey, blob from metadata where datasetname = '%s';", datasetName); + query.print("SELECT layername, metadatakey, blob from layermetadata where datasetname = '%s';", datasetName); this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); if (layerMetaDataStore == nullptr) { #ifdef CDBAdapterPostgreSQL_DEBUG From a19f085cef792d42c7331c8dadd3bebfa94d67ee Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 09:00:18 +0200 Subject: [PATCH 24/50] Added getmetadata call --- adagucserverEC/CDBAdapter.h | 2 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 28 +++----- adagucserverEC/CDBAdapterPostgreSQL.h | 2 +- adagucserverEC/CDBAdapterSQLLite.cpp | 2 +- adagucserverEC/CDBAdapterSQLLite.h | 2 +- adagucserverEC/CRequest.cpp | 37 +++++------ adagucserverEC/Types/LayerMetadataType.h | 4 +- adagucserverEC/utils/LayerMetadataStore.cpp | 44 ++++++++++--- adagucserverEC/utils/LayerMetadataToJson.cpp | 68 +++++++++++++------- adagucserverEC/utils/LayerMetadataToJson.h | 2 +- adagucserverEC/utils/XMLGenUtils.cpp | 10 +++ 11 files changed, 124 insertions(+), 77 deletions(-) diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index f4bf3d9f7..57f5cb5fb 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -98,7 +98,7 @@ class CDBAdapter { virtual int addFilesToDataBase() = 0; virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; - virtual CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) = 0; + virtual CDBStore::Store *getLayerMetadataStore(const char *datasetName) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index c25e4cf28..18c1e117a 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1117,7 +1117,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char return 0; } -CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) { +CDBStore::Store *CDBAdapterPostgreSQL::getLayerMetadataStore(const char *datasetName) { #ifdef MEASURETIME StopWatch_Stop(">CDBAdapterPostgreSQL::getLayerMetadata"); #endif @@ -1133,7 +1133,11 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const } CT::string query; - query.print("SELECT layername, metadatakey, blob from layermetadata where datasetname = '%s';", datasetName); + if (datasetName != nullptr) { + query.print("SELECT datasetname, layername, metadatakey, blob from layermetadata where datasetname = '%s';", datasetName); + } else { + query.print("SELECT datasetname, layername, metadatakey, blob from layermetadata"); + } this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); if (layerMetaDataStore == nullptr) { #ifdef CDBAdapterPostgreSQL_DEBUG @@ -1141,26 +1145,10 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const #endif throw(__LINE__); } - if (layerMetaDataStore->size() == 0) { - CDBDebug("No results \"%s\"", query.c_str()); - throw(__LINE__); - } - } - - auto records = layerMetaDataStore->getRecords(); - for (auto record : records) { - if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { -#ifdef MEASURETIME - StopWatch_Stop("get("blob"); - } } - // CDBDebug(store->getRecord(0)->get("blob")->c_str()); #ifdef MEASURETIME StopWatch_Stop("requestType == REQUEST_WMS_GETMETADATA) { - if (srvParam->Format.equals("application/json")) { - - json result; - getLayerMetadataAsJson(dataSources[j], result); - - printf("%s%c%c\n", "Content-Type:application/json", 13, 10); - printf("%s", result.dump().c_str()); - } else { - printf("%s%c%c\n", "Content-Type:text/plain", 13, 10); - CDataReader reader; - status = reader.open(dataSources[j], CNETCDFREADER_MODE_OPEN_HEADER); - if (status != 0) { - CDBError("Could not open file: %s", dataSources[j]->getFileName()); - throw(__LINE__); - } - CT::string dumpString = CDF::dump(dataSources[j]->getDataObject(0)->cdfObject); - printf("%s", dumpString.c_str()); - reader.close(); + printf("%s%c%c\n", "Content-Type:text/plain", 13, 10); + CDataReader reader; + status = reader.open(dataSources[j], CNETCDFREADER_MODE_OPEN_HEADER); + if (status != 0) { + CDBError("Could not open file: %s", dataSources[j]->getFileName()); + throw(__LINE__); } + CT::string dumpString = CDF::dump(dataSources[j]->getDataObject(0)->cdfObject); + printf("%s", dumpString.c_str()); + reader.close(); return 0; } @@ -3367,6 +3358,16 @@ int CRequest::process_querystring() { CDBError("ADAGUC Server: GetMetaData is restricted"); return 1; } + + if (srvParam->Format.equals("application/json")) { + // GetMetadata for specific dataset and layer + json result; + getLayerMetadataAsJson(srvParam, result); + printf("%s%c%c\n", "Content-Type:application/json", 13, 10); + printf("%s", result.dump().c_str()); + return 0; + } + if (dFound_WMSLAYER == 0) { CDBError("ADAGUC Server: Parameter LAYER missing"); dErrorOccured = 1; diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index b87fa49d0..dfe9ac22d 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -27,6 +27,8 @@ struct LayerMetadataStyle { struct LayerMetadataVariable { CT::string units; + CT::string variableName; + CT::string label; }; struct LayerMetadata { @@ -38,7 +40,7 @@ struct LayerMetadata { double dfLatLonBBOX[4] = {-180, -90, 180, 90}; double dfBBOX[4] = {-180, -90, 180, 90}; int isQueryable = 0; - CT::string name, title, group, abstract, nativeEPSG; + CT::string name, title, group, abstract, nativeEPSG, projstring; std::vector projectionList; std::vector dimList; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 7f61e7196..fbf4866f9 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -18,7 +18,7 @@ int getDimensionListAsJson(WMSLayer *myWMSLayer, json &dimListJson) { dimListJson[dimension->name.c_str()] = item; } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } return 0; @@ -31,6 +31,7 @@ int getLayerBaseMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { layerMetadataItem["group"] = myWMSLayer->layerMetadata.group; layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; + layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; json latlonbox; for (size_t j = 0; j < 4; j++) { @@ -48,18 +49,22 @@ int getLayerBaseMetadataAsJson(WMSLayer *myWMSLayer, json &layerMetadataItem) { gridspec["height"] = myWMSLayer->layerMetadata.height; gridspec["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; gridspec["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + gridspec["projstring"] = myWMSLayer->layerMetadata.projstring; + layerMetadataItem["gridspec"] = gridspec; json variables; for (auto lv : myWMSLayer->layerMetadata.variableList) { json variable; variable["units"] = lv->units; + variable["label"] = lv->label; + variable["variableName"] = lv->variableName; variables.push_back(variable); } layerMetadataItem["variables"] = variables; } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } return 0; @@ -71,7 +76,7 @@ int getProjectionListAsJson(WMSLayer *myWMSLayer, json &projsettings) { projsettings[projection->name.c_str()] = item; } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } return 0; @@ -88,7 +93,7 @@ int getStyleListMetadataAsJson(WMSLayer *myWMSLayer, json &styleListJson) { styleListJson.push_back(item); } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } return 0; @@ -117,7 +122,23 @@ CT::string getLayerMetadataFromDb(WMSLayer *myWMSLayer, CT::string metadataKey) // CDBDebug("Not a dataset"); return ""; } - return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->getLayerMetadata(datasetName, layerName, metadataKey); + CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->getLayerMetadataStore(datasetName); + + auto records = layerMetaDataStore->getRecords(); + for (auto record : records) { + if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { +#ifdef MEASURETIME + StopWatch_Stop("get("blob"); + } + } + +#ifdef MEASURETIME + StopWatch_Stop("layerMetadata.height = gridspec["height"].get(); myWMSLayer->layerMetadata.cellsizeX = gridspec["cellsizex"].get(); myWMSLayer->layerMetadata.cellsizeY = gridspec["cellsizey"].get(); + myWMSLayer->layerMetadata.projstring = gridspec["projstring"].get().c_str(); auto c = i["variables"]; for (auto styleJson : c.items()) { auto variableProps = styleJson.value(); LayerMetadataVariable *variable = new LayerMetadataVariable(); myWMSLayer->layerMetadata.variableList.push_back(variable); variable->units = variableProps["units"].get().c_str(); + variable->label = variableProps["label"].get().c_str(); + variable->variableName = variableProps["variableName"].get().c_str(); } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { CDBError("loadLayerMetadataStructFromMetadataDb %d", e); @@ -235,7 +259,7 @@ int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { bboxArray[3].get_to((projection->dfBBOX[3])); } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerProjectionAndExtentListFromMetadataDb %d", e); @@ -289,7 +313,7 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerStyleListFromMetadataDb %d", e); @@ -307,7 +331,7 @@ int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { } storeLayerMetadataInDb(myWMSLayer, "dimensionlist", dimListJson.dump()); } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { return e; @@ -346,7 +370,7 @@ int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { dimension->values = dimensionProperties["values"].get().c_str(); } } catch (json::exception &e) { - CDBError("Unable to build json structure"); + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { return e; diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp index 083a808f9..8273e7d0f 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.cpp +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -1,36 +1,58 @@ #include "LayerMetadataToJson.h" #include #include "LayerMetadataStore.h" +#include +#include -int getLayerMetadataAsJson(CDataSource *dataSource, json &result) { +CT::string getBlob(CDBStore::Store *layerMetaDataStore, const char *datasetName, const char *layerName, const char *metadataKey) { + auto records = layerMetaDataStore->getRecords(); + for (auto record : records) { + if (record->get("datasetname")->equals(datasetName) && record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { +#ifdef MEASURETIME + StopWatch_Stop("get("blob"); + } + } + return ""; +} + +int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { json dataset; json layer; + CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(srvParams->cfg)->getLayerMetadataStore(nullptr); + auto records = layerMetaDataStore->getRecords(); + std::map> datasetNames; + for (auto record : records) { + CT::string *datasetName = record->get("datasetname"); + CT::string *layerName = record->get("layername"); + if (datasetName != nullptr && layerName != nullptr) { + datasetNames[record->get("datasetname")->c_str()].insert(record->get("layername")->c_str()); + } + } - WMSLayer *myWMSLayer = new WMSLayer(); - myWMSLayer->readFromDb = true; - myWMSLayer->layer = dataSource->cfgLayer; - myWMSLayer->srvParams = dataSource->srvParams; - myWMSLayer->dataSource = dataSource; - loadMyWMSLayerFromMetadataDb(myWMSLayer); + CT::string layerNameInRequest; + if (srvParams->WMSLayers != nullptr && srvParams->WMSLayers->count > 0) { + layerNameInRequest = srvParams->WMSLayers[0].c_str(); + } - json dimListJson, layerMetadataItem, projsettings, styleListJson; + for (auto dataset : datasetNames) { + auto dataSetName = dataset.first; + if (srvParams->datasetLocation.empty() || srvParams->datasetLocation.equals(dataSetName)) { + json datasetJSON; + for (auto layerName : dataset.second) { + if (layerNameInRequest.empty() || layerNameInRequest.equals(layerName.c_str())) { + json layer; + json a; + layer["layer"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "layermetadata").c_str()); + layer["dims"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "dimensionlist").c_str()); + datasetJSON[layerName.c_str()] = layer; + } + } - getDimensionListAsJson(myWMSLayer, dimListJson); - getLayerBaseMetadataAsJson(myWMSLayer, layerMetadataItem); - getProjectionListAsJson(myWMSLayer, projsettings); - getStyleListMetadataAsJson(myWMSLayer, styleListJson); - CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; - if (datasetName.empty()) { - CDBDebug("Not a dataset"); - return 1; + result[dataSetName.c_str()] = datasetJSON; + } } - CT::string layerName = myWMSLayer->dataSource->getLayerName(); - layer["dims"] = dimListJson; - layer["layer"] = layerMetadataItem; - layer["projections"] = projsettings; - layer["styles"] = styleListJson; - dataset[layerName.c_str()] = layer; - result[datasetName.c_str()] = dataset; return 0; } \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataToJson.h b/adagucserverEC/utils/LayerMetadataToJson.h index 78fc077bf..6ea0e9c52 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.h +++ b/adagucserverEC/utils/LayerMetadataToJson.h @@ -3,6 +3,6 @@ #include #include -int getLayerMetadataAsJson(CDataSource *dataSource, json &result); +int getLayerMetadataAsJson(CServerParams *srvParams, json &result); #endif \ No newline at end of file diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 8ec681631..277531caf 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -90,11 +90,21 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { myWMSLayer->layerMetadata.cellsizeX = myWMSLayer->dataSource->dfCellSizeX; myWMSLayer->layerMetadata.cellsizeY = myWMSLayer->dataSource->dfCellSizeY; myWMSLayer->layerMetadata.nativeEPSG = myWMSLayer->dataSource->nativeEPSG; + myWMSLayer->layerMetadata.projstring = myWMSLayer->dataSource->nativeProj4; auto v = myWMSLayer->dataSource->getDataObjectsVector(); for (auto d : (*v)) { LayerMetadataVariable *layerMetadataVariable = new LayerMetadataVariable(); layerMetadataVariable->units = (d->getUnits()); + layerMetadataVariable->variableName = (d->variableName); + + CDF::Attribute *longName = d->cdfVariable->getAttributeNE("long_name"); + if (longName == nullptr) { + longName = d->cdfVariable->getAttributeNE("standard_name"); + } + CT::string label = longName != nullptr ? longName->getDataAsString() : d->variableName; + + layerMetadataVariable->label = (label); myWMSLayer->layerMetadata.variableList.push_back(layerMetadataVariable); } } From 3d0353deb1d2e64ce2bf63780c6cae6e285af727 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 09:26:53 +0200 Subject: [PATCH 25/50] Resolved comments --- NEWS.md | 2 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 11 +++--- adagucserverEC/CXMLGen.cpp | 34 +++++++++---------- adagucserverEC/CXMLGen.h | 10 +++--- .../LayerTypeLiveUpdate.cpp | 2 +- .../LayerTypeLiveUpdate/LayerTypeLiveUpdate.h | 2 +- adagucserverEC/Types/LayerMetadataType.cpp | 4 +-- adagucserverEC/Types/LayerMetadataType.h | 6 ++-- adagucserverEC/utils/LayerMetadataStore.cpp | 33 +++++++----------- adagucserverEC/utils/LayerMetadataStore.h | 23 ++++++------- adagucserverEC/utils/XMLGenUtils.cpp | 12 +++---- adagucserverEC/utils/XMLGenUtils.h | 12 +++---- doc/configuration/Configuration.md | 2 +- doc/configuration/Settings.md | 5 +-- .../routers/edr_utils.py | 2 -- 15 files changed, 76 insertions(+), 84 deletions(-) diff --git a/NEWS.md b/NEWS.md index 493173c93..97be1ccf3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,5 @@ **Version 2.28.0 2024-09-62** -- Metadata for layer items like the projections, dimensions and styles can now be stored in a metadatatable +- Metadata for layer items like variables, projections, dimensions and styles are now stored in a metadatatable. This can be disabled via the `enablemetadatacache` property in [Settings](doc/configuration/Settings.md). **Version 2.27.0 2024-09-02** diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index c25e4cf28..e28a06f19 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -44,6 +44,10 @@ CDBAdapterPostgreSQL::~CDBAdapterPostgreSQL() { #ifdef CDBAdapterPostgreSQL_DEBUG CDBDebug("~CDBAdapterPostgreSQL()"); #endif + if (layerMetaDataStore != nullptr) { + delete layerMetaDataStore; + layerMetaDataStore = nullptr; + } if (dataBaseConnection != NULL) { dataBaseConnection->close2(); } @@ -1128,7 +1132,6 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const #endif CPGSQLDB *dataBaseConnection = getDataBaseConnection(); if (dataBaseConnection == NULL) { - CDBError("No database connection"); throw(__LINE__); } @@ -1139,11 +1142,11 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const #ifdef CDBAdapterPostgreSQL_DEBUG CDBDebug("Unable query: \"%s\"", query.c_str()); #endif - throw(__LINE__); + return ""; } if (layerMetaDataStore->size() == 0) { - CDBDebug("No results \"%s\"", query.c_str()); - throw(__LINE__); + CDBDebug("No results for layerMetaDataStore \"%s\"", query.c_str()); + return ""; } } diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index cb013da5d..f8d73b639 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -41,12 +41,12 @@ const char *CXMLGen::className = "CXMLGen"; int CXMLGen::WCSDescribeCoverage(CServerParams *srvParam, CT::string *XMLDocument) { return OGCGetCapabilities(srvParam, XMLDocument); } -const WMSLayer *getFirstLayerWithoutError(std::vector *myWMSLayerList) { +const MetadataLayer *getFirstLayerWithoutError(std::vector *myWMSLayerList) { if (myWMSLayerList->size() == 0) { return nullptr; } for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; if (layer->hasError == 0) { return layer; } @@ -54,9 +54,9 @@ const WMSLayer *getFirstLayerWithoutError(std::vector *myWMSLayerLis return (*myWMSLayerList)[0]; } -void addErrorInXMLForMisconfiguredLayer(CT::string *XMLDoc, WMSLayer *layer) { XMLDoc->printconcat("\n\n", layer->layerMetadata.name.c_str()); } +void addErrorInXMLForMisconfiguredLayer(CT::string *XMLDoc, MetadataLayer *layer) { XMLDoc->printconcat("\n\n", layer->layerMetadata.name.c_str()); } -int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_0_0_GetCapabilities_Header); @@ -75,7 +75,7 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } @@ -118,7 +118,7 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_1_1_GetCapabilities_Header); @@ -139,7 +139,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector groupKeys; for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; std::string key = ""; if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; @@ -212,7 +212,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; if (layer->layerMetadata.group.equals(groupKeys[groupIndex])) { // CDBError("layer %d %s",groupDepth,layer->name.c_str()); if (layer->hasError != 0) { @@ -296,7 +296,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_3_0_GetCapabilities_Header); @@ -505,7 +505,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector groupKeys; for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; std::string key = ""; if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; @@ -581,7 +581,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; #ifdef CXMLGEN_DEBUG CDBDebug("Comparing %s == %s", layer->group.c_str(), groupKeys[groupIndex].c_str()); #endif @@ -731,7 +731,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WCS&"); @@ -757,7 +757,7 @@ int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorsize() > 0) { for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } @@ -791,7 +791,7 @@ int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *myWMSLayerList) { XMLDoc->copy("\n" "WMSLayers->count; layerIndex++) { for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - WMSLayer *layer = (*myWMSLayerList)[lnr]; + MetadataLayer *layer = (*myWMSLayerList)[lnr]; if (layer->layerMetadata.name.equals(&srvParam->WMSLayers[layerIndex])) { if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); @@ -975,7 +975,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen this->srvParam = _srvParam; int status = 0; - std::vector myWMSLayerList; + std::vector myWMSLayerList; for (size_t j = 0; j < srvParam->cfg->Layer.size(); j++) { if (srvParam->cfg->Layer[j]->attr.type.equals("autoscan")) { @@ -985,7 +985,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen continue; } // Create a new layer and push it in the list - WMSLayer *myWMSLayer = new WMSLayer(); + MetadataLayer *myWMSLayer = new MetadataLayer(); myWMSLayerList.push_back(myWMSLayer); myWMSLayer->layer = srvParam->cfg->Layer[j]; myWMSLayer->srvParams = srvParam; diff --git a/adagucserverEC/CXMLGen.h b/adagucserverEC/CXMLGen.h index 61a563809..468e771c5 100644 --- a/adagucserverEC/CXMLGen.h +++ b/adagucserverEC/CXMLGen.h @@ -48,11 +48,11 @@ class CXMLGen { private: DEF_ERRORFUNCTION(); - int getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *myWMSLayerList); CServerParams *srvParam; CT::string serviceInfo; diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp index 5ad07f8b5..b36bcd672 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp @@ -39,7 +39,7 @@ int layerTypeLiveUpdateRenderIntoDrawImage(CDrawImage *image, CServerParams *srv return 0; } -int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(WMSLayer *myWMSLayer) { +int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *myWMSLayer) { if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); } else { diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h index 1578379f1..5acf1722f 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h @@ -19,6 +19,6 @@ int layerTypeLiveUpdateRenderIntoDrawImage(CDrawImage *image, CServerParams *srv /** * Configures an actual time range in a WMSLayer object. This is used for generating the Layer element in the WMS GetCapabilities file */ -int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(WMSLayer *myWMSLayer); +int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *myWMSLayer); #endif // !LAYERTYPELIVEUPDATE_H diff --git a/adagucserverEC/Types/LayerMetadataType.cpp b/adagucserverEC/Types/LayerMetadataType.cpp index 5bcbdc8f2..a56befc80 100644 --- a/adagucserverEC/Types/LayerMetadataType.cpp +++ b/adagucserverEC/Types/LayerMetadataType.cpp @@ -1,11 +1,11 @@ #include "LayerMetadataType.h" -WMSLayer::WMSLayer() { +MetadataLayer::MetadataLayer() { hasError = 0; dataSource = NULL; } -WMSLayer::~WMSLayer() { +MetadataLayer::~MetadataLayer() { for (size_t j = 0; j < layerMetadata.projectionList.size(); j++) { delete layerMetadata.projectionList[j]; } diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index b87fa49d0..b1ec59dea 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -47,10 +47,10 @@ struct LayerMetadata { }; // TODO should rename this class -class WMSLayer { +class MetadataLayer { public: - WMSLayer(); - ~WMSLayer(); + MetadataLayer(); + ~MetadataLayer(); // TODO: Would be nice to get rid of these in this class CServerConfig::XMLE_Layer *layer; CDataSource *dataSource; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 3f0264716..f21502531 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -4,7 +4,7 @@ #include #include "XMLGenUtils.h" -int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer) { +int storeMyWMSLayerIntoMetadataDb(MetadataLayer *myWMSLayer) { storeLayerMetadataStructIntoMetadataDb(myWMSLayer); storeLayerDimensionListIntoMetadataDb(myWMSLayer); storeLayerProjectionAndExtentListIntoMetadataDb(myWMSLayer); @@ -12,16 +12,7 @@ int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -// Not sure if this will be used -int loadMyWMSLayerFromMetadataDb(WMSLayer *myWMSLayer) { - loadLayerMetadataStructFromMetadataDb(myWMSLayer); - loadLayerDimensionListFromMetadataDb(myWMSLayer); - loadLayerProjectionAndExtentListFromMetadataDb(myWMSLayer); - loadLayerStyleListFromMetadataDb(myWMSLayer); - return 0; -} - -CT::string getLayerMetadataFromDb(WMSLayer *myWMSLayer, CT::string metadataKey) { +CT::string getLayerMetadataFromDb(MetadataLayer *myWMSLayer, CT::string metadataKey) { CT::string layerName = myWMSLayer->dataSource->getLayerName(); CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; if (datasetName.empty()) { @@ -31,7 +22,7 @@ CT::string getLayerMetadataFromDb(WMSLayer *myWMSLayer, CT::string metadataKey) return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->getLayerMetadata(datasetName, layerName, metadataKey); } -int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob) { +int storeLayerMetadataInDb(MetadataLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob) { try { CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; if (datasetName.empty()) { @@ -47,7 +38,7 @@ int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::st return 0; } -int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { +int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *myWMSLayer) { json layerMetadataItem; layerMetadataItem["name"] = myWMSLayer->layerMetadata.name; layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; @@ -79,7 +70,7 @@ int storeLayerMetadataStructIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { +int loadLayerMetadataStructFromMetadataDb(MetadataLayer *myWMSLayer) { if (!myWMSLayer->readFromDb) { return 1; } @@ -125,7 +116,7 @@ int loadLayerMetadataStructFromMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int storeLayerProjectionAndExtentListIntoMetadataDb(WMSLayer *myWMSLayer) { +int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *myWMSLayer) { try { json projsettings; for (auto projection : myWMSLayer->layerMetadata.projectionList) { @@ -139,7 +130,7 @@ int storeLayerProjectionAndExtentListIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { +int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *myWMSLayer) { if (!myWMSLayer->readFromDb) { return 1; } @@ -173,7 +164,7 @@ int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer) { +int storeLayerStyleListIntoMetadataDb(MetadataLayer *myWMSLayer) { try { json styleListJson; for (auto style : myWMSLayer->layerMetadata.styleList) { @@ -190,7 +181,7 @@ int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { +int loadLayerStyleListFromMetadataDb(MetadataLayer *myWMSLayer) { if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { return 0; } @@ -230,7 +221,7 @@ int loadLayerStyleListFromMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { +int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myWMSLayer) { CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; @@ -253,7 +244,7 @@ int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer) { return 0; } -int loadLayerDimensionListFromMetadataDb(WMSLayer *myWMSLayer) { +int loadLayerDimensionListFromMetadataDb(MetadataLayer *myWMSLayer) { if (!myWMSLayer->readFromDb) { return 1; } @@ -296,7 +287,7 @@ int updateMetaDataTable(CDataSource *dataSource) { if (dataSource->srvParams->datasetLocation.empty()) { return 0; } - WMSLayer *myWMSLayer = new WMSLayer(); + MetadataLayer *myWMSLayer = new MetadataLayer(); myWMSLayer->layer = dataSource->cfgLayer; myWMSLayer->srvParams = dataSource->srvParams; myWMSLayer->dataSource = dataSource; diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index 052151cb7..441ea7499 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -5,23 +5,22 @@ #include #include "CXMLGen.h" -int storeLayerMetadataInDb(WMSLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob); -CT::string getLayerMetadataFromDb(WMSLayer *myWMSLayer, CT::string metadataKey); +int storeLayerMetadataInDb(MetadataLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob); +CT::string getLayerMetadataFromDb(MetadataLayer *myWMSLayer, CT::string metadataKey); -int storeMyWMSLayerIntoMetadataDb(WMSLayer *myWMSLayer); -int loadMyWMSLayerFromMetadataDb(WMSLayer *myWMSLayer); +int storeMyWMSLayerIntoMetadataDb(MetadataLayer *myWMSLayer); -int storeLayerMetadataStructIntoMetadataDb(WMSLayer *layer); -int loadLayerMetadataStructFromMetadataDb(WMSLayer *layer); +int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *layer); +int loadLayerMetadataStructFromMetadataDb(MetadataLayer *layer); -int storeLayerProjectionAndExtentListIntoMetadataDb(WMSLayer *layer); -int loadLayerProjectionAndExtentListFromMetadataDb(WMSLayer *layer); +int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *layer); +int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *layer); -int storeLayerDimensionListIntoMetadataDb(WMSLayer *myWMSLayer); -int loadLayerDimensionListFromMetadataDb(WMSLayer *layer); +int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myWMSLayer); +int loadLayerDimensionListFromMetadataDb(MetadataLayer *layer); -int storeLayerStyleListIntoMetadataDb(WMSLayer *myWMSLayer); -int loadLayerStyleListFromMetadataDb(WMSLayer *layer); +int storeLayerStyleListIntoMetadataDb(MetadataLayer *myWMSLayer); +int loadLayerStyleListFromMetadataDb(MetadataLayer *layer); int updateMetaDataTable(CDataSource *dataSource); #endif \ No newline at end of file diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 8ec681631..700817350 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -6,7 +6,7 @@ #include #include "LayerUtils.h" -int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { +int populateMyWMSLayerStruct(MetadataLayer *myWMSLayer, bool readFromDB) { myWMSLayer->readFromDb = readFromDB; if (!myWMSLayer->srvParams->useMetadataTable()) { myWMSLayer->readFromDb = false; @@ -131,7 +131,7 @@ int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDB) { return 0; } -int getDimsForLayer(WMSLayer *myWMSLayer) { +int getDimsForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getDimsForLayer"); #endif @@ -548,7 +548,7 @@ int getDimsForLayer(WMSLayer *myWMSLayer) { return 0; } -int getProjectionInformationForLayer(WMSLayer *myWMSLayer) { +int getProjectionInformationForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getProjectionInformationForLayer"); #endif @@ -644,7 +644,7 @@ int getProjectionInformationForLayer(WMSLayer *myWMSLayer) { return 0; } -int getStylesForLayer(WMSLayer *myWMSLayer) { +int getStylesForLayer(MetadataLayer *myWMSLayer) { if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { return 0; } @@ -695,7 +695,7 @@ bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataPro bool compareDim(const LayerMetadataDim *p2, const LayerMetadataDim *p1) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2) { return strcmp(p2->name.c_str(), p1->name.c_str()) <= 0; } -int getTitleForLayer(WMSLayer *myWMSLayer) { +int getTitleForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getTitleForLayer"); #endif @@ -740,7 +740,7 @@ int getTitleForLayer(WMSLayer *myWMSLayer) { return 0; } -int getFileNameForLayer(WMSLayer *myWMSLayer) { +int getFileNameForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getFileNameForLayer"); #endif diff --git a/adagucserverEC/utils/XMLGenUtils.h b/adagucserverEC/utils/XMLGenUtils.h index ee5c4fa43..ba1706276 100644 --- a/adagucserverEC/utils/XMLGenUtils.h +++ b/adagucserverEC/utils/XMLGenUtils.h @@ -3,14 +3,14 @@ #include "CXMLGen.h" -int getProjectionInformationForLayer(WMSLayer *myWMSLayer); -int getDimsForLayer(WMSLayer *myWMSLayer); -int getStylesForLayer(WMSLayer *myWMSLayer); +int getProjectionInformationForLayer(MetadataLayer *myWMSLayer); +int getDimsForLayer(MetadataLayer *myWMSLayer); +int getStylesForLayer(MetadataLayer *myWMSLayer); bool compareStringCase(const std::string &s1, const std::string &s2); bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2); bool compareDim(const LayerMetadataDim *p1, const LayerMetadataDim *p2); bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2); -int populateMyWMSLayerStruct(WMSLayer *myWMSLayer, bool readFromDb); -int getTitleForLayer(WMSLayer *myWMSLayer); -int getFileNameForLayer(WMSLayer *myWMSLayer); +int populateMyWMSLayerStruct(MetadataLayer *myWMSLayer, bool readFromDb); +int getTitleForLayer(MetadataLayer *myWMSLayer); +int getFileNameForLayer(MetadataLayer *myWMSLayer); #endif \ No newline at end of file diff --git a/doc/configuration/Configuration.md b/doc/configuration/Configuration.md index bfc72e1af..ca8272523 100644 --- a/doc/configuration/Configuration.md +++ b/doc/configuration/Configuration.md @@ -27,7 +27,7 @@ Configuration - [Include](Include.md) - (location) - Include additional configuration files to the service - [Logging](Logging.md) - (debug) - Configure the type of logging -- [Settings](Settings.md) - (enablecleanupsystem, cleanupsystemlimit, cache_age_cacheableresources, cache_age_volatileresources) - Configure global settings of the server / Dataset +- [Settings](Settings.md) - (enablemetadatacache, enablecleanupsystem, cleanupsystemlimit, cache_age_cacheableresources, cache_age_volatileresources) - Configure global settings of the server / Dataset - [Environment](Environment.md) - (name, default) - For within dataset configuration, specify which values should be substituted - [OgcApiEdr](EDRConfiguration/EDR.md) - Configuration options to enable EDR collections diff --git a/doc/configuration/Settings.md b/doc/configuration/Settings.md index e8b8cd9e2..42211f120 100644 --- a/doc/configuration/Settings.md +++ b/doc/configuration/Settings.md @@ -1,10 +1,11 @@ -Settings (enablecleanupsystem) +Settings (enablemetadatacache, enablecleanupsystem, cleanupsystemlimit, cache_age_cacheableresources, cache_age_volatileresources) + =============== Back to [Configuration](./Configuration.md) -Available since: 2.8.6 +- enablemetadatacache (false | true): Defaults to true, uses a layermetadata table in the db to cache layer information. This information is updated during a scan. - enablecleanupsystem (false | true | dryrun): Enables the auto cleanup system. See [FilePath](./FilePath.md) and retentionperiod for details - cleanupsystemlimit (number): Configures how many files will be deleted at once, defaults to 10 (CDBFILESCANNER_CLEANUP_DEFAULT_LIMIT). - cache_age_cacheableresources (number) defaults to 0 (disabled), Sets the cache header for fully specified getmap requests diff --git a/python/python_fastapi_server/routers/edr_utils.py b/python/python_fastapi_server/routers/edr_utils.py index 1f77219b1..bbbaa1d34 100644 --- a/python/python_fastapi_server/routers/edr_utils.py +++ b/python/python_fastapi_server/routers/edr_utils.py @@ -562,8 +562,6 @@ def get_params_for_collection( ) else: param_metadata = get_param_metadata(param_id, edr_collection) - # logger.info(param_id) - # logger.info(param_metadata["wms_layer_name"]) param = Parameter( id=param_metadata["wms_layer_name"], observedProperty=ObservedProperty( From a478bfd4354b6bc913ba260562716c623278c178 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 10:34:39 +0200 Subject: [PATCH 26/50] Fixed nullptr issue --- adagucserverEC/utils/LayerMetadataToJson.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp index 8273e7d0f..b111917de 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.cpp +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -21,6 +21,9 @@ int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { json dataset; json layer; CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(srvParams->cfg)->getLayerMetadataStore(nullptr); + if (layerMetaDataStore == nullptr) { + return 1; + } auto records = layerMetaDataStore->getRecords(); std::map> datasetNames; for (auto record : records) { From 22d50c049a924e3ebb77f908ce7add860a59696c Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 11:05:13 +0200 Subject: [PATCH 27/50] Added test --- adagucserverEC/utils/LayerMetadataStore.cpp | 2 +- adagucserverEC/utils/XMLGenUtils.cpp | 3 +- tests/AdagucTests/TestMetadataRequest.py | 56 +++++++++++++++++++ .../test_GetMetadataRequest_arcus_uwcw.json | 1 + tests/functional_test.py | 4 ++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 tests/AdagucTests/TestMetadataRequest.py create mode 100644 tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 3d4c62784..9b6bb87fe 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -139,7 +139,7 @@ CT::string getLayerMetadataFromDb(MetadataLayer *myMetadataLayer, CT::string met #ifdef MEASURETIME StopWatch_Stop("readFromDb = false; // Get a default file name for this layer to obtain some information int status = getFileNameForLayer(metadataLayer); if (status != 0) { @@ -85,7 +87,6 @@ int populateLayerMetadataStruct(MetadataLayer *metadataLayer, bool readFromDB) { metadataLayer->layerMetadata.dfBBOX[1] = metadataLayer->dataSource->dfBBOX[1]; metadataLayer->layerMetadata.dfBBOX[2] = metadataLayer->dataSource->dfBBOX[2]; metadataLayer->layerMetadata.dfBBOX[3] = metadataLayer->dataSource->dfBBOX[3]; - metadataLayer->layerMetadata.width = metadataLayer->dataSource->dWidth; metadataLayer->layerMetadata.height = metadataLayer->dataSource->dHeight; metadataLayer->layerMetadata.cellsizeX = metadataLayer->dataSource->dfCellSizeX; diff --git a/tests/AdagucTests/TestMetadataRequest.py b/tests/AdagucTests/TestMetadataRequest.py new file mode 100644 index 000000000..8d08c1801 --- /dev/null +++ b/tests/AdagucTests/TestMetadataRequest.py @@ -0,0 +1,56 @@ +# pylint: disable=invalid-name,missing-function-docstring +""" +This class contains tests to test the adaguc-server binary executable file. This is similar to black box testing, it tests the behaviour of the server software. It configures the server and checks if the response is OK. +""" +import json +import os +import os.path +import unittest +import sys +from adaguc.AdagucTestTools import AdagucTestTools + +ADAGUC_PATH = os.environ["ADAGUC_PATH"] + + +class TestMetadataRequest(unittest.TestCase): + """ + TestMetadataRequest class to thest Web Map Service behaviour of adaguc-server. + """ + + testresultspath = "testresults/TestMetadataRequest/" + expectedoutputsspath = "expectedoutputs/TestMetadataRequest/" + env = {"ADAGUC_CONFIG": ADAGUC_PATH + "/data/config/adaguc.autoresource.xml"} + + AdagucTestTools().mkdir_p(testresultspath) + + def test_timeseries_adaguc_tests_arcus_uwcw_air_temperature_hagl(self): + AdagucTestTools().cleanTempDir() + if os.getenv("ADAGUC_DB").endswith(".db"): + print("SKIP: Only PSQL") + return + config = ( + ADAGUC_PATH + + "/data/config/adaguc.tests.dataset.xml," + + ADAGUC_PATH + + "/data/config/datasets/adaguc.tests.arcus_uwcw.xml" + ) + # pylint: disable=unused-variable + status, data, headers = AdagucTestTools().runADAGUCServer( + args=["--updatedb", "--config", config], env=self.env, isCGI=False + ) + self.assertEqual(status, 0) + + filename = "test_GetMetadataRequest_arcus_uwcw.json" + + status, data, headers = AdagucTestTools().runADAGUCServer( + "dataset=adaguc.tests.arcus_uwcw&service=WMS&request=GetMetadata&format=application/json", + {"ADAGUC_CONFIG": ADAGUC_PATH + "/data/config/adaguc.tests.dataset.xml"}, + ) + AdagucTestTools().writetofile(self.testresultspath + filename, data.getvalue()) + self.assertEqual(status, 0) + self.assertEqual( + data.getvalue(), + AdagucTestTools().readfromfile(self.expectedoutputsspath + filename), + ) + + diff --git a/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json new file mode 100644 index 000000000..2e98ac106 --- /dev/null +++ b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json @@ -0,0 +1 @@ +{"adaguc.tests.arcus_uwcw":{"air_temperature_hagl":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"2","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"2"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-05-23T00:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-05-23T00:00:00Z"},"time":{"defaultValue":"2024-05-23T01:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-05-23T01:00:00Z/2024-05-25T12:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"cellsizex":2.262,"cellsizey":-1.404,"height":5,"projstring":"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"name":"air_temperature_hagl","nativeepsg":"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Air temperature at 2 m","variables":[{"label":"Air temperature at height above ground level","units":"C","variableName":"air-temperature-hagl"}]}},"baselayer":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"baselayer","nativeepsg":"","title":"baselayer","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"overlay":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"overlay","nativeepsg":"","title":"overlay","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"wind_speed_hagl_kts":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_kts","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in Knots","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_member_3":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"3","hasMultipleValues":1,"hidden":true,"name":"member","units":"-","values":"3"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_member_3","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms for member 3","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_wrong_dim_order":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_wrong_dim_order","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}}}} \ No newline at end of file diff --git a/tests/functional_test.py b/tests/functional_test.py index d7a969d0b..7915958f3 100644 --- a/tests/functional_test.py +++ b/tests/functional_test.py @@ -5,6 +5,7 @@ """ import unittest import sys +from AdagucTests.TestMetadataRequest import TestMetadataRequest from AdagucTests.TestWMSTimeSeries import TestWMSTimeSeries from AdagucTests.TestWMS import TestWMS from AdagucTests.TestWCS import TestWCS @@ -22,8 +23,11 @@ from AdagucTests.TestDataPostProcessor import TestDataPostProcessor from AdagucTests.TestWMSTimeHeightProfiles import TestWMSTimeHeightProfiles + + suites = [] TestLoader = unittest.TestLoader +suites.append(TestLoader().loadTestsFromTestCase(TestMetadataRequest)) suites.append(TestLoader().loadTestsFromTestCase(TestWMSTimeSeries)) suites.append(TestLoader().loadTestsFromTestCase(TestWMS)) suites.append(TestLoader().loadTestsFromTestCase(TestWCS)) From d7cced39815c5212124d4322343be6925b0ab96b Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 11:41:05 +0200 Subject: [PATCH 28/50] Resolved comments --- CCDFDataModel/CCDFVariable.h | 10 +--------- NEWS.md | 5 +++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/CCDFDataModel/CCDFVariable.h b/CCDFDataModel/CCDFVariable.h index 660e91231..0bb1b942f 100644 --- a/CCDFDataModel/CCDFVariable.h +++ b/CCDFDataModel/CCDFVariable.h @@ -291,15 +291,6 @@ namespace CDF { void setSize(size_t size) { currentSize = size; } size_t getSize() { return currentSize; } - bool hasAttribute(const char *name) const { - for (size_t j = 0; j < attributes.size(); j++) { - if (attributes[j]->name.equals(name)) { - return true; - } - } - return false; - } - Attribute *getAttribute(const char *name) const { Attribute *a = getAttributeNE(name); if (a == nullptr) { @@ -307,6 +298,7 @@ namespace CDF { } return a; } + Attribute *getAttributeNE(const char *name) const { for (size_t j = 0; j < attributes.size(); j++) { if (attributes[j]->name.equals(name)) { diff --git a/NEWS.md b/NEWS.md index 97be1ccf3..beb03a41a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ -**Version 2.28.0 2024-09-62** -- Metadata for layer items like variables, projections, dimensions and styles are now stored in a metadatatable. This can be disabled via the `enablemetadatacache` property in [Settings](doc/configuration/Settings.md). +**Version 2.28.0 2024-09-11** +- Metadata for layer items like variables, projections, dimensions and styles are now stored in a database table called `layermetadata`. This can be disabled via the `enablemetadatacache` property in [Settings](doc/configuration/Settings.md). + **Version 2.27.0 2024-09-02** From bf2d1b90e4c78205f728c1ac3b517526f0021782 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 11 Sep 2024 12:08:20 +0200 Subject: [PATCH 29/50] Resolved comments --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 12 +++++++++--- adagucserverEC/CDBAdapterPostgreSQL.h | 5 ++++- adagucserverEC/CDBAdapterSQLLite.h | 7 +++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index e28a06f19..5162d7163 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1094,7 +1094,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char return -1; } - CT::string tableColumns("datasetname varchar (255), layername varchar (255), metadatakey varchar (255), updatetime TIMESTAMPTZ, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); + CT::string tableColumns("datasetname varchar (511), layername varchar (511), metadatakey varchar (255), updatetime TIMESTAMPTZ, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); int status = dataBaseConnection->checkTable("layermetadata", tableColumns.c_str()); if (status == 1) { @@ -1105,7 +1105,8 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char CT::string updateTime = CTime::currentDateTime().c_str(); updateTime.setSize(19); CT::string query; - query.print("INSERT INTO layermetadata values (E'%s',E'%s', E'%s', E'%s', E'%s') " + query.print("INSERT INTO layermetadata (datasetname, layername, metadatakey, updatetime, blob) " + "VALUES (E'%s',E'%s', E'%s', E'%s', E'%s') " "ON CONFLICT (datasetname, layername, metadatakey) " "DO UPDATE SET blob = excluded.blob, updatetime = excluded.updatetime;", datasetName, layerName, metadataKey, updateTime.c_str(), metadataBlob); @@ -1135,8 +1136,13 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const throw(__LINE__); } + if (CServerParams::checkForValidTokens(datasetName, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-:/.") == false) { + CDBError("Invalid dataset name. "); + throw(__LINE__); + } + CT::string query; - query.print("SELECT layername, metadatakey, blob from layermetadata where datasetname = '%s';", datasetName); + query.print("SELECT layername, metadatakey, blob FROM layermetadata WHERE datasetname = '%s';", datasetName); this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); if (layerMetaDataStore == nullptr) { #ifdef CDBAdapterPostgreSQL_DEBUG diff --git a/adagucserverEC/CDBAdapterPostgreSQL.h b/adagucserverEC/CDBAdapterPostgreSQL.h index e07e0b521..c8917ffa9 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.h +++ b/adagucserverEC/CDBAdapterPostgreSQL.h @@ -22,7 +22,8 @@ * limitations under the License. * ******************************************************************************/ - +#ifndef CDBADAPTERPOSTGRESQL_H +#define CDBADAPTERPOSTGRESQL_H #include "CDBAdapter.h" #include "CDebugger.h" #include "CPGSQLDB.h" @@ -92,3 +93,5 @@ class CDBAdapterPostgreSQL : public CDBAdapter { int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; + +#endif diff --git a/adagucserverEC/CDBAdapterSQLLite.h b/adagucserverEC/CDBAdapterSQLLite.h index c410e1dc0..8b1accba9 100644 --- a/adagucserverEC/CDBAdapterSQLLite.h +++ b/adagucserverEC/CDBAdapterSQLLite.h @@ -23,6 +23,10 @@ * ******************************************************************************/ #ifdef ADAGUC_USE_SQLITE + +#ifndef CDBADAPTERSQLLITE_H +#define CDBADAPTERSQLLITE_H + #include "CDBAdapter.h" #include "CDebugger.h" #include @@ -122,4 +126,7 @@ class CDBAdapterSQLLite : public CDBAdapter { int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey); }; + +#endif + #endif From 9b1f6485972ac78f882bbc3ee2d17755e0470a2f Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 08:53:09 +0200 Subject: [PATCH 30/50] Removed pointers --- adagucserverEC/CDBAdapterPostgreSQL.cpp | 2 +- adagucserverEC/CMakeLists.txt | 1 - adagucserverEC/CXMLGen.cpp | 244 +++++----- adagucserverEC/CXMLGen.h | 10 +- .../LayerTypeLiveUpdate.cpp | 18 +- .../LayerTypeLiveUpdate/LayerTypeLiveUpdate.h | 2 +- adagucserverEC/Types/LayerMetadataType.cpp | 21 - adagucserverEC/Types/LayerMetadataType.h | 26 +- adagucserverEC/utils/LayerMetadataStore.cpp | 249 ++++++----- adagucserverEC/utils/LayerMetadataStore.h | 10 +- adagucserverEC/utils/XMLGenUtils.cpp | 416 +++++++++--------- adagucserverEC/utils/XMLGenUtils.h | 18 +- ...cessor_SubstractLevels_GetCapabilities.xml | 71 ++- 13 files changed, 518 insertions(+), 570 deletions(-) delete mode 100644 adagucserverEC/Types/LayerMetadataType.cpp diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 5162d7163..6d97c3624 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1094,7 +1094,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char return -1; } - CT::string tableColumns("datasetname varchar (511), layername varchar (511), metadatakey varchar (255), updatetime TIMESTAMPTZ, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); + CT::string tableColumns("datasetname varchar (511), layername varchar (511), metadatakey varchar (255), updatetime TIMESTAMP, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); int status = dataBaseConnection->checkTable("layermetadata", tableColumns.c_str()); if (status == 1) { diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index a133293ba..98fda9fdf 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -76,7 +76,6 @@ add_library( utils/LayerUtils.h utils/LayerUtils.cpp Types/LayerMetadataType.h - Types/LayerMetadataType.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.h CDataPostProcessors/CDataPostProcessor_CDPDBZtoRR.cpp diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index f8d73b639..75c80f663 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -41,22 +41,22 @@ const char *CXMLGen::className = "CXMLGen"; int CXMLGen::WCSDescribeCoverage(CServerParams *srvParam, CT::string *XMLDocument) { return OGCGetCapabilities(srvParam, XMLDocument); } -const MetadataLayer *getFirstLayerWithoutError(std::vector *myWMSLayerList) { - if (myWMSLayerList->size() == 0) { +const MetadataLayer *getFirstLayerWithoutError(std::vector *metadataLayerList) { + if (metadataLayerList->size() == 0) { return nullptr; } - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; if (layer->hasError == 0) { return layer; } } - return (*myWMSLayerList)[0]; + return (*metadataLayerList)[0]; } void addErrorInXMLForMisconfiguredLayer(CT::string *XMLDoc, MetadataLayer *layer) { XMLDoc->printconcat("\n\n", layer->layerMetadata.name.c_str()); } -int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_0_0_GetCapabilities_Header); @@ -65,17 +65,16 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorreplaceSelf("[GLOBALLAYERTITLE]", srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); XMLDoc->replaceSelf("[SERVICEONLINERESOURCE]", onlineResource.c_str()); XMLDoc->replaceSelf("[SERVICEINFO]", serviceInfo.c_str()); - const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); + const auto firstWMLayer = getFirstLayerWithoutError(metadataLayerList); if (firstWMLayer != nullptr) { - for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; + for (auto projection : firstWMLayer->layerMetadata.projectionList) { XMLDoc->concat(""); - XMLDoc->concat(&proj->name); + XMLDoc->concat(&projection.name); XMLDoc->concat("\n"); } - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } @@ -92,20 +91,18 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorconcat(""); for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; - XMLDoc->concat(&proj->name); + XMLDoc->concat(&layer->layerMetadata.projectionList[p].name); if (p + 1 < layer->layerMetadata.projectionList.size()) XMLDoc->concat(" "); } XMLDoc->concat("\n"); XMLDoc->printconcat("\n", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[3]); // Dims - for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { - LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; - if (dim->hidden) continue; - XMLDoc->printconcat("\n", dim->name.c_str(), dim->units.c_str()); - XMLDoc->printconcat("", dim->name.c_str(), dim->defaultValue.c_str(), 1); - XMLDoc->concat(dim->values.c_str()); + for (auto dim : layer->layerMetadata.dimList) { + if (dim.hidden) continue; + XMLDoc->printconcat("\n", dim.name.c_str(), dim.units.c_str()); + XMLDoc->printconcat("", dim.name.c_str(), dim.defaultValue.c_str(), 1); + XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); } XMLDoc->concat("\n"); @@ -118,7 +115,7 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_1_1_GetCapabilities_Header); @@ -127,19 +124,18 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorreplaceSelf("[GLOBALLAYERTITLE]", srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); XMLDoc->replaceSelf("[SERVICEONLINERESOURCE]", onlineResource.c_str()); XMLDoc->replaceSelf("[SERVICEINFO]", serviceInfo.c_str()); - const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); + const auto firstWMLayer = getFirstLayerWithoutError(metadataLayerList); if (firstWMLayer != nullptr) { - for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; + for (auto proj : firstWMLayer->layerMetadata.projectionList) { XMLDoc->concat(""); - XMLDoc->concat(&proj->name); + XMLDoc->concat(&proj.name); XMLDoc->concat("\n"); } // Make a unique list of all groups std::vector groupKeys; - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; std::string key = ""; if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; @@ -211,8 +207,8 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; if (layer->layerMetadata.group.equals(groupKeys[groupIndex])) { // CDBError("layer %d %s",groupDepth,layer->name.c_str()); if (layer->hasError != 0) { @@ -229,42 +225,38 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorconcat(&layerTitle); XMLDoc->concat("\n"); - for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; + for (auto proj : firstWMLayer->layerMetadata.projectionList) { XMLDoc->concat(""); - XMLDoc->concat(&proj->name); + XMLDoc->concat(&proj.name); XMLDoc->concat("\n"); - XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[0], proj->dfBBOX[1], proj->dfBBOX[2], - proj->dfBBOX[3]); + XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[0], proj.dfBBOX[1], proj.dfBBOX[2], proj.dfBBOX[3]); } XMLDoc->printconcat("\n", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[3]); // Dims - for (size_t d = 0; d < layer->layerMetadata.dimList.size(); d++) { - LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; - if (dim->hidden) continue; - XMLDoc->printconcat("\n", dim->name.c_str(), dim->units.c_str()); - XMLDoc->printconcat("", dim->name.c_str(), dim->defaultValue.c_str(), 1); - XMLDoc->concat(dim->values.c_str()); + for (auto dim : layer->layerMetadata.dimList) { + if (dim.hidden) continue; + XMLDoc->printconcat("\n", dim.name.c_str(), dim.units.c_str()); + XMLDoc->printconcat("", dim.name.c_str(), dim.defaultValue.c_str(), 1); + XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); } // Styles - for (size_t s = 0; s < layer->layerMetadata.styleList.size(); s++) { - LayerMetadataStyle *style = layer->layerMetadata.styleList[s]; + for (auto style : layer->layerMetadata.styleList) { XMLDoc->concat(" "); } @@ -296,7 +288,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WMS&"); XMLDoc->copy(WMS_1_3_0_GetCapabilities_Header); @@ -469,24 +461,22 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorconcat("\n"); XMLDoc->printconcat("%s\n", srvParam->cfg->WMS[0]->RootLayer[0]->Title[0]->value.c_str()); - const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); + const auto firstWMLayer = getFirstLayerWithoutError(metadataLayerList); if (firstWMLayer != nullptr) { - for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; - if (!proj->name.empty()) { + for (auto proj : firstWMLayer->layerMetadata.projectionList) { + if (!proj.name.empty()) { XMLDoc->concat(""); - XMLDoc->concat(&proj->name); + XMLDoc->concat(&proj.name); XMLDoc->concat("\n"); } } - for (size_t p = 0; p < firstWMLayer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; - if (!proj->name.empty()) { - if (srvParam->checkBBOXXYOrder(proj->name.c_str()) == true) { - XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[1], proj->dfBBOX[0], proj->dfBBOX[3], proj->dfBBOX[2]); + for (auto proj : firstWMLayer->layerMetadata.projectionList) { + if (!proj.name.empty()) { + if (srvParam->checkBBOXXYOrder(proj.name.c_str()) == true) { + XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[1], proj.dfBBOX[0], proj.dfBBOX[3], proj.dfBBOX[2]); } else { - XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[0], proj->dfBBOX[1], proj->dfBBOX[2], proj->dfBBOX[3]); + XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[0], proj.dfBBOX[1], proj.dfBBOX[2], proj.dfBBOX[3]); } } } @@ -504,8 +494,8 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector groupKeys; - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; std::string key = ""; if (layer->layerMetadata.group.length() > 0) key = layer->layerMetadata.group.c_str(); size_t j = 0; @@ -580,8 +570,8 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorsize(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; #ifdef CXMLGEN_DEBUG CDBDebug("Comparing %s == %s", layer->group.c_str(), groupKeys[groupIndex].c_str()); #endif @@ -634,15 +624,11 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[3]); - for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; - - if (srvParam->checkBBOXXYOrder(proj->name.c_str()) == true) { - XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[1], proj->dfBBOX[0], proj->dfBBOX[3], - proj->dfBBOX[2]); + for (auto proj : firstWMLayer->layerMetadata.projectionList) { + if (srvParam->checkBBOXXYOrder(proj.name.c_str()) == true) { + XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[1], proj.dfBBOX[0], proj.dfBBOX[3], proj.dfBBOX[2]); } else { - XMLDoc->printconcat("\n", proj->name.c_str(), proj->dfBBOX[0], proj->dfBBOX[1], proj->dfBBOX[2], - proj->dfBBOX[3]); + XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[0], proj.dfBBOX[1], proj.dfBBOX[2], proj.dfBBOX[3]); } } @@ -661,17 +647,15 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorlayerMetadata.dimList.size(); d++) { - LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; - if (dim->hidden) continue; - if (dim->name.indexOf("time") != -1) { - XMLDoc->printconcat("", dim->name.c_str(), dim->units.c_str(), - dim->defaultValue.c_str(), 1); + for (auto dim : layer->layerMetadata.dimList) { + if (dim.hidden) continue; + if (dim.name.indexOf("time") != -1) { + XMLDoc->printconcat("", dim.name.c_str(), dim.units.c_str(), + dim.defaultValue.c_str(), 1); } else { - XMLDoc->printconcat("", dim->name.c_str(), dim->units.c_str(), dim->defaultValue.c_str(), - 1); + XMLDoc->printconcat("", dim.name.c_str(), dim.units.c_str(), dim.defaultValue.c_str(), 1); } - XMLDoc->concat(dim->values.c_str()); + XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); } if (inspireMetadataIsAvailable) { @@ -696,20 +680,19 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorlayerMetadata.styleList.size(); s++) { - LayerMetadataStyle *style = layer->layerMetadata.styleList[s]; + for (auto style : layer->layerMetadata.styleList) { XMLDoc->concat(" "); } @@ -731,7 +714,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList) { CT::string onlineResource = srvParam->getOnlineResource(); onlineResource.concat("SERVICE=WCS&"); @@ -754,10 +737,10 @@ int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorreplaceSelf("[SERVICEONLINERESOURCE]", onlineResource.c_str()); XMLDoc->replaceSelf("[SERVICEINFO]", serviceInfo.c_str()); - if (myWMSLayerList->size() > 0) { + if (metadataLayerList->size() > 0) { - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); } @@ -791,7 +774,7 @@ int CXMLGen::getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList) { +int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *metadataLayerList) { XMLDoc->copy("\n" "\n"); - const auto firstWMLayer = getFirstLayerWithoutError(myWMSLayerList); + const auto firstWMLayer = getFirstLayerWithoutError(metadataLayerList); if (firstWMLayer != nullptr) { for (size_t layerIndex = 0; layerIndex < (unsigned)srvParam->WMSLayers->count; layerIndex++) { - for (size_t lnr = 0; lnr < myWMSLayerList->size(); lnr++) { - MetadataLayer *layer = (*myWMSLayerList)[lnr]; + for (size_t lnr = 0; lnr < metadataLayerList->size(); lnr++) { + MetadataLayer *layer = (*metadataLayerList)[lnr]; if (layer->layerMetadata.name.equals(&srvParam->WMSLayers[layerIndex])) { if (layer->hasError != 0) { addErrorInXMLForMisconfiguredLayer(XMLDoc, layer); @@ -815,12 +798,13 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorlayerMetadata.dimList.size(); d++) { - LayerMetadataDim *dim = layer->layerMetadata.dimList[d]; - // if(dim->hasMultipleValues==0){ - if (dim->units.equals("ISO8601")) { + int d = 0; + for (auto dim : layer->layerMetadata.dimList) { + // if(dim.hasMultipleValues==0){ + if (dim.units.equals("ISO8601")) { timeDimIndex = d; } + d++; } if (srvParam->requestType == REQUEST_WCS_DESCRIBECOVERAGE) { @@ -833,7 +817,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector%s\n", layer->layerMetadata.name.c_str(), layer->layerMetadata.name.c_str(), layerTitle.c_str()); if (layer->layerMetadata.variableList.size() > 0) { - XMLDoc->printconcat(" %s\n", layer->layerMetadata.variableList[0]->units.c_str()); + XMLDoc->printconcat(" %s\n", layer->layerMetadata.variableList[0].units.c_str()); } XMLDoc->printconcat(" \n" " %f %f\n" @@ -842,7 +826,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector= 0) { // For information about this, visit http://www.galdosinc.com/archives/151 - CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex]->values.splitToArray("/"); + CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex].values.splitToArray("/"); if (timeDimSplit->count == 3) { XMLDoc->concat(" \n"); XMLDoc->printconcat(" %s\n", timeDimSplit[0].c_str()); @@ -855,16 +839,16 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorconcat(" \n" " \n" " \n"); - for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = layer->layerMetadata.projectionList[p]; - CT::string encodedProjString(proj->name.c_str()); + for (auto proj : layer->layerMetadata.projectionList) { + + CT::string encodedProjString(proj.name.c_str()); // encodedProjString.encodeURLSelf(); XMLDoc->printconcat(" \n" " %f %f\n" " %f %f\n" " \n", - encodedProjString.c_str(), proj->dfBBOX[0], proj->dfBBOX[1], proj->dfBBOX[2], proj->dfBBOX[3]); + encodedProjString.c_str(), proj.dfBBOX[0], proj.dfBBOX[1], proj.dfBBOX[2], proj.dfBBOX[3]); } int width = layer->layerMetadata.width - 1; int height = layer->layerMetadata.height - 1; @@ -897,8 +881,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector= 0) { XMLDoc->concat(" \n"); - if (layer->layerMetadata.dimList[timeDimIndex]->hasMultipleValues == 0) { - CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex]->values.splitToArray("/"); + if (layer->layerMetadata.dimList[timeDimIndex].hasMultipleValues == 0) { + CT::string *timeDimSplit = layer->layerMetadata.dimList[timeDimIndex].values.splitToArray("/"); if (timeDimSplit->count == 3) { XMLDoc->concat(" \n"); XMLDoc->printconcat(" %s\n", timeDimSplit[0].c_str()); @@ -909,7 +893,7 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorlayerMetadata.dimList[timeDimIndex]->values.splitToArray(","); + CT::string *positions = layer->layerMetadata.dimList[timeDimIndex].values.splitToArray(","); for (size_t p = 0; p < positions->count; p++) { XMLDoc->printconcat(" %s\n", (positions[p]).c_str()); } @@ -936,10 +920,8 @@ int CXMLGen::getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vectorconcat(" \n"); - for (size_t p = 0; p < layer->layerMetadata.projectionList.size(); p++) { - LayerMetadataProjection *proj = firstWMLayer->layerMetadata.projectionList[p]; - CT::string encodedProjString(proj->name.c_str()); - + for (auto proj : layer->layerMetadata.projectionList) { + CT::string encodedProjString(proj.name.c_str()); XMLDoc->printconcat(" %s\n", encodedProjString.c_str()); } @@ -975,7 +957,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen this->srvParam = _srvParam; int status = 0; - std::vector myWMSLayerList; + std::vector metadataLayerList; for (size_t j = 0; j < srvParam->cfg->Layer.size(); j++) { if (srvParam->cfg->Layer[j]->attr.type.equals("autoscan")) { @@ -985,19 +967,19 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen continue; } // Create a new layer and push it in the list - MetadataLayer *myWMSLayer = new MetadataLayer(); - myWMSLayerList.push_back(myWMSLayer); - myWMSLayer->layer = srvParam->cfg->Layer[j]; - myWMSLayer->srvParams = srvParam; - populateMyWMSLayerStruct(myWMSLayer, true); + MetadataLayer *metadataLayer = new MetadataLayer(); + metadataLayerList.push_back(metadataLayer); + metadataLayer->layer = srvParam->cfg->Layer[j]; + metadataLayer->srvParams = srvParam; + populateMetadataLayerStruct(metadataLayer, true); } #ifdef CXMLGEN_DEBUG - if (myWMSLayerList.size() > 0) { + if (metadataLayerList.size() > 0) { CT::string finalLayerList; - finalLayerList = myWMSLayerList[0]->name.c_str(); - for (size_t j = 1; j < myWMSLayerList.size(); j++) { - finalLayerList.printconcat(",%s", myWMSLayerList[j]->name.c_str()); + finalLayerList = metadataLayerList[0]->name.c_str(); + for (size_t j = 1; j < metadataLayerList.size(); j++) { + finalLayerList.printconcat(",%s", metadataLayerList[j]->name.c_str()); } CDBDebug("Final layerlist: \"%s\"", finalLayerList.c_str()); } @@ -1010,13 +992,13 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen status = 0; if (srvParam->requestType == REQUEST_WMS_GETCAPABILITIES) { if (srvParam->OGCVersion == WMS_VERSION_1_0_0) { - status = getWMS_1_0_0_Capabilities(&XMLDoc, &myWMSLayerList); + status = getWMS_1_0_0_Capabilities(&XMLDoc, &metadataLayerList); } if (srvParam->OGCVersion == WMS_VERSION_1_1_1) { - status = getWMS_1_1_1_Capabilities(&XMLDoc, &myWMSLayerList); + status = getWMS_1_1_1_Capabilities(&XMLDoc, &metadataLayerList); } if (srvParam->OGCVersion == WMS_VERSION_1_3_0) { - status = getWMS_1_3_0_Capabilities(&XMLDoc, &myWMSLayerList); + status = getWMS_1_3_0_Capabilities(&XMLDoc, &metadataLayerList); } } try { @@ -1025,7 +1007,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen CServerParams::showWCSNotEnabledErrorMessage(); throw(__LINE__); #else - status = getWCS_1_0_0_Capabilities(&XMLDoc, &myWMSLayerList); + status = getWCS_1_0_0_Capabilities(&XMLDoc, &metadataLayerList); #endif } @@ -1034,7 +1016,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen CServerParams::showWCSNotEnabledErrorMessage(); throw(__LINE__); #else - status = getWCS_1_0_0_DescribeCoverage(&XMLDoc, &myWMSLayerList); + status = getWCS_1_0_0_DescribeCoverage(&XMLDoc, &metadataLayerList); #endif } } catch (int e) { @@ -1043,10 +1025,10 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen bool errorsHaveOccured = false; - for (size_t j = 0; j < myWMSLayerList.size(); j++) { - if (myWMSLayerList[j]->hasError) errorsHaveOccured = true; - delete myWMSLayerList[j]; - myWMSLayerList[j] = NULL; + for (size_t j = 0; j < metadataLayerList.size(); j++) { + if (metadataLayerList[j]->hasError) errorsHaveOccured = true; + delete metadataLayerList[j]; + metadataLayerList[j] = NULL; } if (status != 0) { diff --git a/adagucserverEC/CXMLGen.h b/adagucserverEC/CXMLGen.h index 468e771c5..161766fd9 100644 --- a/adagucserverEC/CXMLGen.h +++ b/adagucserverEC/CXMLGen.h @@ -48,11 +48,11 @@ class CXMLGen { private: DEF_ERRORFUNCTION(); - int getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *myWMSLayerList); - int getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *myWMSLayerList); + int getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList); + int getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList); + int getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList); + int getWCS_1_0_0_Capabilities(CT::string *XMLDoc, std::vector *metadataLayerList); + int getWCS_1_0_0_DescribeCoverage(CT::string *XMLDoc, std::vector *metadataLayerList); CServerParams *srvParam; CT::string serviceInfo; diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp index b36bcd672..571c99ead 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp @@ -39,11 +39,11 @@ int layerTypeLiveUpdateRenderIntoDrawImage(CDrawImage *image, CServerParams *srv return 0; } -int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *myWMSLayer) { - if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); +int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *metadataLayer) { + if (metadataLayer->dataSource->cfgLayer->Title.size() != 0) { + metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->cfgLayer->Title[0]->value.c_str()); } else { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); + metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->cfgLayer->Name[0]->value.c_str()); } CTime timeInstance; timeInstance.init("seconds since 1970", "standard"); @@ -54,12 +54,8 @@ int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *myWMSL CT::string startTime = timeInstance.dateToISOString(timeInstance.offsetToDate(startTimeOffset)); CT::string stopTime = timeInstance.dateToISOString(timeInstance.offsetToDate(stopTimeOffset)); CT::string resTime = "PT1S"; - LayerMetadataDim *dim = new LayerMetadataDim(); - myWMSLayer->layerMetadata.dimList.push_back(dim); - dim->name.copy("time"); - dim->units.copy("ISO8601"); - dim->values.copy(startTime + "/" + stopTime + "/" + resTime); - dim->defaultValue.copy(stopTime.c_str()); - dim->hasMultipleValues = true; + LayerMetadataDim dim = {name : "time", units : "ISO8601", values : startTime + "/" + stopTime + "/" + resTime, defaultValue : stopTime, hasMultipleValues : true, hidden : false}; + metadataLayer->layerMetadata.dimList.push_back(dim); + return 0; } \ No newline at end of file diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h index 5acf1722f..7326981b1 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.h @@ -19,6 +19,6 @@ int layerTypeLiveUpdateRenderIntoDrawImage(CDrawImage *image, CServerParams *srv /** * Configures an actual time range in a WMSLayer object. This is used for generating the Layer element in the WMS GetCapabilities file */ -int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *myWMSLayer); +int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *metadataLayer); #endif // !LAYERTYPELIVEUPDATE_H diff --git a/adagucserverEC/Types/LayerMetadataType.cpp b/adagucserverEC/Types/LayerMetadataType.cpp deleted file mode 100644 index a56befc80..000000000 --- a/adagucserverEC/Types/LayerMetadataType.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "LayerMetadataType.h" - -MetadataLayer::MetadataLayer() { - hasError = 0; - dataSource = NULL; -} - -MetadataLayer::~MetadataLayer() { - for (size_t j = 0; j < layerMetadata.projectionList.size(); j++) { - delete layerMetadata.projectionList[j]; - } - layerMetadata.projectionList.clear(); - for (size_t j = 0; j < layerMetadata.dimList.size(); j++) { - delete layerMetadata.dimList[j]; - } - layerMetadata.dimList.clear(); - for (size_t j = 0; j < layerMetadata.styleList.size(); j++) { - delete layerMetadata.styleList[j]; - } - layerMetadata.styleList.clear(); -} diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index b1ec59dea..4edef00b3 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -11,10 +11,17 @@ struct LayerMetadataDim { CT::string values; CT::string defaultValue; int hasMultipleValues; - bool hidden = false; + bool hidden; }; struct LayerMetadataProjection { + LayerMetadataProjection() {} + LayerMetadataProjection(CT::string &name, double bbox[]) { + this->name = name; + for (size_t j = 0; j < 4; j++) { + this->dfBBOX[j] = bbox[j]; + } + } CT::string name; double dfBBOX[4]; }; @@ -30,7 +37,6 @@ struct LayerMetadataVariable { }; struct LayerMetadata { - int width = -1; int height = -1; double cellsizeX = 0; @@ -39,26 +45,22 @@ struct LayerMetadata { double dfBBOX[4] = {-180, -90, 180, 90}; int isQueryable = 0; CT::string name, title, group, abstract, nativeEPSG; - - std::vector projectionList; - std::vector dimList; - std::vector styleList; - std::vector variableList; + std::vector projectionList; + std::vector dimList; + std::vector styleList; + std::vector variableList; }; // TODO should rename this class class MetadataLayer { public: - MetadataLayer(); - ~MetadataLayer(); // TODO: Would be nice to get rid of these in this class CServerConfig::XMLE_Layer *layer; - CDataSource *dataSource; + CDataSource *dataSource = nullptr; CServerParams *srvParams; CT::string fileName; bool readFromDb = false; - - int hasError; + int hasError = 0; LayerMetadata layerMetadata; }; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index f21502531..7c6997309 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -4,109 +4,107 @@ #include #include "XMLGenUtils.h" -int storeMyWMSLayerIntoMetadataDb(MetadataLayer *myWMSLayer) { - storeLayerMetadataStructIntoMetadataDb(myWMSLayer); - storeLayerDimensionListIntoMetadataDb(myWMSLayer); - storeLayerProjectionAndExtentListIntoMetadataDb(myWMSLayer); - storeLayerStyleListIntoMetadataDb(myWMSLayer); +int storeMetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer) { + storeLayerMetadataStructIntoMetadataDb(metadataLayer); + storeLayerDimensionListIntoMetadataDb(metadataLayer); + storeLayerProjectionAndExtentListIntoMetadataDb(metadataLayer); + storeLayerStyleListIntoMetadataDb(metadataLayer); return 0; } -CT::string getLayerMetadataFromDb(MetadataLayer *myWMSLayer, CT::string metadataKey) { - CT::string layerName = myWMSLayer->dataSource->getLayerName(); - CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; +CT::string getLayerMetadataFromDb(MetadataLayer *metadataLayer, CT::string metadataKey) { + CT::string layerName = metadataLayer->dataSource->getLayerName(); + CT::string datasetName = metadataLayer->dataSource->srvParams->datasetLocation; if (datasetName.empty()) { // CDBDebug("Not a dataset"); return ""; } - return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->getLayerMetadata(datasetName, layerName, metadataKey); + return CDBFactory::getDBAdapter(metadataLayer->dataSource->srvParams->cfg)->getLayerMetadata(datasetName, layerName, metadataKey); } -int storeLayerMetadataInDb(MetadataLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob) { +int storeLayerMetadataInDb(MetadataLayer *metadataLayer, CT::string metadataKey, std::string metadataBlob) { try { - CT::string datasetName = myWMSLayer->dataSource->srvParams->datasetLocation; + CT::string datasetName = metadataLayer->dataSource->srvParams->datasetLocation; if (datasetName.empty()) { CDBDebug("Not a dataset"); return 1; } - CT::string layerName = myWMSLayer->dataSource->getLayerName(); + CT::string layerName = metadataLayer->dataSource->getLayerName(); - return CDBFactory::getDBAdapter(myWMSLayer->dataSource->srvParams->cfg)->storeLayerMetadata(datasetName, layerName, metadataKey, metadataBlob.c_str()); + return CDBFactory::getDBAdapter(metadataLayer->dataSource->srvParams->cfg)->storeLayerMetadata(datasetName, layerName, metadataKey, metadataBlob.c_str()); } catch (int e) { return e; } return 0; } -int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *myWMSLayer) { +int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *metadataLayer) { json layerMetadataItem; - layerMetadataItem["name"] = myWMSLayer->layerMetadata.name; - layerMetadataItem["title"] = myWMSLayer->layerMetadata.title; - layerMetadataItem["group"] = myWMSLayer->layerMetadata.group; - layerMetadataItem["abstract"] = myWMSLayer->layerMetadata.abstract; - layerMetadataItem["nativeepsg"] = myWMSLayer->layerMetadata.nativeEPSG; - layerMetadataItem["isqueryable"] = myWMSLayer->layerMetadata.isQueryable; - layerMetadataItem["latlonboxleft"] = myWMSLayer->layerMetadata.dfLatLonBBOX[0]; - layerMetadataItem["latlonboxright"] = myWMSLayer->layerMetadata.dfLatLonBBOX[1]; - layerMetadataItem["latlonboxbottom"] = myWMSLayer->layerMetadata.dfLatLonBBOX[2]; - layerMetadataItem["latlonboxtop"] = myWMSLayer->layerMetadata.dfLatLonBBOX[3]; - layerMetadataItem["bboxleft"] = myWMSLayer->layerMetadata.dfBBOX[0]; - layerMetadataItem["bboxright"] = myWMSLayer->layerMetadata.dfBBOX[1]; - layerMetadataItem["bboxbottom"] = myWMSLayer->layerMetadata.dfBBOX[2]; - layerMetadataItem["bboxtop"] = myWMSLayer->layerMetadata.dfBBOX[3]; - layerMetadataItem["width"] = myWMSLayer->layerMetadata.width; - layerMetadataItem["height"] = myWMSLayer->layerMetadata.height; - layerMetadataItem["cellsizex"] = myWMSLayer->layerMetadata.cellsizeX; - layerMetadataItem["cellsizey"] = myWMSLayer->layerMetadata.cellsizeY; + layerMetadataItem["name"] = metadataLayer->layerMetadata.name; + layerMetadataItem["title"] = metadataLayer->layerMetadata.title; + layerMetadataItem["group"] = metadataLayer->layerMetadata.group; + layerMetadataItem["abstract"] = metadataLayer->layerMetadata.abstract; + layerMetadataItem["nativeepsg"] = metadataLayer->layerMetadata.nativeEPSG; + layerMetadataItem["isqueryable"] = metadataLayer->layerMetadata.isQueryable; + layerMetadataItem["latlonboxleft"] = metadataLayer->layerMetadata.dfLatLonBBOX[0]; + layerMetadataItem["latlonboxright"] = metadataLayer->layerMetadata.dfLatLonBBOX[1]; + layerMetadataItem["latlonboxbottom"] = metadataLayer->layerMetadata.dfLatLonBBOX[2]; + layerMetadataItem["latlonboxtop"] = metadataLayer->layerMetadata.dfLatLonBBOX[3]; + layerMetadataItem["bboxleft"] = metadataLayer->layerMetadata.dfBBOX[0]; + layerMetadataItem["bboxright"] = metadataLayer->layerMetadata.dfBBOX[1]; + layerMetadataItem["bboxbottom"] = metadataLayer->layerMetadata.dfBBOX[2]; + layerMetadataItem["bboxtop"] = metadataLayer->layerMetadata.dfBBOX[3]; + layerMetadataItem["width"] = metadataLayer->layerMetadata.width; + layerMetadataItem["height"] = metadataLayer->layerMetadata.height; + layerMetadataItem["cellsizex"] = metadataLayer->layerMetadata.cellsizeX; + layerMetadataItem["cellsizey"] = metadataLayer->layerMetadata.cellsizeY; json variables; - for (auto lv : myWMSLayer->layerMetadata.variableList) { + for (auto lv : metadataLayer->layerMetadata.variableList) { json variable; - variable["units"] = lv->units; + variable["units"] = lv.units; variables.push_back(variable); } layerMetadataItem["variables"] = variables; - storeLayerMetadataInDb(myWMSLayer, "layermetadata", layerMetadataItem.dump()); + storeLayerMetadataInDb(metadataLayer, "layermetadata", layerMetadataItem.dump()); return 0; } -int loadLayerMetadataStructFromMetadataDb(MetadataLayer *myWMSLayer) { - if (!myWMSLayer->readFromDb) { +int loadLayerMetadataStructFromMetadataDb(MetadataLayer *metadataLayer) { + if (!metadataLayer->readFromDb) { return 1; } try { - CT::string layerMetadataAsJson = getLayerMetadataFromDb(myWMSLayer, "layermetadata"); + CT::string layerMetadataAsJson = getLayerMetadataFromDb(metadataLayer, "layermetadata"); if (layerMetadataAsJson.empty()) { return 1; } json a; auto i = a.parse(layerMetadataAsJson.c_str()); - myWMSLayer->layerMetadata.name = i["name"].get().c_str(); - myWMSLayer->layerMetadata.title = i["title"].get().c_str(); - myWMSLayer->layerMetadata.group = i["group"].get().c_str(); - myWMSLayer->layerMetadata.abstract = i["abstract"].get().c_str(); - myWMSLayer->layerMetadata.isQueryable = i["isqueryable"].get(); - myWMSLayer->layerMetadata.nativeEPSG = i["nativeepsg"].get().c_str(); - myWMSLayer->layerMetadata.dfLatLonBBOX[0] = i["latlonboxleft"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[1] = i["latlonboxright"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[2] = i["latlonboxbottom"].get(); - myWMSLayer->layerMetadata.dfLatLonBBOX[3] = i["latlonboxtop"].get(); - myWMSLayer->layerMetadata.dfBBOX[0] = i["bboxleft"].get(); - myWMSLayer->layerMetadata.dfBBOX[1] = i["bboxright"].get(); - myWMSLayer->layerMetadata.dfBBOX[2] = i["bboxbottom"].get(); - myWMSLayer->layerMetadata.dfBBOX[3] = i["bboxtop"].get(); - myWMSLayer->layerMetadata.width = i["width"].get(); - myWMSLayer->layerMetadata.height = i["height"].get(); - myWMSLayer->layerMetadata.cellsizeX = i["cellsizex"].get(); - myWMSLayer->layerMetadata.cellsizeY = i["cellsizey"].get(); + metadataLayer->layerMetadata.name = i["name"].get().c_str(); + metadataLayer->layerMetadata.title = i["title"].get().c_str(); + metadataLayer->layerMetadata.group = i["group"].get().c_str(); + metadataLayer->layerMetadata.abstract = i["abstract"].get().c_str(); + metadataLayer->layerMetadata.isQueryable = i["isqueryable"].get(); + metadataLayer->layerMetadata.nativeEPSG = i["nativeepsg"].get().c_str(); + metadataLayer->layerMetadata.dfLatLonBBOX[0] = i["latlonboxleft"].get(); + metadataLayer->layerMetadata.dfLatLonBBOX[1] = i["latlonboxright"].get(); + metadataLayer->layerMetadata.dfLatLonBBOX[2] = i["latlonboxbottom"].get(); + metadataLayer->layerMetadata.dfLatLonBBOX[3] = i["latlonboxtop"].get(); + metadataLayer->layerMetadata.dfBBOX[0] = i["bboxleft"].get(); + metadataLayer->layerMetadata.dfBBOX[1] = i["bboxright"].get(); + metadataLayer->layerMetadata.dfBBOX[2] = i["bboxbottom"].get(); + metadataLayer->layerMetadata.dfBBOX[3] = i["bboxtop"].get(); + metadataLayer->layerMetadata.width = i["width"].get(); + metadataLayer->layerMetadata.height = i["height"].get(); + metadataLayer->layerMetadata.cellsizeX = i["cellsizex"].get(); + metadataLayer->layerMetadata.cellsizeY = i["cellsizey"].get(); auto c = i["variables"]; for (auto styleJson : c.items()) { auto variableProps = styleJson.value(); - LayerMetadataVariable *variable = new LayerMetadataVariable(); - myWMSLayer->layerMetadata.variableList.push_back(variable); - variable->units = variableProps["units"].get().c_str(); + LayerMetadataVariable variable = {variableProps["units"].get().c_str()}; + metadataLayer->layerMetadata.variableList.push_back(variable); } - } catch (json::exception &e) { return 1; } catch (int e) { @@ -116,30 +114,30 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *myWMSLayer) { return 0; } -int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *myWMSLayer) { +int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *metadataLayer) { try { json projsettings; - for (auto projection : myWMSLayer->layerMetadata.projectionList) { - json item = {projection->dfBBOX[0], projection->dfBBOX[1], projection->dfBBOX[2], projection->dfBBOX[3]}; - projsettings[projection->name.c_str()] = item; + for (auto projection : metadataLayer->layerMetadata.projectionList) { + json item = {projection.dfBBOX[0], projection.dfBBOX[1], projection.dfBBOX[2], projection.dfBBOX[3]}; + projsettings[projection.name.c_str()] = item; } - storeLayerMetadataInDb(myWMSLayer, "projected_extents", projsettings.dump()); + storeLayerMetadataInDb(metadataLayer, "projected_extents", projsettings.dump()); } catch (int e) { return e; } return 0; } -int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *myWMSLayer) { - if (!myWMSLayer->readFromDb) { +int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *metadataLayer) { + if (!metadataLayer->readFromDb) { return 1; } - if (myWMSLayer->layerMetadata.projectionList.size() != 0) { - CDBError("myWMSLayer->layerMetadata.projectionList is not empty"); + if (metadataLayer->layerMetadata.projectionList.size() != 0) { + CDBError("metadataLayer->layerMetadata.projectionList is not empty"); return 1; } try { - CT::string projInfo = getLayerMetadataFromDb(myWMSLayer, "projected_extents"); + CT::string projInfo = getLayerMetadataFromDb(metadataLayer, "projected_extents"); if (projInfo.empty()) { return 1; } @@ -147,13 +145,13 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *myWMSLayer) { auto c = a.parse(projInfo.c_str()); for (auto d : c.items()) { auto bboxArray = d.value(); - LayerMetadataProjection *projection = new LayerMetadataProjection(); - myWMSLayer->layerMetadata.projectionList.push_back(projection); - projection->name = d.key().c_str(); - bboxArray[0].get_to((projection->dfBBOX[0])); - bboxArray[1].get_to((projection->dfBBOX[1])); - bboxArray[2].get_to((projection->dfBBOX[2])); - bboxArray[3].get_to((projection->dfBBOX[3])); + LayerMetadataProjection projection; + projection.name = d.key().c_str(); + bboxArray[0].get_to((projection.dfBBOX[0])); + bboxArray[1].get_to((projection.dfBBOX[1])); + bboxArray[2].get_to((projection.dfBBOX[2])); + bboxArray[3].get_to((projection.dfBBOX[3])); + metadataLayer->layerMetadata.projectionList.push_back(projection); } } catch (json::exception &e) { return 1; @@ -164,38 +162,38 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *myWMSLayer) { return 0; } -int storeLayerStyleListIntoMetadataDb(MetadataLayer *myWMSLayer) { +int storeLayerStyleListIntoMetadataDb(MetadataLayer *metadataLayer) { try { json styleListJson; - for (auto style : myWMSLayer->layerMetadata.styleList) { + for (auto style : metadataLayer->layerMetadata.styleList) { json item; - item["abstract"] = style->abstract.c_str(); - item["title"] = style->title.c_str(); - item["name"] = style->name.c_str(); + item["abstract"] = style.abstract.c_str(); + item["title"] = style.title.c_str(); + item["name"] = style.name.c_str(); styleListJson.push_back(item); } - storeLayerMetadataInDb(myWMSLayer, "stylelist", styleListJson.dump()); + storeLayerMetadataInDb(metadataLayer, "stylelist", styleListJson.dump()); } catch (int e) { return e; } return 0; } -int loadLayerStyleListFromMetadataDb(MetadataLayer *myWMSLayer) { - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { +int loadLayerStyleListFromMetadataDb(MetadataLayer *metadataLayer) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { return 0; } - if (!myWMSLayer->readFromDb) { + if (!metadataLayer->readFromDb) { return 1; } - if (myWMSLayer->layerMetadata.styleList.size() != 0) { - CDBError("myWMSLayer->layerMetadata.styleList is not empty"); + if (metadataLayer->layerMetadata.styleList.size() != 0) { + CDBError("metadataLayer->layerMetadata.styleList is not empty"); return 1; } try { - CT::string styleListAsJson = getLayerMetadataFromDb(myWMSLayer, "stylelist"); + CT::string styleListAsJson = getLayerMetadataFromDb(metadataLayer, "stylelist"); if (styleListAsJson.empty()) { return 1; } @@ -205,11 +203,12 @@ int loadLayerStyleListFromMetadataDb(MetadataLayer *myWMSLayer) { for (auto styleJson : c.items()) { auto styleProperties = styleJson.value(); - LayerMetadataStyle *style = new LayerMetadataStyle(); - myWMSLayer->layerMetadata.styleList.push_back(style); - style->name = styleProperties["name"].get().c_str(); - style->abstract = styleProperties["abstract"].get().c_str(); - style->title = styleProperties["title"].get().c_str(); + LayerMetadataStyle style = { + name : styleProperties["name"].get().c_str(), + title : styleProperties["title"].get().c_str(), + abstract : styleProperties["abstract"].get().c_str(), + }; + metadataLayer->layerMetadata.styleList.push_back(style); } } catch (json::exception &e) { @@ -221,21 +220,21 @@ int loadLayerStyleListFromMetadataDb(MetadataLayer *myWMSLayer) { return 0; } -int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myWMSLayer) { +int storeLayerDimensionListIntoMetadataDb(MetadataLayer *metadataLayer) { CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; - for (auto dimension : myWMSLayer->layerMetadata.dimList) { + for (auto dimension : metadataLayer->layerMetadata.dimList) { json item; - item["defaultValue"] = dimension->defaultValue.c_str(); - item["hasMultipleValues"] = dimension->hasMultipleValues; - item["hidden"] = dimension->hidden; - item["name"] = dimension->name.c_str(); - item["units"] = dimension->units.c_str(); - item["values"] = dimension->values.c_str(); - dimListJson[dimension->name.c_str()] = item; + item["defaultValue"] = dimension.defaultValue.c_str(); + item["hasMultipleValues"] = dimension.hasMultipleValues; + item["hidden"] = dimension.hidden; + item["name"] = dimension.name.c_str(); + item["units"] = dimension.units.c_str(); + item["values"] = dimension.values.c_str(); + dimListJson[dimension.name.c_str()] = item; } - storeLayerMetadataInDb(myWMSLayer, "dimensionlist", dimListJson.dump()); + storeLayerMetadataInDb(metadataLayer, "dimensionlist", dimListJson.dump()); } catch (json::exception &e) { return 1; } catch (int e) { @@ -244,16 +243,16 @@ int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myWMSLayer) { return 0; } -int loadLayerDimensionListFromMetadataDb(MetadataLayer *myWMSLayer) { - if (!myWMSLayer->readFromDb) { +int loadLayerDimensionListFromMetadataDb(MetadataLayer *metadataLayer) { + if (!metadataLayer->readFromDb) { return 1; } - if (myWMSLayer->layerMetadata.dimList.size() != 0) { - CDBError("myWMSLayer->layerMetadata.dimList is not empty"); + if (metadataLayer->layerMetadata.dimList.size() != 0) { + CDBError("metadataLayer->layerMetadata.dimList is not empty"); return 1; } try { - CT::string dimensionListAsJson = getLayerMetadataFromDb(myWMSLayer, "dimensionlist"); + CT::string dimensionListAsJson = getLayerMetadataFromDb(metadataLayer, "dimensionlist"); if (dimensionListAsJson.empty()) { return 1; } @@ -264,15 +263,15 @@ int loadLayerDimensionListFromMetadataDb(MetadataLayer *myWMSLayer) { for (auto d : c.items()) { auto dimensionProperties = d.value(); - LayerMetadataDim *dimension = new LayerMetadataDim(); - myWMSLayer->layerMetadata.dimList.push_back(dimension); - dimension->name = d.key().c_str(); - dimension->defaultValue = dimensionProperties["defaultValue"].get().c_str(); - dimension->hasMultipleValues = dimensionProperties["hasMultipleValues"].get(); - dimension->hidden = dimensionProperties["hidden"].get(); - dimension->name = dimensionProperties["name"].get().c_str(); - dimension->units = dimensionProperties["units"].get().c_str(); - dimension->values = dimensionProperties["values"].get().c_str(); + LayerMetadataDim dimension = { + name : dimensionProperties["name"].get().c_str(), + units : dimensionProperties["units"].get().c_str(), + values : dimensionProperties["values"].get().c_str(), + defaultValue : dimensionProperties["defaultValue"].get().c_str(), + hasMultipleValues : dimensionProperties["hasMultipleValues"].get(), + hidden : dimensionProperties["hidden"].get(), + }; + metadataLayer->layerMetadata.dimList.push_back(dimension); } } catch (json::exception &e) { return 1; @@ -287,12 +286,12 @@ int updateMetaDataTable(CDataSource *dataSource) { if (dataSource->srvParams->datasetLocation.empty()) { return 0; } - MetadataLayer *myWMSLayer = new MetadataLayer(); - myWMSLayer->layer = dataSource->cfgLayer; - myWMSLayer->srvParams = dataSource->srvParams; - myWMSLayer->dataSource = dataSource; - populateMyWMSLayerStruct(myWMSLayer, false); - storeMyWMSLayerIntoMetadataDb(myWMSLayer); - delete myWMSLayer; + MetadataLayer *metadataLayer = new MetadataLayer(); + metadataLayer->layer = dataSource->cfgLayer; + metadataLayer->srvParams = dataSource->srvParams; + metadataLayer->dataSource = dataSource; + populateMetadataLayerStruct(metadataLayer, false); + storeMetadataLayerIntoMetadataDb(metadataLayer); + delete metadataLayer; return 0; } \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index 441ea7499..3ff3b1ca4 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -5,10 +5,10 @@ #include #include "CXMLGen.h" -int storeLayerMetadataInDb(MetadataLayer *myWMSLayer, CT::string metadataKey, std::string metadataBlob); -CT::string getLayerMetadataFromDb(MetadataLayer *myWMSLayer, CT::string metadataKey); +int storeLayerMetadataInDb(MetadataLayer *metadataLayer, CT::string metadataKey, std::string metadataBlob); +CT::string getLayerMetadataFromDb(MetadataLayer *metadataLayer, CT::string metadataKey); -int storeMyWMSLayerIntoMetadataDb(MetadataLayer *myWMSLayer); +int storeMetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer); int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *layer); int loadLayerMetadataStructFromMetadataDb(MetadataLayer *layer); @@ -16,10 +16,10 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *layer); int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *layer); int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *layer); -int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myWMSLayer); +int storeLayerDimensionListIntoMetadataDb(MetadataLayer *metadataLayer); int loadLayerDimensionListFromMetadataDb(MetadataLayer *layer); -int storeLayerStyleListIntoMetadataDb(MetadataLayer *myWMSLayer); +int storeLayerStyleListIntoMetadataDb(MetadataLayer *metadataLayer); int loadLayerStyleListFromMetadataDb(MetadataLayer *layer); int updateMetaDataTable(CDataSource *dataSource); diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 700817350..4571d753c 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -6,132 +6,132 @@ #include #include "LayerUtils.h" -int populateMyWMSLayerStruct(MetadataLayer *myWMSLayer, bool readFromDB) { - myWMSLayer->readFromDb = readFromDB; - if (!myWMSLayer->srvParams->useMetadataTable()) { - myWMSLayer->readFromDb = false; +int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { + metadataLayer->readFromDb = readFromDB; + if (!metadataLayer->srvParams->useMetadataTable()) { + metadataLayer->readFromDb = false; } // Make the layer name CT::string layerUniqueName; - if (makeUniqueLayerName(&layerUniqueName, myWMSLayer->layer) != 0) { - myWMSLayer->hasError = true; + if (makeUniqueLayerName(&layerUniqueName, metadataLayer->layer) != 0) { + metadataLayer->hasError = true; return 1; } - myWMSLayer->layerMetadata.name.copy(&layerUniqueName); + metadataLayer->layerMetadata.name.copy(&layerUniqueName); // Create and datasource - if (myWMSLayer->dataSource == NULL) { - myWMSLayer->dataSource = new CDataSource(); - if (myWMSLayer->dataSource->setCFGLayer(myWMSLayer->srvParams, myWMSLayer->srvParams->configObj->Configuration[0], myWMSLayer->layer, myWMSLayer->layerMetadata.name.c_str(), -1) != 0) { + if (metadataLayer->dataSource == NULL) { + metadataLayer->dataSource = new CDataSource(); + if (metadataLayer->dataSource->setCFGLayer(metadataLayer->srvParams, metadataLayer->srvParams->configObj->Configuration[0], metadataLayer->layer, metadataLayer->layerMetadata.name.c_str(), -1) != + 0) { return 1; } } // Make the group CT::string layerGroup = ""; - if (myWMSLayer->layer->Group.size() > 0) { - if (myWMSLayer->layer->Group[0]->attr.value.empty() == false) { - layerGroup.copy(myWMSLayer->layer->Group[0]->attr.value.c_str()); + if (metadataLayer->layer->Group.size() > 0) { + if (metadataLayer->layer->Group[0]->attr.value.empty() == false) { + layerGroup.copy(metadataLayer->layer->Group[0]->attr.value.c_str()); } } - myWMSLayer->layerMetadata.group.copy(&layerGroup); + metadataLayer->layerMetadata.group.copy(&layerGroup); // Check if this layer is querable int datasetRestriction = CServerParams::checkDataRestriction(); if ((datasetRestriction & ALLOW_GFI)) { - myWMSLayer->layerMetadata.isQueryable = 1; + metadataLayer->layerMetadata.isQueryable = 1; } // Get Abstract - if (myWMSLayer->dataSource->cfgLayer->Abstract.size() > 0) { - myWMSLayer->layerMetadata.abstract = myWMSLayer->dataSource->cfgLayer->Abstract[0]->value; + if (metadataLayer->dataSource->cfgLayer->Abstract.size() > 0) { + metadataLayer->layerMetadata.abstract = metadataLayer->dataSource->cfgLayer->Abstract[0]->value; } // Fill in Layer title, with fallback to Name (later this can be set based on metadata or info from the file) - if (myWMSLayer->dataSource->cfgLayer->Title.size() != 0) { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Title[0]->value.c_str()); + if (metadataLayer->dataSource->cfgLayer->Title.size() != 0) { + metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->cfgLayer->Title[0]->value.c_str()); } else { - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->cfgLayer->Name[0]->value.c_str()); + metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->cfgLayer->Name[0]->value.c_str()); } - bool readFileInfo = readFromDB ? (loadLayerMetadataStructFromMetadataDb(myWMSLayer) != 0) : true; + bool readFileInfo = readFromDB ? (loadLayerMetadataStructFromMetadataDb(metadataLayer) != 0) : true; if (readFileInfo) { // Get a default file name for this layer to obtain some information - int status = getFileNameForLayer(myWMSLayer); + int status = getFileNameForLayer(metadataLayer); if (status != 0) { - myWMSLayer->hasError = 1; + metadataLayer->hasError = 1; return 1; } - if (myWMSLayer->dataSource->timeSteps.size() == 0) { - myWMSLayer->dataSource->addStep(myWMSLayer->fileName.c_str(), NULL); + if (metadataLayer->dataSource->timeSteps.size() == 0) { + metadataLayer->dataSource->addStep(metadataLayer->fileName.c_str(), NULL); } - if (getTitleForLayer(myWMSLayer) != 0) { - myWMSLayer->hasError = 1; + if (getTitleForLayer(metadataLayer) != 0) { + metadataLayer->hasError = 1; return 1; } CDataReader reader; - status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); + status = reader.open(metadataLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); if (status != 0) { - CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); + CDBError("Could not open file: %s", metadataLayer->dataSource->getFileName()); return 1; } - myWMSLayer->layerMetadata.dfBBOX[0] = myWMSLayer->dataSource->dfBBOX[0]; - myWMSLayer->layerMetadata.dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[1]; - myWMSLayer->layerMetadata.dfBBOX[2] = myWMSLayer->dataSource->dfBBOX[2]; - myWMSLayer->layerMetadata.dfBBOX[3] = myWMSLayer->dataSource->dfBBOX[3]; + metadataLayer->layerMetadata.dfBBOX[0] = metadataLayer->dataSource->dfBBOX[0]; + metadataLayer->layerMetadata.dfBBOX[1] = metadataLayer->dataSource->dfBBOX[1]; + metadataLayer->layerMetadata.dfBBOX[2] = metadataLayer->dataSource->dfBBOX[2]; + metadataLayer->layerMetadata.dfBBOX[3] = metadataLayer->dataSource->dfBBOX[3]; - myWMSLayer->layerMetadata.width = myWMSLayer->dataSource->dWidth; - myWMSLayer->layerMetadata.height = myWMSLayer->dataSource->dHeight; - myWMSLayer->layerMetadata.cellsizeX = myWMSLayer->dataSource->dfCellSizeX; - myWMSLayer->layerMetadata.cellsizeY = myWMSLayer->dataSource->dfCellSizeY; - myWMSLayer->layerMetadata.nativeEPSG = myWMSLayer->dataSource->nativeEPSG; + metadataLayer->layerMetadata.width = metadataLayer->dataSource->dWidth; + metadataLayer->layerMetadata.height = metadataLayer->dataSource->dHeight; + metadataLayer->layerMetadata.cellsizeX = metadataLayer->dataSource->dfCellSizeX; + metadataLayer->layerMetadata.cellsizeY = metadataLayer->dataSource->dfCellSizeY; + metadataLayer->layerMetadata.nativeEPSG = metadataLayer->dataSource->nativeEPSG; - auto v = myWMSLayer->dataSource->getDataObjectsVector(); + auto v = metadataLayer->dataSource->getDataObjectsVector(); for (auto d : (*v)) { - LayerMetadataVariable *layerMetadataVariable = new LayerMetadataVariable(); - layerMetadataVariable->units = (d->getUnits()); - myWMSLayer->layerMetadata.variableList.push_back(layerMetadataVariable); + LayerMetadataVariable layerMetadataVariable = {d->getUnits()}; + metadataLayer->layerMetadata.variableList.push_back(layerMetadataVariable); } } - if (getDimsForLayer(myWMSLayer) != 0) { - myWMSLayer->hasError = 1; + if (getDimsForLayer(metadataLayer) != 0) { + metadataLayer->hasError = 1; return 1; } // CDBDebug("getProjectionInformationForLayer"); - if (getProjectionInformationForLayer(myWMSLayer) != 0) { - myWMSLayer->hasError = 1; + if (getProjectionInformationForLayer(metadataLayer) != 0) { + metadataLayer->hasError = 1; return 1; } // CDBDebug("getStylesForLayer"); - if (getStylesForLayer(myWMSLayer) != 0) { - myWMSLayer->hasError = 1; + if (getStylesForLayer(metadataLayer) != 0) { + metadataLayer->hasError = 1; return 1; } - std::map projectionMap; + std::map projectionMap; // Make a unique list of projections - for (auto p : myWMSLayer->layerMetadata.projectionList) { - projectionMap[p->name.c_str()] = p; + for (auto p : metadataLayer->layerMetadata.projectionList) { + projectionMap[p.name.c_str()] = p; } - myWMSLayer->layerMetadata.projectionList.clear(); + metadataLayer->layerMetadata.projectionList.clear(); for (auto p : projectionMap) { - myWMSLayer->layerMetadata.projectionList.push_back(p.second); + metadataLayer->layerMetadata.projectionList.push_back(p.second); } - std::sort(myWMSLayer->layerMetadata.projectionList.begin(), myWMSLayer->layerMetadata.projectionList.end(), compareProjection); - std::sort(myWMSLayer->layerMetadata.dimList.begin(), myWMSLayer->layerMetadata.dimList.end(), compareDim); + std::sort(metadataLayer->layerMetadata.projectionList.begin(), metadataLayer->layerMetadata.projectionList.end(), compareProjection); + std::sort(metadataLayer->layerMetadata.dimList.begin(), metadataLayer->layerMetadata.dimList.end(), compareDim); return 0; } -int getDimsForLayer(MetadataLayer *myWMSLayer) { +int getDimsForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getDimsForLayer"); #endif @@ -141,50 +141,54 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { // int hastimedomain = 0; // Dimensions - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { - if (loadLayerDimensionListFromMetadataDb(myWMSLayer) == 0) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { + if (loadLayerDimensionListFromMetadataDb(metadataLayer) == 0) { // CDBDebug("LayerMetadata: dimensionList information fetched!"); return 0; } #ifdef CXMLGEN_DEBUG CDBDebug("Start looping dimensions"); - CDBDebug("Number of dimensions is %d", myWMSLayer->dataSource->cfgLayer->Dimension.size()); + CDBDebug("Number of dimensions is %d", metadataLayer->dataSource->cfgLayer->Dimension.size()); #endif /* Auto configure dimensions */ - for (size_t i = 0; i < myWMSLayer->dataSource->cfgLayer->Dimension.size(); i++) { + for (size_t i = 0; i < metadataLayer->dataSource->cfgLayer->Dimension.size(); i++) { /* This dimension is a filetimedate type, its values come from the modification date of the file */ - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.equals("filetimedate")) { - CT::string fileDate = CDirReader::getFileDate(myWMSLayer->layer->FilePath[0]->value.c_str()); - LayerMetadataDim *dim = new LayerMetadataDim(); - myWMSLayer->layerMetadata.dimList.push_back(dim); - dim->name.copy("time"); - dim->units.copy("ISO8601"); - dim->values.copy(fileDate.c_str()); - dim->defaultValue.copy(fileDate.c_str()); - dim->hasMultipleValues = true; + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.equals("filetimedate")) { + CT::string fileDate = CDirReader::getFileDate(metadataLayer->layer->FilePath[0]->value.c_str()); + + LayerMetadataDim dim; + dim.name.copy("time"); + dim.units.copy("ISO8601"); + dim.values.copy(fileDate.c_str()); + dim.defaultValue.copy(fileDate.c_str()); + dim.hasMultipleValues = true; + dim.hidden = false; + metadataLayer->layerMetadata.dimList.push_back(dim); break; } #ifdef CXMLGEN_DEBUG - CDBDebug("%d = %s / %s", i, myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(), myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + CDBDebug("%d = %s / %s", i, metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(), metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); #endif - if (i == 0 && myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.equals("none")) break; + if (i == 0 && metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.equals("none")) break; // Shorthand dimName - const char *pszDimName = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); + const char *pszDimName = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); // Create a new dim to store in the layer - LayerMetadataDim *dim = new LayerMetadataDim(); - myWMSLayer->layerMetadata.dimList.push_back(dim); - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + LayerMetadataDim dim; + dim.hidden = false; + dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + // Get the tablename CT::string tableName; - CServerParams *srvParam = myWMSLayer->dataSource->srvParams; + CServerParams *srvParam = metadataLayer->dataSource->srvParams; try { tableName = CDBFactory::getDBAdapter(srvParam->cfg) - ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName, myWMSLayer->dataSource); + ->getTableNameForPathFilterAndDimension(metadataLayer->layer->FilePath[0]->value.c_str(), metadataLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName, + metadataLayer->dataSource); } catch (int e) { - CDBError("Unable to create tableName from '%s' '%s' '%s'", myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName); + CDBError("Unable to create tableName from '%s' '%s' '%s'", metadataLayer->layer->FilePath[0]->value.c_str(), metadataLayer->layer->FilePath[0]->attr.filter.c_str(), pszDimName); return 1; } @@ -192,17 +196,17 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { bool isTimeDim = false; CDataReader reader; - int status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); + int status = reader.open(metadataLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); if (status != 0) { - CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); + CDBError("Could not open file: %s", metadataLayer->dataSource->getFileName()); return 1; } - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { hasMultipleValues = true; /* Automatically scan the time dimension, two types are avaible, start/stop/resolution and individual values */ // TODO try to detect automatically the time resolution of the layer. - CT::string varName = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); + CT::string varName = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str(); // CDBDebug("VarName = [%s]",varName.c_str()); int ind = varName.indexOf("time"); if (ind >= 0) { @@ -210,7 +214,7 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { CT::string units; isTimeDim = true; try { - myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")->getAttribute("units")->getDataAsString(&units); + metadataLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")->getAttribute("units")->getDataAsString(&units); } catch (int e) { } @@ -259,7 +263,7 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { isConst = false; } try { - CTime *time = CTime::GetCTimeInstance(myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")); + CTime *time = CTime::GetCTimeInstance(metadataLayer->dataSource->getDataObject(0)->cdfObject->getVariable("time")); if (time == nullptr) { CDBDebug(CTIME_GETINSTANCE_ERROR_MESSAGE); return 1; @@ -355,8 +359,8 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("Calculated a timeresolution of %s", iso8601timeRes.c_str()); #endif - myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.copy(iso8601timeRes.c_str()); - myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.copy("ISO8601"); + metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.copy(iso8601timeRes.c_str()); + metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.copy("ISO8601"); } } catch (int e) { } @@ -390,22 +394,22 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { // if(srvParam->requestType==REQUEST_WMS_GETCAPABILITIES) { - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); // Try to get units from the variable - dim->units.copy("NA"); - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { + dim.units.copy("NA"); + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { CT::string units; try { - myWMSLayer->dataSource->getDataObject(0)->cdfObject->getVariable(dim->name.c_str())->getAttribute("units")->getDataAsString(&units); - dim->units.copy(&units); + metadataLayer->dataSource->getDataObject(0)->cdfObject->getVariable(dim.name.c_str())->getAttribute("units")->getDataAsString(&units); + dim.units.copy(&units); } catch (int e) { } } - dim->hasMultipleValues = 1; + dim.hasMultipleValues = 1; if (isTimeDim == true) { - dim->units.copy("ISO8601"); + dim.units.copy("ISO8601"); for (size_t j = 0; j < values->getSize(); j++) { // 2011-01-01T22:00:01Z // 01234567890123456789 @@ -414,29 +418,29 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { values->getRecord(j)->get(0)->printconcat("Z"); } } - dim->units.copy("ISO8601"); + dim.units.copy("ISO8601"); } - if (!myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { + if (!metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { // Units are configured in the configuration file. - dim->units.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); + dim.units.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); } - const char *pszDefaultV = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); + const char *pszDefaultV = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); CT::string defaultV; if (pszDefaultV != NULL) defaultV = pszDefaultV; if (defaultV.length() == 0 || defaultV.equals("max", 3)) { - dim->defaultValue.copy(values->getRecord(values->getSize() - 1)->get(0)->c_str()); + dim.defaultValue.copy(values->getRecord(values->getSize() - 1)->get(0)->c_str()); } else if (defaultV.equals("min", 3)) { - dim->defaultValue.copy(values->getRecord(0)->get(0)->c_str()); + dim.defaultValue.copy(values->getRecord(0)->get(0)->c_str()); } else { - dim->defaultValue.copy(&defaultV); + dim.defaultValue.copy(&defaultV); } - dim->values.copy(values->getRecord(0)->get(0)); + dim.values.copy(values->getRecord(0)->get(0)); for (size_t j = 1; j < values->getSize(); j++) { - dim->values.printconcat(",%s", values->getRecord(j)->get(0)->c_str()); + dim.values.printconcat(",%s", values->getRecord(j)->get(0)->c_str()); } } } @@ -490,75 +494,76 @@ int getDimsForLayer(MetadataLayer *myWMSLayer) { } delete[] values;*/ - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.empty()) { // TODO CDBError("Dimension interval '%d' not defined", i); return 1; } - // strncpy(szInterval,myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(),32);szInterval[31]='\0'; - const char *pszInterval = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(); + // strncpy(szInterval,metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(),32);szInterval[31]='\0'; + const char *pszInterval = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.interval.c_str(); // hastimedomain = 1; // if(srvParam->requestType==REQUEST_WMS_GETCAPABILITIES) { CT::string dimUnits("ISO8601"); - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty() == false) { - dimUnits.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty() == false) { + dimUnits.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); } - dim->name.copy(myWMSLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); - dim->units.copy(dimUnits.c_str()); - dim->hasMultipleValues = 0; - // myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str() - const char *pszDefaultV = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); + dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.units.copy(dimUnits.c_str()); + dim.hasMultipleValues = 0; + // metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str() + const char *pszDefaultV = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str(); CT::string defaultV; if (pszDefaultV != NULL) defaultV = pszDefaultV; if (defaultV.length() == 0 || defaultV.equals("max", 3)) { - dim->defaultValue.copy(szMaxTime); + dim.defaultValue.copy(szMaxTime); } else if (defaultV.equals("min", 3)) { - dim->defaultValue.copy(szMinTime); + dim.defaultValue.copy(szMinTime); } else { - dim->defaultValue.copy(&defaultV); + dim.defaultValue.copy(&defaultV); } - if (dim->defaultValue.length() == 19) { - dim->defaultValue.concat("Z"); + if (dim.defaultValue.length() == 19) { + dim.defaultValue.concat("Z"); } CT::string minTime = szMinTime; if (minTime.equals(szMaxTime)) { - dim->values.print("%s", szMinTime); + dim.values.print("%s", szMinTime); } else { - dim->values.print("%s/%s/%s", szMinTime, szMaxTime, pszInterval); + dim.values.print("%s/%s/%s", szMinTime, szMaxTime, pszInterval); } } } // Check for forced values - if (!myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue.empty()) { - dim->values = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; - dim->defaultValue = myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; - dim->hasMultipleValues = false; + if (!metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue.empty()) { + dim.values = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; + dim.defaultValue = metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.fixvalue; + dim.hasMultipleValues = false; } // Check if it should be hidden - if (myWMSLayer->dataSource->cfgLayer->Dimension[i]->attr.hidden == true) { - dim->hidden = true; + if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.hidden == true) { + dim.hidden = true; } + metadataLayer->layerMetadata.dimList.push_back(dim); } } return 0; } -int getProjectionInformationForLayer(MetadataLayer *myWMSLayer) { +int getProjectionInformationForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getProjectionInformationForLayer"); #endif - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { - if (myWMSLayer->dataSource->cfgLayer->LatLonBox.size() == 0) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { + if (metadataLayer->dataSource->cfgLayer->LatLonBox.size() == 0) { return 0; } } - if (loadLayerProjectionAndExtentListFromMetadataDb(myWMSLayer) == 0) { + if (loadLayerProjectionAndExtentListFromMetadataDb(metadataLayer) == 0) { return 0; } @@ -566,13 +571,13 @@ int getProjectionInformationForLayer(MetadataLayer *myWMSLayer) { CGeoParams geo; CDataReader reader; - int status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); + int status = reader.open(metadataLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); if (status != 0) { - CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); + CDBError("Could not open file: %s", metadataLayer->dataSource->getFileName()); return 1; } - CServerParams *srvParam = myWMSLayer->dataSource->srvParams; + CServerParams *srvParam = metadataLayer->dataSource->srvParams; for (size_t p = 0; p < srvParam->cfg->Projection.size(); p++) { geo.CRS.copy(srvParam->cfg->Projection[p]->attr.id.c_str()); @@ -581,7 +586,7 @@ int getProjectionInformationForLayer(MetadataLayer *myWMSLayer) { StopWatch_Stop("start initreproj %s", geo.CRS.c_str()); #endif CImageWarper warper; - status = warper.initreproj(myWMSLayer->dataSource, &geo, &srvParam->cfg->Projection); + status = warper.initreproj(metadataLayer->dataSource, &geo, &srvParam->cfg->Projection); #ifdef MEASURETIME StopWatch_Stop("finished initreproj"); @@ -598,90 +603,77 @@ int getProjectionInformationForLayer(MetadataLayer *myWMSLayer) { return 1; } - // Find the max extent of the image - LayerMetadataProjection *myProjection = new LayerMetadataProjection(); - myWMSLayer->layerMetadata.projectionList.push_back(myProjection); - - // Set the projection string - myProjection->name.copy(srvParam->cfg->Projection[p]->attr.id.c_str()); - - // Calculate the extent for this projection - #ifdef MEASURETIME StopWatch_Stop("start findExtent"); #endif - warper.findExtent(myWMSLayer->dataSource, myProjection->dfBBOX); + double bboxToFind[4]; + + warper.findExtent(metadataLayer->dataSource, bboxToFind); + metadataLayer->layerMetadata.projectionList.push_back(LayerMetadataProjection(srvParam->cfg->Projection[p]->attr.id, bboxToFind)); #ifdef MEASURETIME StopWatch_Stop("finished findExtent"); #endif #ifdef CXMLGEN_DEBUG - CDBDebug("PROJ=%s\tBBOX=(%f,%f,%f,%f)", myProjection->name.c_str(), myProjection->dfBBOX[0], myProjection->dfBBOX[1], myProjection->dfBBOX[2], myProjection->dfBBOX[3]); + CDBDebug("PROJ=%s\tBBOX=(%f,%f,%f,%f)", myProjection.name.c_str(), myProjection.dfBBOX[0], myProjection.dfBBOX[1], myProjection.dfBBOX[2], myProjection.dfBBOX[3]); #endif // TODO!!! THIS IS DONE WAY TO OFTEN! // Calculate the latlonBBOX if (srvParam->cfg->Projection[p]->attr.id.equals("EPSG:4326")) { - for (int k = 0; k < 4; k++) myWMSLayer->layerMetadata.dfLatLonBBOX[k] = myProjection->dfBBOX[k]; + for (int k = 0; k < 4; k++) metadataLayer->layerMetadata.dfLatLonBBOX[k] = bboxToFind[k]; } warper.closereproj(); } // Add the layers native projection as well - if (!myWMSLayer->dataSource->nativeEPSG.empty()) { - LayerMetadataProjection *myProjection = new LayerMetadataProjection(); - myWMSLayer->layerMetadata.projectionList.push_back(myProjection); - myProjection->name.copy(myWMSLayer->dataSource->nativeEPSG.c_str()); - myProjection->dfBBOX[0] = myWMSLayer->dataSource->dfBBOX[0]; - myProjection->dfBBOX[3] = myWMSLayer->dataSource->dfBBOX[1]; - myProjection->dfBBOX[2] = myWMSLayer->dataSource->dfBBOX[2]; - myProjection->dfBBOX[1] = myWMSLayer->dataSource->dfBBOX[3]; + if (!metadataLayer->dataSource->nativeEPSG.empty()) { + metadataLayer->layerMetadata.projectionList.push_back(LayerMetadataProjection(metadataLayer->dataSource->nativeEPSG, metadataLayer->dataSource->dfBBOX)); } return 0; } -int getStylesForLayer(MetadataLayer *myWMSLayer) { - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { +int getStylesForLayer(MetadataLayer *metadataLayer) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded || metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { return 0; } - if (loadLayerStyleListFromMetadataDb(myWMSLayer) == 0) { + if (loadLayerStyleListFromMetadataDb(metadataLayer) == 0) { return 0; } // Auto configure styles - if (myWMSLayer->hasError == false) { - if (myWMSLayer->dataSource->cfgLayer->Styles.size() == 0) { - if (myWMSLayer->dataSource->dLayerType != CConfigReaderLayerTypeCascaded && myWMSLayer->dataSource->dLayerType != CConfigReaderLayerTypeLiveUpdate) { + if (metadataLayer->hasError == false) { + if (metadataLayer->dataSource->cfgLayer->Styles.size() == 0) { + if (metadataLayer->dataSource->dLayerType != CConfigReaderLayerTypeCascaded && metadataLayer->dataSource->dLayerType != CConfigReaderLayerTypeLiveUpdate) { #ifdef CXMLGEN_DEBUG - CDBDebug("cfgLayer->attr.type %d", myWMSLayer->dataSource->dLayerType); + CDBDebug("cfgLayer->attr.type %d", metadataLayer->dataSource->dLayerType); #endif - int status = CAutoConfigure::autoConfigureStyles(myWMSLayer->dataSource); + int status = CAutoConfigure::autoConfigureStyles(metadataLayer->dataSource); if (status != 0) { - myWMSLayer->hasError = 1; - CDBError("Unable to autoconfigure styles for layer %s", myWMSLayer->layerMetadata.name.c_str()); + metadataLayer->hasError = 1; + CDBError("Unable to autoconfigure styles for layer %s", metadataLayer->layerMetadata.name.c_str()); } // Get the defined styles for this layer } } } - CT::PointerList *styleListFromDataSource = myWMSLayer->dataSource->getStyleListForDataSource(myWMSLayer->dataSource); + CT::PointerList *styleListFromDataSource = metadataLayer->dataSource->getStyleListForDataSource(metadataLayer->dataSource); if (styleListFromDataSource == NULL) return 1; for (size_t j = 0; j < styleListFromDataSource->size(); j++) { - - LayerMetadataStyle *style = new LayerMetadataStyle(); - style->name.copy(styleListFromDataSource->get(j)->styleCompositionName.c_str()); - style->title.copy(styleListFromDataSource->get(j)->styleTitle.c_str()); - style->abstract.copy(styleListFromDataSource->get(j)->styleAbstract.c_str()); - - myWMSLayer->layerMetadata.styleList.push_back(style); + LayerMetadataStyle style = { + name : styleListFromDataSource->get(j)->styleCompositionName, + title : styleListFromDataSource->get(j)->styleTitle, + abstract : styleListFromDataSource->get(j)->styleAbstract + }; + metadataLayer->layerMetadata.styleList.push_back(style); } delete styleListFromDataSource; @@ -691,69 +683,69 @@ int getStylesForLayer(MetadataLayer *myWMSLayer) { bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) <= 0; } -bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } -bool compareDim(const LayerMetadataDim *p2, const LayerMetadataDim *p1) { return strcmp(p1->name.c_str(), p2->name.c_str()) <= 0; } -bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2) { return strcmp(p2->name.c_str(), p1->name.c_str()) <= 0; } +bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } +bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } +bool compareStyle(const LayerMetadataStyle &p1, const LayerMetadataStyle &p2) { return strcmp(p2.name.c_str(), p1.name.c_str()) <= 0; } -int getTitleForLayer(MetadataLayer *myWMSLayer) { +int getTitleForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getTitleForLayer"); #endif // Is this a cascaded WMS server? - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeCascaded) { return 0; } // This a liveupdate layer - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { - return layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(myWMSLayer); + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeLiveUpdate) { + return layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(metadataLayer); } // Get a nice name for this layer (if not configured) from the file attributes - if (myWMSLayer->dataSource->cfgLayer->Title.size() == 0) { - if (myWMSLayer->fileName.empty()) { - CDBError("No file name specified for layer %s", myWMSLayer->dataSource->layerName.c_str()); + if (metadataLayer->dataSource->cfgLayer->Title.size() == 0) { + if (metadataLayer->fileName.empty()) { + CDBError("No file name specified for layer %s", metadataLayer->dataSource->layerName.c_str()); return 1; } // TODO, possibly read file metadata from db in future? CDataReader reader; - int status = reader.open(myWMSLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); // TODO, would open header also work? - if (status != 0 || myWMSLayer->dataSource->getNumDataObjects() == 0) { - CDBError("Could not open file: %s", myWMSLayer->dataSource->getFileName()); + int status = reader.open(metadataLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); // TODO, would open header also work? + if (status != 0 || metadataLayer->dataSource->getNumDataObjects() == 0) { + CDBError("Could not open file: %s", metadataLayer->dataSource->getFileName()); return 1; } - CDF::Attribute *longName = myWMSLayer->dataSource->getDataObject(0)->cdfVariable->getAttributeNE("long_name"); + CDF::Attribute *longName = metadataLayer->dataSource->getDataObject(0)->cdfVariable->getAttributeNE("long_name"); if (longName != nullptr) { - myWMSLayer->layerMetadata.title.copy(longName->getDataAsString()); + metadataLayer->layerMetadata.title.copy(longName->getDataAsString()); // Concat variable name prefixed with longname - myWMSLayer->layerMetadata.title.printconcat(" (%s)", myWMSLayer->dataSource->getDataObject(0)->cdfVariable->name.c_str()); + metadataLayer->layerMetadata.title.printconcat(" (%s)", metadataLayer->dataSource->getDataObject(0)->cdfVariable->name.c_str()); } else { - CDF::Attribute *standardName = myWMSLayer->dataSource->getDataObject(0)->cdfVariable->getAttributeNE("standard_name"); + CDF::Attribute *standardName = metadataLayer->dataSource->getDataObject(0)->cdfVariable->getAttributeNE("standard_name"); if (standardName != nullptr) { - myWMSLayer->layerMetadata.title.copy(standardName->getDataAsString()); + metadataLayer->layerMetadata.title.copy(standardName->getDataAsString()); // Concat variable name prefixed with standardname - myWMSLayer->layerMetadata.title.printconcat(" (%s)", myWMSLayer->dataSource->getDataObject(0)->cdfVariable->name.c_str()); + metadataLayer->layerMetadata.title.printconcat(" (%s)", metadataLayer->dataSource->getDataObject(0)->cdfVariable->name.c_str()); } else { // Only variable name - myWMSLayer->layerMetadata.title.copy(myWMSLayer->dataSource->getDataObject(0)->cdfVariable->name); + metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->getDataObject(0)->cdfVariable->name); } } } return 0; } -int getFileNameForLayer(MetadataLayer *myWMSLayer) { +int getFileNameForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("getFileNameForLayer"); #endif - if (!myWMSLayer->fileName.empty()) { + if (!metadataLayer->fileName.empty()) { CDBDebug("seems already done"); return 0; } - CServerParams *srvParam = myWMSLayer->dataSource->srvParams; + CServerParams *srvParam = metadataLayer->dataSource->srvParams; - if (myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || myWMSLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { - if (myWMSLayer->dataSource->cfgLayer->Dimension.size() == 0) { - myWMSLayer->fileName.copy(myWMSLayer->dataSource->cfgLayer->FilePath[0]->value.c_str()); - if (CAutoConfigure::autoConfigureDimensions(myWMSLayer->dataSource) != 0) { + if (metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeDataBase || metadataLayer->dataSource->dLayerType == CConfigReaderLayerTypeStyled) { + if (metadataLayer->dataSource->cfgLayer->Dimension.size() == 0) { + metadataLayer->fileName.copy(metadataLayer->dataSource->cfgLayer->FilePath[0]->value.c_str()); + if (CAutoConfigure::autoConfigureDimensions(metadataLayer->dataSource) != 0) { CDBError("Unable to autoconfigure dimensions"); return 1; } @@ -761,28 +753,28 @@ int getFileNameForLayer(MetadataLayer *myWMSLayer) { /* A dimension where the default value is set to filetimedate should not be queried from the db */ bool dataBaseDimension = true; - if (myWMSLayer->layer->Dimension.size() == 1 && myWMSLayer->layer->Dimension[0]->attr.defaultV.equals("filetimedate")) { + if (metadataLayer->layer->Dimension.size() == 1 && metadataLayer->layer->Dimension[0]->attr.defaultV.equals("filetimedate")) { dataBaseDimension = false; } // Check if any dimension is given: - if (dataBaseDimension == false || (myWMSLayer->layer->Dimension.size() == 0) || (myWMSLayer->layer->Dimension.size() == 1 && myWMSLayer->layer->Dimension[0]->attr.name.equals("none"))) { + if (dataBaseDimension == false || (metadataLayer->layer->Dimension.size() == 0) || (metadataLayer->layer->Dimension.size() == 1 && metadataLayer->layer->Dimension[0]->attr.name.equals("none"))) { #ifdef CXMLGEN_DEBUG - CDBDebug("Layer %s has no dimensions", myWMSLayer->dataSource->layerName.c_str()); + CDBDebug("Layer %s has no dimensions", metadataLayer->dataSource->layerName.c_str()); #endif // If not, just return the filename as configured in the layer std::vector fileList; try { - fileList = CDBFileScanner::searchFileNames(myWMSLayer->dataSource->cfgLayer->FilePath[0]->value.c_str(), myWMSLayer->dataSource->cfgLayer->FilePath[0]->attr.filter, NULL); + fileList = CDBFileScanner::searchFileNames(metadataLayer->dataSource->cfgLayer->FilePath[0]->value.c_str(), metadataLayer->dataSource->cfgLayer->FilePath[0]->attr.filter, NULL); } catch (int linenr) { }; - myWMSLayer->fileName.copy(fileList[0].c_str()); + metadataLayer->fileName.copy(fileList[0].c_str()); return 0; } // Auto scan in case of autowms if (srvParam->isAutoLocalFileResourceEnabled() == true) { - int status = CDBFactory::getDBAdapter(srvParam->cfg)->autoUpdateAndScanDimensionTables(myWMSLayer->dataSource); + int status = CDBFactory::getDBAdapter(srvParam->cfg)->autoUpdateAndScanDimensionTables(metadataLayer->dataSource); if (status != 0) { CDBError("Unable to checkDimTables"); return 1; @@ -791,13 +783,13 @@ int getFileNameForLayer(MetadataLayer *myWMSLayer) { // Find the first occuring filename. CT::string tableName; - CT::string dimName(myWMSLayer->layer->Dimension[0]->attr.name.c_str()); + CT::string dimName(metadataLayer->layer->Dimension[0]->attr.name.c_str()); try { - tableName = - CDBFactory::getDBAdapter(srvParam->cfg) - ->getTableNameForPathFilterAndDimension(myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str(), myWMSLayer->dataSource); + tableName = CDBFactory::getDBAdapter(srvParam->cfg) + ->getTableNameForPathFilterAndDimension(metadataLayer->layer->FilePath[0]->value.c_str(), metadataLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str(), + metadataLayer->dataSource); } catch (int e) { - CDBError("Unable to create tableName from '%s' '%s' '%s'", myWMSLayer->layer->FilePath[0]->value.c_str(), myWMSLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str()); + CDBError("Unable to create tableName from '%s' '%s' '%s'", metadataLayer->layer->FilePath[0]->value.c_str(), metadataLayer->layer->FilePath[0]->attr.filter.c_str(), dimName.c_str()); return 1; } @@ -806,7 +798,7 @@ int getFileNameForLayer(MetadataLayer *myWMSLayer) { bool databaseError = false; if (values == NULL) { - CDBError("No files found for %s ", myWMSLayer->dataSource->layerName.c_str()); + CDBError("No files found for %s ", metadataLayer->dataSource->layerName.c_str()); databaseError = true; } if (databaseError == false) { @@ -814,11 +806,11 @@ int getFileNameForLayer(MetadataLayer *myWMSLayer) { #ifdef CXMLGEN_DEBUG CDBDebug("Query succeeded: Filename = %s", values->getRecord(0)->get(0)->c_str()); #endif - myWMSLayer->fileName.copy(values->getRecord(0)->get(0)); + metadataLayer->fileName.copy(values->getRecord(0)->get(0)); } else { // The file is not in the database, probably an error during the database scan has been detected earlier. // Ignore the file for now too - CDBError("Query for '%s' not succeeded", myWMSLayer->layer->FilePath[0]->value.c_str()); + CDBError("Query for '%s' not succeeded", metadataLayer->layer->FilePath[0]->value.c_str()); databaseError = true; } delete values; diff --git a/adagucserverEC/utils/XMLGenUtils.h b/adagucserverEC/utils/XMLGenUtils.h index ba1706276..d4be9ab92 100644 --- a/adagucserverEC/utils/XMLGenUtils.h +++ b/adagucserverEC/utils/XMLGenUtils.h @@ -3,14 +3,14 @@ #include "CXMLGen.h" -int getProjectionInformationForLayer(MetadataLayer *myWMSLayer); -int getDimsForLayer(MetadataLayer *myWMSLayer); -int getStylesForLayer(MetadataLayer *myWMSLayer); +int getProjectionInformationForLayer(MetadataLayer *metadataLayer); +int getDimsForLayer(MetadataLayer *metadataLayer); +int getStylesForLayer(MetadataLayer *metadataLayer); bool compareStringCase(const std::string &s1, const std::string &s2); -bool compareProjection(const LayerMetadataProjection *p1, const LayerMetadataProjection *p2); -bool compareDim(const LayerMetadataDim *p1, const LayerMetadataDim *p2); -bool compareStyle(const LayerMetadataStyle *p1, const LayerMetadataStyle *p2); -int populateMyWMSLayerStruct(MetadataLayer *myWMSLayer, bool readFromDb); -int getTitleForLayer(MetadataLayer *myWMSLayer); -int getFileNameForLayer(MetadataLayer *myWMSLayer); +bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2); +bool compareDim(const LayerMetadataDim &p1, const LayerMetadataDim &p2); +bool compareStyle(const LayerMetadataStyle &p1, const LayerMetadataStyle &p2); +int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDb); +int getTitleForLayer(MetadataLayer *metadataLayer); +int getFileNameForLayer(MetadataLayer *metadataLayer); #endif \ No newline at end of file diff --git a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml index bc63631be..3b6551ec9 100644 --- a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml +++ b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.27.0, of Sep 6 2024 09:44:02 + ADAGUCServer version 2.28.0, of Sep 11 2024 22:42:40 @@ -89,7 +89,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -130,24 +130,23 @@ 10.856452 48.895303 55.973600 - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + 2021-06-22T20:00:00Z @@ -158,23 +157,23 @@ 32.676474 37.353267 65.888228 - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + From 7ef7f50bf2091d83e373c97a448d890a396dac2f Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 09:07:39 +0200 Subject: [PATCH 31/50] Resolved comments --- adagucserverEC/utils/XMLGenUtils.cpp | 1 - adagucserverEC/utils/XMLGenUtils.h | 1 - 2 files changed, 2 deletions(-) diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 4571d753c..44b9681e0 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -685,7 +685,6 @@ bool compareStringCase(const std::string &s1, const std::string &s2) { return st bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } -bool compareStyle(const LayerMetadataStyle &p1, const LayerMetadataStyle &p2) { return strcmp(p2.name.c_str(), p1.name.c_str()) <= 0; } int getTitleForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG diff --git a/adagucserverEC/utils/XMLGenUtils.h b/adagucserverEC/utils/XMLGenUtils.h index d4be9ab92..de97d2b5a 100644 --- a/adagucserverEC/utils/XMLGenUtils.h +++ b/adagucserverEC/utils/XMLGenUtils.h @@ -9,7 +9,6 @@ int getStylesForLayer(MetadataLayer *metadataLayer); bool compareStringCase(const std::string &s1, const std::string &s2); bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2); bool compareDim(const LayerMetadataDim &p1, const LayerMetadataDim &p2); -bool compareStyle(const LayerMetadataStyle &p1, const LayerMetadataStyle &p2); int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDb); int getTitleForLayer(MetadataLayer *metadataLayer); int getFileNameForLayer(MetadataLayer *metadataLayer); From 895f0cbce14479115fcdfde39fd9a65face2a0e1 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 09:25:25 +0200 Subject: [PATCH 32/50] Resolved comments --- adagucserverEC/CServerConfig_CPPXSD.h | 20 ++++++++--------- adagucserverEC/CXMLSerializerInterface.cpp | 2 +- hclasses/CTString.cpp | 25 +++------------------- hclasses/CTString.h | 7 +----- 4 files changed, 15 insertions(+), 39 deletions(-) diff --git a/adagucserverEC/CServerConfig_CPPXSD.h b/adagucserverEC/CServerConfig_CPPXSD.h index 30ca99ad2..c1e0bda52 100644 --- a/adagucserverEC/CServerConfig_CPPXSD.h +++ b/adagucserverEC/CServerConfig_CPPXSD.h @@ -296,7 +296,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -641,7 +641,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -901,7 +901,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { @@ -1383,7 +1383,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -1452,7 +1452,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -1490,7 +1490,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -1545,7 +1545,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -1616,7 +1616,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; @@ -1866,7 +1866,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { @@ -2009,7 +2009,7 @@ class CServerConfig : public CXMLSerializerInterface { if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } if (rc == 1) { pt2Class = NULL; diff --git a/adagucserverEC/CXMLSerializerInterface.cpp b/adagucserverEC/CXMLSerializerInterface.cpp index 07a774542..3a9a4dd48 100644 --- a/adagucserverEC/CXMLSerializerInterface.cpp +++ b/adagucserverEC/CXMLSerializerInterface.cpp @@ -35,7 +35,7 @@ void CXMLObjectInterface::addElement(CXMLObjectInterface *baseClass, int rc, con if (rc == 0) if (value != NULL) { this->value.copy(value); - this->value.trimWhiteSpacesAndLinesSelf(); + this->value.trimSelf(true); } } diff --git a/hclasses/CTString.cpp b/hclasses/CTString.cpp index b08a8563c..086306e40 100644 --- a/hclasses/CTString.cpp +++ b/hclasses/CTString.cpp @@ -451,36 +451,17 @@ namespace CT { replaceSelf("<", ">"); } - void string::trimSelf() { + void string::trimSelf(bool trimWhiteSpace) { int s = -1, e = privatelength; const char *value = useStack ? stackValue : heapValue; for (size_t j = 0; j < privatelength; j++) { - if (value[j] != ' ') { + if (trimWhiteSpace ? value[j] != ' ' && value[j] != '\n' && value[j] != '\r' : value[j] != ' ') { s = j; break; } } for (size_t j = privatelength - 1; j > 0; j--) { - if (value[j] != ' ') { - e = j; - break; - } - } - substringSelf(s, e + 1); - } - - void string::trimWhiteSpacesAndLinesSelf() { - - int s = -1, e = privatelength; - const char *value = useStack ? stackValue : heapValue; - for (size_t j = 0; j < privatelength; j++) { - if (value[j] != ' ' && value[j] != '\n' && value[j] != '\r') { - s = j; - break; - } - } - for (size_t j = privatelength - 1; j > 0; j--) { - if (value[j] != ' ' && value[j] != '\n' && value[j] != '\r') { + if (trimWhiteSpace ? value[j] != ' ' && value[j] != '\n' && value[j] != '\r' : value[j] != ' ') { e = j; break; } diff --git a/hclasses/CTString.h b/hclasses/CTString.h index e08fedde7..013281a1e 100644 --- a/hclasses/CTString.h +++ b/hclasses/CTString.h @@ -353,12 +353,7 @@ namespace CT { /** * Removes spaces in this string */ - void trimSelf(); - - /** - * Removes spaces in this string - */ - void trimWhiteSpacesAndLinesSelf(); + void trimSelf(bool trimWhiteSpace = false); /** * Returns a new string with removed spaces From 84e93e67ff1b641161c50f0deb7d56bb0c61e0ce Mon Sep 17 00:00:00 2001 From: Lukas Phaf Date: Thu, 12 Sep 2024 11:31:44 +0200 Subject: [PATCH 33/50] Fix compare and struct initialisation. --- .../LayerTypeLiveUpdate.cpp | 2 +- adagucserverEC/utils/LayerMetadataStore.cpp | 18 +++++++++--------- adagucserverEC/utils/XMLGenUtils.cpp | 12 ++++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp index 571c99ead..afcd38796 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp @@ -54,7 +54,7 @@ int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *metada CT::string startTime = timeInstance.dateToISOString(timeInstance.offsetToDate(startTimeOffset)); CT::string stopTime = timeInstance.dateToISOString(timeInstance.offsetToDate(stopTimeOffset)); CT::string resTime = "PT1S"; - LayerMetadataDim dim = {name : "time", units : "ISO8601", values : startTime + "/" + stopTime + "/" + resTime, defaultValue : stopTime, hasMultipleValues : true, hidden : false}; + LayerMetadataDim dim = {.name = "time", .units = "ISO8601", .values = startTime + "/" + stopTime + "/" + resTime, .defaultValue = stopTime, .hasMultipleValues = true, .hidden = false}; metadataLayer->layerMetadata.dimList.push_back(dim); return 0; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 7c6997309..073127da4 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -204,9 +204,9 @@ int loadLayerStyleListFromMetadataDb(MetadataLayer *metadataLayer) { for (auto styleJson : c.items()) { auto styleProperties = styleJson.value(); LayerMetadataStyle style = { - name : styleProperties["name"].get().c_str(), - title : styleProperties["title"].get().c_str(), - abstract : styleProperties["abstract"].get().c_str(), + .name = styleProperties["name"].get().c_str(), + .title = styleProperties["title"].get().c_str(), + .abstract = styleProperties["abstract"].get().c_str(), }; metadataLayer->layerMetadata.styleList.push_back(style); } @@ -264,12 +264,12 @@ int loadLayerDimensionListFromMetadataDb(MetadataLayer *metadataLayer) { auto dimensionProperties = d.value(); LayerMetadataDim dimension = { - name : dimensionProperties["name"].get().c_str(), - units : dimensionProperties["units"].get().c_str(), - values : dimensionProperties["values"].get().c_str(), - defaultValue : dimensionProperties["defaultValue"].get().c_str(), - hasMultipleValues : dimensionProperties["hasMultipleValues"].get(), - hidden : dimensionProperties["hidden"].get(), + .name = dimensionProperties["name"].get().c_str(), + .units = dimensionProperties["units"].get().c_str(), + .values = dimensionProperties["values"].get().c_str(), + .defaultValue = dimensionProperties["defaultValue"].get().c_str(), + .hasMultipleValues = dimensionProperties["hasMultipleValues"].get(), + .hidden = dimensionProperties["hidden"].get(), }; metadataLayer->layerMetadata.dimList.push_back(dimension); } diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 44b9681e0..f1688b1c0 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -669,9 +669,9 @@ int getStylesForLayer(MetadataLayer *metadataLayer) { for (size_t j = 0; j < styleListFromDataSource->size(); j++) { LayerMetadataStyle style = { - name : styleListFromDataSource->get(j)->styleCompositionName, - title : styleListFromDataSource->get(j)->styleTitle, - abstract : styleListFromDataSource->get(j)->styleAbstract + .name = styleListFromDataSource->get(j)->styleCompositionName, + .title = styleListFromDataSource->get(j)->styleTitle, + .abstract = styleListFromDataSource->get(j)->styleAbstract }; metadataLayer->layerMetadata.styleList.push_back(style); } @@ -681,10 +681,10 @@ int getStylesForLayer(MetadataLayer *metadataLayer) { return 0; } -bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) <= 0; } +bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) < 0; } -bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } -bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.name.c_str(), p2.name.c_str()) <= 0; } +bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2) { return strcmp(p1.name.c_str(), p2.name.c_str()) < 0; } +bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.name.c_str(), p2.name.c_str()) < 0; } int getTitleForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG From 79e3b6472c751f51e93bb1c4523aab9382accdfc Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 14:21:39 +0200 Subject: [PATCH 34/50] Stylelist and projected_extents are now returned in metadata call --- adagucserverEC/CXMLGen.cpp | 2 +- adagucserverEC/utils/LayerMetadataStore.cpp | 3 ++- adagucserverEC/utils/LayerMetadataToJson.cpp | 2 ++ .../test_GetMetadataRequest_arcus_uwcw.json | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index f74978a60..53cd5aa06 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -971,7 +971,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen metadataLayerList.push_back(metadataLayer); metadataLayer->layer = srvParam->cfg->Layer[j]; metadataLayer->srvParams = srvParam; - populateLayerMetadataStruct(metadataLayer, false); + populateLayerMetadataStruct(metadataLayer, true); } #ifdef CXMLGEN_DEBUG diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 6cc329dea..c2e08f3f3 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -84,7 +84,6 @@ int getProjectionListAsJson(MetadataLayer *metadataLayer, json &projsettings) { int getStyleListMetadataAsJson(MetadataLayer *metadataLayer, json &styleListJson) { try { - json styleListJson; for (auto style : metadataLayer->layerMetadata.styleList) { json item; item["abstract"] = style.abstract.c_str(); @@ -275,10 +274,12 @@ int storeLayerStyleListIntoMetadataDb(MetadataLayer *metadataLayer) { try { json styleListJson; if (getStyleListMetadataAsJson(metadataLayer, styleListJson) != 0) { + CDBWarning("Unable to convert stylelist to json"); return 1; } storeLayerMetadataInDb(metadataLayer, "stylelist", styleListJson.dump()); } catch (int e) { + CDBWarning("Unable to store stylelist json in db"); return e; } return 0; diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp index b111917de..2ffe33a40 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.cpp +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -49,6 +49,8 @@ int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { json a; layer["layer"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "layermetadata").c_str()); layer["dims"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "dimensionlist").c_str()); + layer["styles"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "stylelist").c_str()); + layer["projected_extents"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "projected_extents").c_str()); datasetJSON[layerName.c_str()] = layer; } } diff --git a/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json index 2e98ac106..d956da471 100644 --- a/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json +++ b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json @@ -1 +1 @@ -{"adaguc.tests.arcus_uwcw":{"air_temperature_hagl":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"2","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"2"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-05-23T00:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-05-23T00:00:00Z"},"time":{"defaultValue":"2024-05-23T01:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-05-23T01:00:00Z/2024-05-25T12:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"cellsizex":2.262,"cellsizey":-1.404,"height":5,"projstring":"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"name":"air_temperature_hagl","nativeepsg":"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Air temperature at 2 m","variables":[{"label":"Air temperature at height above ground level","units":"C","variableName":"air-temperature-hagl"}]}},"baselayer":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"baselayer","nativeepsg":"","title":"baselayer","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"overlay":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"overlay","nativeepsg":"","title":"overlay","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"wind_speed_hagl_kts":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_kts","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in Knots","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_member_3":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"3","hasMultipleValues":1,"hidden":true,"name":"member","units":"-","values":"3"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_member_3","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms for member 3","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_wrong_dim_order":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_wrong_dim_order","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}}}} \ No newline at end of file +{"adaguc.tests.arcus_uwcw":{"air_temperature_hagl":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"2","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"2"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-05-23T00:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-05-23T00:00:00Z"},"time":{"defaultValue":"2024-05-23T01:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-05-23T01:00:00Z/2024-05-25T12:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"cellsizex":2.262,"cellsizey":-1.404,"height":5,"projstring":"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"name":"air_temperature_hagl","nativeepsg":"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Air temperature at 2 m","variables":[{"label":"Air temperature at height above ground level","units":"C","variableName":"air-temperature-hagl"}]},"projected_extents":{"CRS:84":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"EPSG:25831":[279486.1812954197,5426455.295657888,1106564.2353373389,6238397.008695408],"EPSG:25832":[-159076.87617991457,5426455.835210936,667922.7209491676,6244030.589292412],"EPSG:28992":[-240356.71842208208,110966.9656863024,587386.5771091208,907716.2661845956],"EPSG:3067":[-1463498.9830776574,5546449.239554093,-474452.673272648,6541622.309507573],"EPSG:32661":[1998797.905457981,-2749996.025036212,2930377.6013502805,-1808590.9618508],"EPSG:3411":[2678953.9310080702,-3278077.37705375,3855679.6740727946,-2102870.5947563853],"EPSG:3412":[-10153.773965045302,32170157.134147152,7858652.989459536,40121957.37289446],"EPSG:3575":[-778454.8974484425,-4476517.292346511,101208.7696378053,-3679953.3333079913],"EPSG:3857":[-1614.132616502462,6273334.420260729,1257409.3082554217,7560605.756670097],"EPSG:40000":[-1209.3506458945153,-4778668.033235625,935993.5627266401,-3831580.444517908],"EPSG:4258":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"EPSG:4326":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[-1197.2203277786082,5222308.94273356,932634.6353395386,5940218.262292647],"EPSG:7399":[-1117.3532306667896,5767402.687526328,870418.1666894319,6487641.4120019935],"EPSG:900913":[-1614.132616502462,6273334.420260729,1257409.3082554217,7560605.756670097],"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs":[-0.014499999999999957,48.99100000000001,11.2955,56.011]},"styles":[{"abstract":"","name":"auto/nearest","title":"auto/nearest"},{"abstract":"","name":"auto/bilinear","title":"auto/bilinear"},{"abstract":"","name":"auto/point","title":"auto/point"},{"abstract":"","name":"auto/barb","title":"auto/barb"}]},"baselayer":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"baselayer","nativeepsg":"","title":"baselayer","variables":[{"label":"Feature index","units":"","variableName":"features"}]},"projected_extents":{"CRS:84":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:25831":[-16131031.150574679,-19857792.70362381,17091777.78093742,19706964.9756592],"EPSG:25832":[-16131031.150574652,-19857962.084163167,17091777.78093727,19707318.918934327],"EPSG:28992":[-663975781.0572813,-403859772.41377914,410004471.97730243,413938428.1487843],"EPSG:3067":[-16131031.150574679,-19857792.70362381,17091777.78093741,19706964.9756592],"EPSG:32661":[-4.09756247202162e+23,-4.0900725774866876e+23,4.0975624720216196e+23,4.100060117865506e+23],"EPSG:3411":[-3.995085417515975e+23,-3.999958751107789e+23,3.999958751107789e+23,3.995085417515976e+23],"EPSG:3412":[-220508982.9324559,-220643392.92584136,220508982.93245587,220105916.71017215],"EPSG:3575":[-12703704.705042275,-12726968.206273872,12734725.857185293,12726968.206273874],"EPSG:3857":[-20037508.342789244,-242528680.94374272,20037508.342789255,18440002.895114224],"EPSG:40000":[-4.1222962495187324e+23,-4.114761144352805e+23,4.122296249518732e+23,4.124808971695681e+23],"EPSG:4258":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:4326":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[-17004040.858209416,-8625154.6651,16248305.708955677,8343003.652507055],"EPSG:7399":[-18037455.66495995,-9020047.848073646,17235790.968739517,8751339.20952538],"EPSG:900913":[-20037508.342789244,-242528680.94374272,20037508.342789255,18440002.895114224]},"styles":[{"abstract":"Land sea mask","name":"baselayer/nearest","title":"Land sea mask"}]},"overlay":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"overlay","nativeepsg":"","title":"overlay","variables":[{"label":"Feature index","units":"","variableName":"features"}]},"projected_extents":{"CRS:84":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:25831":[-16131031.150574679,-19857792.70362381,17091777.78093742,19706964.9756592],"EPSG:25832":[-16131031.150574652,-19857962.084163167,17091777.78093727,19707318.918934327],"EPSG:28992":[-663975781.0572813,-403859772.41377914,410004471.97730243,413938428.1487843],"EPSG:3067":[-16131031.150574679,-19857792.70362381,17091777.78093741,19706964.9756592],"EPSG:32661":[-4.09756247202162e+23,-4.0900725774866876e+23,4.0975624720216196e+23,4.100060117865506e+23],"EPSG:3411":[-3.995085417515975e+23,-3.999958751107789e+23,3.999958751107789e+23,3.995085417515976e+23],"EPSG:3412":[-220508982.9324559,-220643392.92584136,220508982.93245587,220105916.71017215],"EPSG:3575":[-12703704.705042275,-12726968.206273872,12734725.857185293,12726968.206273874],"EPSG:3857":[-20037508.342789244,-242528680.94374272,20037508.342789255,18440002.895114224],"EPSG:40000":[-4.1222962495187324e+23,-4.114761144352805e+23,4.122296249518732e+23,4.124808971695681e+23],"EPSG:4258":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:4326":[-180.0,-90.0,180.0000000000001,83.64513],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[-17004040.858209416,-8625154.6651,16248305.708955677,8343003.652507055],"EPSG:7399":[-18037455.66495995,-9020047.848073646,17235790.968739517,8751339.20952538],"EPSG:900913":[-20037508.342789244,-242528680.94374272,20037508.342789255,18440002.895114224]},"styles":[{"abstract":"Overlay countries","name":"overlay/polyline","title":"Overlay countries"}]},"wind_speed_hagl_kts":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_kts","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in Knots","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]},"projected_extents":{"CRS:84":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:25831":[437811.3655334021,5527784.335255393,934735.1907710517,6042106.724119729],"EPSG:25832":[7141.2223584101885,5527784.271765889,504001.52913632896,6046941.873044835],"EPSG:28992":[-78730.1086434589,212375.7679525322,418554.62119069515,716123.02374393],"EPSG:3067":[-1274464.275777185,5684017.862768228,-659259.1754318473,6314598.569791713],"EPSG:32661":[2152026.007675293,-2632289.9953658665,2729605.075927979,-2031799.0456094583],"EPSG:3411":[2919775.9260751205,-3076944.352398663,3661780.3901171233,-2338373.3575575305],"EPSG:3412":[1251745.5108308387,33196861.728375863,6007392.513716896,38141160.413573585],"EPSG:3575":[-599627.5303498495,-4380831.106729937,-64449.0017876477,-3873941.537594699],"EPSG:3857":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"EPSG:40000":[152943.66969345344,-4660251.504392219,734009.1307122523,-4056135.8607741036],"EPSG:4258":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:4326":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[169222.94852299697,5316800.382979992,743044.8942217636,5775068.926668733],"EPSG:7399":[152515.37622983695,5863250.73743419,689689.3479157749,6323585.901325594],"EPSG:900913":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031]},"styles":[{"abstract":"","name":"auto/nearest","title":"auto/nearest"},{"abstract":"","name":"auto/bilinear","title":"auto/bilinear"},{"abstract":"","name":"auto/point","title":"auto/point"},{"abstract":"","name":"auto/barb","title":"auto/barb"}]},"wind_speed_hagl_ms":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]},"projected_extents":{"CRS:84":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:25831":[437811.3655334021,5527784.335255393,934735.1907710517,6042106.724119729],"EPSG:25832":[7141.2223584101885,5527784.271765889,504001.52913632896,6046941.873044835],"EPSG:28992":[-78730.1086434589,212375.7679525322,418554.62119069515,716123.02374393],"EPSG:3067":[-1274464.275777185,5684017.862768228,-659259.1754318473,6314598.569791713],"EPSG:32661":[2152026.007675293,-2632289.9953658665,2729605.075927979,-2031799.0456094583],"EPSG:3411":[2919775.9260751205,-3076944.352398663,3661780.3901171233,-2338373.3575575305],"EPSG:3412":[1251745.5108308387,33196861.728375863,6007392.513716896,38141160.413573585],"EPSG:3575":[-599627.5303498495,-4380831.106729937,-64449.0017876477,-3873941.537594699],"EPSG:3857":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"EPSG:40000":[152943.66969345344,-4660251.504392219,734009.1307122523,-4056135.8607741036],"EPSG:4258":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:4326":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[169222.94852299697,5316800.382979992,743044.8942217636,5775068.926668733],"EPSG:7399":[152515.37622983695,5863250.73743419,689689.3479157749,6323585.901325594],"EPSG:900913":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031]},"styles":[{"abstract":"","name":"auto/nearest","title":"auto/nearest"},{"abstract":"","name":"auto/bilinear","title":"auto/bilinear"},{"abstract":"","name":"auto/point","title":"auto/point"},{"abstract":"","name":"auto/barb","title":"auto/barb"}]},"wind_speed_hagl_ms_member_3":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"3","hasMultipleValues":1,"hidden":true,"name":"member","units":"-","values":"3"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_member_3","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms for member 3","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]},"projected_extents":{"CRS:84":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:25831":[437811.3655334021,5527784.335255393,934735.1907710517,6042106.724119729],"EPSG:25832":[7141.2223584101885,5527784.271765889,504001.52913632896,6046941.873044835],"EPSG:28992":[-78730.1086434589,212375.7679525322,418554.62119069515,716123.02374393],"EPSG:3067":[-1274464.275777185,5684017.862768228,-659259.1754318473,6314598.569791713],"EPSG:32661":[2152026.007675293,-2632289.9953658665,2729605.075927979,-2031799.0456094583],"EPSG:3411":[2919775.9260751205,-3076944.352398663,3661780.3901171233,-2338373.3575575305],"EPSG:3412":[1251745.5108308387,33196861.728375863,6007392.513716896,38141160.413573585],"EPSG:3575":[-599627.5303498495,-4380831.106729937,-64449.0017876477,-3873941.537594699],"EPSG:3857":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"EPSG:40000":[152943.66969345344,-4660251.504392219,734009.1307122523,-4056135.8607741036],"EPSG:4258":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:4326":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[169222.94852299697,5316800.382979992,743044.8942217636,5775068.926668733],"EPSG:7399":[152515.37622983695,5863250.73743419,689689.3479157749,6323585.901325594],"EPSG:900913":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031]},"styles":[{"abstract":"","name":"auto/nearest","title":"auto/nearest"},{"abstract":"","name":"auto/bilinear","title":"auto/bilinear"},{"abstract":"","name":"auto/point","title":"auto/point"},{"abstract":"","name":"auto/barb","title":"auto/barb"}]},"wind_speed_hagl_ms_wrong_dim_order":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_wrong_dim_order","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]},"projected_extents":{"CRS:84":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:25831":[437811.3655334021,5527784.335255393,934735.1907710517,6042106.724119729],"EPSG:25832":[7141.2223584101885,5527784.271765889,504001.52913632896,6046941.873044835],"EPSG:28992":[-78730.1086434589,212375.7679525322,418554.62119069515,716123.02374393],"EPSG:3067":[-1274464.275777185,5684017.862768228,-659259.1754318473,6314598.569791713],"EPSG:32661":[2152026.007675293,-2632289.9953658665,2729605.075927979,-2031799.0456094583],"EPSG:3411":[2919775.9260751205,-3076944.352398663,3661780.3901171233,-2338373.3575575305],"EPSG:3412":[1251745.5108308387,33196861.728375863,6007392.513716896,38141160.413573585],"EPSG:3575":[-599627.5303498495,-4380831.106729937,-64449.0017876477,-3873941.537594699],"EPSG:3857":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"EPSG:40000":[152943.66969345344,-4660251.504392219,734009.1307122523,-4056135.8607741036],"EPSG:4258":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:4326":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"EPSG:50001":[-2000000.0,-2000000.0,10000000.0,8500000.0],"EPSG:54030":[169222.94852299697,5316800.382979992,743044.8942217636,5775068.926668733],"EPSG:7399":[152515.37622983695,5863250.73743419,689689.3479157749,6323585.901325594],"EPSG:900913":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031]},"styles":[{"abstract":"","name":"auto/nearest","title":"auto/nearest"},{"abstract":"","name":"auto/bilinear","title":"auto/bilinear"},{"abstract":"","name":"auto/point","title":"auto/point"},{"abstract":"","name":"auto/barb","title":"auto/barb"}]}}} \ No newline at end of file From 85438af47a960a74637d1d7d862f47915dec30bf Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 17:10:01 +0200 Subject: [PATCH 35/50] Added exception logic in metadata call --- adagucserverEC/utils/LayerMetadataToJson.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp index 2ffe33a40..03e3c6f5f 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.cpp +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -47,10 +47,13 @@ int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { if (layerNameInRequest.empty() || layerNameInRequest.equals(layerName.c_str())) { json layer; json a; - layer["layer"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "layermetadata").c_str()); - layer["dims"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "dimensionlist").c_str()); - layer["styles"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "stylelist").c_str()); - layer["projected_extents"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "projected_extents").c_str()); + try { + layer["layer"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "layermetadata").c_str()); + layer["dims"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "dimensionlist").c_str()); + // layer["styles"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "stylelist").c_str()); + // layer["projected_extents"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "projected_extents").c_str()); + } catch (json::exception &e) { + } datasetJSON[layerName.c_str()] = layer; } } From 6a82023ab979311b9fd4eeedd80e1b06b1c88a87 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Thu, 12 Sep 2024 17:19:26 +0200 Subject: [PATCH 36/50] Fixed bbox listings in CXMLGen --- adagucserverEC/CXMLGen.cpp | 6 +- ...cessor_SubstractLevels_GetCapabilities.xml | 67 ++++++++++--------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 75c80f663..87c478605 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -225,7 +225,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorconcat(&layerTitle); XMLDoc->concat("\n"); - for (auto proj : firstWMLayer->layerMetadata.projectionList) { + for (auto proj : layer->layerMetadata.projectionList) { XMLDoc->concat(""); XMLDoc->concat(&proj.name); XMLDoc->concat("\n"); @@ -262,7 +262,7 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorlayer->MetadataURL.size() > 0) { - CT::string layerMetaDataURL = firstWMLayer->layer->MetadataURL[0]->value.c_str(); + CT::string layerMetaDataURL = layer->layer->MetadataURL[0]->value.c_str(); layerMetaDataURL.replaceSelf("&", "&"); XMLDoc->concat(" \n"); XMLDoc->concat(" text/xml\n"); @@ -624,7 +624,7 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vector", layer->layerMetadata.dfLatLonBBOX[0], layer->layerMetadata.dfLatLonBBOX[2], layer->layerMetadata.dfLatLonBBOX[1], layer->layerMetadata.dfLatLonBBOX[3]); - for (auto proj : firstWMLayer->layerMetadata.projectionList) { + for (auto proj : layer->layerMetadata.projectionList) { if (srvParam->checkBBOXXYOrder(proj.name.c_str()) == true) { XMLDoc->printconcat("\n", proj.name.c_str(), proj.dfBBOX[1], proj.dfBBOX[0], proj.dfBBOX[3], proj.dfBBOX[2]); } else { diff --git a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml index 3b6551ec9..286a716bc 100644 --- a/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml +++ b/tests/expectedoutputs/TestDataPostProcessor/test_DataPostProcessor_SubstractLevels_GetCapabilities.xml @@ -15,7 +15,7 @@ view infoMapAccessService - ADAGUCServer version 2.28.0, of Sep 11 2024 22:42:40 + ADAGUCServer version 2.28.0, of Sep 12 2024 17:14:13 @@ -130,23 +130,24 @@ 10.856452 48.895303 55.973600 - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + + 2021-06-22T20:00:00Z @@ -157,23 +158,23 @@ 32.676474 37.353267 65.888228 - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + From 11fd40d982c33be667244d2c150e4bd789f6b6c1 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 10:02:18 +0200 Subject: [PATCH 37/50] Taking changes from get-layer-metadata --- adagucserverEC/CDBAdapter.h | 2 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 40 ++-- adagucserverEC/CDBAdapterPostgreSQL.h | 2 +- adagucserverEC/CDBAdapterSQLLite.cpp | 2 +- adagucserverEC/CDBAdapterSQLLite.h | 2 +- adagucserverEC/CMakeLists.txt | 2 + adagucserverEC/Types/LayerMetadataType.h | 4 +- adagucserverEC/utils/LayerMetadataStore.cpp | 236 +++++++++++++------ adagucserverEC/utils/LayerMetadataStore.h | 16 +- adagucserverEC/utils/LayerMetadataToJson.cpp | 66 ++++++ adagucserverEC/utils/LayerMetadataToJson.h | 8 + adagucserverEC/utils/XMLGenUtils.cpp | 37 +-- 12 files changed, 298 insertions(+), 119 deletions(-) create mode 100644 adagucserverEC/utils/LayerMetadataToJson.cpp create mode 100644 adagucserverEC/utils/LayerMetadataToJson.h diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index f4bf3d9f7..57f5cb5fb 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -98,7 +98,7 @@ class CDBAdapter { virtual int addFilesToDataBase() = 0; virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; - virtual CT::string getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) = 0; + virtual CDBStore::Store *getLayerMetadataStore(const char *datasetName) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 6d97c3624..73c56f989 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1122,7 +1122,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char return 0; } -CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey) { +CDBStore::Store *CDBAdapterPostgreSQL::getLayerMetadataStore(const char *datasetName) { #ifdef MEASURETIME StopWatch_Stop(">CDBAdapterPostgreSQL::getLayerMetadata"); #endif @@ -1133,43 +1133,31 @@ CT::string CDBAdapterPostgreSQL::getLayerMetadata(const char *datasetName, const #endif CPGSQLDB *dataBaseConnection = getDataBaseConnection(); if (dataBaseConnection == NULL) { - throw(__LINE__); + return nullptr; } - if (CServerParams::checkForValidTokens(datasetName, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-:/.") == false) { - CDBError("Invalid dataset name. "); - throw(__LINE__); + CT::string query; + if (datasetName != nullptr) { + if (CServerParams::checkForValidTokens(datasetName, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-:/.") == false) { + CDBError("Invalid dataset name. "); + throw(__LINE__); + } + query.print("SELECT datasetname, layername, metadatakey, blob FROM layermetadata WHERE datasetname = '%s';", datasetName); + } else { + query.print("SELECT datasetname, layername, metadatakey, blob FROM layermetadata"); } - CT::string query; - query.print("SELECT layername, metadatakey, blob FROM layermetadata WHERE datasetname = '%s';", datasetName); this->layerMetaDataStore = dataBaseConnection->queryToStore(query.c_str()); if (layerMetaDataStore == nullptr) { #ifdef CDBAdapterPostgreSQL_DEBUG CDBDebug("Unable query: \"%s\"", query.c_str()); #endif - return ""; - } - if (layerMetaDataStore->size() == 0) { - CDBDebug("No results for layerMetaDataStore \"%s\"", query.c_str()); - return ""; + return nullptr; } } - auto records = layerMetaDataStore->getRecords(); - for (auto record : records) { - if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { -#ifdef MEASURETIME - StopWatch_Stop("get("blob"); - } - } - // CDBDebug(store->getRecord(0)->get("blob")->c_str()); - #ifdef MEASURETIME StopWatch_Stop(" projectionList; std::vector dimList; std::vector styleList; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 073127da4..d608ab9f1 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -4,7 +4,101 @@ #include #include "XMLGenUtils.h" -int storeMetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer) { +int getDimensionListAsJson(MetadataLayer *metadataLayer, json &dimListJson) { + try { + + for (auto dimension : metadataLayer->layerMetadata.dimList) { + json item; + item["defaultValue"] = dimension.defaultValue.c_str(); + item["hasMultipleValues"] = dimension.hasMultipleValues; + item["hidden"] = dimension.hidden; + item["name"] = dimension.name.c_str(); + item["units"] = dimension.units.c_str(); + item["values"] = dimension.values.c_str(); + dimListJson[dimension.name.c_str()] = item; + } + } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); + return 1; + } + return 0; +} + +int getLayerBaseMetadataAsJson(MetadataLayer *metadataLayer, json &layerMetadataItem) { + try { + layerMetadataItem["name"] = metadataLayer->layerMetadata.name; + layerMetadataItem["title"] = metadataLayer->layerMetadata.title; + layerMetadataItem["group"] = metadataLayer->layerMetadata.group; + layerMetadataItem["abstract"] = metadataLayer->layerMetadata.abstract; + layerMetadataItem["nativeepsg"] = metadataLayer->layerMetadata.nativeEPSG; + + layerMetadataItem["isqueryable"] = metadataLayer->layerMetadata.isQueryable; + json latlonbox; + for (size_t j = 0; j < 4; j++) { + latlonbox.push_back(metadataLayer->layerMetadata.dfLatLonBBOX[j]); + } + layerMetadataItem["latlonbox"] = latlonbox; + + json gridspec; + json bbox; + for (size_t j = 0; j < 4; j++) { + bbox.push_back(metadataLayer->layerMetadata.dfBBOX[j]); + } + gridspec["bbox"] = bbox; + gridspec["width"] = metadataLayer->layerMetadata.width; + gridspec["height"] = metadataLayer->layerMetadata.height; + gridspec["cellsizex"] = metadataLayer->layerMetadata.cellsizeX; + gridspec["cellsizey"] = metadataLayer->layerMetadata.cellsizeY; + gridspec["projstring"] = metadataLayer->layerMetadata.projstring; + + layerMetadataItem["gridspec"] = gridspec; + + json variables; + for (auto lv : metadataLayer->layerMetadata.variableList) { + json variable; + variable["units"] = lv.units; + variable["label"] = lv.label; + variable["variableName"] = lv.variableName; + variables.push_back(variable); + } + layerMetadataItem["variables"] = variables; + + } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); + return 1; + } + return 0; +} +int getProjectionListAsJson(MetadataLayer *metadataLayer, json &projsettings) { + try { + for (auto projection : metadataLayer->layerMetadata.projectionList) { + json item = {projection.dfBBOX[0], projection.dfBBOX[1], projection.dfBBOX[2], projection.dfBBOX[3]}; + projsettings[projection.name.c_str()] = item; + } + } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); + return 1; + } + return 0; +} + +int getStyleListMetadataAsJson(MetadataLayer *metadataLayer, json &styleListJson) { + try { + for (auto style : metadataLayer->layerMetadata.styleList) { + json item; + item["abstract"] = style.abstract.c_str(); + item["title"] = style.title.c_str(); + item["name"] = style.name.c_str(); + styleListJson.push_back(item); + } + } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); + return 1; + } + return 0; +} + +int storemetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer) { storeLayerMetadataStructIntoMetadataDb(metadataLayer); storeLayerDimensionListIntoMetadataDb(metadataLayer); storeLayerProjectionAndExtentListIntoMetadataDb(metadataLayer); @@ -12,6 +106,14 @@ int storeMetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer) { return 0; } +int loadmetadataLayerFromMetadataDb(MetadataLayer *metadataLayer) { + loadLayerMetadataStructFromMetadataDb(metadataLayer); + loadLayerDimensionListFromMetadataDb(metadataLayer); + loadLayerProjectionAndExtentListFromMetadataDb(metadataLayer); + loadLayerStyleListFromMetadataDb(metadataLayer); + return 0; +} + CT::string getLayerMetadataFromDb(MetadataLayer *metadataLayer, CT::string metadataKey) { CT::string layerName = metadataLayer->dataSource->getLayerName(); CT::string datasetName = metadataLayer->dataSource->srvParams->datasetLocation; @@ -19,7 +121,25 @@ CT::string getLayerMetadataFromDb(MetadataLayer *metadataLayer, CT::string metad // CDBDebug("Not a dataset"); return ""; } - return CDBFactory::getDBAdapter(metadataLayer->dataSource->srvParams->cfg)->getLayerMetadata(datasetName, layerName, metadataKey); + CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(metadataLayer->dataSource->srvParams->cfg)->getLayerMetadataStore(datasetName); + if (layerMetaDataStore == nullptr) { + return ""; + } + auto records = layerMetaDataStore->getRecords(); + for (auto record : records) { + if (record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { +#ifdef MEASURETIME + StopWatch_Stop("get("blob"); + } + } + +#ifdef MEASURETIME + StopWatch_Stop("layerMetadata.name; - layerMetadataItem["title"] = metadataLayer->layerMetadata.title; - layerMetadataItem["group"] = metadataLayer->layerMetadata.group; - layerMetadataItem["abstract"] = metadataLayer->layerMetadata.abstract; - layerMetadataItem["nativeepsg"] = metadataLayer->layerMetadata.nativeEPSG; - layerMetadataItem["isqueryable"] = metadataLayer->layerMetadata.isQueryable; - layerMetadataItem["latlonboxleft"] = metadataLayer->layerMetadata.dfLatLonBBOX[0]; - layerMetadataItem["latlonboxright"] = metadataLayer->layerMetadata.dfLatLonBBOX[1]; - layerMetadataItem["latlonboxbottom"] = metadataLayer->layerMetadata.dfLatLonBBOX[2]; - layerMetadataItem["latlonboxtop"] = metadataLayer->layerMetadata.dfLatLonBBOX[3]; - layerMetadataItem["bboxleft"] = metadataLayer->layerMetadata.dfBBOX[0]; - layerMetadataItem["bboxright"] = metadataLayer->layerMetadata.dfBBOX[1]; - layerMetadataItem["bboxbottom"] = metadataLayer->layerMetadata.dfBBOX[2]; - layerMetadataItem["bboxtop"] = metadataLayer->layerMetadata.dfBBOX[3]; - layerMetadataItem["width"] = metadataLayer->layerMetadata.width; - layerMetadataItem["height"] = metadataLayer->layerMetadata.height; - layerMetadataItem["cellsizex"] = metadataLayer->layerMetadata.cellsizeX; - layerMetadataItem["cellsizey"] = metadataLayer->layerMetadata.cellsizeY; - json variables; - for (auto lv : metadataLayer->layerMetadata.variableList) { - json variable; - variable["units"] = lv.units; - variables.push_back(variable); + + if (getLayerBaseMetadataAsJson(metadataLayer, layerMetadataItem) != 0) { + return 1; } - layerMetadataItem["variables"] = variables; storeLayerMetadataInDb(metadataLayer, "layermetadata", layerMetadataItem.dump()); return 0; @@ -87,25 +187,33 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *metadataLayer) { metadataLayer->layerMetadata.abstract = i["abstract"].get().c_str(); metadataLayer->layerMetadata.isQueryable = i["isqueryable"].get(); metadataLayer->layerMetadata.nativeEPSG = i["nativeepsg"].get().c_str(); - metadataLayer->layerMetadata.dfLatLonBBOX[0] = i["latlonboxleft"].get(); - metadataLayer->layerMetadata.dfLatLonBBOX[1] = i["latlonboxright"].get(); - metadataLayer->layerMetadata.dfLatLonBBOX[2] = i["latlonboxbottom"].get(); - metadataLayer->layerMetadata.dfLatLonBBOX[3] = i["latlonboxtop"].get(); - metadataLayer->layerMetadata.dfBBOX[0] = i["bboxleft"].get(); - metadataLayer->layerMetadata.dfBBOX[1] = i["bboxright"].get(); - metadataLayer->layerMetadata.dfBBOX[2] = i["bboxbottom"].get(); - metadataLayer->layerMetadata.dfBBOX[3] = i["bboxtop"].get(); - metadataLayer->layerMetadata.width = i["width"].get(); - metadataLayer->layerMetadata.height = i["height"].get(); - metadataLayer->layerMetadata.cellsizeX = i["cellsizex"].get(); - metadataLayer->layerMetadata.cellsizeY = i["cellsizey"].get(); + + json latlonbox = i["latlonbox"]; + for (size_t j = 0; j < 4; j += 1) { + latlonbox[j].get_to((metadataLayer->layerMetadata.dfLatLonBBOX[j])); + } + json gridspec = i["gridspec"]; + json bbox = gridspec["bbox"]; + for (size_t j = 0; j < 4; j += 1) { + bbox[j].get_to((metadataLayer->layerMetadata.dfBBOX[j])); + } + metadataLayer->layerMetadata.width = gridspec["width"].get(); + metadataLayer->layerMetadata.height = gridspec["height"].get(); + metadataLayer->layerMetadata.cellsizeX = gridspec["cellsizex"].get(); + metadataLayer->layerMetadata.cellsizeY = gridspec["cellsizey"].get(); + metadataLayer->layerMetadata.projstring = gridspec["projstring"].get().c_str(); auto c = i["variables"]; for (auto styleJson : c.items()) { auto variableProps = styleJson.value(); - LayerMetadataVariable variable = {variableProps["units"].get().c_str()}; + LayerMetadataVariable variable = { + .variableName = variableProps["variableName"].get().c_str(), + .units = variableProps["units"].get().c_str(), + .label = variableProps["label"].get().c_str(), + }; metadataLayer->layerMetadata.variableList.push_back(variable); } } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { CDBError("loadLayerMetadataStructFromMetadataDb %d", e); @@ -117,9 +225,8 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *metadataLayer) { int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *metadataLayer) { try { json projsettings; - for (auto projection : metadataLayer->layerMetadata.projectionList) { - json item = {projection.dfBBOX[0], projection.dfBBOX[1], projection.dfBBOX[2], projection.dfBBOX[3]}; - projsettings[projection.name.c_str()] = item; + if (getProjectionListAsJson(metadataLayer, projsettings) != 0) { + return 1; } storeLayerMetadataInDb(metadataLayer, "projected_extents", projsettings.dump()); } catch (int e) { @@ -154,6 +261,7 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *metadataLayer) metadataLayer->layerMetadata.projectionList.push_back(projection); } } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerProjectionAndExtentListFromMetadataDb %d", e); @@ -165,15 +273,13 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *metadataLayer) int storeLayerStyleListIntoMetadataDb(MetadataLayer *metadataLayer) { try { json styleListJson; - for (auto style : metadataLayer->layerMetadata.styleList) { - json item; - item["abstract"] = style.abstract.c_str(); - item["title"] = style.title.c_str(); - item["name"] = style.name.c_str(); - styleListJson.push_back(item); + if (getStyleListMetadataAsJson(metadataLayer, styleListJson) != 0) { + CDBWarning("Unable to convert stylelist to json"); + return 1; } storeLayerMetadataInDb(metadataLayer, "stylelist", styleListJson.dump()); } catch (int e) { + CDBWarning("Unable to store stylelist json in db"); return e; } return 0; @@ -204,14 +310,15 @@ int loadLayerStyleListFromMetadataDb(MetadataLayer *metadataLayer) { for (auto styleJson : c.items()) { auto styleProperties = styleJson.value(); LayerMetadataStyle style = { - .name = styleProperties["name"].get().c_str(), - .title = styleProperties["title"].get().c_str(), - .abstract = styleProperties["abstract"].get().c_str(), + .name = styleProperties["name"].get().c_str(), + .title = styleProperties["title"].get().c_str(), + .abstract = styleProperties["abstract"].get().c_str(), }; metadataLayer->layerMetadata.styleList.push_back(style); } } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { // CDBError("loadLayerStyleListFromMetadataDb %d", e); @@ -224,18 +331,12 @@ int storeLayerDimensionListIntoMetadataDb(MetadataLayer *metadataLayer) { CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; - for (auto dimension : metadataLayer->layerMetadata.dimList) { - json item; - item["defaultValue"] = dimension.defaultValue.c_str(); - item["hasMultipleValues"] = dimension.hasMultipleValues; - item["hidden"] = dimension.hidden; - item["name"] = dimension.name.c_str(); - item["units"] = dimension.units.c_str(); - item["values"] = dimension.values.c_str(); - dimListJson[dimension.name.c_str()] = item; + if (getDimensionListAsJson(metadataLayer, dimListJson) != 0) { + return 1; } storeLayerMetadataInDb(metadataLayer, "dimensionlist", dimListJson.dump()); } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { return e; @@ -264,16 +365,17 @@ int loadLayerDimensionListFromMetadataDb(MetadataLayer *metadataLayer) { auto dimensionProperties = d.value(); LayerMetadataDim dimension = { - .name = dimensionProperties["name"].get().c_str(), - .units = dimensionProperties["units"].get().c_str(), - .values = dimensionProperties["values"].get().c_str(), - .defaultValue = dimensionProperties["defaultValue"].get().c_str(), - .hasMultipleValues = dimensionProperties["hasMultipleValues"].get(), - .hidden = dimensionProperties["hidden"].get(), + .name = dimensionProperties["name"].get().c_str(), + .units = dimensionProperties["units"].get().c_str(), + .values = dimensionProperties["values"].get().c_str(), + .defaultValue = dimensionProperties["defaultValue"].get().c_str(), + .hasMultipleValues = dimensionProperties["hasMultipleValues"].get(), + .hidden = dimensionProperties["hidden"].get(), }; metadataLayer->layerMetadata.dimList.push_back(dimension); } } catch (json::exception &e) { + CDBWarning("Unable to build json structure"); return 1; } catch (int e) { return e; @@ -291,7 +393,7 @@ int updateMetaDataTable(CDataSource *dataSource) { metadataLayer->srvParams = dataSource->srvParams; metadataLayer->dataSource = dataSource; populateMetadataLayerStruct(metadataLayer, false); - storeMetadataLayerIntoMetadataDb(metadataLayer); + storemetadataLayerIntoMetadataDb(metadataLayer); delete metadataLayer; return 0; } \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataStore.h b/adagucserverEC/utils/LayerMetadataStore.h index 3ff3b1ca4..c959d922a 100644 --- a/adagucserverEC/utils/LayerMetadataStore.h +++ b/adagucserverEC/utils/LayerMetadataStore.h @@ -4,11 +4,17 @@ #include #include #include "CXMLGen.h" +#include -int storeLayerMetadataInDb(MetadataLayer *metadataLayer, CT::string metadataKey, std::string metadataBlob); -CT::string getLayerMetadataFromDb(MetadataLayer *metadataLayer, CT::string metadataKey); +int getDimensionListAsJson(MetadataLayer *myMetadataLayer, json &dimListJson); +int getLayerBaseMetadataAsJson(MetadataLayer *myMetadataLayer, json &layerMetadataItem); +int getProjectionListAsJson(MetadataLayer *myMetadataLayer, json &projsettings); +int getStyleListMetadataAsJson(MetadataLayer *myMetadataLayer, json &styleListJson); -int storeMetadataLayerIntoMetadataDb(MetadataLayer *metadataLayer); +int storeLayerMetadataInDb(MetadataLayer *myMetadataLayer, CT::string metadataKey, std::string metadataBlob); +CT::string getLayerMetadataFromDb(MetadataLayer *myMetadataLayer, CT::string metadataKey); + +int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *myMetadataLayer); int storeLayerMetadataStructIntoMetadataDb(MetadataLayer *layer); int loadLayerMetadataStructFromMetadataDb(MetadataLayer *layer); @@ -16,10 +22,10 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *layer); int storeLayerProjectionAndExtentListIntoMetadataDb(MetadataLayer *layer); int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *layer); -int storeLayerDimensionListIntoMetadataDb(MetadataLayer *metadataLayer); +int storeLayerDimensionListIntoMetadataDb(MetadataLayer *myMetadataLayer); int loadLayerDimensionListFromMetadataDb(MetadataLayer *layer); -int storeLayerStyleListIntoMetadataDb(MetadataLayer *metadataLayer); +int storeLayerStyleListIntoMetadataDb(MetadataLayer *myMetadataLayer); int loadLayerStyleListFromMetadataDb(MetadataLayer *layer); int updateMetaDataTable(CDataSource *dataSource); diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp new file mode 100644 index 000000000..03e3c6f5f --- /dev/null +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -0,0 +1,66 @@ +#include "LayerMetadataToJson.h" +#include +#include "LayerMetadataStore.h" +#include +#include + +CT::string getBlob(CDBStore::Store *layerMetaDataStore, const char *datasetName, const char *layerName, const char *metadataKey) { + auto records = layerMetaDataStore->getRecords(); + for (auto record : records) { + if (record->get("datasetname")->equals(datasetName) && record->get("layername")->equals(layerName) && record->get("metadatakey")->equals(metadataKey)) { +#ifdef MEASURETIME + StopWatch_Stop("get("blob"); + } + } + return ""; +} + +int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { + json dataset; + json layer; + CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(srvParams->cfg)->getLayerMetadataStore(nullptr); + if (layerMetaDataStore == nullptr) { + return 1; + } + auto records = layerMetaDataStore->getRecords(); + std::map> datasetNames; + for (auto record : records) { + CT::string *datasetName = record->get("datasetname"); + CT::string *layerName = record->get("layername"); + if (datasetName != nullptr && layerName != nullptr) { + datasetNames[record->get("datasetname")->c_str()].insert(record->get("layername")->c_str()); + } + } + + CT::string layerNameInRequest; + if (srvParams->WMSLayers != nullptr && srvParams->WMSLayers->count > 0) { + layerNameInRequest = srvParams->WMSLayers[0].c_str(); + } + + for (auto dataset : datasetNames) { + auto dataSetName = dataset.first; + if (srvParams->datasetLocation.empty() || srvParams->datasetLocation.equals(dataSetName)) { + json datasetJSON; + for (auto layerName : dataset.second) { + if (layerNameInRequest.empty() || layerNameInRequest.equals(layerName.c_str())) { + json layer; + json a; + try { + layer["layer"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "layermetadata").c_str()); + layer["dims"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "dimensionlist").c_str()); + // layer["styles"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "stylelist").c_str()); + // layer["projected_extents"] = a.parse(getBlob(layerMetaDataStore, dataSetName.c_str(), layerName.c_str(), "projected_extents").c_str()); + } catch (json::exception &e) { + } + datasetJSON[layerName.c_str()] = layer; + } + } + + result[dataSetName.c_str()] = datasetJSON; + } + } + + return 0; +} \ No newline at end of file diff --git a/adagucserverEC/utils/LayerMetadataToJson.h b/adagucserverEC/utils/LayerMetadataToJson.h new file mode 100644 index 000000000..6ea0e9c52 --- /dev/null +++ b/adagucserverEC/utils/LayerMetadataToJson.h @@ -0,0 +1,8 @@ +#ifndef LAYERMETADATATOJSON_H +#define LAYERMETADATATOJSON_H +#include +#include + +int getLayerMetadataAsJson(CServerParams *srvParams, json &result); + +#endif \ No newline at end of file diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index f1688b1c0..34fbc71d1 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -55,9 +55,9 @@ int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { } else { metadataLayer->layerMetadata.title.copy(metadataLayer->dataSource->cfgLayer->Name[0]->value.c_str()); } - bool readFileInfo = readFromDB ? (loadLayerMetadataStructFromMetadataDb(metadataLayer) != 0) : true; if (readFileInfo) { + metadataLayer->readFromDb = false; // Get a default file name for this layer to obtain some information int status = getFileNameForLayer(metadataLayer); if (status != 0) { @@ -91,10 +91,20 @@ int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { metadataLayer->layerMetadata.cellsizeX = metadataLayer->dataSource->dfCellSizeX; metadataLayer->layerMetadata.cellsizeY = metadataLayer->dataSource->dfCellSizeY; metadataLayer->layerMetadata.nativeEPSG = metadataLayer->dataSource->nativeEPSG; + metadataLayer->layerMetadata.projstring = metadataLayer->dataSource->nativeProj4; auto v = metadataLayer->dataSource->getDataObjectsVector(); for (auto d : (*v)) { - LayerMetadataVariable layerMetadataVariable = {d->getUnits()}; + CDF::Attribute *longName = d->cdfVariable->getAttributeNE("long_name"); + if (longName == nullptr) { + longName = d->cdfVariable->getAttributeNE("standard_name"); + } + CT::string label = longName != nullptr ? longName->getDataAsString() : d->variableName; + LayerMetadataVariable layerMetadataVariable = { + .variableName = d->cdfVariable->name, + .units = d->getUnits(), + .label = label, + }; metadataLayer->layerMetadata.variableList.push_back(layerMetadataVariable); } } @@ -568,8 +578,6 @@ int getProjectionInformationForLayer(MetadataLayer *metadataLayer) { return 0; } - CGeoParams geo; - CDataReader reader; int status = reader.open(metadataLayer->dataSource, CNETCDFREADER_MODE_OPEN_DIMENSIONS); if (status != 0) { @@ -580,13 +588,18 @@ int getProjectionInformationForLayer(MetadataLayer *metadataLayer) { CServerParams *srvParam = metadataLayer->dataSource->srvParams; for (size_t p = 0; p < srvParam->cfg->Projection.size(); p++) { + CGeoParams geo; geo.CRS.copy(srvParam->cfg->Projection[p]->attr.id.c_str()); #ifdef MEASURETIME StopWatch_Stop("start initreproj %s", geo.CRS.c_str()); #endif CImageWarper warper; - status = warper.initreproj(metadataLayer->dataSource, &geo, &srvParam->cfg->Projection); + int status = warper.initreproj(metadataLayer->dataSource, &geo, &srvParam->cfg->Projection); + if (status != 0) { + warper.closereproj(); + return 1; + } #ifdef MEASURETIME StopWatch_Stop("finished initreproj"); @@ -598,19 +611,14 @@ int getProjectionInformationForLayer(MetadataLayer *metadataLayer) { CDBDebug("Unable to initialize projection "); } #endif - if (status != 0) { - warper.closereproj(); - return 1; - } #ifdef MEASURETIME StopWatch_Stop("start findExtent"); #endif double bboxToFind[4]; - warper.findExtent(metadataLayer->dataSource, bboxToFind); - metadataLayer->layerMetadata.projectionList.push_back(LayerMetadataProjection(srvParam->cfg->Projection[p]->attr.id, bboxToFind)); + metadataLayer->layerMetadata.projectionList.push_back(LayerMetadataProjection(geo.CRS.c_str(), bboxToFind)); #ifdef MEASURETIME StopWatch_Stop("finished findExtent"); @@ -622,7 +630,7 @@ int getProjectionInformationForLayer(MetadataLayer *metadataLayer) { // TODO!!! THIS IS DONE WAY TO OFTEN! // Calculate the latlonBBOX - if (srvParam->cfg->Projection[p]->attr.id.equals("EPSG:4326")) { + if (geo.CRS.equals("EPSG:4326")) { for (int k = 0; k < 4; k++) metadataLayer->layerMetadata.dfLatLonBBOX[k] = bboxToFind[k]; } @@ -669,10 +677,7 @@ int getStylesForLayer(MetadataLayer *metadataLayer) { for (size_t j = 0; j < styleListFromDataSource->size(); j++) { LayerMetadataStyle style = { - .name = styleListFromDataSource->get(j)->styleCompositionName, - .title = styleListFromDataSource->get(j)->styleTitle, - .abstract = styleListFromDataSource->get(j)->styleAbstract - }; + .name = styleListFromDataSource->get(j)->styleCompositionName, .title = styleListFromDataSource->get(j)->styleTitle, .abstract = styleListFromDataSource->get(j)->styleAbstract}; metadataLayer->layerMetadata.styleList.push_back(style); } From 33f5e1cd8886ccb9efd438cc6298427ef752c6d3 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 10:07:24 +0200 Subject: [PATCH 38/50] Fixed tests --- adagucserverEC/Types/LayerMetadataType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index 207fadbd6..ba2d78541 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -16,7 +16,7 @@ struct LayerMetadataDim { struct LayerMetadataProjection { LayerMetadataProjection() {} - LayerMetadataProjection(CT::string &name, double bbox[]) { + LayerMetadataProjection(CT::string name, double bbox[]) { this->name = name; for (size_t j = 0; j < 4; j++) { this->dfBBOX[j] = bbox[j]; From 52b2fa95d1f8f4a97819f09919a486c00faa336b Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 10:34:24 +0200 Subject: [PATCH 39/50] Using TIMESTAMPTZ in layermetadatatable --- CCDFDataModel/CTime.cpp | 2 +- adagucserverEC/CDBAdapterPostgreSQL.cpp | 4 ++-- adagucserverEC/CDBAdapterSQLLite.cpp | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CCDFDataModel/CTime.cpp b/CCDFDataModel/CTime.cpp index 5f5198dd7..e873760e1 100644 --- a/CCDFDataModel/CTime.cpp +++ b/CCDFDataModel/CTime.cpp @@ -878,7 +878,7 @@ CT::string CTime::currentDateTime() { strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", gmtime(&curTime.tv_sec)); char currentTime[100] = ""; - snprintf(currentTime, 99, "%s:%03dZ", buffer, milli); + snprintf(currentTime, 99, "%s.%03dZ", buffer, milli); return currentTime; } diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index 73c56f989..ebdfda971 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -624,6 +624,7 @@ void CDBAdapterPostgreSQL::addToLookupTable(const char *path, const char *filter CT::string CDBAdapterPostgreSQL::generateRandomTableName() { CT::string tableName; tableName.print("t%s_%s", CTime::currentDateTime().c_str(), CServerParams::randomString(20).c_str()); + tableName.replaceSelf(".", ""); tableName.replaceSelf(":", ""); tableName.replaceSelf("-", ""); tableName.replaceSelf("Z", ""); @@ -1094,7 +1095,7 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char return -1; } - CT::string tableColumns("datasetname varchar (511), layername varchar (511), metadatakey varchar (255), updatetime TIMESTAMP, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); + CT::string tableColumns("datasetname varchar (511), layername varchar (511), metadatakey varchar (255), updatetime TIMESTAMPTZ, blob JSONB, PRIMARY KEY (datasetname, layername, metadatakey)"); int status = dataBaseConnection->checkTable("layermetadata", tableColumns.c_str()); if (status == 1) { @@ -1103,7 +1104,6 @@ int CDBAdapterPostgreSQL::storeLayerMetadata(const char *datasetName, const char } CT::string updateTime = CTime::currentDateTime().c_str(); - updateTime.setSize(19); CT::string query; query.print("INSERT INTO layermetadata (datasetname, layername, metadatakey, updatetime, blob) " "VALUES (E'%s',E'%s', E'%s', E'%s', E'%s') " diff --git a/adagucserverEC/CDBAdapterSQLLite.cpp b/adagucserverEC/CDBAdapterSQLLite.cpp index 217fec095..dd0a60478 100644 --- a/adagucserverEC/CDBAdapterSQLLite.cpp +++ b/adagucserverEC/CDBAdapterSQLLite.cpp @@ -922,6 +922,7 @@ CT::string CDBAdapterSQLLite::getTableNameForPathFilterAndDimension(const char * randomTableString.concat("_"); randomTableString.concat(CServerParams::randomString(20)); randomTableString.replaceSelf(":", ""); + randomTableString.replaceSelf(".", ""); randomTableString.replaceSelf("-", ""); randomTableString.replaceSelf("Z", ""); From a48c9d256d626ae5ce41c8ef634b33cd01db0b99 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 12:50:38 +0200 Subject: [PATCH 40/50] Added --updatelayermetadata option to update layermetadata --- adagucserverEC/CDBFileScanner.cpp | 36 ++++- adagucserverEC/CDBFileScanner.h | 2 + adagucserverEC/CMakeLists.txt | 4 + adagucserverEC/CRequest.cpp | 154 ------------------- adagucserverEC/CRequest.h | 1 - adagucserverEC/Definitions.h | 1 - adagucserverEC/adagucserver.cpp | 125 +++++++-------- adagucserverEC/utils/ConfigurationUtils.cpp | 21 +++ adagucserverEC/utils/ConfigurationUtils.h | 12 ++ adagucserverEC/utils/UpdateLayerMetadata.cpp | 58 +++++++ adagucserverEC/utils/UpdateLayerMetadata.h | 9 ++ 11 files changed, 191 insertions(+), 232 deletions(-) create mode 100644 adagucserverEC/utils/ConfigurationUtils.cpp create mode 100644 adagucserverEC/utils/ConfigurationUtils.h create mode 100644 adagucserverEC/utils/UpdateLayerMetadata.cpp create mode 100644 adagucserverEC/utils/UpdateLayerMetadata.h diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 988ea299a..f3f59f123 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -32,6 +32,7 @@ #include "CCreateTiles.h" #include #include "utils/LayerMetadataStore.h" +#include "utils/ConfigurationUtils.h" const char *CDBFileScanner::className = "CDBFileScanner"; std::vector CDBFileScanner::tableNamesDone; // #define CDBFILESCANNER_DEBUG @@ -951,7 +952,34 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: if (fileToUpdate.length() == 0) { // No file specified, just scan the directory for matching filenames. try { - fileList = searchFileNames(dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); + if (scanFlags & CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY) { + if (checkIfPathIsFile(dataSource->cfgLayer->FilePath[0]->value.c_str())) { + fileList.push_back(dataSource->cfgLayer->FilePath[0]->value.c_str()); + CDBDebug("Obtained filename from layer configuration [%s]", dataSource->cfgLayer->FilePath[0]->value.c_str()); + } else { + CDBDebug("CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY"); + int status = CRequest::setDimValuesForDataSource(dataSource, dataSource->srvParams); + if (status != 0) { + CDBError("setDimValuesForDataSource"); + return 1; + } + status = CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); + if (status != 0) { + CDBError("fillDimValuesForDataSource"); + return 1; + } + status = CRequest::queryDimValuesForDataSource(dataSource, dataSource->srvParams); + if (status != 0) { + CDBError("queryDimValuesForDataSource"); + return 1; + } + fileList.push_back(dataSource->getFileName()); + CDBDebug("Queried file from database with filename [%s]", dataSource->getFileName()); + } + } else { + fileList = searchFileNames(dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); + } + } catch (int linenr) { CDBDebug("Exception in searchFileNames [%s] [%s]", dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); return 0; @@ -1089,10 +1117,8 @@ std::vector CDBFileScanner::searchFileNames(const char *path, CT::s } } } - // CDBDebug("Checking if this is a file: [%s]", filePath.c_str()); - if (filePath.endsWith(".nc") || filePath.endsWith(".h5") || filePath.endsWith(".hdf5") || filePath.endsWith(".he5") || filePath.endsWith(".png") || filePath.endsWith(".csv") || - filePath.endsWith(".geojson") || filePath.endsWith(".json") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("dodsc://")) { - // Add single file or opendap URL. + + if (checkIfPathIsFile(filePath)) { std::vector fileList; fileList.push_back(filePath.c_str()); // CDBDebug("%s is a file",filePath.c_str()); diff --git a/adagucserverEC/CDBFileScanner.h b/adagucserverEC/CDBFileScanner.h index 316024310..157efb038 100644 --- a/adagucserverEC/CDBFileScanner.h +++ b/adagucserverEC/CDBFileScanner.h @@ -42,6 +42,8 @@ #define CDBFILESCANNER_RECREATETABLES 32 #define CDBFILESCANNER_CLEANFILES 64 #define CDBFILESCANNER_DONOTTILE 128 +#define CDBUPDATE_LAYER_METADATA 256 +#define CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY 512 // Return type to indicate nothing was found. #define CDBFILESCANNER_RETURN_FILEDOESNOTMATCH 100 diff --git a/adagucserverEC/CMakeLists.txt b/adagucserverEC/CMakeLists.txt index 5dd9b9d62..69b234c70 100644 --- a/adagucserverEC/CMakeLists.txt +++ b/adagucserverEC/CMakeLists.txt @@ -77,6 +77,10 @@ add_library( utils/LayerUtils.cpp utils/LayerMetadataToJson.h utils/LayerMetadataToJson.cpp + utils/UpdateLayerMetadata.h + utils/UpdateLayerMetadata.cpp + utils/ConfigurationUtils.h + utils/ConfigurationUtils.cpp Types/LayerMetadataType.h CDataPostProcessors/CDataPostProcessor_AddFeatures.cpp CDataPostProcessors/CDataPostProcessor_AddFeatures.h diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index 2c2086e1c..ab16cc12a 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -414,151 +414,6 @@ int CRequest::generateGetReferenceTimesDoc(CT::string *result, CDataSource *data return 0; } -int CRequest::process_wms_getstyles_request() { - // int status; - // if(srvParam->serviceType==SERVICE_WMS){ - // if(srvParam->Geo->dWidth>MAX_IMAGE_WIDTH){ - // CDBError("Parameter WIDTH must be smaller than %d",MAX_IMAGE_WIDTH); - // return 1; - // } - // if(srvParam->Geo->dHeight>MAX_IMAGE_HEIGHT){ - // CDBError("Parameter HEIGHT must be smaller than %d",MAX_IMAGE_HEIGHT); - // return 1; - // } - // } - // CDrawImage plotCanvas; - // plotCanvas.setTrueColor(true); - // plotCanvas.createImage(int(srvParam->Geo->dWidth),int(srvParam->Geo->dHeight)); - // plotCanvas.create685Palette(); - // - // CImageDataWriter imageDataWriter; - // - // CDataSource * dataSource = new CDataSource(); - // //dataSource->setCFGLayer(srvParam,srvParam->configObj->Configuration[0],srvParam->cfg->Layer[0],"prediction",0); - // dataSource->addStep("",NULL); - // dataSource->getCDFDims()->addDimension("time","0",0); - // dataSource->setTimeStep(0); - // dataSource->srvParams=srvParam; - // dataSource->cfg=srvParam->configObj->Configuration[0]; - // dataSource->cfgLayer=srvParam->cfg->Layer[0]; - // CDataSource::DataObject *newDataObject = new CDataSource::DataObject(); - // newDataObject->variableName.copy("test"); - // dataSource->getDataObjectsVector()->push_back(newDataObject); - // dataSource->dLayerType=CConfigReaderLayerTypeStyled; - // - // - // - // - // plotCanvas.rectangle(0,0,plotCanvas.Geo->dWidth,plotCanvas.Geo->dHeight,CColor(255,255,255,255),CColor(255,255,255,255)); - // - // int legendWidth = 200; - // int legendHeight = 600; - // - // - // - // - // - // - // int posX=0; - // int posY=0; - // - // bool errorOccured = false; - // - // bool legendOnlyMode = true; - // try{ - // - // for(size_t j=0;jcfg->Style.size();j++){ - // CServerConfig::XMLE_Style* style = srvParam->cfg->Style[j]; - // CDBDebug("style %s",style->attr.name.c_str()); - // - // CT::PointerList *legendList = NULL; - // - // if(legendOnlyMode == false){ - // legendList = CServerParams::getLegendNames(style->Legend); - // }else{ - // legendList = new CT::PointerList(); - // for(size_t j=0;jcfg->Legend.size();j++){ - // - // legendList->push_back(new CT::string(srvParam->cfg->Legend[j]->attr.name.c_str())); - // - // } - // } - // - // CDBDebug("Found %d legends",legendList->size()); - // for(size_t i=0;isize();i++){ - // CDBDebug("legend %s",(*legendList)[i]->c_str()); - // - // int legendIndex = - // CImageDataWriter::getServerLegendIndexByName((*legendList)[i]->c_str(),srvParam->cfg->Legend); - // if(legendIndex == -1){ - // CDBError("Legend %s is not configured"); - // delete legendList; - // throw (__LINE__); - // } - // CDBDebug("Found legend index %d",legendIndex); - // - // CT::PointerList *renderMethodList = - // CImageDataWriter::getRenderMethodListForDataSource(dataSource,style); - // - // CDBDebug("Found %d rendermethods",renderMethodList->size()); - // // for(size_t r=0;rsize();r++){ - // // CDBDebug("Using - // %s->%s->%s",style->attr.name.c_str(),(*legendList)[i]->c_str(),(*renderMethodList)[r]->c_str()); - // // CT::string styleName; - // // styleName.print("%s/%s",style->attr.name.c_str(),(*renderMethodList)[r]->c_str()); - // // if(legendOnlyMode){ - // // styleName.print("%s",(*legendList)[i]->c_str()); - // // } - // // - // // - // // - // CImageDataWriter::makeStyleConfig(dataSource->styleConfiguration,dataSource);//,style->attr.name.c_str(),(*legendList)[i]->c_str(),(*renderMethodList)[r]->c_str()); - // // - // // CDrawImage legendImage; - // // legendImage.enableTransparency(true); - // // legendImage.createImage(&plotCanvas,legendWidth,legendHeight); - // // status = legendImage.createGDPalette(srvParam->cfg->Legend[legendIndex]);if(status != - // 0)throw(__LINE__); - // // - // // - // // - // legendImage.rectangle(0,0,legendImage.Geo->dWidth-1,legendImage.Geo->dHeight-1,CColor(255,255,255,255),CColor(0,0,255,255)); - // // status = imageDataWriter.createLegend(dataSource,&legendImage);if(status != 0)throw(__LINE__); - // // //posX = (legendNr++)*legendWidth; - // // - // // plotCanvas.draw(posX,posY,0,0,&legendImage); - // // - // plotCanvas.drawText(posX+4,posY+legendHeight-4,srvParam->cfg->WMS[0]->SubTitleFont[0]->attr.location.c_str(),8,0,styleName.c_str(),CColor(0,0,0,255),textBGColor); - // // - // // posX+=legendWidth; - // // if(posX>plotCanvas.Geo->dWidth){ - // // posX=0; - // // posY+=legendHeight; - // // } - // // if(legendOnlyMode)break; - // // } - // delete renderMethodList; - // } - // delete legendList; - // if(legendOnlyMode)break; - // } - // }catch(int e){ - // errorOccured = true; - // } - // - // - // - // - // delete dataSource; - // - // if(errorOccured){ - // return 1; - // } - // printf("%s%c%c\n","Content-Type:image/png",13,10); - // plotCanvas.printImagePng(); - return 0; -} - int CRequest::process_wms_getlegendgraphic_request() { if (srvParam->WMSLayers != NULL) for (size_t j = 0; j < srvParam->WMSLayers->count; j++) { @@ -2935,8 +2790,6 @@ int CRequest::process_querystring() { srvParam->requestType = REQUEST_WMS_GETLEGENDGRAPHIC; else if (REQUEST.equals("GETMETADATA")) srvParam->requestType = REQUEST_WMS_GETMETADATA; - else if (REQUEST.equals("GETSTYLES")) - srvParam->requestType = REQUEST_WMS_GETSTYLES; else if (REQUEST.equals("GETREFERENCETIMES")) srvParam->requestType = REQUEST_WMS_GETREFERENCETIMES; else { @@ -3061,13 +2914,6 @@ int CRequest::process_querystring() { // WMS Service if (dErrorOccured == 0 && srvParam->serviceType == SERVICE_WMS) { // CDBDebug("Entering WMS service"); - - if (srvParam->requestType == REQUEST_WMS_GETSTYLES) { - - if (process_wms_getstyles_request() != 0) return 1; - return 0; - } - if (srvParam->requestType == REQUEST_WMS_GETREFERENCETIMES) { int status = process_wms_getreferencetimes_request(); if (status != 0) { diff --git a/adagucserverEC/CRequest.h b/adagucserverEC/CRequest.h index 57b264958..a6f47e13a 100644 --- a/adagucserverEC/CRequest.h +++ b/adagucserverEC/CRequest.h @@ -200,7 +200,6 @@ class CRequest { int process_wms_getmap_request(); int process_wms_getmetadata_request(); int process_wms_getfeatureinfo_request(); - int process_wms_getstyles_request(); int process_wms_getlegendgraphic_request(); int process_wcs_getcap_request(); int process_wcs_describecov_request(); diff --git a/adagucserverEC/Definitions.h b/adagucserverEC/Definitions.h index 041475aa1..714d2f574 100755 --- a/adagucserverEC/Definitions.h +++ b/adagucserverEC/Definitions.h @@ -53,7 +53,6 @@ #define REQUEST_WCS_DESCRIBECOVERAGE 6 #define REQUEST_WCS_GETCOVERAGE 7 #define REQUEST_WMS_GETMETADATA 8 -#define REQUEST_WMS_GETSTYLES 9 #define REQUEST_WMS_GETPOINTVALUE 10 #define REQUEST_WMS_GETREFERENCETIMES 11 #define REQUEST_WMS_GETHISTOGRAM 12 diff --git a/adagucserverEC/adagucserver.cpp b/adagucserverEC/adagucserver.cpp index 3568bd98d..94b60e05b 100644 --- a/adagucserverEC/adagucserver.cpp +++ b/adagucserverEC/adagucserver.cpp @@ -30,6 +30,10 @@ #include #include "ProjCache.h" +#include "adagucserver.h" +#include "Types/ProjectionStore.h" +#include "utils/UpdateLayerMetadata.h" +#include "utils/ConfigurationUtils.h" DEF_ERRORMAIN(); @@ -78,35 +82,6 @@ void serverWarningFunction(const char *msg) { void serverLogFunctionCMDLine(const char *msg) { printf("%s", msg); } -#include "adagucserver.h" -#include "Types/ProjectionStore.h" - -void serverLogFunctionNothing(const char *) {} - -/* Set config file from environment variable ADAGUC_CONFIG */ -int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset = nullptr) { - char *configfile = getenv("ADAGUC_CONFIG"); - if (configfile != NULL) { - CT::string configWithAdditionalDataset = configfile; - if (additionalDataset != nullptr && strlen(additionalDataset) > 0) { - configWithAdditionalDataset.concat(","); - configWithAdditionalDataset.concat(additionalDataset); - } - int status = request->setConfigFile(configWithAdditionalDataset.c_str()); - - /* Check logging level */ - if (request->getServerParams()->isDebugLoggingEnabled() == false) { - setDebugFunction(serverLogFunctionNothing); - } - - return status; - } else { - CDBError("No configuration file is set. Please set ADAGUC_CONFIG environment variable accordingly."); - return 1; - } - return 0; -} - /** * @param layerPathToScan: the provided file to scan */ @@ -128,49 +103,42 @@ std::set findDataSetsToScan(CT::string layerPathToScan, bool verbos CDBDebug("directoryOfFileToScan = [%s]", directoryOfFileToScan.c_str()); } srvParam->verbose = false; - std::vector listOfDatasets; - for (size_t j = 0; j < srvParam->cfg->Dataset.size(); j++) { - if (srvParam->cfg->Dataset[j]->attr.enabled.equals("true") && srvParam->cfg->Dataset[j]->attr.location.empty() == false) { - if (verbose) { - CDBDebug("Dataset locations %s", srvParam->cfg->Dataset[j]->attr.location.c_str()); - } - auto files = CDirReader::listDir(srvParam->cfg->Dataset[j]->attr.location.c_str(), false, "^.*\\.xml$"); - for (auto &dataset : files) { - if (verbose) { - CDBDebug("Testing dataset %s", dataset.c_str()); - } - CRequest configParser; - auto configSrvParam = configParser.getServerParams(); - configSrvParam->verbose = false; - setCRequestConfigFromEnvironment(&configParser, dataset.c_str()); - - if (configSrvParam && configSrvParam->cfg) { - auto layers = configSrvParam->cfg->Layer; - for (size_t j = 0; j < layers.size(); j++) { - if (layers[j]->attr.type.equals("database")) { - if (layers[j]->FilePath.size() > 0) { - CT::string filePath = CDirReader::makeCleanPath(layers[j]->FilePath[0]->value); - // Directories need to end with a / - CT::string filePathWithTrailingSlash = filePath + "/"; - CT::string filter = layers[j]->FilePath[0]->attr.filter; - // CDBDebug(" %s %s", directoryOfFileToScan.c_str(), directoryOfFileToScan.c_str()); - // When the FilePath in the Layer configuration is exactly the same as the file to scan, give a Match - if (layerPathToScan.equals(filePath)) { - if (verbose) { - CDBDebug("Exactly matching: %s", filePath.c_str()); - } - datasetsToScan.insert(dataset.c_str()); - break; - // When the directory of the file to scan matches the FilePath and the filter matches, give a Match - } else if (directoryOfFileToScan.startsWith(filePathWithTrailingSlash)) { - if (CDirReader::testRegEx(layerPathToScan.basename(), filter.c_str()) == 1) { - if (verbose) { - CDBDebug("Directories Matching: %s / %s", filePath.c_str(), filter.c_str()); - } - datasetsToScan.insert(dataset.c_str()); - break; - } + auto datasetList = getEnabledDatasetsConfigurations(srvParam); + + for (auto &dataset : datasetList) { + if (verbose) { + CDBDebug("Testing dataset %s", dataset.c_str()); + } + CRequest configParser; + auto configSrvParam = configParser.getServerParams(); + configSrvParam->verbose = false; + setCRequestConfigFromEnvironment(&configParser, dataset.c_str()); + + if (configSrvParam && configSrvParam->cfg) { + auto layers = configSrvParam->cfg->Layer; + for (size_t j = 0; j < layers.size(); j++) { + if (layers[j]->attr.type.equals("database")) { + if (layers[j]->FilePath.size() > 0) { + CT::string filePath = CDirReader::makeCleanPath(layers[j]->FilePath[0]->value); + // Directories need to end with a / + CT::string filePathWithTrailingSlash = filePath + "/"; + CT::string filter = layers[j]->FilePath[0]->attr.filter; + // CDBDebug(" %s %s", directoryOfFileToScan.c_str(), directoryOfFileToScan.c_str()); + // When the FilePath in the Layer configuration is exactly the same as the file to scan, give a Match + if (layerPathToScan.equals(filePath)) { + if (verbose) { + CDBDebug("Exactly matching: %s", filePath.c_str()); + } + datasetsToScan.insert(dataset.c_str()); + break; + // When the directory of the file to scan matches the FilePath and the filter matches, give a Match + } else if (directoryOfFileToScan.startsWith(filePathWithTrailingSlash)) { + if (CDirReader::testRegEx(layerPathToScan.basename(), filter.c_str()) == 1) { + if (verbose) { + CDBDebug("Directories Matching: %s / %s", filePath.c_str(), filter.c_str()); } + datasetsToScan.insert(dataset.c_str()); + break; } } } @@ -178,6 +146,7 @@ std::set findDataSetsToScan(CT::string layerPathToScan, bool verbos } } } + return datasetsToScan; } @@ -218,6 +187,7 @@ int _main(int argc, char **argv, char **) { static struct option long_options[] = {{"updatedb", no_argument, 0, 0}, {"config", required_argument, 0, 0}, {"createtiles", no_argument, 0, 0}, + {"updatelayermetadata", no_argument, 0, 0}, {"tailpath", required_argument, 0, 0}, {"path", required_argument, 0, 0}, {"rescan", no_argument, 0, 0}, @@ -246,6 +216,10 @@ int _main(int argc, char **argv, char **) { automaticallyFindMatchingDataset = true; } + if (strncmp(long_options[opt_idx].name, "updatelayermetadata", 19) == 0) { + scanFlags += CDBUPDATE_LAYER_METADATA; + } + if (strncmp(long_options[opt_idx].name, "test", 4) == 0) { CDBDebug("Test"); CProj4ToCF proj4ToCF; @@ -345,6 +319,15 @@ int _main(int argc, char **argv, char **) { } readyerror(); return status; + } else if (scanFlags & CDBUPDATE_LAYER_METADATA) { + CRequest baseRequest; + int status = setCRequestConfigFromEnvironment(&baseRequest); + if (status != 0) { + CDBError("setCRequestConfigFromEnvironment failed"); + return 1; + } + status = updateLayerMetadata(baseRequest); + return status; } /* Check if layers need to be obtained. */ diff --git a/adagucserverEC/utils/ConfigurationUtils.cpp b/adagucserverEC/utils/ConfigurationUtils.cpp new file mode 100644 index 000000000..90ff9c5ba --- /dev/null +++ b/adagucserverEC/utils/ConfigurationUtils.cpp @@ -0,0 +1,21 @@ +#include "./ConfigurationUtils.h" + +std::vector getEnabledDatasetsConfigurations(CServerParams *srvParam) { + std::vector datasetList; + for (auto dataset : srvParam->cfg->Dataset) { + if (dataset->attr.enabled.equals("true") && dataset->attr.location.empty() == false) { + if (srvParam->verbose) { + CDBDebug("Dataset locations %s", dataset->attr.location.c_str()); + } + auto files = CDirReader::listDir(dataset->attr.location.c_str(), false, "^.*\\.xml$"); + datasetList.insert(datasetList.end(), files.begin(), files.end()); + } + } + return datasetList; +} + +// TODO: configure a list of possible extensions for adaguc at a central place +bool checkIfPathIsFile(CT::string filePath) { + return (filePath.endsWith(".nc") || filePath.endsWith(".h5") || filePath.endsWith(".hdf5") || filePath.endsWith(".he5") || filePath.endsWith(".png") || filePath.endsWith(".csv") || + filePath.endsWith(".geojson") || filePath.endsWith(".json") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("dodsc://")); +} diff --git a/adagucserverEC/utils/ConfigurationUtils.h b/adagucserverEC/utils/ConfigurationUtils.h new file mode 100644 index 000000000..3d8656008 --- /dev/null +++ b/adagucserverEC/utils/ConfigurationUtils.h @@ -0,0 +1,12 @@ +#ifndef CONFIGURATIONUTILS_H +#define CONFIGURATIONUTILS_H + +#include +#include +#include + +std::vector getEnabledDatasetsConfigurations(CServerParams *srvParam); + +bool checkIfPathIsFile(CT::string filePath); + +#endif diff --git a/adagucserverEC/utils/UpdateLayerMetadata.cpp b/adagucserverEC/utils/UpdateLayerMetadata.cpp new file mode 100644 index 000000000..58d83e8cc --- /dev/null +++ b/adagucserverEC/utils/UpdateLayerMetadata.cpp @@ -0,0 +1,58 @@ +#include "UpdateLayerMetadata.h" +#include +#include +#include "ConfigurationUtils.h" + +void serverLogFunctionNothing(const char *) {} + +/* Set config file from environment variable ADAGUC_CONFIG */ +int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset) { + char *configfile = getenv("ADAGUC_CONFIG"); + if (configfile != NULL) { + CT::string configWithAdditionalDataset = configfile; + if (additionalDataset != nullptr && strlen(additionalDataset) > 0) { + configWithAdditionalDataset.concat(","); + configWithAdditionalDataset.concat(additionalDataset); + } + int status = request->setConfigFile(configWithAdditionalDataset.c_str()); + + /* Check logging level */ + if (request->getServerParams()->isDebugLoggingEnabled() == false) { + setDebugFunction(serverLogFunctionNothing); + } + + return status; + } else { + CDBError("No configuration file is set. Please set ADAGUC_CONFIG environment variable accordingly."); + return 1; + } + return 0; +} + +int updateLayerMetadata(CRequest &request) { + CServerParams *srvParam = request.getServerParams(); + + auto datasetList = getEnabledDatasetsConfigurations(srvParam); + // TODO: Remove datasets in metadatable which don't have a matching configuration + // TODO: Remove dimension tables which don't have a matching configuration + + for (auto &dataset : datasetList) { + if (dataset.length() > 0) { + CDBDebug("***** Scanning dataset [%s]", dataset.c_str()); + } + CRequest requestPerDataset; + // dataset = "/data/adaguc-datasets/test.uwcw_ha43_dini_5p5km_10x8.xml"; + // dataset = "/data/adaguc-datasets/testdata.xml"; + int status = setCRequestConfigFromEnvironment(&requestPerDataset, dataset.c_str()); + if (status != 0) { + CDBError("Unable to read configuration file"); + return 1; + } + status = requestPerDataset.updatedb(nullptr, nullptr, CDBFILESCANNER_UPDATEDB | CDBFILESCANNER_DONTREMOVEDATAFROMDB | CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY, ""); + if (status != 0) { + CDBError("Error occured in updating the database"); + } + // return 0; + } + return 0; +} diff --git a/adagucserverEC/utils/UpdateLayerMetadata.h b/adagucserverEC/utils/UpdateLayerMetadata.h new file mode 100644 index 000000000..b07be6342 --- /dev/null +++ b/adagucserverEC/utils/UpdateLayerMetadata.h @@ -0,0 +1,9 @@ +#ifndef UPDATELAYERMETADATA_H +#define UPDATELAYERMETADATA_H +#include + +int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset = nullptr); + +int updateLayerMetadata(CRequest &request); + +#endif \ No newline at end of file From 552e28c86cea7947e002f5aa3149ec6f503e3251 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 14:31:42 +0200 Subject: [PATCH 41/50] Using already existing data base filename loader --- adagucserverEC/CAutoConfigure.cpp | 59 ++++++++++++-------- adagucserverEC/CAutoConfigure.h | 8 +++ adagucserverEC/CDBFileScanner.cpp | 21 ++----- adagucserverEC/utils/UpdateLayerMetadata.cpp | 12 +++- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/adagucserverEC/CAutoConfigure.cpp b/adagucserverEC/CAutoConfigure.cpp index cd245a449..f218ac03f 100644 --- a/adagucserverEC/CAutoConfigure.cpp +++ b/adagucserverEC/CAutoConfigure.cpp @@ -463,26 +463,7 @@ int CAutoConfigure::autoConfigureStyles(CDataSource *dataSource) { return 0; } -int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { - - if (dataSource == NULL) { - CDBError("datasource == NULL"); - return 1; - } - if (dataSource->cfgLayer == NULL) { - CDBError("datasource->cfgLayer == NULL"); - return 1; - } - if (dataSource->getNumDataObjects() == 0) { - CDBError("dataSource->getNumDataObjects()==0"); - return 1; - } - if (dataSource->getDataObject(0)->cdfVariable != NULL) { -#ifdef CAUTOCONFIGURE_DEBUG - CDBDebug("already loaded: dataSource->getDataObject(0)->cdfVariable!=NULL"); -#endif - return 0; - } +int CAutoConfigure::getFileNameForDataSource(CDataSource *dataSource, std::string &fileName) { CT::string foundFileName = dataSource->getFileName(); if (foundFileName.empty()) { @@ -499,7 +480,12 @@ int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { if (dataSource->requiredDims.size() == 0) { removeRequiredDims = true; if (dataSource->cfgLayer->Dimension.size() > 0) { - CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); + try { + CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); + } catch (ServiceExceptionCode e) { + CDBDebug("Unable to fillDimValuesForDataSource"); + return 1; + } } else { CDBDebug("Required dims is still zero, add none now"); COGCDims *ogcDim = new COGCDims(); @@ -510,7 +496,7 @@ int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { ogcDim->netCDFDimName.copy("none"); } } - CDBStore::Store *store = CDBFactory::getDBAdapter(dataSource->srvParams->cfg)->getFilesAndIndicesForDimensions(dataSource, 1000); + CDBStore::Store *store = CDBFactory::getDBAdapter(dataSource->srvParams->cfg)->getFilesAndIndicesForDimensions(dataSource, 1); if (store != NULL && store->getSize() > 0) { CT::string fileNamestr = store->getRecord(0)->get(0)->c_str(); // CDBDebug("fileName from DB: %s", fileNamestr.c_str()); @@ -532,7 +518,36 @@ int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { return 1; } } + fileName = foundFileName.c_str(); + return 0; +} + +int CAutoConfigure::justLoadAFileHeader(CDataSource *dataSource) { + if (dataSource == NULL) { + CDBError("datasource == NULL"); + return 1; + } + if (dataSource->cfgLayer == NULL) { + CDBError("datasource->cfgLayer == NULL"); + return 1; + } + if (dataSource->getNumDataObjects() == 0) { + CDBError("dataSource->getNumDataObjects()==0"); + return 1; + } + if (dataSource->getDataObject(0)->cdfVariable != NULL) { +#ifdef CAUTOCONFIGURE_DEBUG + CDBDebug("already loaded: dataSource->getDataObject(0)->cdfVariable!=NULL"); +#endif + return 0; + } + + std::string foundFileName; + if (getFileNameForDataSource(dataSource, foundFileName) != 0) { + CDBDebug("Unable to getFileNameForDataSource"); + return 1; + } /* Open a file */ try { // CDBDebug("Loading header [%s]", foundFileName.c_str()); diff --git a/adagucserverEC/CAutoConfigure.h b/adagucserverEC/CAutoConfigure.h index e8dba75ad..81bd3cc3f 100644 --- a/adagucserverEC/CAutoConfigure.h +++ b/adagucserverEC/CAutoConfigure.h @@ -56,5 +56,13 @@ class CAutoConfigure { public: static int autoConfigureDimensions(CDataSource *dataSource); static int autoConfigureStyles(CDataSource *dataSource); + + /** + * Find the default filename for a datasource from the database + * @param dataSource + * @param fileName - The filename to return + * @returns Zero on success. + */ + static int getFileNameForDataSource(CDataSource *dataSource, std::string &fileName); }; #endif diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index f3f59f123..67b5ffe54 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -958,23 +958,14 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: CDBDebug("Obtained filename from layer configuration [%s]", dataSource->cfgLayer->FilePath[0]->value.c_str()); } else { CDBDebug("CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY"); - int status = CRequest::setDimValuesForDataSource(dataSource, dataSource->srvParams); - if (status != 0) { - CDBError("setDimValuesForDataSource"); - return 1; - } - status = CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); - if (status != 0) { - CDBError("fillDimValuesForDataSource"); - return 1; - } - status = CRequest::queryDimValuesForDataSource(dataSource, dataSource->srvParams); - if (status != 0) { - CDBError("queryDimValuesForDataSource"); + + std::string fileName; + if (CAutoConfigure::getFileNameForDataSource(dataSource, fileName) != 0) { + CDBDebug("Unable to getFileNameForDataSource"); return 1; } - fileList.push_back(dataSource->getFileName()); - CDBDebug("Queried file from database with filename [%s]", dataSource->getFileName()); + fileList.push_back(fileName); + CDBDebug("Queried file from database with filename [%s]", fileName.c_str()); } } else { fileList = searchFileNames(dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); diff --git a/adagucserverEC/utils/UpdateLayerMetadata.cpp b/adagucserverEC/utils/UpdateLayerMetadata.cpp index 58d83e8cc..212d85bbc 100644 --- a/adagucserverEC/utils/UpdateLayerMetadata.cpp +++ b/adagucserverEC/utils/UpdateLayerMetadata.cpp @@ -2,6 +2,9 @@ #include #include #include "ConfigurationUtils.h" +#include +#include +#include void serverLogFunctionNothing(const char *) {} @@ -33,7 +36,7 @@ int updateLayerMetadata(CRequest &request) { CServerParams *srvParam = request.getServerParams(); auto datasetList = getEnabledDatasetsConfigurations(srvParam); - // TODO: Remove datasets in metadatable which don't have a matching configuration + // TODO: Remove datasets and layers in metadatable which don't have a matching configuration // TODO: Remove dimension tables which don't have a matching configuration for (auto &dataset : datasetList) { @@ -46,11 +49,14 @@ int updateLayerMetadata(CRequest &request) { int status = setCRequestConfigFromEnvironment(&requestPerDataset, dataset.c_str()); if (status != 0) { CDBError("Unable to read configuration file"); - return 1; + continue; } - status = requestPerDataset.updatedb(nullptr, nullptr, CDBFILESCANNER_UPDATEDB | CDBFILESCANNER_DONTREMOVEDATAFROMDB | CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY, ""); + CT::string layerPathToScan; + CT::string tailPath; + status = requestPerDataset.updatedb(&tailPath, &layerPathToScan, CDBFILESCANNER_UPDATEDB | CDBFILESCANNER_DONTREMOVEDATAFROMDB | CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY, ""); if (status != 0) { CDBError("Error occured in updating the database"); + continue; } // return 0; } From 47186dfbcfd7f8366668ff3276df453ac1f626ef Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 15:28:44 +0200 Subject: [PATCH 42/50] --updatelayermetadata does now clean as well --- adagucserverEC/CAutoConfigure.cpp | 3 + adagucserverEC/CDBAdapter.h | 1 + adagucserverEC/CDBAdapterPostgreSQL.cpp | 13 ++++ adagucserverEC/CDBAdapterPostgreSQL.h | 1 + adagucserverEC/CDBAdapterSQLLite.cpp | 1 + adagucserverEC/CDBAdapterSQLLite.h | 1 + adagucserverEC/CDBFileScanner.cpp | 2 - adagucserverEC/utils/LayerMetadataStore.cpp | 1 - adagucserverEC/utils/UpdateLayerMetadata.cpp | 69 +++++++++++++++++++- 9 files changed, 88 insertions(+), 4 deletions(-) diff --git a/adagucserverEC/CAutoConfigure.cpp b/adagucserverEC/CAutoConfigure.cpp index f218ac03f..c29645b3a 100644 --- a/adagucserverEC/CAutoConfigure.cpp +++ b/adagucserverEC/CAutoConfigure.cpp @@ -479,6 +479,9 @@ int CAutoConfigure::getFileNameForDataSource(CDataSource *dataSource, std::strin bool removeRequiredDims = false; if (dataSource->requiredDims.size() == 0) { removeRequiredDims = true; + if (CAutoConfigure::autoConfigureDimensions(dataSource) != 0) { + CDBWarning("Unable to autoconfigure dims"); + } if (dataSource->cfgLayer->Dimension.size() > 0) { try { CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index 57f5cb5fb..d783e0f40 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -99,6 +99,7 @@ class CDBAdapter { virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; virtual CDBStore::Store *getLayerMetadataStore(const char *datasetName) = 0; + virtual int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index ebdfda971..afd58d8ab 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1161,3 +1161,16 @@ CDBStore::Store *CDBAdapterPostgreSQL::getLayerMetadataStore(const char *dataset #endif return layerMetaDataStore; } + +int CDBAdapterPostgreSQL::dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName) { + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + return -1; + } + + CT::string query; + query.print("DELETE FROM layermetadata " + "WHERE datasetname='%s' AND layername = '%s';", + datasetName, layerName); + return dataBaseConnection->query(query.c_str()); +} \ No newline at end of file diff --git a/adagucserverEC/CDBAdapterPostgreSQL.h b/adagucserverEC/CDBAdapterPostgreSQL.h index e2a057cdd..dc1db04b4 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.h +++ b/adagucserverEC/CDBAdapterPostgreSQL.h @@ -92,6 +92,7 @@ class CDBAdapterPostgreSQL : public CDBAdapter { int addFilesToDataBase(); int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CDBStore::Store *getLayerMetadataStore(const char *datasetName); + int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName); }; #endif diff --git a/adagucserverEC/CDBAdapterSQLLite.cpp b/adagucserverEC/CDBAdapterSQLLite.cpp index dd0a60478..86a1b1ed2 100644 --- a/adagucserverEC/CDBAdapterSQLLite.cpp +++ b/adagucserverEC/CDBAdapterSQLLite.cpp @@ -1308,5 +1308,6 @@ CDBStore::Store *CDBAdapterSQLLite::getFilesForIndices(CDataSource *dataSource, int CDBAdapterSQLLite::storeLayerMetadata(const char *, const char *, const char *, const char *) { return 0; } CDBStore::Store *CDBAdapterSQLLite::getLayerMetadataStore(const char *) { return nullptr; } +int CDBAdapterSQLLite::dropLayerFromLayerMetadataStore(const char *, const char *) { return 0; }; #endif diff --git a/adagucserverEC/CDBAdapterSQLLite.h b/adagucserverEC/CDBAdapterSQLLite.h index 0a086e0d6..d8c959358 100644 --- a/adagucserverEC/CDBAdapterSQLLite.h +++ b/adagucserverEC/CDBAdapterSQLLite.h @@ -125,6 +125,7 @@ class CDBAdapterSQLLite : public CDBAdapter { int addFilesToDataBase(); int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CDBStore::Store *getLayerMetadataStore(const char *datasetName); + int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName); }; #endif diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 67b5ffe54..8e22133cb 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -957,8 +957,6 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: fileList.push_back(dataSource->cfgLayer->FilePath[0]->value.c_str()); CDBDebug("Obtained filename from layer configuration [%s]", dataSource->cfgLayer->FilePath[0]->value.c_str()); } else { - CDBDebug("CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY"); - std::string fileName; if (CAutoConfigure::getFileNameForDataSource(dataSource, fileName) != 0) { CDBDebug("Unable to getFileNameForDataSource"); diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index d608ab9f1..26b252ec0 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -328,7 +328,6 @@ int loadLayerStyleListFromMetadataDb(MetadataLayer *metadataLayer) { } int storeLayerDimensionListIntoMetadataDb(MetadataLayer *metadataLayer) { - CDBDebug("storeLayerDimensionListIntoMetadataDb"); try { json dimListJson; if (getDimensionListAsJson(metadataLayer, dimListJson) != 0) { diff --git a/adagucserverEC/utils/UpdateLayerMetadata.cpp b/adagucserverEC/utils/UpdateLayerMetadata.cpp index 212d85bbc..e4372b523 100644 --- a/adagucserverEC/utils/UpdateLayerMetadata.cpp +++ b/adagucserverEC/utils/UpdateLayerMetadata.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "LayerUtils.h" void serverLogFunctionNothing(const char *) {} @@ -39,9 +40,16 @@ int updateLayerMetadata(CRequest &request) { // TODO: Remove datasets and layers in metadatable which don't have a matching configuration // TODO: Remove dimension tables which don't have a matching configuration + std::map> dataSetConfigsWithLayers; + for (auto &dataset : datasetList) { + CT::string datasetAsCTString = dataset.c_str(); + CT::string baseDataSetNameCT = datasetAsCTString.basename(); + baseDataSetNameCT.replaceSelf(".xml", ""); + std::string datasetBaseName = baseDataSetNameCT.c_str(); + if (dataset.length() > 0) { - CDBDebug("***** Scanning dataset [%s]", dataset.c_str()); + CDBDebug("\n\n *********************************** Updating metadatatable for dataset [%s] **************************************************", dataset.c_str()); } CRequest requestPerDataset; // dataset = "/data/adaguc-datasets/test.uwcw_ha43_dini_5p5km_10x8.xml"; @@ -51,6 +59,16 @@ int updateLayerMetadata(CRequest &request) { CDBError("Unable to read configuration file"); continue; } + for (auto layer : requestPerDataset.getServerParams()->cfg->Layer) { + CT::string layerName; + makeUniqueLayerName(&layerName, layer); + if (isalpha(layerName.charAt(0)) == 0) { + CT::string tmp = layerName; + layerName.print("ID_%s", tmp.c_str()); + } + + dataSetConfigsWithLayers[datasetBaseName].insert(layerName.c_str()); + } CT::string layerPathToScan; CT::string tailPath; status = requestPerDataset.updatedb(&tailPath, &layerPathToScan, CDBFILESCANNER_UPDATEDB | CDBFILESCANNER_DONTREMOVEDATAFROMDB | CDBFILESCANNER_UPDATEDB_ONLYFILEFROMDEFAULTQUERY, ""); @@ -60,5 +78,54 @@ int updateLayerMetadata(CRequest &request) { } // return 0; } + + // Check for datasets which are not configured anymore. + json dataset; + json layer; + + CDBStore::Store *layerMetaDataStore = CDBFactory::getDBAdapter(srvParam->cfg)->getLayerMetadataStore(nullptr); + if (layerMetaDataStore == nullptr) { + return 1; + } + auto records = layerMetaDataStore->getRecords(); + std::map> datasetNamesFromDB; + for (auto record : records) { + CT::string *datasetName = record->get("datasetname"); + CT::string *layerName = record->get("layername"); + if (datasetName != nullptr && layerName != nullptr) { + datasetNamesFromDB[record->get("datasetname")->c_str()].insert(record->get("layername")->c_str()); + } + } + + std::map> layersToDeleteFromMetadataTable; + for (auto datasetFromDB : datasetNamesFromDB) { + for (auto layerNameDb : datasetFromDB.second) { + bool hasLayer = false; + for (auto datasetConfig : dataSetConfigsWithLayers) { + if (datasetConfig.first == datasetFromDB.first) { + for (auto layerNameConfig : datasetConfig.second) { + if (layerNameConfig == layerNameDb) { + hasLayer = true; + break; + } + } + } + } + if (!hasLayer) { + // CDBDebug("NO: %s/%s ", datasetFromDB.first.c_str(), layerNameDb.c_str()); + layersToDeleteFromMetadataTable[datasetFromDB.first].insert(layerNameDb); + } else { + // CDBDebug("YES: %s/%s ", datasetFromDB.first.c_str(), layerNameDb.c_str()); + } + } + } + + for (auto dataset : layersToDeleteFromMetadataTable) { + for (auto layer : dataset.second) { + CDBDebug("DROP: %s/%s ", dataset.first.c_str(), layer.c_str()); + CDBFactory::getDBAdapter(srvParam->cfg)->dropLayerFromLayerMetadataStore(dataset.first.c_str(), layer.c_str()); + } + } + return 0; } From 36841ece5a9b4329a9200e08349955bdef23acc3 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 15:29:45 +0200 Subject: [PATCH 43/50] Updated populateMetadataLayerStruct --- adagucserverEC/CXMLGen.cpp | 2 +- adagucserverEC/utils/LayerMetadataStore.cpp | 2 +- adagucserverEC/utils/XMLGenUtils.cpp | 2 +- adagucserverEC/utils/XMLGenUtils.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 53cd5aa06..87c478605 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -971,7 +971,7 @@ int CXMLGen::OGCGetCapabilities(CServerParams *_srvParam, CT::string *XMLDocumen metadataLayerList.push_back(metadataLayer); metadataLayer->layer = srvParam->cfg->Layer[j]; metadataLayer->srvParams = srvParam; - populateLayerMetadataStruct(metadataLayer, true); + populateMetadataLayerStruct(metadataLayer, true); } #ifdef CXMLGEN_DEBUG diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index c2e08f3f3..d608ab9f1 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -392,7 +392,7 @@ int updateMetaDataTable(CDataSource *dataSource) { metadataLayer->layer = dataSource->cfgLayer; metadataLayer->srvParams = dataSource->srvParams; metadataLayer->dataSource = dataSource; - populateLayerMetadataStruct(metadataLayer, false); + populateMetadataLayerStruct(metadataLayer, false); storemetadataLayerIntoMetadataDb(metadataLayer); delete metadataLayer; return 0; diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 119f3e99b..34fbc71d1 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -6,7 +6,7 @@ #include #include "LayerUtils.h" -int populateLayerMetadataStruct(MetadataLayer *metadataLayer, bool readFromDB) { +int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { metadataLayer->readFromDb = readFromDB; if (!metadataLayer->srvParams->useMetadataTable()) { metadataLayer->readFromDb = false; diff --git a/adagucserverEC/utils/XMLGenUtils.h b/adagucserverEC/utils/XMLGenUtils.h index 2d5b7955f..de97d2b5a 100644 --- a/adagucserverEC/utils/XMLGenUtils.h +++ b/adagucserverEC/utils/XMLGenUtils.h @@ -9,7 +9,7 @@ int getStylesForLayer(MetadataLayer *metadataLayer); bool compareStringCase(const std::string &s1, const std::string &s2); bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2); bool compareDim(const LayerMetadataDim &p1, const LayerMetadataDim &p2); -int populateLayerMetadataStruct(MetadataLayer *metadataLayer, bool readFromDb); +int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDb); int getTitleForLayer(MetadataLayer *metadataLayer); int getFileNameForLayer(MetadataLayer *metadataLayer); #endif \ No newline at end of file From 61a5b8a299e524fb634cc3f64fbfa343915034e7 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Fri, 13 Sep 2024 15:57:57 +0200 Subject: [PATCH 44/50] Fixed tests --- adagucserverEC/CAutoConfigure.cpp | 3 --- adagucserverEC/CDBFileScanner.cpp | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/adagucserverEC/CAutoConfigure.cpp b/adagucserverEC/CAutoConfigure.cpp index c29645b3a..f218ac03f 100644 --- a/adagucserverEC/CAutoConfigure.cpp +++ b/adagucserverEC/CAutoConfigure.cpp @@ -479,9 +479,6 @@ int CAutoConfigure::getFileNameForDataSource(CDataSource *dataSource, std::strin bool removeRequiredDims = false; if (dataSource->requiredDims.size() == 0) { removeRequiredDims = true; - if (CAutoConfigure::autoConfigureDimensions(dataSource) != 0) { - CDBWarning("Unable to autoconfigure dims"); - } if (dataSource->cfgLayer->Dimension.size() > 0) { try { CRequest::fillDimValuesForDataSource(dataSource, dataSource->srvParams); diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 8e22133cb..7d855f675 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -958,6 +958,11 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: CDBDebug("Obtained filename from layer configuration [%s]", dataSource->cfgLayer->FilePath[0]->value.c_str()); } else { std::string fileName; + if (dataSource->requiredDims.size() == 0) { + if (CAutoConfigure::autoConfigureDimensions(dataSource) != 0) { + CDBWarning("Unable to autoconfigure dims"); + } + } if (CAutoConfigure::getFileNameForDataSource(dataSource, fileName) != 0) { CDBDebug("Unable to getFileNameForDataSource"); return 1; From 41e7dd59b41c8fee22325d2c5c3520044bc75b13 Mon Sep 17 00:00:00 2001 From: Lukas Phaf Date: Fri, 13 Sep 2024 18:00:16 +0200 Subject: [PATCH 45/50] Get rid of default constructor for LayerMetadataProjection. --- adagucserverEC/Types/LayerMetadataType.h | 3 +-- adagucserverEC/utils/LayerMetadataStore.cpp | 17 ++++++++++------- adagucserverEC/utils/XMLGenUtils.cpp | 6 +++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index ba2d78541..19c76cdcc 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -15,8 +15,7 @@ struct LayerMetadataDim { }; struct LayerMetadataProjection { - LayerMetadataProjection() {} - LayerMetadataProjection(CT::string name, double bbox[]) { + LayerMetadataProjection(const CT::string& name, const double bbox[]) { this->name = name; for (size_t j = 0; j < 4; j++) { this->dfBBOX[j] = bbox[j]; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 26b252ec0..5fe504588 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -249,15 +249,18 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *metadataLayer) return 1; } json a; - auto c = a.parse(projInfo.c_str()); - for (auto d : c.items()) { + auto c = json::parse(projInfo.c_str()); + for (const auto& d : c.items()) { auto bboxArray = d.value(); - LayerMetadataProjection projection; + double bbox[4] = + { + bboxArray[0].get_to((bbox[0])), + bboxArray[1].get_to((bbox[1])), + bboxArray[2].get_to((bbox[2])), + bboxArray[3].get_to((bbox[3])), + }; + LayerMetadataProjection projection(d.key().c_str(), bbox); projection.name = d.key().c_str(); - bboxArray[0].get_to((projection.dfBBOX[0])); - bboxArray[1].get_to((projection.dfBBOX[1])); - bboxArray[2].get_to((projection.dfBBOX[2])); - bboxArray[3].get_to((projection.dfBBOX[3])); metadataLayer->layerMetadata.projectionList.push_back(projection); } } catch (json::exception &e) { diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 34fbc71d1..75ba168e7 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -127,11 +127,11 @@ int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { std::map projectionMap; // Make a unique list of projections - for (auto p : metadataLayer->layerMetadata.projectionList) { - projectionMap[p.name.c_str()] = p; + for (const auto& p : metadataLayer->layerMetadata.projectionList) { + projectionMap.emplace(p.name.c_str(), p); } metadataLayer->layerMetadata.projectionList.clear(); - for (auto p : projectionMap) { + for (const auto& p : projectionMap) { metadataLayer->layerMetadata.projectionList.push_back(p.second); } From fdad104d0123fb8c836beaead7a5105c9c42af4c Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 23 Sep 2024 08:19:33 +0200 Subject: [PATCH 46/50] Added advisory lock to lock layermetadatatable --- adagucserverEC/CDBAdapter.h | 3 + adagucserverEC/CDBAdapterPostgreSQL.cpp | 47 ++++++++++++ adagucserverEC/CDBAdapterPostgreSQL.h | 2 + adagucserverEC/CDBAdapterSQLLite.h | 3 + adagucserverEC/CDBFileScanner.cpp | 2 +- adagucserverEC/CRequest.cpp | 4 +- adagucserverEC/Definitions.h | 2 + adagucserverEC/adagucserver.cpp | 16 ++++ adagucserverEC/utils/LayerMetadataStore.cpp | 15 ++-- adagucserverEC/utils/LayerMetadataToJson.cpp | 2 +- adagucserverEC/utils/UpdateLayerMetadata.cpp | 2 +- python/lib/adaguc/runAdaguc.py | 79 +++++++++++--------- python/python_fastapi_server/main.py | 48 +++++++++--- requirements.in | 1 + requirements.txt | 19 +++-- 15 files changed, 181 insertions(+), 64 deletions(-) diff --git a/adagucserverEC/CDBAdapter.h b/adagucserverEC/CDBAdapter.h index d783e0f40..56422c49c 100644 --- a/adagucserverEC/CDBAdapter.h +++ b/adagucserverEC/CDBAdapter.h @@ -100,6 +100,9 @@ class CDBAdapter { virtual int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob) = 0; virtual CDBStore::Store *getLayerMetadataStore(const char *datasetName) = 0; virtual int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName) = 0; + + virtual bool tryAdvisoryLock(size_t key) = 0; + virtual bool advisoryUnLock(size_t key) = 0; }; #endif diff --git a/adagucserverEC/CDBAdapterPostgreSQL.cpp b/adagucserverEC/CDBAdapterPostgreSQL.cpp index afd58d8ab..a8387d112 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.cpp +++ b/adagucserverEC/CDBAdapterPostgreSQL.cpp @@ -1173,4 +1173,51 @@ int CDBAdapterPostgreSQL::dropLayerFromLayerMetadataStore(const char *datasetNam "WHERE datasetname='%s' AND layername = '%s';", datasetName, layerName); return dataBaseConnection->query(query.c_str()); +} + +bool CDBAdapterPostgreSQL::tryAdvisoryLock(size_t key) { + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + return false; + } + CT::string query; + query.print("SELECT pg_try_advisory_lock(%d) as \"result\";", key); + auto *store = dataBaseConnection->queryToStore(query.c_str()); + if (store == nullptr || store->getSize() != 1) { + CDBError("Query failed [%s]:", dataBaseConnection->getError()); + return false; + } + auto result = store->getRecord(0)->get("result"); + bool succesfullylocked = result != nullptr && result->equals("t"); + if (succesfullylocked) { + CDBDebug("pg_try_advisory_lock succesfullylocked"); + } else { + CDBDebug("pg_try_advisory_lock NOT succesfullylocked"); + } + delete store; + return succesfullylocked; +} + +bool CDBAdapterPostgreSQL::advisoryUnLock(size_t key) { + CPGSQLDB *dataBaseConnection = getDataBaseConnection(); + if (dataBaseConnection == NULL) { + return false; + } + CT::string query; + + query.print("SELECT pg_advisory_unlock(%d) as \"result\";", key); + auto store = dataBaseConnection->queryToStore(query.c_str()); + if (store == nullptr || store->getSize() != 1) { + CDBError("Query failed [%s]:", dataBaseConnection->getError()); + return false; + } + auto result = store->getRecord(0)->get("result"); + bool succesfullyunlocked = result != nullptr && result->equals("t"); + if (succesfullyunlocked) { + CDBDebug("pg_advisory_unlock succesfullyunlocked"); + } else { + CDBWarning("pg_advisory_unlock NOT succesfullyunlocked"); + } + delete store; + return succesfullyunlocked; } \ No newline at end of file diff --git a/adagucserverEC/CDBAdapterPostgreSQL.h b/adagucserverEC/CDBAdapterPostgreSQL.h index dc1db04b4..43bb97908 100644 --- a/adagucserverEC/CDBAdapterPostgreSQL.h +++ b/adagucserverEC/CDBAdapterPostgreSQL.h @@ -93,6 +93,8 @@ class CDBAdapterPostgreSQL : public CDBAdapter { int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CDBStore::Store *getLayerMetadataStore(const char *datasetName); int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName); + bool tryAdvisoryLock(size_t); + bool advisoryUnLock(size_t); }; #endif diff --git a/adagucserverEC/CDBAdapterSQLLite.h b/adagucserverEC/CDBAdapterSQLLite.h index d8c959358..88983e811 100644 --- a/adagucserverEC/CDBAdapterSQLLite.h +++ b/adagucserverEC/CDBAdapterSQLLite.h @@ -126,6 +126,9 @@ class CDBAdapterSQLLite : public CDBAdapter { int storeLayerMetadata(const char *datasetName, const char *layerName, const char *metadataKey, const char *metadatablob); CDBStore::Store *getLayerMetadataStore(const char *datasetName); int dropLayerFromLayerMetadataStore(const char *datasetName, const char *layerName); + + bool tryAdvisoryLock(size_t) { return true; }; + bool advisoryUnLock(size_t) { return true; } }; #endif diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 7d855f675..5d9099122 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -968,7 +968,7 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: return 1; } fileList.push_back(fileName); - CDBDebug("Queried file from database with filename [%s]", fileName.c_str()); + // CDBDebug("Queried file from database with filename [%s]", fileName.c_str()); } } else { fileList = searchFileNames(dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); diff --git a/adagucserverEC/CRequest.cpp b/adagucserverEC/CRequest.cpp index ab16cc12a..eeda9d978 100644 --- a/adagucserverEC/CRequest.cpp +++ b/adagucserverEC/CRequest.cpp @@ -3422,11 +3422,11 @@ int CRequest::updatedb(CT::string *tailPath, CT::string *layerPathToScan, int sc } else { CDBDebug("***** Finished DB Update *****"); } - + // TODO: 2024-09-20: Probably not the right place to clear these CDFObjectStore::getCDFObjectStore()->clear(); CConvertGeoJSON::clearFeatureStore(); CDFStore::clear(); - CDBFactory::clear(); + return errorHasOccured > 0; } diff --git a/adagucserverEC/Definitions.h b/adagucserverEC/Definitions.h index 714d2f574..ecf952586 100755 --- a/adagucserverEC/Definitions.h +++ b/adagucserverEC/Definitions.h @@ -188,3 +188,5 @@ // Client errors #define HTTP_STATUSCODE_404_NOT_FOUND 32 #define HTTP_STATUSCODE_422_UNPROCESSABLE_ENTITY 33 + +#define LOCK_METADATATABLE_ID 1 \ No newline at end of file diff --git a/adagucserverEC/adagucserver.cpp b/adagucserverEC/adagucserver.cpp index 94b60e05b..e12307788 100644 --- a/adagucserverEC/adagucserver.cpp +++ b/adagucserverEC/adagucserver.cpp @@ -34,6 +34,8 @@ #include "Types/ProjectionStore.h" #include "utils/UpdateLayerMetadata.h" #include "utils/ConfigurationUtils.h" +#include "CDBFactory.h" +#include "CConvertGeoJSON.h" DEF_ERRORMAIN(); @@ -326,7 +328,19 @@ int _main(int argc, char **argv, char **) { CDBError("setCRequestConfigFromEnvironment failed"); return 1; } + auto db = CDBFactory::getDBAdapter(baseRequest.getServerParams()->cfg); + if (db == nullptr || db->tryAdvisoryLock(LOCK_METADATATABLE_ID) == false) { + CDBDebug("UPDATELAYERMETADATA: Skipping updateLayerMetadata already busy (tryAdvisoryLock)"); + return 1; + } else { + CDBDebug("UPDATELAYERMETADATA: tryAdvisoryLock obtained"); + } + + CDBDebug("UPDATELAYERMETADATA: STARTING"); status = updateLayerMetadata(baseRequest); + CDBDebug("UPDATELAYERMETADATA: DONE"); + db->advisoryUnLock(LOCK_METADATATABLE_ID); + CDBDebug("UPDATELAYERMETADATA: Unlocked"); return status; } @@ -434,6 +448,8 @@ int main(int argc, char **argv, char **envp) { CDFObjectStore::getCDFObjectStore()->clear(); + CDBFactory::clear(); + proj_clear_cache(); BBOXProjectionClearCache(); diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 5fe504588..4ce5c1c6d 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -250,15 +250,14 @@ int loadLayerProjectionAndExtentListFromMetadataDb(MetadataLayer *metadataLayer) } json a; auto c = json::parse(projInfo.c_str()); - for (const auto& d : c.items()) { + for (const auto &d : c.items()) { auto bboxArray = d.value(); - double bbox[4] = - { - bboxArray[0].get_to((bbox[0])), - bboxArray[1].get_to((bbox[1])), - bboxArray[2].get_to((bbox[2])), - bboxArray[3].get_to((bbox[3])), - }; + double bbox[4] = { + bboxArray[0].get_to((bbox[0])), + bboxArray[1].get_to((bbox[1])), + bboxArray[2].get_to((bbox[2])), + bboxArray[3].get_to((bbox[3])), + }; LayerMetadataProjection projection(d.key().c_str(), bbox); projection.name = d.key().c_str(); metadataLayer->layerMetadata.projectionList.push_back(projection); diff --git a/adagucserverEC/utils/LayerMetadataToJson.cpp b/adagucserverEC/utils/LayerMetadataToJson.cpp index 03e3c6f5f..05a9ef1e5 100644 --- a/adagucserverEC/utils/LayerMetadataToJson.cpp +++ b/adagucserverEC/utils/LayerMetadataToJson.cpp @@ -30,7 +30,7 @@ int getLayerMetadataAsJson(CServerParams *srvParams, json &result) { CT::string *datasetName = record->get("datasetname"); CT::string *layerName = record->get("layername"); if (datasetName != nullptr && layerName != nullptr) { - datasetNames[record->get("datasetname")->c_str()].insert(record->get("layername")->c_str()); + datasetNames[datasetName->c_str()].insert(layerName->c_str()); } } diff --git a/adagucserverEC/utils/UpdateLayerMetadata.cpp b/adagucserverEC/utils/UpdateLayerMetadata.cpp index e4372b523..acf7acf63 100644 --- a/adagucserverEC/utils/UpdateLayerMetadata.cpp +++ b/adagucserverEC/utils/UpdateLayerMetadata.cpp @@ -93,7 +93,7 @@ int updateLayerMetadata(CRequest &request) { CT::string *datasetName = record->get("datasetname"); CT::string *layerName = record->get("layername"); if (datasetName != nullptr && layerName != nullptr) { - datasetNamesFromDB[record->get("datasetname")->c_str()].insert(record->get("layername")->c_str()); + datasetNamesFromDB[datasetName->c_str()].insert(layerName->c_str()); } } diff --git a/python/lib/adaguc/runAdaguc.py b/python/lib/adaguc/runAdaguc.py index a14c6f309..5551b14e1 100644 --- a/python/lib/adaguc/runAdaguc.py +++ b/python/lib/adaguc/runAdaguc.py @@ -72,11 +72,14 @@ def get_random_string(self, length): def setConfiguration(self, configFile): self.ADAGUC_CONFIG = configFile - def scanDataset(self, datasetName): - config = self.ADAGUC_CONFIG + "," + datasetName - """ Setup a new environment """ - adagucenv = {} - """ Set required environment variables """ + def isLoggingEnabled(self): + return os.getenv( + "ADAGUC_ENABLELOGBUFFER", "TRUE" + ) != "DISABLELOGGING" + + def getAdagucEnv(self, adagucenv = {}): + + """ Set required environment variables for adaguc to run""" adagucenv["ADAGUC_CONFIG"] = self.ADAGUC_CONFIG adagucenv["ADAGUC_LOGFILE"] = self.ADAGUC_LOGFILE adagucenv["ADAGUC_PATH"] = self.ADAGUC_PATH @@ -85,26 +88,46 @@ def scanDataset(self, datasetName): adagucenv["ADAGUC_DATASET_DIR"] = self.ADAGUC_DATASET_DIR adagucenv["ADAGUC_TMP"] = self.ADAGUC_TMP adagucenv["ADAGUC_FONT"] = self.ADAGUC_FONT + adagucenv["ADAGUC_DATARESTRICTION"] = "FALSE" + if os.getenv("ADAGUC_DB"): + adagucenv["ADAGUC_DB"] = os.getenv("ADAGUC_DB") + adagucenv["ADAGUC_ENABLELOGBUFFER"] = os.getenv( + "ADAGUC_ENABLELOGBUFFER", "TRUE" + ) + ld_library_path = os.getenv("LD_LIBRARY_PATH") + if ld_library_path: + adagucenv["LD_LIBRARY_PATH"] = ld_library_path + + + return adagucenv + def updateLayerMetadata(self): + """Uses the adaguc executable to update the layermetadatatable""" + adagucenv = self.getAdagucEnv() status, data, headers = asyncio.run( self.runADAGUCServer( - args=["--updatedb", "--config", config], env=adagucenv, isCGI=False + args=["--updatelayermetadata"], env=adagucenv, isCGI=False, showLogOnError = False ) ) + + return status, data.getvalue().decode() + + def scanDataset(self, datasetName): + config = self.ADAGUC_CONFIG + "," + datasetName + adagucenv = self.getAdagucEnv() + status, data, headers = asyncio.run( + self.runADAGUCServer( + args=["--updatedb", "--config", config], env=adagucenv, isCGI=False, showLogOnError = False + ) + ) + + return data.getvalue().decode() def runGetMapUrl(self, url): - adagucenv = {} - """ Set required environment variables """ - adagucenv["ADAGUC_CONFIG"] = self.ADAGUC_CONFIG - adagucenv["ADAGUC_LOGFILE"] = self.ADAGUC_LOGFILE - adagucenv["ADAGUC_PATH"] = self.ADAGUC_PATH - adagucenv["ADAGUC_DATA_DIR"] = self.ADAGUC_DATA_DIR - adagucenv["ADAGUC_AUTOWMS_DIR"] = self.ADAGUC_AUTOWMS_DIR - adagucenv["ADAGUC_DATASET_DIR"] = self.ADAGUC_DATASET_DIR - adagucenv["ADAGUC_TMP"] = self.ADAGUC_TMP - adagucenv["ADAGUC_FONT"] = self.ADAGUC_FONT + adagucenv = self.getAdagucEnv() + status, data, headers = asyncio.run( self.runADAGUCServer(url, env=adagucenv, showLogOnError=False) ) @@ -148,7 +171,7 @@ def cache_wanted(self, url: str): Returns: boolean """ - if not runAdaguc.use_cache: + if not runAdaguc.use_cache or not url: return False if "request=getcapabilities" in url.lower(): return True @@ -164,26 +187,10 @@ async def runADAGUCServer( showLogOnError=True, showLog=False, ): - # adagucenv=os.environ.copy() - # adagucenv.update(env) - adagucenv = env + adagucenv = self.getAdagucEnv(env) + - adagucenv["ADAGUC_ENABLELOGBUFFER"] = os.getenv( - "ADAGUC_ENABLELOGBUFFER", "TRUE" - ) - adagucenv["ADAGUC_CONFIG"] = self.ADAGUC_CONFIG - adagucenv["ADAGUC_LOGFILE"] = self.ADAGUC_LOGFILE - adagucenv["ADAGUC_PATH"] = self.ADAGUC_PATH - adagucenv["ADAGUC_DATARESTRICTION"] = "FALSE" - adagucenv["ADAGUC_DATA_DIR"] = self.ADAGUC_DATA_DIR - adagucenv["ADAGUC_AUTOWMS_DIR"] = self.ADAGUC_AUTOWMS_DIR - adagucenv["ADAGUC_DATASET_DIR"] = self.ADAGUC_DATASET_DIR - adagucenv["ADAGUC_TMP"] = self.ADAGUC_TMP - adagucenv["ADAGUC_FONT"] = self.ADAGUC_FONT - ld_library_path = os.getenv("LD_LIBRARY_PATH") - if ld_library_path: - adagucenv["LD_LIBRARY_PATH"] = ld_library_path # Forward all environment variables starting with ADAGUCENV_ prefix: str = "ADAGUCENV_" @@ -242,7 +249,7 @@ async def runADAGUCServer( print("=== START ADAGUC HTTP HEADER ===") print(headers) print("=== END ADAGUC HTTP HEADER ===") - else: + elif isCGI: print("Process: No HTTP Headers written") print("--- END ADAGUC DEBUG INFO ---\n") diff --git a/python/python_fastapi_server/main.py b/python/python_fastapi_server/main.py index de16742d7..509fed2ca 100644 --- a/python/python_fastapi_server/main.py +++ b/python/python_fastapi_server/main.py @@ -1,13 +1,9 @@ +"""Main file where FastAPI is defined and started""" import logging - -from configure_logging import configure_logging - -configure_logging(logging) - import os import time from urllib.parse import urlsplit - +from apscheduler.schedulers.asyncio import AsyncIOScheduler import uvicorn from brotli_asgi import BrotliMiddleware from fastapi import FastAPI, Request @@ -22,22 +18,54 @@ from routers.opendap import opendapRouter from routers.wmswcs import testadaguc, wmsWcsRouter from routers.caching_middleware import CachingMiddleware +from routers.setup_adaguc import setup_adaguc +from configure_logging import configure_logging + +configure_logging(logging) logger = logging.getLogger(__name__) -app = FastAPI() +def update_layermetadatatable(): + """Update layermetadata table in adaguc for GetCapabilities caching""" + adaguc = setup_adaguc(False) + logger.info("Calling updateLayerMetadata") + status, log = adaguc.updateLayerMetadata() + if adaguc.isLoggingEnabled(): + logger.info(log) + else: + logger.info("Logging for updateLayerMetadata is disabled, status was %d", status) + + +async def lifespan(_fastapiapp: FastAPI): + """Captures FASTAPI Lifespan events to start the AsyncIOScheduler""" + + logger.info("=== Starting AsyncIO Scheduler ===") + # start scheduler to refresh collections & docs every minute + scheduler = AsyncIOScheduler() + scheduler.add_job(update_layermetadatatable, "cron", [], minute="*/1", jitter=0, max_instances=1, coalesce=True) + scheduler.start() + + yield + + logger.info("=== Stopping AsyncIO Scheduler ===") + scheduler.shutdown() + + +app = FastAPI(lifespan=lifespan) # Set uvicorn access log format using middleware -access_log_format = ( +ACCESS_LOG_FORMAT = ( 'accesslog %(h)s ; %(t)s ; %(H)s ; %(m)s ; %(U)s ; %(q)s ; %(s)s ; %(M)s ; "%(a)s"' ) logging.getLogger("uvicorn.access").handlers.clear() -app.add_middleware(AccessLoggerMiddleware, format=access_log_format) +app.add_middleware(AccessLoggerMiddleware, format=ACCESS_LOG_FORMAT) logging.getLogger("access").propagate = False + @app.middleware("http") async def add_hsts_header(request: Request, call_next): + """Middleware to HTTP Strict Transport Security (HSTS) header""" response = await call_next(request) if "EXTERNALADDRESS" in os.environ: external_address = os.environ["EXTERNALADDRESS"] @@ -60,6 +88,7 @@ async def add_hsts_header(request: Request, call_next): @app.middleware("http") async def add_process_time_header(request: Request, call_next): + """Middle ware to at X-Process-Time to each request""" start_time = time.time() response = await call_next(request) process_time = time.time() - start_time @@ -79,6 +108,7 @@ async def add_process_time_header(request: Request, call_next): @app.get("/") async def root(): + """Root page""" return { "message": "ADAGUC server base URL, use /wms, /wcs, /autowms, /adagucopendap or /ogcapi" diff --git a/requirements.in b/requirements.in index 8cdccca1b..8ecf8babe 100644 --- a/requirements.in +++ b/requirements.in @@ -4,6 +4,7 @@ # pip-sync aiocache~=0.12.2 +APScheduler~=3.10.4 Brotli~=1.0 Jinja2~=3.1 OWSLib~=0.29.2 diff --git a/requirements.txt b/requirements.txt index 4a327cfde..c63e797ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,10 +8,12 @@ aiocache==0.12.2 # via -r requirements.in annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.5.0 # via # httpx # starlette +apscheduler==3.10.4 + # via -r requirements.in asgi-logger==0.1.0 # via -r requirements.in asgiref==3.8.1 @@ -68,7 +70,7 @@ httpcore==1.0.5 # via httpx httpx==0.26.0 # via -r requirements.in -idna==3.8 +idna==3.10 # via # anyio # httpx @@ -94,14 +96,14 @@ packaging==24.1 # via gunicorn pillow==10.4.0 # via -r requirements.in -pydantic==2.8.2 +pydantic==2.9.2 # via # -r requirements.in # covjson-pydantic # edr-pydantic # fastapi # geojson-pydantic -pydantic-core==2.20.1 +pydantic-core==2.23.4 # via pydantic python-dateutil==2.9.0.post0 # via @@ -110,6 +112,7 @@ python-dateutil==2.9.0.post0 pytz==2023.4 # via # -r requirements.in + # apscheduler # owslib pyyaml==6.0.2 # via owslib @@ -118,7 +121,9 @@ redis==5.0.8 requests==2.32.3 # via owslib six==1.16.0 - # via python-dateutil + # via + # apscheduler + # python-dateutil sniffio==1.3.1 # via # anyio @@ -135,7 +140,9 @@ typing-extensions==4.12.2 # pydantic # pydantic-core # uvicorn -urllib3==2.2.2 +tzlocal==5.2 + # via apscheduler +urllib3==2.2.3 # via requests uvicorn==0.23.2 # via -r requirements.in From 38fce6e48dd423a3a18100257961fef85f5fc25a Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Mon, 23 Sep 2024 21:07:51 +0200 Subject: [PATCH 47/50] Rewrite of updatelayer metadata from two nested maps into two sets --- adagucserverEC/CDBFileScanner.cpp | 2 +- adagucserverEC/utils/ConfigurationUtils.cpp | 26 +++++++ adagucserverEC/utils/ConfigurationUtils.h | 3 + adagucserverEC/utils/UpdateLayerMetadata.cpp | 77 ++++---------------- adagucserverEC/utils/UpdateLayerMetadata.h | 2 - python/lib/adaguc/runAdaguc.py | 2 +- python/python_fastapi_server/main.py | 2 +- 7 files changed, 48 insertions(+), 66 deletions(-) diff --git a/adagucserverEC/CDBFileScanner.cpp b/adagucserverEC/CDBFileScanner.cpp index 5d9099122..7d855f675 100644 --- a/adagucserverEC/CDBFileScanner.cpp +++ b/adagucserverEC/CDBFileScanner.cpp @@ -968,7 +968,7 @@ int CDBFileScanner::updatedb(CDataSource *dataSource, CT::string *_tailPath, CT: return 1; } fileList.push_back(fileName); - // CDBDebug("Queried file from database with filename [%s]", fileName.c_str()); + CDBDebug("Queried file from database with filename [%s]", fileName.c_str()); } } else { fileList = searchFileNames(dataSource->cfgLayer->FilePath[0]->value.c_str(), filter.c_str(), tailPath.c_str()); diff --git a/adagucserverEC/utils/ConfigurationUtils.cpp b/adagucserverEC/utils/ConfigurationUtils.cpp index 90ff9c5ba..8e3594361 100644 --- a/adagucserverEC/utils/ConfigurationUtils.cpp +++ b/adagucserverEC/utils/ConfigurationUtils.cpp @@ -19,3 +19,29 @@ bool checkIfPathIsFile(CT::string filePath) { return (filePath.endsWith(".nc") || filePath.endsWith(".h5") || filePath.endsWith(".hdf5") || filePath.endsWith(".he5") || filePath.endsWith(".png") || filePath.endsWith(".csv") || filePath.endsWith(".geojson") || filePath.endsWith(".json") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("dodsc://")); } + +void serverLogFunctionNothing(const char *) {} + +/* Set config file from environment variable ADAGUC_CONFIG */ +int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset) { + char *configfile = getenv("ADAGUC_CONFIG"); + if (configfile != NULL) { + CT::string configWithAdditionalDataset = configfile; + if (additionalDataset != nullptr && strlen(additionalDataset) > 0) { + configWithAdditionalDataset.concat(","); + configWithAdditionalDataset.concat(additionalDataset); + } + int status = request->setConfigFile(configWithAdditionalDataset.c_str()); + + /* Check logging level */ + if (request->getServerParams()->isDebugLoggingEnabled() == false) { + setDebugFunction(serverLogFunctionNothing); + } + + return status; + } else { + CDBError("No configuration file is set. Please set ADAGUC_CONFIG environment variable accordingly."); + return 1; + } + return 0; +} diff --git a/adagucserverEC/utils/ConfigurationUtils.h b/adagucserverEC/utils/ConfigurationUtils.h index 3d8656008..dd62f2165 100644 --- a/adagucserverEC/utils/ConfigurationUtils.h +++ b/adagucserverEC/utils/ConfigurationUtils.h @@ -4,9 +4,12 @@ #include #include #include +#include std::vector getEnabledDatasetsConfigurations(CServerParams *srvParam); bool checkIfPathIsFile(CT::string filePath); +int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset = nullptr); + #endif diff --git a/adagucserverEC/utils/UpdateLayerMetadata.cpp b/adagucserverEC/utils/UpdateLayerMetadata.cpp index acf7acf63..486d35c79 100644 --- a/adagucserverEC/utils/UpdateLayerMetadata.cpp +++ b/adagucserverEC/utils/UpdateLayerMetadata.cpp @@ -7,40 +7,15 @@ #include #include "LayerUtils.h" -void serverLogFunctionNothing(const char *) {} - -/* Set config file from environment variable ADAGUC_CONFIG */ -int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset) { - char *configfile = getenv("ADAGUC_CONFIG"); - if (configfile != NULL) { - CT::string configWithAdditionalDataset = configfile; - if (additionalDataset != nullptr && strlen(additionalDataset) > 0) { - configWithAdditionalDataset.concat(","); - configWithAdditionalDataset.concat(additionalDataset); - } - int status = request->setConfigFile(configWithAdditionalDataset.c_str()); - - /* Check logging level */ - if (request->getServerParams()->isDebugLoggingEnabled() == false) { - setDebugFunction(serverLogFunctionNothing); - } - - return status; - } else { - CDBError("No configuration file is set. Please set ADAGUC_CONFIG environment variable accordingly."); - return 1; - } - return 0; -} +typedef std::pair DatasetAndLayerPair; int updateLayerMetadata(CRequest &request) { CServerParams *srvParam = request.getServerParams(); auto datasetList = getEnabledDatasetsConfigurations(srvParam); - // TODO: Remove datasets and layers in metadatable which don't have a matching configuration // TODO: Remove dimension tables which don't have a matching configuration - std::map> dataSetConfigsWithLayers; + std::set dataSetConfigsWithLayers; for (auto &dataset : datasetList) { CT::string datasetAsCTString = dataset.c_str(); @@ -52,8 +27,7 @@ int updateLayerMetadata(CRequest &request) { CDBDebug("\n\n *********************************** Updating metadatatable for dataset [%s] **************************************************", dataset.c_str()); } CRequest requestPerDataset; - // dataset = "/data/adaguc-datasets/test.uwcw_ha43_dini_5p5km_10x8.xml"; - // dataset = "/data/adaguc-datasets/testdata.xml"; + int status = setCRequestConfigFromEnvironment(&requestPerDataset, dataset.c_str()); if (status != 0) { CDBError("Unable to read configuration file"); @@ -67,7 +41,7 @@ int updateLayerMetadata(CRequest &request) { layerName.print("ID_%s", tmp.c_str()); } - dataSetConfigsWithLayers[datasetBaseName].insert(layerName.c_str()); + dataSetConfigsWithLayers.insert(std::make_pair(datasetBaseName, layerName.c_str())); } CT::string layerPathToScan; CT::string tailPath; @@ -76,10 +50,9 @@ int updateLayerMetadata(CRequest &request) { CDBError("Error occured in updating the database"); continue; } - // return 0; } - // Check for datasets which are not configured anymore. + // Check for datasets and or layers which are not configured anymore. json dataset; json layer; @@ -88,43 +61,25 @@ int updateLayerMetadata(CRequest &request) { return 1; } auto records = layerMetaDataStore->getRecords(); - std::map> datasetNamesFromDB; + + std::set datasetNamesFromDB; + for (auto record : records) { CT::string *datasetName = record->get("datasetname"); CT::string *layerName = record->get("layername"); if (datasetName != nullptr && layerName != nullptr) { - datasetNamesFromDB[datasetName->c_str()].insert(layerName->c_str()); + datasetNamesFromDB.insert(std::make_pair(datasetName->c_str(), layerName->c_str())); } } - std::map> layersToDeleteFromMetadataTable; - for (auto datasetFromDB : datasetNamesFromDB) { - for (auto layerNameDb : datasetFromDB.second) { - bool hasLayer = false; - for (auto datasetConfig : dataSetConfigsWithLayers) { - if (datasetConfig.first == datasetFromDB.first) { - for (auto layerNameConfig : datasetConfig.second) { - if (layerNameConfig == layerNameDb) { - hasLayer = true; - break; - } - } - } - } - if (!hasLayer) { - // CDBDebug("NO: %s/%s ", datasetFromDB.first.c_str(), layerNameDb.c_str()); - layersToDeleteFromMetadataTable[datasetFromDB.first].insert(layerNameDb); - } else { - // CDBDebug("YES: %s/%s ", datasetFromDB.first.c_str(), layerNameDb.c_str()); - } - } - } + std::set layersToDeleteFromMetadataTable; - for (auto dataset : layersToDeleteFromMetadataTable) { - for (auto layer : dataset.second) { - CDBDebug("DROP: %s/%s ", dataset.first.c_str(), layer.c_str()); - CDBFactory::getDBAdapter(srvParam->cfg)->dropLayerFromLayerMetadataStore(dataset.first.c_str(), layer.c_str()); - } + std::set_difference(datasetNamesFromDB.begin(), datasetNamesFromDB.end(), dataSetConfigsWithLayers.begin(), dataSetConfigsWithLayers.end(), + std::inserter(layersToDeleteFromMetadataTable, layersToDeleteFromMetadataTable.end())); + + for (auto p : layersToDeleteFromMetadataTable) { + CDBDebug("DROP: %s/%s ", p.first.c_str(), p.second.c_str()); + CDBFactory::getDBAdapter(srvParam->cfg)->dropLayerFromLayerMetadataStore(p.first.c_str(), p.second.c_str()); } return 0; diff --git a/adagucserverEC/utils/UpdateLayerMetadata.h b/adagucserverEC/utils/UpdateLayerMetadata.h index b07be6342..a08787fae 100644 --- a/adagucserverEC/utils/UpdateLayerMetadata.h +++ b/adagucserverEC/utils/UpdateLayerMetadata.h @@ -2,8 +2,6 @@ #define UPDATELAYERMETADATA_H #include -int setCRequestConfigFromEnvironment(CRequest *request, const char *additionalDataset = nullptr); - int updateLayerMetadata(CRequest &request); #endif \ No newline at end of file diff --git a/python/lib/adaguc/runAdaguc.py b/python/lib/adaguc/runAdaguc.py index 5551b14e1..d38fa00a1 100644 --- a/python/lib/adaguc/runAdaguc.py +++ b/python/lib/adaguc/runAdaguc.py @@ -106,7 +106,7 @@ def updateLayerMetadata(self): adagucenv = self.getAdagucEnv() status, data, headers = asyncio.run( self.runADAGUCServer( - args=["--updatelayermetadata"], env=adagucenv, isCGI=False, showLogOnError = False + args=["--updatelayermetadata"], env=adagucenv, isCGI=False, showLogOnError = True ) ) diff --git a/python/python_fastapi_server/main.py b/python/python_fastapi_server/main.py index 509fed2ca..d72d3e108 100644 --- a/python/python_fastapi_server/main.py +++ b/python/python_fastapi_server/main.py @@ -42,7 +42,7 @@ async def lifespan(_fastapiapp: FastAPI): logger.info("=== Starting AsyncIO Scheduler ===") # start scheduler to refresh collections & docs every minute scheduler = AsyncIOScheduler() - scheduler.add_job(update_layermetadatatable, "cron", [], minute="*/1", jitter=0, max_instances=1, coalesce=True) + scheduler.add_job(update_layermetadatatable, "cron", [], minute="*", jitter=0, max_instances=1, coalesce=True) scheduler.start() yield From 560c8887b33290e0dc7616c85ddb6515275ba7cb Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 24 Sep 2024 09:07:04 +0200 Subject: [PATCH 48/50] Added extra metadata entries --- adagucserverEC/CXMLGen.cpp | 15 +++++++------- .../LayerTypeLiveUpdate.cpp | 3 ++- adagucserverEC/Types/LayerMetadataType.h | 5 +++-- adagucserverEC/utils/LayerMetadataStore.cpp | 12 ++++++----- adagucserverEC/utils/XMLGenUtils.cpp | 20 +++++++++++-------- .../test_GetMetadataRequest_arcus_uwcw.json | 2 +- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/adagucserverEC/CXMLGen.cpp b/adagucserverEC/CXMLGen.cpp index 87c478605..ebd21a808 100644 --- a/adagucserverEC/CXMLGen.cpp +++ b/adagucserverEC/CXMLGen.cpp @@ -100,8 +100,8 @@ int CXMLGen::getWMS_1_0_0_Capabilities(CT::string *XMLDoc, std::vectorlayerMetadata.dimList) { if (dim.hidden) continue; - XMLDoc->printconcat("\n", dim.name.c_str(), dim.units.c_str()); - XMLDoc->printconcat("", dim.name.c_str(), dim.defaultValue.c_str(), 1); + XMLDoc->printconcat("\n", dim.serviceName.c_str(), dim.units.c_str()); + XMLDoc->printconcat("", dim.serviceName.c_str(), dim.defaultValue.c_str(), 1); XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); } @@ -237,8 +237,8 @@ int CXMLGen::getWMS_1_1_1_Capabilities(CT::string *XMLDoc, std::vectorlayerMetadata.dimList) { if (dim.hidden) continue; - XMLDoc->printconcat("\n", dim.name.c_str(), dim.units.c_str()); - XMLDoc->printconcat("", dim.name.c_str(), dim.defaultValue.c_str(), 1); + XMLDoc->printconcat("\n", dim.serviceName.c_str(), dim.units.c_str()); + XMLDoc->printconcat("", dim.serviceName.c_str(), dim.defaultValue.c_str(), 1); XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); } @@ -649,11 +649,12 @@ int CXMLGen::getWMS_1_3_0_Capabilities(CT::string *XMLDoc, std::vectorlayerMetadata.dimList) { if (dim.hidden) continue; - if (dim.name.indexOf("time") != -1) { - XMLDoc->printconcat("", dim.name.c_str(), dim.units.c_str(), + if (dim.serviceName.indexOf("time") != -1) { + XMLDoc->printconcat("", dim.serviceName.c_str(), dim.units.c_str(), dim.defaultValue.c_str(), 1); } else { - XMLDoc->printconcat("", dim.name.c_str(), dim.units.c_str(), dim.defaultValue.c_str(), 1); + XMLDoc->printconcat("", dim.serviceName.c_str(), dim.units.c_str(), + dim.defaultValue.c_str(), 1); } XMLDoc->concat(dim.values.c_str()); XMLDoc->concat("\n"); diff --git a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp index afcd38796..9143f3342 100644 --- a/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp +++ b/adagucserverEC/LayerTypeLiveUpdate/LayerTypeLiveUpdate.cpp @@ -54,7 +54,8 @@ int layerTypeLiveUpdateConfigureWMSLayerForGetCapabilities(MetadataLayer *metada CT::string startTime = timeInstance.dateToISOString(timeInstance.offsetToDate(startTimeOffset)); CT::string stopTime = timeInstance.dateToISOString(timeInstance.offsetToDate(stopTimeOffset)); CT::string resTime = "PT1S"; - LayerMetadataDim dim = {.name = "time", .units = "ISO8601", .values = startTime + "/" + stopTime + "/" + resTime, .defaultValue = stopTime, .hasMultipleValues = true, .hidden = false}; + LayerMetadataDim dim = { + .serviceName = "time", .cdfName = "time", .units = "ISO8601", .values = startTime + "/" + stopTime + "/" + resTime, .defaultValue = stopTime, .hasMultipleValues = true, .hidden = false}; metadataLayer->layerMetadata.dimList.push_back(dim); return 0; diff --git a/adagucserverEC/Types/LayerMetadataType.h b/adagucserverEC/Types/LayerMetadataType.h index 19c76cdcc..903028a20 100644 --- a/adagucserverEC/Types/LayerMetadataType.h +++ b/adagucserverEC/Types/LayerMetadataType.h @@ -6,7 +6,8 @@ #include struct LayerMetadataDim { - CT::string name; + CT::string serviceName; + CT::string cdfName; CT::string units; CT::string values; CT::string defaultValue; @@ -15,7 +16,7 @@ struct LayerMetadataDim { }; struct LayerMetadataProjection { - LayerMetadataProjection(const CT::string& name, const double bbox[]) { + LayerMetadataProjection(const CT::string &name, const double bbox[]) { this->name = name; for (size_t j = 0; j < 4; j++) { this->dfBBOX[j] = bbox[j]; diff --git a/adagucserverEC/utils/LayerMetadataStore.cpp b/adagucserverEC/utils/LayerMetadataStore.cpp index 4ce5c1c6d..f707e2f07 100644 --- a/adagucserverEC/utils/LayerMetadataStore.cpp +++ b/adagucserverEC/utils/LayerMetadataStore.cpp @@ -12,10 +12,11 @@ int getDimensionListAsJson(MetadataLayer *metadataLayer, json &dimListJson) { item["defaultValue"] = dimension.defaultValue.c_str(); item["hasMultipleValues"] = dimension.hasMultipleValues; item["hidden"] = dimension.hidden; - item["name"] = dimension.name.c_str(); + item["serviceName"] = dimension.serviceName.c_str(); + item["cdfName"] = dimension.cdfName.c_str(); item["units"] = dimension.units.c_str(); item["values"] = dimension.values.c_str(); - dimListJson[dimension.name.c_str()] = item; + dimListJson[dimension.serviceName.c_str()] = item; } } catch (json::exception &e) { CDBWarning("Unable to build json structure"); @@ -26,7 +27,7 @@ int getDimensionListAsJson(MetadataLayer *metadataLayer, json &dimListJson) { int getLayerBaseMetadataAsJson(MetadataLayer *metadataLayer, json &layerMetadataItem) { try { - layerMetadataItem["name"] = metadataLayer->layerMetadata.name; + layerMetadataItem["layername"] = metadataLayer->layerMetadata.name; layerMetadataItem["title"] = metadataLayer->layerMetadata.title; layerMetadataItem["group"] = metadataLayer->layerMetadata.group; layerMetadataItem["abstract"] = metadataLayer->layerMetadata.abstract; @@ -181,7 +182,7 @@ int loadLayerMetadataStructFromMetadataDb(MetadataLayer *metadataLayer) { } json a; auto i = a.parse(layerMetadataAsJson.c_str()); - metadataLayer->layerMetadata.name = i["name"].get().c_str(); + metadataLayer->layerMetadata.name = i["layername"].get().c_str(); metadataLayer->layerMetadata.title = i["title"].get().c_str(); metadataLayer->layerMetadata.group = i["group"].get().c_str(); metadataLayer->layerMetadata.abstract = i["abstract"].get().c_str(); @@ -366,7 +367,8 @@ int loadLayerDimensionListFromMetadataDb(MetadataLayer *metadataLayer) { auto dimensionProperties = d.value(); LayerMetadataDim dimension = { - .name = dimensionProperties["name"].get().c_str(), + .serviceName = dimensionProperties["serviceName"].get().c_str(), + .cdfName = dimensionProperties["cdfName"].get().c_str(), .units = dimensionProperties["units"].get().c_str(), .values = dimensionProperties["values"].get().c_str(), .defaultValue = dimensionProperties["defaultValue"].get().c_str(), diff --git a/adagucserverEC/utils/XMLGenUtils.cpp b/adagucserverEC/utils/XMLGenUtils.cpp index 75ba168e7..5b29ce9cb 100644 --- a/adagucserverEC/utils/XMLGenUtils.cpp +++ b/adagucserverEC/utils/XMLGenUtils.cpp @@ -127,11 +127,11 @@ int populateMetadataLayerStruct(MetadataLayer *metadataLayer, bool readFromDB) { std::map projectionMap; // Make a unique list of projections - for (const auto& p : metadataLayer->layerMetadata.projectionList) { + for (const auto &p : metadataLayer->layerMetadata.projectionList) { projectionMap.emplace(p.name.c_str(), p); } metadataLayer->layerMetadata.projectionList.clear(); - for (const auto& p : projectionMap) { + for (const auto &p : projectionMap) { metadataLayer->layerMetadata.projectionList.push_back(p.second); } @@ -169,7 +169,8 @@ int getDimsForLayer(MetadataLayer *metadataLayer) { CT::string fileDate = CDirReader::getFileDate(metadataLayer->layer->FilePath[0]->value.c_str()); LayerMetadataDim dim; - dim.name.copy("time"); + dim.serviceName.copy("time"); + dim.cdfName.copy("time"); dim.units.copy("ISO8601"); dim.values.copy(fileDate.c_str()); dim.defaultValue.copy(fileDate.c_str()); @@ -188,7 +189,8 @@ int getDimsForLayer(MetadataLayer *metadataLayer) { // Create a new dim to store in the layer LayerMetadataDim dim; dim.hidden = false; - dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.serviceName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.cdfName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str()); // Get the tablename CT::string tableName; @@ -404,14 +406,15 @@ int getDimsForLayer(MetadataLayer *metadataLayer) { // if(srvParam->requestType==REQUEST_WMS_GETCAPABILITIES) { - dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.serviceName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.cdfName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str()); // Try to get units from the variable dim.units.copy("NA"); if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty()) { CT::string units; try { - metadataLayer->dataSource->getDataObject(0)->cdfObject->getVariable(dim.name.c_str())->getAttribute("units")->getDataAsString(&units); + metadataLayer->dataSource->getDataObject(0)->cdfObject->getVariable(dim.cdfName.c_str())->getAttribute("units")->getDataAsString(&units); dim.units.copy(&units); } catch (int e) { } @@ -518,7 +521,8 @@ int getDimsForLayer(MetadataLayer *metadataLayer) { if (metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.empty() == false) { dimUnits.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.units.c_str()); } - dim.name.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.serviceName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->value.c_str()); + dim.cdfName.copy(metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.name.c_str()); dim.units.copy(dimUnits.c_str()); dim.hasMultipleValues = 0; // metadataLayer->dataSource->cfgLayer->Dimension[i]->attr.defaultV.c_str() @@ -689,7 +693,7 @@ int getStylesForLayer(MetadataLayer *metadataLayer) { bool compareStringCase(const std::string &s1, const std::string &s2) { return strcmp(s1.c_str(), s2.c_str()) < 0; } bool compareProjection(const LayerMetadataProjection &p1, const LayerMetadataProjection &p2) { return strcmp(p1.name.c_str(), p2.name.c_str()) < 0; } -bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.name.c_str(), p2.name.c_str()) < 0; } +bool compareDim(const LayerMetadataDim &p2, const LayerMetadataDim &p1) { return strcmp(p1.serviceName.c_str(), p2.serviceName.c_str()) < 0; } int getTitleForLayer(MetadataLayer *metadataLayer) { #ifdef CXMLGEN_DEBUG diff --git a/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json index 2e98ac106..7c64ba394 100644 --- a/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json +++ b/tests/expectedoutputs/TestMetadataRequest/test_GetMetadataRequest_arcus_uwcw.json @@ -1 +1 @@ -{"adaguc.tests.arcus_uwcw":{"air_temperature_hagl":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"2","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"2"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-05-23T00:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-05-23T00:00:00Z"},"time":{"defaultValue":"2024-05-23T01:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-05-23T01:00:00Z/2024-05-25T12:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"cellsizex":2.262,"cellsizey":-1.404,"height":5,"projstring":"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"name":"air_temperature_hagl","nativeepsg":"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Air temperature at 2 m","variables":[{"label":"Air temperature at height above ground level","units":"C","variableName":"air-temperature-hagl"}]}},"baselayer":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"baselayer","nativeepsg":"","title":"baselayer","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"overlay":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"name":"overlay","nativeepsg":"","title":"overlay","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"wind_speed_hagl_kts":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_kts","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in Knots","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_member_3":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"3","hasMultipleValues":1,"hidden":true,"name":"member","units":"-","values":"3"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_member_3","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms for member 3","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_wrong_dim_order":{"dims":{"height_above_ground_level_in_m":{"defaultValue":"10","hasMultipleValues":1,"hidden":true,"name":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"defaultValue":"1","hasMultipleValues":1,"hidden":false,"name":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"name":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"name":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"name":"wind_speed_hagl_ms_wrong_dim_order","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}}}} \ No newline at end of file +{"adaguc.tests.arcus_uwcw":{"air_temperature_hagl":{"dims":{"height_above_ground_level_in_m":{"cdfName":"temp_at_hagl","defaultValue":"2","hasMultipleValues":1,"hidden":true,"serviceName":"height_above_ground_level_in_m","units":"m","values":"2"},"member":{"cdfName":"member","defaultValue":"1","hasMultipleValues":1,"hidden":false,"serviceName":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"cdfName":"forecast_reference_time","defaultValue":"2024-05-23T00:00:00Z","hasMultipleValues":1,"hidden":false,"serviceName":"reference_time","units":"ISO8601","values":"2024-05-23T00:00:00Z"},"time":{"cdfName":"time","defaultValue":"2024-05-23T01:00:00Z","hasMultipleValues":0,"hidden":false,"serviceName":"time","units":"ISO8601","values":"2024-05-23T01:00:00Z/2024-05-25T12:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"cellsizex":2.262,"cellsizey":-1.404,"height":5,"projstring":"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[-0.014499999999999957,48.99100000000001,11.2955,56.011],"layername":"air_temperature_hagl","nativeepsg":"PROJ4:%2Bproj%3Dlonglat%20%2Bellps%3DWGS84%20%2Bdatum%3DWGS84%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Air temperature at 2 m","variables":[{"label":"Air temperature at height above ground level","units":"C","variableName":"air-temperature-hagl"}]}},"baselayer":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"layername":"baselayer","nativeepsg":"","title":"baselayer","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"overlay":{"dims":null,"layer":{"abstract":"","gridspec":{"bbox":[-180.0,83.64513,180.0000000000001,-90.0],"cellsizex":180.00000000000006,"cellsizey":86.822565,"height":2,"projstring":"","width":2},"group":"baselayers","isqueryable":1,"latlonbox":[-180.0,-90.0,180.0000000000001,83.64513],"layername":"overlay","nativeepsg":"","title":"overlay","variables":[{"label":"Feature index","units":"","variableName":"features"}]}},"wind_speed_hagl_kts":{"dims":{"height_above_ground_level_in_m":{"cdfName":"wind_at_hagl","defaultValue":"10","hasMultipleValues":1,"hidden":true,"serviceName":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"cdfName":"member","defaultValue":"1","hasMultipleValues":1,"hidden":false,"serviceName":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"cdfName":"forecast_reference_time","defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"serviceName":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"cdfName":"time","defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"serviceName":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"layername":"wind_speed_hagl_kts","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in Knots","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms":{"dims":{"height_above_ground_level_in_m":{"cdfName":"wind_at_hagl","defaultValue":"10","hasMultipleValues":1,"hidden":true,"serviceName":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"cdfName":"member","defaultValue":"1","hasMultipleValues":1,"hidden":false,"serviceName":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"cdfName":"forecast_reference_time","defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"serviceName":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"cdfName":"time","defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"serviceName":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"layername":"wind_speed_hagl_ms","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_member_3":{"dims":{"height_above_ground_level_in_m":{"cdfName":"wind_at_hagl","defaultValue":"10","hasMultipleValues":1,"hidden":true,"serviceName":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"cdfName":"member","defaultValue":"3","hasMultipleValues":1,"hidden":true,"serviceName":"member","units":"-","values":"3"},"reference_time":{"cdfName":"forecast_reference_time","defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"serviceName":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"cdfName":"time","defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"serviceName":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"layername":"wind_speed_hagl_ms_member_3","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms for member 3","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}},"wind_speed_hagl_ms_wrong_dim_order":{"dims":{"height_above_ground_level_in_m":{"cdfName":"wind_at_hagl","defaultValue":"10","hasMultipleValues":1,"hidden":true,"serviceName":"height_above_ground_level_in_m","units":"m","values":"10"},"member":{"cdfName":"member","defaultValue":"1","hasMultipleValues":1,"hidden":false,"serviceName":"member","units":"-","values":"1,2,3,4,5"},"reference_time":{"cdfName":"forecast_reference_time","defaultValue":"2024-06-05T03:00:00Z","hasMultipleValues":1,"hidden":false,"serviceName":"reference_time","units":"ISO8601","values":"2024-06-05T03:00:00Z"},"time":{"cdfName":"time","defaultValue":"2024-06-05T04:00:00Z","hasMultipleValues":0,"hidden":false,"serviceName":"time","units":"ISO8601","values":"2024-06-05T04:00:00Z/2024-06-07T15:00:00Z/PT1H"}},"layer":{"abstract":"","gridspec":{"bbox":[237556.04779691307,6429395.966709785,1008078.3936105771,7241407.977298031],"cellsizex":154104.4691627328,"cellsizey":-162402.4021176491,"height":5,"projstring":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs","width":5},"group":"","isqueryable":1,"latlonbox":[2.1340022857099457,49.902432406618686,9.055722285710363,54.37452297558314],"layername":"wind_speed_hagl_ms_wrong_dim_order","nativeepsg":"PROJ4:%2Bproj%3Dmerc%20%2Ba%3D6378137%20%2Bb%3D6378137%20%2Blat_ts%3D0%2E0%20%2Blon_0%3D0%2E0%20%2Bx_0%3D0%2E0%20%2By_0%3D0%20%2Bk%3D1%2E0%20%2Bunits%3Dm%20%2Bnadgrids%3D@null%20%2Bwktext%20%20%2Bno_defs","title":"UWCW_HA43ENS(NL) Wind speed at height above ground level in ms","variables":[{"label":"Wind speed at height above ground level","units":"kts","variableName":"wind-speed-hagl"}]}}}} \ No newline at end of file From 1518d194884924458e34464dca6c52cf234e17c0 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Tue, 24 Sep 2024 12:27:38 +0200 Subject: [PATCH 49/50] Solved bug where brotli caused huge delays when storing cached data in Redis --- python/lib/adaguc/runAdaguc.py | 5 ++--- .../python_fastapi_server/routers/caching_middleware.py | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/python/lib/adaguc/runAdaguc.py b/python/lib/adaguc/runAdaguc.py index d38fa00a1..ba249c8bf 100644 --- a/python/lib/adaguc/runAdaguc.py +++ b/python/lib/adaguc/runAdaguc.py @@ -2,7 +2,6 @@ import os from PIL import Image from io import BytesIO -import brotli import shutil import random import string @@ -314,7 +313,7 @@ async def response_to_cache(redis_pool, key, headers: str, data): entrytime + f"{len(cacheable_headers_json):06d}".encode("utf-8") + cacheable_headers_json - + brotli.compress(data.getvalue()), + + data.getvalue(), ex=ttl, ) await redis_client.aclose() @@ -335,5 +334,5 @@ async def get_cached_response(redis_pool, key): headers = json.loads(cached[16 : 16 + headers_len].decode("utf-8")) headers.append(f"age: {age}") - data = brotli.decompress(cached[16 + headers_len :]) + data = cached[16 + headers_len :] return age, headers, BytesIO(data) diff --git a/python/python_fastapi_server/routers/caching_middleware.py b/python/python_fastapi_server/routers/caching_middleware.py index 0c18de12a..867bfe6f3 100644 --- a/python/python_fastapi_server/routers/caching_middleware.py +++ b/python/python_fastapi_server/routers/caching_middleware.py @@ -10,7 +10,6 @@ import redis.asyncio as redis # This can also be used to connect to a Redis cluster import json -import brotli ADAGUC_REDIS = os.environ.get("ADAGUC_REDIS") @@ -32,7 +31,7 @@ async def get_cached_response(redis_pool, request): headers_len = int(cached[10:16].decode("utf-8")) headers = json.loads(cached[16 : 16 + headers_len].decode("utf-8")) - data = brotli.decompress(cached[16 + headers_len :]) + data = cached[16 + headers_len :] return age, headers, data @@ -51,15 +50,14 @@ async def response_to_cache(redis_pool, request, headers, data, ex: int): entrytime = f"{calendar.timegm(datetime.utcnow().utctimetuple()):10d}".encode( "utf-8" ) - compressed_data = brotli.compress(data) - if len(compressed_data) < MAX_SIZE_FOR_CACHING: + if len(data) < MAX_SIZE_FOR_CACHING: redis_client = redis.Redis(connection_pool=redis_pool) await redis_client.set( key, entrytime + f"{len(headers_json):06d}".encode("utf-8") + headers_json - + brotli.compress(data), + + data, ex=ex, ) await redis_client.aclose() From 2ec2e62304cd96566e764df752318290683ee652 Mon Sep 17 00:00:00 2001 From: Maarten Plieger Date: Wed, 25 Sep 2024 15:15:35 +0200 Subject: [PATCH 50/50] Reverted brotli change --- python/lib/adaguc/runAdaguc.py | 5 +++-- python/python_fastapi_server/routers/caching_middleware.py | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python/lib/adaguc/runAdaguc.py b/python/lib/adaguc/runAdaguc.py index ba249c8bf..584d743c9 100644 --- a/python/lib/adaguc/runAdaguc.py +++ b/python/lib/adaguc/runAdaguc.py @@ -2,6 +2,7 @@ import os from PIL import Image from io import BytesIO +import brotli import shutil import random import string @@ -313,7 +314,7 @@ async def response_to_cache(redis_pool, key, headers: str, data): entrytime + f"{len(cacheable_headers_json):06d}".encode("utf-8") + cacheable_headers_json - + data.getvalue(), + + brotli.compress(data.getvalue(), quality = 4), ex=ttl, ) await redis_client.aclose() @@ -334,5 +335,5 @@ async def get_cached_response(redis_pool, key): headers = json.loads(cached[16 : 16 + headers_len].decode("utf-8")) headers.append(f"age: {age}") - data = cached[16 + headers_len :] + data = brotli.decompress(cached[16 + headers_len :]) return age, headers, BytesIO(data) diff --git a/python/python_fastapi_server/routers/caching_middleware.py b/python/python_fastapi_server/routers/caching_middleware.py index 867bfe6f3..3f17368bf 100644 --- a/python/python_fastapi_server/routers/caching_middleware.py +++ b/python/python_fastapi_server/routers/caching_middleware.py @@ -10,6 +10,7 @@ import redis.asyncio as redis # This can also be used to connect to a Redis cluster import json +import brotli ADAGUC_REDIS = os.environ.get("ADAGUC_REDIS") @@ -31,7 +32,7 @@ async def get_cached_response(redis_pool, request): headers_len = int(cached[10:16].decode("utf-8")) headers = json.loads(cached[16 : 16 + headers_len].decode("utf-8")) - data = cached[16 + headers_len :] + data = brotli.decompress(cached[16 + headers_len :]) return age, headers, data @@ -50,6 +51,7 @@ async def response_to_cache(redis_pool, request, headers, data, ex: int): entrytime = f"{calendar.timegm(datetime.utcnow().utctimetuple()):10d}".encode( "utf-8" ) + compressed_data = brotli.compress(data, quality=4) if len(data) < MAX_SIZE_FOR_CACHING: redis_client = redis.Redis(connection_pool=redis_pool) await redis_client.set( @@ -57,7 +59,7 @@ async def response_to_cache(redis_pool, request, headers, data, ex: int): entrytime + f"{len(headers_json):06d}".encode("utf-8") + headers_json - + data, + + compressed_data, ex=ex, ) await redis_client.aclose()