49using std::ostringstream;
50using std::istringstream;
53#define prolog string("FoDapCovJsonTransform::").append(__func__).append("() - ")
55#include <libdap/DDS.h>
56#include <libdap/DMR.h>
57#include <libdap/D4Group.h>
58#include <libdap/D4Attributes.h>
59#include <libdap/Structure.h>
60#include <libdap/Constructor.h>
61#include <libdap/Array.h>
62#include <libdap/Grid.h>
63#include <libdap/Sequence.h>
64#include <libdap/Byte.h>
65#include <libdap/UInt16.h>
66#include <libdap/Int16.h>
67#include <libdap/UInt32.h>
68#include <libdap/Int32.h>
69#include <libdap/Float32.h>
70#include <libdap/Float64.h>
71#include <libdap/Str.h>
72#include <libdap/Url.h>
75#include <BESInternalError.h>
76#include <DapFunctionUtils.h>
77#include <RequestServiceTimer.h>
78#include "FoDapCovJsonTransform.h"
79#include "focovjson_utils.h"
80#include "FoCovJsonRequestHandler.h"
83#define FoDapCovJsonTransform_debug_key "focovjson"
86bool FoDapCovJsonTransform::canConvert()
95cerr<<
"Before X and Y and Z and T"<<endl;
96cerr<<
"Number of parameters is "<<this->parameters.size() <<endl;
97cerr<<
"shapeVals is "<<shapeVals.size() <<endl;
98cerr<<
"Number of Axis is "<<this->axes.size() <<endl;
99for (
int i = 0; i <this->axes.size(); i++) {
100cerr<<
"Axis name is "<<this->axes[i]->name << endl;
101cerr<<
"Axis value is "<<this->axes[i]->values << endl;
107 bool ret_value =
false;
108 if(
true == is_simple_cf_geographic ||
true == is_dap2_grid) {
117 domainType =
"Point";
121 domainType =
"PointSeries";
125 domainType =
"VerticalProfile";
140 if(xExists && yExists && zExists && tExists) {
142 if (shapeVals.size() < 4)
147 if((shapeVals[0] > 1) && (shapeVals[1] > 1) && (shapeVals[2] >= 1) && (shapeVals[3] >= 0)) {
154 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] >= 1) && ((shapeVals[3] <= 1) && (shapeVals[3] >= 0))) {
155 domainType =
"Vertical Profile";
163 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1) && (shapeVals[3] >= 0)) {
164 domainType =
"Point Series";
170 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1) && (shapeVals[3] == 1)) {
171 domainType =
"Point";
182 else if(xExists && yExists && !zExists && tExists) {
184 if (shapeVals.size() < 3)
196 if((shapeVals[0] >= 1) && (shapeVals[1] >= 1) && (shapeVals[2] >= 0)) {
205 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] >= 0)) {
206 domainType =
"Point Series";
212 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1)) {
213 domainType =
"Point";
223 else if(xExists && yExists && !zExists && !tExists) {
225 if (shapeVals.size() < 2)
230 if((shapeVals[0] > 1) && (shapeVals[1] > 1)) {
237 else if((shapeVals[0] == 1) && (shapeVals[1] == 1)) {
238 domainType =
"Point";
250unsigned int FoDapCovJsonTransform::covjsonSimpleTypeArrayWorker(
ostream *strm, T *values,
unsigned int indx,
253 unsigned int currentDimSize = (*shape)[currentDim];
259 for(
unsigned int i = 0; i < currentDimSize; i++) {
260 if(currentDim < shape->size() - 1) {
261 BESDEBUG(FoDapCovJsonTransform_debug_key,
262 "covjsonSimpleTypeArrayWorker() - Recursing! indx: " << indx <<
" currentDim: " << currentDim <<
" currentDimSize: " << currentDimSize << endl);
263 indx = covjsonSimpleTypeArrayWorker<T>(strm, values, indx, shape, currentDim + 1,is_axis_t_sgeo,a_type);
264 if(i + 1 != currentDimSize) {
272 if(
typeid(T) ==
typeid(
string)) {
274 string val =
reinterpret_cast<string*
>(values)[indx++];
275 *strm <<
"\"" << focovjson::escape_for_covjson(val) <<
"\"";
281 std::ostringstream tmp_stream;
282 long long tmp_value = 0;
284 case libdap::dods_byte_c: {
285 unsigned char tmp_byte_value =
reinterpret_cast<unsigned char *
>(values)[indx++];
286 tmp_value = (
long long) tmp_byte_value;
290 case libdap::dods_uint16_c: {
291 unsigned short tmp_uint16_value =
reinterpret_cast<unsigned short *
>(values)[indx++];
292 tmp_value = (
long long) tmp_uint16_value;
296 case libdap::dods_int16_c: {
297 short tmp_int16_value =
reinterpret_cast<short *
>(values)[indx++];
298 tmp_value = (
long long) tmp_int16_value;
302 case libdap::dods_uint32_c: {
303 unsigned int tmp_uint_value =
reinterpret_cast<unsigned int *
>(values)[indx++];
304 tmp_value = (
long long) tmp_uint_value;
308 case libdap::dods_int32_c: {
309 int tmp_int_value =
reinterpret_cast<int *
>(values)[indx++];
310 tmp_value = (
long long) tmp_int_value;
314 case libdap::dods_float32_c: {
315 float tmp_float_value =
reinterpret_cast<float *
>(values)[indx++];
317 tmp_value = (
long long) tmp_float_value;
321 case libdap::dods_float64_c: {
322 double tmp_double_value =
reinterpret_cast<double *
>(values)[indx++];
324 tmp_value = (
long long) tmp_double_value;
329 throw BESInternalError(
"Attempt to extract CF time information from an invalid source", __FILE__, __LINE__);
333 axis_t_value = cf_time_to_greg(tmp_value);
335 cerr<<
"time value is " <<axis_t_value <<endl;
336 cerr<<
"CF time unit is "<<axis_t_units <<endl;
338 *strm <<
"\"" << focovjson::escape_for_covjson(axis_t_value) <<
"\"";
341 *strm << values[indx++];
350void FoDapCovJsonTransform::covjsonSimpleTypeArray(
ostream *strm, libdap::Array *a,
string indent,
bool sendData)
352 string childindent = indent + _indent_increment;
353 bool axisRetrieved =
false;
354 bool parameterRetrieved =
false;
356 currDataType = a->var()->type_name();
362 getAttributes(strm, a->get_attr_table(), a->name(), &axisRetrieved, ¶meterRetrieved);
369 if((axisRetrieved ==
true) && (parameterRetrieved ==
false)) {
370 struct Axis *currAxis;
371 currAxis = axes[axisCount - 1];
373 int numDim = a->dimensions(
true);
374 vector<unsigned int> shape(numDim);
375 long length = focovjson::computeConstrainedShape(a, &shape);
381 bool handle_axis_t_here =
true;
382 if(is_simple_cf_geographic==
false && dsg_type == UNSUPPORTED_DSG && currAxis->name.compare(
"t") == 0)
383 handle_axis_t_here =
false;
384 if (handle_axis_t_here) {
386 currAxis->values +=
"\"values\": [";
387 unsigned int indx = 0;
388 vector<T> src(length);
389 a->value(src.data());
392 bool is_time_axis_for_sgeo =
false;
393 if((is_simple_cf_geographic || dsg_type != UNSUPPORTED_DSG) && currAxis->name.compare(
"t") == 0)
394 is_time_axis_for_sgeo =
true;
397 indx = covjsonSimpleTypeArrayWorker(&astrm, src.data(), 0, &shape, 0,is_time_axis_for_sgeo,a->var()->type());
398 currAxis->values += astrm.str();
400 currAxis->values +=
"]";
404 if (length != indx) {
405 BESDEBUG(FoDapCovJsonTransform_debug_key,
406 "covjsonSimpleTypeArray(Axis) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
408 assert(length == indx);
411 currAxis->values +=
"\"values\": []";
417 else if(axisRetrieved ==
false && parameterRetrieved ==
true) {
418 struct Parameter *currParameter;
419 currParameter = parameters[parameterCount - 1];
422cerr<<
"Parameter name is "<< currParameter->name<<endl;
424 int numDim = a->dimensions(
true);
425 vector<unsigned int> shape(numDim);
426 long length = focovjson::computeConstrainedShape(a, &shape);
432 currParameter->shape +=
"\"shape\": [";
433 for(vector<unsigned int>::size_type i = 0; i < shape.size(); i++) {
435 currParameter->shape +=
", ";
444 istringstream (otemp.str());
445 istringstream (otemp.str()) >> tempVal;
446 shapeVals.push_back(tempVal);
450 if((i == 0) && tExists && is_simple_cf_geographic ==
false && dsg_type == UNSUPPORTED_DSG) {
451 currParameter->shape +=
"1";
454 currParameter->shape += otemp.str();
457 currParameter->shape +=
"],";
460 currParameter->values +=
"\"values\": [";
461 unsigned int indx = 0;
462 vector<T> src(length);
463 a->value(src.data());
466 indx = covjsonSimpleTypeArrayWorker(&pstrm, src.data(), 0, &shape, 0,
false,a->var()->type());
467 currParameter->values += pstrm.str();
469 currParameter->values +=
"]";
471 if (length != indx) {
472 BESDEBUG(FoDapCovJsonTransform_debug_key,
473 "covjsonSimpleTypeArray(Parameter) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
475 assert(length == indx);
478 currParameter->values +=
"\"values\": []";
483void FoDapCovJsonTransform::covjsonStringArray(
ostream *strm, libdap::Array *a,
string indent,
bool sendData)
485 string childindent = indent + _indent_increment;
486 bool axisRetrieved =
false;
487 bool parameterRetrieved =
false;
489 currDataType = a->var()->type_name();
497 getAttributes(strm, a->get_attr_table(), a->name(), &axisRetrieved, ¶meterRetrieved);
504 if((axisRetrieved ==
true) && (parameterRetrieved ==
false)) {
505 struct Axis *currAxis;
506 currAxis = axes[axisCount - 1];
508 int numDim = a->dimensions(
true);
509 vector<unsigned int> shape(numDim);
510 long length = focovjson::computeConstrainedShape(a, &shape);
512 bool handle_axis_t_here =
true;
513 if(is_simple_cf_geographic==
false && dsg_type == UNSUPPORTED_DSG && currAxis->name.compare(
"t") == 0)
514 handle_axis_t_here =
false;
515 if (handle_axis_t_here) {
517 currAxis->values +=
"\"values\": ";
518 unsigned int indx = 0;
520 vector<string> sourceValues;
521 a->value(sourceValues);
524 indx = covjsonSimpleTypeArrayWorker(&astrm, (
string *) (sourceValues.data()), 0, &shape, 0,
false,a->var()->type());
525 currAxis->values += astrm.str();
527 if (length != indx) {
528 BESDEBUG(FoDapCovJsonTransform_debug_key,
529 "covjsonStringArray(Axis) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
531 assert(length == indx);
534 currAxis->values +=
"\"values\": []";
540 else if(axisRetrieved ==
false && parameterRetrieved ==
true) {
541 struct Parameter *currParameter;
542 currParameter = parameters[parameterCount - 1];
544 int numDim = a->dimensions(
true);
545 vector<unsigned int> shape(numDim);
546 long length = focovjson::computeConstrainedShape(a, &shape);
548 currParameter->shape +=
"\"shape\": [";
549 for(vector<unsigned int>::size_type i = 0; i < shape.size(); i++) {
551 currParameter->shape +=
", ";
560 istringstream (otemp.str());
561 istringstream (otemp.str()) >> tempVal;
562 shapeVals.push_back(tempVal);
566 if((i == 0) && tExists && is_simple_cf_geographic ==
false && dsg_type == UNSUPPORTED_DSG) {
568 currParameter->shape +=
"1";
571 currParameter->shape += otemp.str();
574 currParameter->shape +=
"],";
577 currParameter->values +=
"\"values\": ";
578 unsigned int indx = 0;
580 vector<string> sourceValues;
581 a->value(sourceValues);
584 indx = covjsonSimpleTypeArrayWorker(&pstrm, (
string *) (sourceValues.data()), 0, &shape, 0,
false,a->var()->type());
585 currParameter->values += pstrm.str();
587 if (length != indx) {
588 BESDEBUG(FoDapCovJsonTransform_debug_key,
589 "covjsonStringArray(Parameter) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
591 assert(length == indx);
594 currParameter->values +=
"\"values\": []";
599void FoDapCovJsonTransform::addAxis(
string name,
string values)
601 struct Axis *newAxis =
new Axis;
603 newAxis->name = name;
604 newAxis->values = values;
606cerr <<
"axis name is "<< name <<endl;
607cerr <<
"axis value is "<< values <<endl;
609 this->axes.push_back(newAxis);
613void FoDapCovJsonTransform::addParameter(
string id,
string name,
string type,
string dataType,
string unit,
614 string longName,
string standardName,
string shape,
string values)
616 struct Parameter *newParameter =
new Parameter;
618 newParameter->id = id;
619 newParameter->name = name;
620 newParameter->type = type;
621 newParameter->dataType = dataType;
622 newParameter->unit = unit;
623 newParameter->longName = longName;
624 newParameter->standardName = standardName;
625 newParameter->shape = shape;
626 newParameter->values = values;
628 this->parameters.push_back(newParameter);
629 this->parameterCount++;
632void FoDapCovJsonTransform::getAttributes(
ostream *strm, libdap::AttrTable &attr_table,
string name,
633 bool *axisRetrieved,
bool *parameterRetrieved)
636 string currAxisTimeOrigin;
639 string currStandardName;
644 *axisRetrieved =
false;
645 *parameterRetrieved =
false;
651 if (is_simple_cf_geographic || dsg_type!=UNSUPPORTED_DSG)
652 getAttributes_simple_cf_geographic_dsg(strm,attr_table,name,axisRetrieved,parameterRetrieved);
656 if((name.compare(
"lon") == 0) || (name.compare(
"LON") == 0)
657 || (name.compare(
"longitude") == 0) || (name.compare(
"LONGITUDE") == 0)
658 || (name.compare(
"COADSX") == 0)) {
669 else if((name.compare(
"lat") == 0) || (name.compare(
"LAT") == 0)
670 || (name.compare(
"latitude") == 0) || (name.compare(
"LATITUDE") == 0)
671 || (name.compare(
"COADSY") == 0)) {
682 else if((name.compare(
"lev") == 0) || (name.compare(
"LEV") == 0)
683 || (name.compare(
"height") == 0) || (name.compare(
"HEIGHT") == 0)
684 || (name.compare(
"depth") == 0) || (name.compare(
"DEPTH") == 0)
685 || (name.compare(
"pres") == 0) || (name.compare(
"PRES") == 0)) {
696 else if((name.compare(
"time") == 0) || (name.compare(
"TIME") == 0)) {
712 if(attr_table.get_size() != 0) {
713 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
714 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
716 for(libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
720 switch (attr_table.get_attr_type(at_iter)) {
721 case libdap::Attr_container: {
722 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
724 getAttributes(strm, *atbl, name, axisRetrieved, parameterRetrieved);
728 vector<string> *values = attr_table.get_attr_vector(at_iter);
730 for(vector<string>::size_type i = 0; i < values->size(); i++) {
731 string currName = attr_table.get_name(at_iter);
732 string currValue = (*values)[i];
751 if(currName.compare(
"units") == 0) {
752 currUnit = currValue;
754 if(currAxisName.compare(
"t") == 0) {
755 currAxisTimeOrigin = currValue;
766 else if(currName.compare(
"long_name") == 0) {
767 currLongName = currValue;
770 else if(currName.compare(
"standard_name") == 0) {
771 currStandardName = currValue;
785 if(currAxisName.compare(
"t") == 0) {
786 addAxis(currAxisName,
"\"values\": [\"" + sanitizeTimeOriginString(currAxisTimeOrigin) +
"\"]");
789 addAxis(currAxisName,
"");
800 if ((is_geo_dap2_grid ==
false) &&
801 ((currUnit.find(
"east") != string::npos) || (currUnit.find(
"East") != string::npos) ||
802 (currUnit.find(
"north") != string::npos) || (currUnit.find(
"North") != string::npos)))
803 coordRefType =
"ProjectedCRS";
806 *axisRetrieved =
true;
809 addParameter(
"", name,
"", currDataType, currUnit, currLongName, currStandardName,
"",
"");
810 *parameterRetrieved =
true;
818void FoDapCovJsonTransform::
819 getAttributes_simple_cf_geographic_dsg(
ostream *strm, libdap::AttrTable &attr_table,
const string& name,
820 bool *axisRetrieved,
bool *parameterRetrieved)
825 string currStandardName;
830 *axisRetrieved =
false;
831 *parameterRetrieved =
false;
836 if(axisVar_x.name == name) {
846 else if(axisVar_y.name == name) {
856 else if(axisVar_z.name == name) {
866 else if(axisVar_t.name == name) {
878 for (
unsigned int i = 0; i <par_vars.size(); i++) {
879 if(par_vars[i] == name){
887 if(attr_table.get_size() != 0) {
888 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
889 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
891 for(libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
895 switch (attr_table.get_attr_type(at_iter)) {
896 case libdap::Attr_container: {
897 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
899 getAttributes_simple_cf_geographic_dsg(strm, *atbl, name, axisRetrieved, parameterRetrieved);
903 vector<string> *values = attr_table.get_attr_vector(at_iter);
905 for(vector<string>::size_type i = 0; i < values->size(); i++) {
906 string currName = attr_table.get_name(at_iter);
907 string currValue = (*values)[i];
926 if(currName.compare(
"units") == 0)
927 currUnit = currValue;
935 else if(currName.compare(
"long_name") == 0) {
936 currLongName = currValue;
939 else if(currName.compare(
"standard_name") == 0) {
940 currStandardName = currValue;
945 if (axisVar_z.name == name) {
947 for(vector<string>::size_type i = 0; i < values->size(); i++) {
948 string currName = attr_table.get_name(at_iter);
949 if (currName ==
"positive") {
950 string currValue = (*values)[i];
951 axis_z_direction = currValue;
965 addAxis(currAxisName,
"");
970 if (currAxisName.compare(
"t") == 0)
971 axis_t_units = currUnit;
972 if (currAxisName.compare(
"z") == 0) {
973 axis_z_standardName=currStandardName;
974 axis_z_units = currUnit;
976 *axisRetrieved =
true;
979 addParameter(
"", name,
"", currDataType, currUnit, currLongName, currStandardName,
"",
"");
980 *parameterRetrieved =
true;
989string FoDapCovJsonTransform::sanitizeTimeOriginString(
string timeOrigin)
1009 vector<string> subStrs = {
"hours",
"hour",
"minutes",
"minute",
1010 "seconds",
"second",
"since",
" " };
1012 string cleanTimeOrigin = timeOrigin;
1015 if(timeOrigin.find(
"base_time") != string::npos) {
1016 cleanTimeOrigin =
"2020-01-01T12:00:00Z";
1019 for(
unsigned int i = 0; i < subStrs.size(); i++)
1020 focovjson::removeSubstring(cleanTimeOrigin, subStrs[i]);
1023 return cleanTimeOrigin;
1028 if (!_dds)
throw BESInternalError(
"File out COVJSON, null DDS passed to constructor", __FILE__, __LINE__);
1033 if (!_dmr)
throw BESInternalError(
"File out COVJSON, null DMR passed to constructor", __FILE__, __LINE__);
1039 strm << BESIndent::LMarg <<
"FoDapCovJsonTransform::dump - (" << (
void *)
this <<
")" << endl;
1040 BESIndent::Indent();
1044 BESIndent::UnIndent();
1047void FoDapCovJsonTransform::transform(
ostream &ostrm,
bool sendData,
bool testOverride)
1049 transform(&ostrm, _dds,
"", sendData, testOverride);
1052void FoDapCovJsonTransform::transform_dap4(
ostream &ostrm,
bool sendData,
bool testOverride)
1054 transform(&ostrm, _dmr,
"", sendData, testOverride);
1057void FoDapCovJsonTransform::transform(
ostream *strm, libdap::Constructor *cnstrctr,
string indent,
bool sendData)
1059 vector<libdap::BaseType *> leaves;
1060 vector<libdap::BaseType *> nodes;
1062 libdap::DDS::Vars_iter vi = cnstrctr->var_begin();
1063 libdap::DDS::Vars_iter ve = cnstrctr->var_end();
1067 for(; vi != ve; vi++) {
1068 if((*vi)->send_p()) {
1069 libdap::BaseType *v = *vi;
1070 libdap::Type type = v->type();
1072 if(type == libdap::dods_array_c) {
1073 type = v->var()->type();
1075 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type())) {
1079 leaves.push_back(v);
1084 transformNodeWorker(strm, leaves, nodes, indent, sendData);
1091 for(vector<libdap::BaseType *>::size_type l = 0; l < leaves.size(); l++) {
1092 libdap::BaseType *v = leaves[l];
1093 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Processing LEAF: " << v->name() << endl);
1098 transform(strm, v, indent + _indent_increment, sendData);
1102 for(vector<libdap::BaseType *>::size_type n = 0; n < nodes.size(); n++) {
1103 libdap::BaseType *v = nodes[n];
1104 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Processing NODE: " << v->name() << endl);
1109 transform(strm, v, indent + _indent_increment, sendData);
1113void FoDapCovJsonTransform::printCoverageJSON(
ostream *strm,
string indent,
bool testOverride)
1119 canConvertToCovJson =
true;
1122 canConvertToCovJson = canConvert();
1126 if(canConvertToCovJson) {
1129 printCoverage(strm, indent);
1133 throw BESInternalError(
"File cannot be converted to CovJSON format due to missing or incompatible spatial dimensions", __FILE__, __LINE__);
1137void FoDapCovJsonTransform::printCoverage(
ostream *strm,
string indent)
1139 string child_indent1 = indent + _indent_increment;
1140 string child_indent2 = child_indent1 + _indent_increment;
1142 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing COVERAGE" << endl);
1144 *strm << indent <<
"{" << endl;
1145 *strm << child_indent1 <<
"\"type\": \"Coverage\"," << endl;
1147 printDomain(strm, child_indent1);
1149 printParameters(strm, child_indent1);
1151 printRanges(strm, child_indent1);
1153 *strm << indent <<
"}" << endl;
1156void FoDapCovJsonTransform::printDomain(
ostream *strm,
string indent)
1158 string child_indent1 = indent + _indent_increment;
1160 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing DOMAIN" << endl);
1162 *strm << indent <<
"\"domain\": {" << endl;
1163 *strm << child_indent1 <<
"\"type\" : \"Domain\"," << endl;
1164 *strm << child_indent1 <<
"\"domainType\": \"" + domainType +
"\"," << endl;
1167 printAxes(strm, child_indent1);
1170 printReference(strm, child_indent1);
1172 *strm << indent <<
"}," << endl;
1175void FoDapCovJsonTransform::printAxes(
ostream *strm,
string indent)
1177 string child_indent1 = indent + _indent_increment;
1178 string child_indent2 = child_indent1 + _indent_increment;
1180 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing AXES" << endl);
1184 std::vector<std::string> t_bnd_val;
1185 if(axisVar_t_bnd_val.size() >0) {
1186 t_bnd_val.resize(axisVar_t_bnd_val.size());
1187 for (
unsigned i = 0; i < axisVar_t_bnd_val.size();i++) {
1188 t_bnd_val[i] = cf_time_to_greg((
long long)(axisVar_t_bnd_val[i]));
1196 std::vector<std::string> x_bnd_val;
1197 if(axisVar_x_bnd_val.empty() ==
false) {
1198 x_bnd_val.resize(axisVar_x_bnd_val.size());
1199 for (
unsigned i = 0; i < axisVar_x_bnd_val.size();i++) {
1200 ostringstream temp_strm;
1201 temp_strm<<axisVar_x_bnd_val[i];
1202 x_bnd_val[i] = temp_strm.str();
1210 std::vector<std::string> y_bnd_val;
1211 if(axisVar_y_bnd_val.empty() ==
false) {
1212 y_bnd_val.resize(axisVar_y_bnd_val.size());
1213 for (
unsigned i = 0; i < axisVar_y_bnd_val.size();i++) {
1214 ostringstream temp_strm;
1215 temp_strm<<axisVar_y_bnd_val[i];
1216 y_bnd_val[i] = temp_strm.str();
1224 std::vector<std::string> z_bnd_val;
1225 if(axisVar_z_bnd_val.empty() ==
false) {
1226 z_bnd_val.resize(axisVar_z_bnd_val.size());
1227 for (
unsigned i = 0; i < axisVar_z_bnd_val.size();i++) {
1228 ostringstream temp_strm;
1229 temp_strm<<axisVar_z_bnd_val[i];
1230 z_bnd_val[i] = temp_strm.str();
1241 *strm << indent <<
"\"axes\": {" << endl;
1242 for(
unsigned int i = 0; i < axisCount; i++) {
1243 for(
unsigned int j = 0; j < axisCount; j++) {
1247 if(xExists && yExists && zExists && tExists) {
1248 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1249 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1250 *strm << child_indent2 << axes[j]->values << endl;
1251 print_bound(strm, x_bnd_val,child_indent2,
false);
1253 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1254 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1255 *strm << child_indent2 << axes[j]->values << endl;
1256 print_bound(strm, y_bnd_val,child_indent2,
false);
1258 else if((i == 2) && (axes[j]->name.compare(
"z") == 0)) {
1259 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1260 *strm << child_indent2 << axes[j]->values << endl;
1261 print_bound(strm, z_bnd_val,child_indent2,
false);
1263 else if((i == 3) && (axes[j]->name.compare(
"t") == 0)) {
1264 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1265 *strm << child_indent2 << axes[j]->values << endl;
1266 print_bound(strm, t_bnd_val,child_indent2,
true);
1270 else if(xExists && yExists && !zExists && tExists) {
1271 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1272 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1273 *strm << child_indent2 << axes[j]->values << endl;
1274 print_bound(strm, x_bnd_val,child_indent2,
false);
1276 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1277 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1278 *strm << child_indent2 << axes[j]->values << endl;
1279 print_bound(strm, y_bnd_val,child_indent2,
false);
1281 else if((i == 2) && (axes[j]->name.compare(
"t") == 0)) {
1282 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1283 *strm << child_indent2 << axes[j]->values << endl;
1284 print_bound(strm, t_bnd_val,child_indent2,
true);
1288 else if(xExists && yExists && !zExists && !tExists) {
1289 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1290 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1291 *strm << child_indent2 << axes[j]->values << endl;
1292 print_bound(strm, x_bnd_val,child_indent2,
false);
1294 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1295 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1296 *strm << child_indent2 << axes[j]->values << endl;
1297 print_bound(strm, y_bnd_val,child_indent2,
false);
1301 if(i == axisCount - 1) {
1302 *strm << child_indent1 <<
"}" << endl;
1305 *strm << child_indent1 <<
"}," << endl;
1308 *strm << indent <<
"}," << endl;
1311void FoDapCovJsonTransform::printReference(
ostream *strm,
string indent)
1313 string child_indent1 = indent + _indent_increment;
1314 string child_indent2 = child_indent1 + _indent_increment;
1315 string child_indent3 = child_indent2 + _indent_increment;
1316 string child_indent4 = child_indent3 + _indent_increment;
1317 string child_indent5 = child_indent4 + _indent_increment;
1320 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing REFERENCES" << endl);
1323 coordVars +=
"\"x\"";
1327 if(!coordVars.empty()) {
1330 coordVars +=
"\"y\"";
1333 if(zExists && !is_simple_cf_geographic && (dsg_type == UNSUPPORTED_DSG)) {
1334 if(!coordVars.empty()) {
1337 coordVars +=
"\"z\"";
1340 *strm << indent <<
"\"referencing\": [{" << endl;
1344 *strm << child_indent1 <<
"\"coordinates\": [\"t\"]," << endl;
1345 *strm << child_indent1 <<
"\"system\": {" << endl;
1346 *strm << child_indent2 <<
"\"type\": \"TemporalRS\"," << endl;
1347 *strm << child_indent2 <<
"\"calendar\": \"Gregorian\"" << endl;
1348 *strm << child_indent1 <<
"}" << endl;
1349 *strm << indent <<
"}," << endl;
1350 *strm << indent <<
"{" << endl;
1354 *strm << child_indent1 <<
"\"coordinates\": [" << coordVars <<
"]," << endl;
1355 *strm << child_indent1 <<
"\"system\": {" << endl;
1356 *strm << child_indent2 <<
"\"type\": \"" + coordRefType +
"\"," << endl;
1360 if(coordRefType.compare(
"ProjectedCRS") == 0) {
1362 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/EPSG/0/27700\"" << endl;
1365 if(xExists && yExists && zExists) {
1367 if(!is_simple_cf_geographic &&(dsg_type == UNSUPPORTED_DSG))
1368 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/EPSG/0/4979\"" << endl;
1372 if(!is_simple_cf_geographic && (dsg_type==UNSUPPORTED_DSG) && (!is_geo_dap2_grid))
1373 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/OGC/1.3/CRS84\"" << endl;
1377 *strm << child_indent1 <<
"}" << endl;
1379 if (zExists && (is_simple_cf_geographic || dsg_type != UNSUPPORTED_DSG)) {
1380 *strm << indent <<
"}," << endl;
1381 *strm << indent <<
"{" << endl;
1382 *strm << child_indent1 <<
"\"coordinates\": [" <<
"\"z\"]," << endl;
1383 *strm << child_indent1 <<
"\"system\": {" << endl;
1384 *strm << child_indent2 <<
"\"type\": \"" <<
"VerticalCRS" <<
"\"," << endl;
1385 *strm << child_indent2 <<
"\"cs\": {" << endl;
1386 *strm << child_indent3 <<
"\"csAxes\": [{" << endl;
1387 *strm << child_indent4 <<
"\"name\": {" << endl;
1388 if (axis_z_standardName ==
"")
1389 *strm << child_indent5 <<
"\"en\": \"" << axisVar_z.name <<
"\"" << endl;
1391 *strm << child_indent5 <<
"\"en\": \"" << axis_z_standardName <<
"\"" << endl;
1392 *strm << child_indent4 <<
"}," << endl;
1393 if (axis_z_direction !=
"")
1394 *strm << child_indent4 <<
"\"direction\": \"" << axis_z_direction <<
"\","<<endl;
1395 if (axis_z_units !=
"") {
1396 *strm << child_indent4 <<
"\"units\": {" << endl;
1397 *strm << child_indent5 <<
"\"symbol\": \"" << axis_z_units <<
"\"" << endl;
1398 *strm << child_indent4 <<
"}" << endl;
1400 *strm << child_indent3 <<
"}]"<<endl;
1401 *strm << child_indent2 <<
"}"<<endl;
1402 *strm << child_indent1 <<
"}"<<endl;
1403 *strm << indent <<
"}]"<<endl;
1406 *strm << indent <<
"}]" << endl;
1410void FoDapCovJsonTransform::printParameters(
ostream *strm,
string indent)
1412 string child_indent1 = indent + _indent_increment;
1413 string child_indent2 = child_indent1 + _indent_increment;
1414 string child_indent3 = child_indent2 + _indent_increment;
1415 string child_indent4 = child_indent3 + _indent_increment;
1417 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing PARAMETERS" << endl);
1420 *strm << indent <<
"\"parameters\": {" << endl;
1421 for(
unsigned int i = 0; i < parameterCount; i++) {
1422 *strm << child_indent1 <<
"\"" << parameters[i]->name <<
"\": {" << endl;
1423 *strm << child_indent2 <<
"\"type\": \"Parameter\"," << endl;
1424 *strm << child_indent2 <<
"\"description\": {" << endl;
1426 if(parameters[i]->longName.compare(
"") != 0) {
1427 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->longName <<
"\"" << endl;
1429 else if(parameters[i]->standardName.compare(
"") != 0) {
1430 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->standardName <<
"\"" << endl;
1433 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->name <<
"\"" << endl;
1436 *strm << child_indent2 <<
"}," << endl;
1437 *strm << child_indent2 <<
"\"unit\": {" << endl;
1438 *strm << child_indent3 <<
"\"label\": {" << endl;
1439 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->unit <<
"\"" << endl;
1440 *strm << child_indent3 <<
"}," << endl;
1441 *strm << child_indent3 <<
"\"symbol\": {" << endl;
1442 *strm << child_indent4 <<
"\"value\": \"" << parameters[i]->unit <<
"\"," << endl;
1443 *strm << child_indent4 <<
"\"type\": \"http://www.opengis.net/def/uom/UCUM/\"" << endl;
1444 *strm << child_indent3 <<
"}" << endl;
1445 *strm << child_indent2 <<
"}," << endl;
1446 *strm << child_indent2 <<
"\"observedProperty\": {" << endl;
1452 if(parameters[i]->standardName.compare(
"") != 0) {
1453 *strm << child_indent3 <<
"\"id\": \"http://vocab.nerc.ac.uk/standard_name/" << parameters[i]->standardName <<
"/\"," << endl;
1461 *strm << child_indent3 <<
"\"label\": {" << endl;
1463 if(parameters[i]->longName.compare(
"") != 0) {
1464 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->longName <<
"\"" << endl;
1466 else if(parameters[i]->standardName.compare(
"") != 0) {
1467 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->standardName <<
"\"" << endl;
1470 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->name <<
"\"" << endl;
1473 *strm << child_indent3 <<
"}" << endl;
1474 *strm << child_indent2 <<
"}" << endl;
1476 if(i == parameterCount - 1) {
1477 *strm << child_indent1 <<
"}" << endl;
1480 *strm << child_indent1 <<
"}," << endl;
1484 *strm << indent <<
"}," << endl;
1487void FoDapCovJsonTransform::printRanges(
ostream *strm,
string indent)
1489 string child_indent1 = indent + _indent_increment;
1490 string child_indent2 = child_indent1 + _indent_increment;
1491 string child_indent3 = child_indent2 + _indent_increment;
1494 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing RANGES" << endl);
1497 axisNames +=
"\"t\"";
1501 if(!axisNames.empty()) {
1504 axisNames +=
"\"z\"";
1508 if(!axisNames.empty()) {
1511 axisNames +=
"\"y\"";
1515 if(!axisNames.empty()) {
1518 axisNames +=
"\"x\"";
1522 *strm << indent <<
"\"ranges\": {" << endl;
1523 for(
unsigned int i = 0; i < parameterCount; i++) {
1526 if(parameters[i]->dataType.find(
"int") == 0 || parameters[i]->dataType.find(
"Int") == 0
1527 || parameters[i]->dataType.find(
"integer") == 0 || parameters[i]->dataType.find(
"Integer") == 0) {
1528 dataType =
"integer";
1530 else if(parameters[i]->dataType.find(
"float") == 0 || parameters[i]->dataType.find(
"Float") == 0) {
1533 else if(parameters[i]->dataType.find(
"string") == 0 || parameters[i]->dataType.find(
"String") == 0) {
1534 dataType =
"string";
1537 dataType =
"string";
1542 *strm << child_indent1 <<
"\"" << parameters[i]->name <<
"\": {" << endl;
1543 *strm << child_indent2 <<
"\"type\": \"NdArray\"," << endl;
1544 *strm << child_indent2 <<
"\"dataType\": \"" << dataType <<
"\", " << endl;
1551 if (dsg_type !=SPOINT) {
1552 if (dsg_type == POINTS)
1553 axisNames =
"\"t\"";
1554 else if (dsg_type == PROFILE)
1555 axisNames =
"\"z\"";
1556 *strm << child_indent2 <<
"\"axisNames\": [" << axisNames <<
"]," << endl;
1557 if (parameters[i]->shape!=
"")
1558 *strm << child_indent2 << parameters[i]->shape << endl;
1560 *strm << child_indent2 << parameters[i]->values << endl;
1562 if(i == parameterCount - 1) {
1563 *strm << child_indent1 <<
"}" << endl;
1566 *strm << child_indent1 <<
"}," << endl;
1570 *strm << indent <<
"}" << endl;
1573void FoDapCovJsonTransform::transform(
ostream *strm, libdap::DDS *dds,
string indent,
bool sendData,
bool testOverride)
1580 vector<string> dap2_grid_map_names;
1581 for (
const auto &var:dds->variables()) {
1583 libdap::Type type = var->type();
1584 if (type == libdap::dods_grid_c) {
1585 is_dap2_grid =
true;
1586 auto vgrid =
dynamic_cast<libdap::Grid*
>(var);
1587 for (libdap::Grid::Map_iter i = vgrid->map_begin(); i != vgrid->map_end(); ++i) {
1588 dap2_grid_map_names.emplace_back((*i)->name());
1590cout <<
"grid map name: "<<(*i)->name() <<endl;
1599 is_geo_dap2_grid = check_geo_dap2_grid(dds,dap2_grid_map_names);
1602 vector<libdap::BaseType *> leaves;
1603 vector<libdap::BaseType *> nodes;
1606 libdap::DDS::Vars_iter vi = dds->var_begin();
1607 libdap::DDS::Vars_iter ve = dds->var_end();
1611 if (is_dap2_grid ==
true) {
1613 for(; vi != ve; vi++) {
1614 if((*vi)->send_p()) {
1615 libdap::BaseType *v = *vi;
1616 libdap::Type type = v->type();
1617 if (type == libdap::dods_grid_c) {
1618 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type())) {
1622 leaves.push_back(v);
1629 for(; vi != ve; vi++) {
1630 if((*vi)->send_p()) {
1631 libdap::BaseType *v = *vi;
1632 libdap::Type type = v->type();
1633 if(type == libdap::dods_array_c) {
1634 type = v->var()->type();
1636 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type())) {
1640 leaves.push_back(v);
1646 bool is_simple_discrete = check_update_simple_dsg(dds);
1649 if (is_simple_discrete ==
false && FoCovJsonRequestHandler::get_simple_geo())
1650 check_update_simple_geo(dds, sendData);
1655 transformNodeWorker(strm, leaves, nodes, indent + _indent_increment + _indent_increment, sendData);
1662 printCoverageJSON(strm, indent, testOverride);
1665void FoDapCovJsonTransform::transform(
ostream *strm, libdap::DMR *dmr,
const string& indent,
bool sendData,
bool testOverride)
1669 libdap::D4Group *root_grp = dmr->root();
1672 vector<libdap::BaseType *> leaves;
1673 vector<libdap::BaseType *> nodes;
1675 for (
auto i = root_grp->var_begin(), e = root_grp->var_end(); i != e; ++i) {
1677 if ((*i)->send_p()) {
1678 libdap::BaseType *v = *i;
1679 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type()))
1682 leaves.push_back(v);
1688 bool is_simple_discrete = check_update_simple_dsg(dds);
1691 if (is_simple_discrete ==
false && FoCovJsonRequestHandler::get_simple_geo())
1692 check_update_simple_geo(dds, sendData);
1698 if (FoCovJsonRequestHandler::get_simple_geo())
1699 check_update_simple_geo_dap4(root_grp);
1704 transformNodeWorker(strm, leaves, nodes, indent + _indent_increment + _indent_increment, sendData);
1711 printCoverageJSON(strm, indent, testOverride);
1715void FoDapCovJsonTransform::transform(
ostream *strm, libdap::BaseType *bt,
string indent,
bool sendData)
1717 switch(bt->type()) {
1719 case libdap::dods_byte_c:
1720 case libdap::dods_int16_c:
1721 case libdap::dods_uint16_c:
1722 case libdap::dods_int32_c:
1723 case libdap::dods_uint32_c:
1724 case libdap::dods_float32_c:
1725 case libdap::dods_float64_c:
1726 case libdap::dods_str_c:
1727 case libdap::dods_url_c:
1728 case libdap::dods_int8_c:
1729 case libdap::dods_uint8_c:
1730 case libdap::dods_int64_c:
1731 case libdap::dods_uint64_c:
1733 transformAtomic(strm, bt, indent, sendData);
1736 case libdap::dods_structure_c:
1737 transform(strm, (libdap::Structure *) bt, indent, sendData);
1740 case libdap::dods_grid_c:
1741 is_dap2_grid =
true;
1742 transform(strm, (libdap::Grid *) bt, indent, sendData);
1745 case libdap::dods_sequence_c:
1746 transform(strm, (libdap::Sequence *) bt, indent, sendData);
1749 case libdap::dods_array_c:
1750 transform(strm, (libdap::Array *) bt, indent, sendData);
1753 case libdap::dods_enum_c:
1754 case libdap::dods_group_c: {
1755 string s = (string)
"File out COVJSON, DAP4 types not yet supported.";
1756 throw BESInternalError(s, __FILE__, __LINE__);
1761 string s = (string)
"File out COVJSON, Unrecognized type.";
1762 throw BESInternalError(s, __FILE__, __LINE__);
1769void FoDapCovJsonTransform::transformAtomic(libdap::BaseType *b,
const string& indent,
bool sendData)
1771 string childindent = indent + _indent_increment;
1772 struct Axis *newAxis =
new Axis;
1773cerr<<
"b name is "<<b->name() <<endl;
1776 newAxis->name =
"test";
1778 newAxis->values +=
"\"values\": [";
1779 if(b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c) {
1780 libdap::Str *strVar = (libdap::Str *) b;
1781 string tmpString = strVar->value();
1782 newAxis->values +=
"\"";
1783 newAxis->values += focovjson::escape_for_covjson(tmpString);
1784 newAxis->values +=
"\"";
1787 ostringstream otemp;
1788 istringstream itemp;
1790 b->print_val(otemp,
"",
false);
1791 istringstream (otemp.str());
1792 istringstream (otemp.str()) >> tempVal;
1793 newAxis->values += otemp.str();
1795 newAxis->values +=
"]";
1798 newAxis->values +=
"\"values\": []";
1801 axes.push_back(newAxis);
1806void FoDapCovJsonTransform::transformAtomic(
ostream *strm, libdap::BaseType *b,
const string& indent,
bool sendData) {
1808 string childindent = indent + _indent_increment;
1809 bool axisRetrieved =
false;
1810 bool parameterRetrieved =
false;
1812 getAttributes(strm, b->get_attr_table(), b->name(), &axisRetrieved, ¶meterRetrieved);
1814 if((axisRetrieved ==
true) && (parameterRetrieved ==
false)) {
1815 struct Axis *currAxis;
1816 currAxis = axes[axisCount - 1];
1819 currAxis->values +=
"\"values\": [";
1821 bool is_cf_time_axis =
false;
1822 if ((is_simple_cf_geographic || dsg_type != UNSUPPORTED_DSG) && currAxis->name.compare(
"t") == 0)
1823 is_cf_time_axis =
true;
1825 if (b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c) {
1827 const auto s =
dynamic_cast<libdap::Str *
>(b);
1828 string val = s->value();
1829 currAxis->values +=
"\"" + focovjson::escape_for_covjson(val) +
"\"";
1832 else if (is_cf_time_axis) {
1835 string axis_t_value;
1836 std::ostringstream tmp_stream;
1837 long long tmp_value = 0;
1838 switch (b->type()) {
1839 case libdap::dods_byte_c: {
1840 const auto tmp_byte =
dynamic_cast<libdap::Byte *
>(b);
1841 tmp_value = (
long long) (tmp_byte->value());
1845 case libdap::dods_uint16_c: {
1846 const auto tmp_uint16 =
dynamic_cast<libdap::UInt16 *
>(b);
1847 tmp_value = (
long long) (tmp_uint16->value());
1851 case libdap::dods_int16_c: {
1852 const auto tmp_int16 =
dynamic_cast<libdap::Int16 *
>(b);
1853 tmp_value = (
long long) (tmp_int16->value());
1857 case libdap::dods_uint32_c: {
1858 const auto tmp_uint32 =
dynamic_cast<libdap::UInt32 *
>(b);
1859 tmp_value = (
long long) (tmp_uint32->value());
1863 case libdap::dods_int32_c: {
1864 const auto tmp_int32 =
dynamic_cast<libdap::Int32 *
>(b);
1865 tmp_value = (
long long) (tmp_int32->value());
1869 case libdap::dods_float32_c: {
1871 const auto tmp_float32 =
dynamic_cast<libdap::Float32 *
>(b);
1872 tmp_value = (
long long) (tmp_float32->value());
1876 case libdap::dods_float64_c: {
1878 const auto tmp_float64 =
dynamic_cast<libdap::Float64 *
>(b);
1879 tmp_value = (
long long) (tmp_float64->value());
1884 throw BESInternalError(
"Attempt to extract CF time information from an invalid source", __FILE__, __LINE__);
1887 axis_t_value = cf_time_to_greg(tmp_value);
1889 currAxis->values +=
"\"" + focovjson::escape_for_covjson(axis_t_value) +
"\"";
1892 ostringstream otemp;
1893 b->print_val(otemp,
"",
false);
1894 currAxis->values += otemp.str();
1896 currAxis->values +=
"]";
1902 currAxis->values +=
"\"values\": []";
1907 else if(axisRetrieved ==
false && parameterRetrieved ==
true) {
1908 struct Parameter *currParameter;
1909 currParameter = parameters[parameterCount - 1];
1911 currParameter->values +=
"\"values\": [";
1912 if (b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c) {
1914 const auto s =
dynamic_cast<libdap::Str *
>(b);
1915 string val = s->value();
1916 currParameter->values +=
"\"" + focovjson::escape_for_covjson(val) +
"\"";
1920 ostringstream otemp;
1921 b->print_val(otemp,
"",
false);
1922 currParameter->values += otemp.str();
1924 currParameter->values +=
"]";
1928 currParameter->values +=
"\"values\": []";
1934void FoDapCovJsonTransform::transform(
ostream *strm, libdap::Array *a,
string indent,
bool sendData)
1936 BESDEBUG(FoDapCovJsonTransform_debug_key,
1937 "FoCovJsonTransform::transform() - Processing Array. " <<
" a->type(): " << a->type() <<
" a->var()->type(): " << a->var()->type() << endl);
1941 switch(a->var()->type()) {
1943 case libdap::dods_byte_c:
1944 covjsonSimpleTypeArray<libdap::dods_byte>(strm, a, indent, sendData);
1947 case libdap::dods_int16_c:
1948 covjsonSimpleTypeArray<libdap::dods_int16>(strm, a, indent, sendData);
1951 case libdap::dods_uint16_c:
1952 covjsonSimpleTypeArray<libdap::dods_uint16>(strm, a, indent, sendData);
1955 case libdap::dods_int32_c:
1956 covjsonSimpleTypeArray<libdap::dods_int32>(strm, a, indent, sendData);
1959 case libdap::dods_uint32_c:
1960 covjsonSimpleTypeArray<libdap::dods_uint32>(strm, a, indent, sendData);
1963 case libdap::dods_float32_c:
1964 covjsonSimpleTypeArray<libdap::dods_float32>(strm, a, indent, sendData);
1967 case libdap::dods_float64_c:
1968 covjsonSimpleTypeArray<libdap::dods_float64>(strm, a, indent, sendData);
1971 case libdap::dods_str_c: {
1972 covjsonStringArray(strm, a, indent, sendData);
1976 case libdap::dods_url_c: {
1977 covjsonStringArray(strm, a, indent, sendData);
1981 case libdap::dods_structure_c:
1982 throw BESInternalError(
"File out COVJSON, Arrays of Structure objects not a supported return type.", __FILE__, __LINE__);
1984 case libdap::dods_grid_c:
1985 throw BESInternalError(
"File out COVJSON, Arrays of Grid objects not a supported return type.", __FILE__, __LINE__);
1987 case libdap::dods_sequence_c:
1988 throw BESInternalError(
"File out COVJSON, Arrays of Sequence objects not a supported return type.", __FILE__, __LINE__);
1990 case libdap::dods_array_c:
1991 throw BESInternalError(
"File out COVJSON, Arrays of Array objects not a supported return type.", __FILE__, __LINE__);
1993 case libdap::dods_int8_c:
1994 case libdap::dods_uint8_c:
1995 case libdap::dods_int64_c:
1996 case libdap::dods_uint64_c:
1997 case libdap::dods_enum_c:
1998 case libdap::dods_group_c:
1999 throw BESInternalError(
"File out COVJSON, DAP4 types not yet supported.", __FILE__, __LINE__);
2002 throw BESInternalError(
"File out COVJSON, Unrecognized type.", __FILE__, __LINE__);
2006bool FoDapCovJsonTransform::check_update_simple_dsg(libdap::DDS *dds) {
2008 bool ret_value =
false;
2009 DSGType sDC_candidate = UNSUPPORTED_DSG;
2011 libdap::AttrTable &globals = dds->get_attr_table();
2012 auto i = globals.attr_begin();
2013 auto e = globals.attr_end();
2014 for (; i != e; i++) {
2015 if (globals.get_attr_type(i) == libdap::Attr_container) {
2016 string attr_name = globals.get_name(i);
2018 libdap::AttrTable *container = globals.get_attr_table(i);
2019 auto ci = container->attr_begin();
2020 auto ce = container->attr_end();
2021 bool find_featureType =
false;
2022 for (; ci != ce; ci++) {
2023 if (container->get_attr_type(ci) == libdap::Attr_string) {
2024 string c_attr_name = container->get_name(ci);
2025 if (c_attr_name ==
"featureType") {
2026 string attr_val = container->get_attr(ci,0);
2027 if (attr_val ==
"point")
2028 sDC_candidate = SPOINT;
2029 else if (attr_val ==
"timeSeries")
2030 sDC_candidate = POINTS;
2031 else if (attr_val ==
"profile")
2032 sDC_candidate = PROFILE;
2033 find_featureType =
true;
2038 if (find_featureType)
2043 else if (globals.get_attr_type(i) == libdap::Attr_string) {
2044 string attr_name = globals.get_name(i);
2046 if (attr_name ==
"featureType") {
2047 string attr_val = globals.get_attr(i,0);
2048 if (attr_val ==
"point")
2049 sDC_candidate = SPOINT;
2050 else if (attr_val ==
"timeSeries")
2051 sDC_candidate = POINTS;
2052 else if (attr_val ==
"profile")
2053 sDC_candidate = PROFILE;
2061 cerr<<
"point "<<endl;
2062else if(cf_timeSeries)
2063 cerr<<
"timeSeries "<<endl;
2065 cerr<<
"Profile "<<endl;
2069 if (sDC_candidate != UNSUPPORTED_DSG) {
2071 libdap::DDS::Vars_iter vi = dds->var_begin();
2072 libdap::DDS::Vars_iter ve = dds->var_end();
2073 for(; vi != ve; vi++) {
2074 if ((*vi)->send_p()) {
2075 libdap::BaseType *v = *vi;
2076 if (is_supported_vars_by_type(v) ==
false)
2078 libdap::AttrTable &attrs = v->get_attr_table();
2079 unsigned int num_attrs = attrs.get_size();
2085 libdap::AttrTable::Attr_iter di = attrs.attr_begin();
2086 libdap::AttrTable::Attr_iter de = attrs.attr_end();
2087 for (; di != de; di++) {
2088 string cf_attr_name =
"axis";
2089 string attr_name = attrs.get_name(di);
2090 unsigned int num_vals = attrs.get_attr_num(di);
2091 if (num_vals == 1 && cf_attr_name == attr_name) {
2092 string val = attrs.get_attr(di,0);
2103 if (is_simple_dsg(sDC_candidate)) {
2107 ret_value = obtain_valid_dsg_par_vars(dds);
2112cerr<<
"axisVar_x.name is "<<axisVar_x.name <<endl;
2113cerr<<
"axisVar_x.dim_name is "<<axisVar_x.dim_name <<endl;
2114cerr<<
"axisVar_x.dim_size is "<<axisVar_x.dim_size <<endl;
2115cerr<<
"axisVar_x.bound_name is "<<axisVar_x.bound_name <<endl;
2117cerr<<
"axisVar_y.name is "<<axisVar_y.name <<endl;
2118cerr<<
"axisVar_y.dim_name is "<<axisVar_y.dim_name <<endl;
2119cerr<<
"axisVar_y.dim_size is "<<axisVar_y.dim_size <<endl;
2120cerr<<
"axisVar_y.bound_name is "<<axisVar_y.bound_name <<endl;
2122cerr<<
"axisVar_z.name is "<<axisVar_z.name <<endl;
2123cerr<<
"axisVar_z.dim_name is "<<axisVar_z.dim_name <<endl;
2124cerr<<
"axisVar_z.dim_size is "<<axisVar_z.dim_size <<endl;
2125cerr<<
"axisVar_z.bound_name is "<<axisVar_z.bound_name <<endl;
2127cerr<<
"axisVar_t.name is "<<axisVar_t.name <<endl;
2128cerr<<
"axisVar_t.dim_name is "<<axisVar_t.dim_name <<endl;
2129cerr<<
"axisVar_t.dim_size is "<<axisVar_t.dim_size <<endl;
2130cerr<<
"axisVar_t.bound_name is "<<axisVar_t.bound_name <<endl;
2136bool FoDapCovJsonTransform::is_simple_dsg(DSGType dsg) {
2139 dsg_type = is_single_point();
2140 else if (dsg == POINTS)
2141 dsg_type = is_point_series();
2142 else if (dsg == PROFILE)
2143 dsg_type = is_single_profile();
2144 return (dsg_type != UNSUPPORTED_DSG);
2147DSGType FoDapCovJsonTransform::is_single_point()
const {
2149 DSGType ret_dsg = SPOINT;
2150 if ((axisVar_z.name !=
"" && axisVar_z.dim_size >1) ||
2151 (axisVar_t.name !=
"" && axisVar_t.dim_size >1))
2152 ret_dsg = UNSUPPORTED_DSG;
2157DSGType FoDapCovJsonTransform::is_point_series()
const {
2159 DSGType ret_dsg = POINTS;
2160 if ((axisVar_z.name !=
"" && axisVar_z.dim_size >1) ||
2161 (axisVar_t.name ==
"" ))
2162 ret_dsg = UNSUPPORTED_DSG;
2168DSGType FoDapCovJsonTransform::is_single_profile()
const {
2170 DSGType ret_dsg = PROFILE;
2171 if ((axisVar_t.name !=
"" && axisVar_t.dim_size >1) ||
2172 (axisVar_z.name ==
"" ))
2173 ret_dsg = UNSUPPORTED_DSG;
2178bool FoDapCovJsonTransform::is_simple_dsg_common()
const {
2180 bool ret_value =
true;
2181 if (axisVar_x.name ==
"" || axisVar_y.name ==
"")
2183 else if (axisVar_x.dim_size >1 || axisVar_y.dim_size >1)
2192bool FoDapCovJsonTransform::is_supported_vars_by_type(libdap::BaseType*v)
const{
2194 bool ret_value =
false;
2195 libdap::Type type = v->type();
2196 if (type == libdap::dods_array_c)
2197 type = v->var()->type();
2199 case libdap::dods_byte_c:
2200 case libdap::dods_int16_c:
2201 case libdap::dods_uint16_c:
2202 case libdap::dods_int32_c:
2203 case libdap::dods_uint32_c:
2204 case libdap::dods_float32_c:
2205 case libdap::dods_float64_c:
2206 case libdap::dods_str_c:
2207 case libdap::dods_url_c:
2216void FoDapCovJsonTransform::handle_axisVars_array(libdap::BaseType*v,axisVar & this_axisVar) {
2218 auto d_a =
dynamic_cast<libdap::Array *
>(v);
2219 if (d_a !=
nullptr) {
2221 int d_ndims = d_a->dimensions();
2225 libdap::Array::Dim_iter di = d_a->dim_begin();
2226 this_axisVar.dim_size = d_a->dimension_size(di,
true);
2227 this_axisVar.name = d_a->name();
2228 this_axisVar.dim_name = d_a->dimension_name(di);
2234void FoDapCovJsonTransform::set_axisVar(libdap::BaseType*v,
const string &val) {
2240 if (v->type() == libdap::dods_array_c)
2241 handle_axisVars_array(v,axisVar_x);
2243 axisVar_x.name = v->name();
2244 axisVar_x.dim_size = 0;
2247 else if (val ==
"Y") {
2248 if (v->type() == libdap::dods_array_c)
2249 handle_axisVars_array(v,axisVar_y);
2251 axisVar_y.name = v->name();
2252 axisVar_y.dim_size = 0;
2255 else if (val ==
"Z") {
2256 if (v->type() == libdap::dods_array_c)
2257 handle_axisVars_array(v,axisVar_z);
2259 axisVar_z.name = v->name();
2260 axisVar_z.dim_size = 0;
2263 else if (val ==
"T") {
2264 if (v->type() == libdap::dods_array_c)
2265 handle_axisVars_array(v,axisVar_t);
2267 axisVar_t.name = v->name();
2268 axisVar_t.dim_size = 0;
2273bool FoDapCovJsonTransform::is_cf_grid_mapping_var(libdap::BaseType *v)
const {
2275 bool ret_value =
false;
2276 libdap::AttrTable attr_table = v->get_attr_table();
2278 if (attr_table.get_size() != 0) {
2280 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
2281 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
2283 for (libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
2285 if (attr_table.get_attr_type(at_iter) == libdap::Attr_string &&
2286 attr_table.get_name(at_iter) ==
"grid_mapping_name") {
2296bool FoDapCovJsonTransform::is_fake_coor_vars(libdap::Array *d_a)
const{
2298 bool ret_value =
false;
2300 if (d_a->dimensions() == 1) {
2301 libdap::Array::Dim_iter i = d_a->dim_begin();
2302 string dim_name = d_a->dimension_name(i);
2303 if (dim_name == d_a->name()) {
2304 libdap::AttrTable attr_table = d_a->get_attr_table();
2305 if (attr_table.get_size() == 0)
2313bool FoDapCovJsonTransform::is_valid_single_point_par_var(libdap::BaseType *v)
const {
2315 bool ret_value =
true;
2316 if (v->name() == axisVar_x.name || v->name() == axisVar_y.name ||
2317 v->name() == axisVar_z.name || v->name() == axisVar_t.name ||
2318 is_cf_grid_mapping_var(v))
2324bool FoDapCovJsonTransform::is_valid_array_dsg_par_var(libdap::Array *d_a)
const {
2326 bool ret_value =
false;
2328 if (d_a->dimensions() == 1) {
2330 libdap::Array::Dim_iter i = d_a->dim_begin();
2331 int dim_size = d_a->dimension_size(i);
2332 string dim_name = d_a->dimension_name(i);
2333 bool fake_coor = is_fake_coor_vars(d_a);
2334 bool real_coor =
false;
2335 if (d_a->name() == axisVar_t.name || d_a->name() == axisVar_z.name || d_a->name() == axisVar_x.name || d_a->name() == axisVar_y.name)
2337 if (real_coor ==
false && fake_coor ==
false) {
2338 if ((dsg_type == SPOINT)
2339 ||(dsg_type == POINTS && dim_name == axisVar_t.dim_name && dim_size == axisVar_t.dim_size)
2340 ||(dsg_type == PROFILE && dim_name == axisVar_z.dim_name && dim_size == axisVar_z.dim_size))
2347bool FoDapCovJsonTransform::is_valid_dsg_par_var(libdap::BaseType *v) {
2349 bool ret_value =
true;
2350 if (v->type() != libdap::dods_array_c) {
2352 if (dsg_type != SPOINT)
2355 ret_value = is_valid_single_point_par_var(v);
2359 auto d_a =
dynamic_cast<libdap::Array *
>(v);
2360 ret_value = is_valid_array_dsg_par_var(d_a);
2366bool FoDapCovJsonTransform::obtain_valid_dsg_par_vars(libdap::DDS *dds) {
2368 libdap::DDS::Vars_iter vi = dds->var_begin();
2369 libdap::DDS::Vars_iter ve = dds->var_end();
2370 for(; vi != ve; vi++) {
2371 if ((*vi)->send_p()) {
2372 libdap::BaseType *v = *vi;
2373 if (is_supported_vars_by_type(v) ==
false)
2375 else if (is_valid_dsg_par_var(v) ==
true)
2376 par_vars.push_back(v->name());
2379 return (par_vars.empty()==
false);
2384void FoDapCovJsonTransform::check_update_simple_geo(libdap::DDS *dds,
bool sendData) {
2386 libdap::DDS::Vars_iter vi = dds->var_begin();
2387 libdap::DDS::Vars_iter ve = dds->var_end();
2390 bool has_axis_var_x =
false;
2391 short axis_var_x_count = 0;
2392 bool has_axis_var_y =
false;
2393 short axis_var_y_count = 0;
2394 bool has_axis_var_z =
false;
2395 short axis_var_z_count = 0;
2396 bool has_axis_var_t =
false;
2397 short axis_var_t_count = 0;
2399 string units_name =
"units";
2400 for (; vi != ve; vi++) {
2404 if((*vi)->send_p()) {
2405 libdap::BaseType *v = *vi;
2406 libdap::Type type = v->type();
2409 if(type == libdap::dods_array_c) {
2410 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
2411 int d_ndims = d_a->dimensions();
2419 libdap::AttrTable &attrs = d_a->get_attr_table();
2420 unsigned int num_attrs = attrs.get_size();
2422 libdap::AttrTable::Attr_iter i = attrs.attr_begin();
2423 libdap::AttrTable::Attr_iter e = attrs.attr_end();
2424 for (; i != e; i++) {
2425 string attr_name = attrs.get_name(i);
2429 unsigned int num_vals = attrs.get_attr_num(i);
2430 if (num_vals == 1) {
2432 bool is_attr_units =
false;
2433 if((attr_name.size() == units_name.size())
2434 && (attr_name.compare(units_name) == 0))
2435 is_attr_units =
true;
2436 if(is_attr_units ==
false)
2437 if(attr_name.size() == (units_name.size()+1) &&
2438 attr_name[units_name.size()] ==
'\0' &&
2439 attr_name.compare(0,units_name.size(),units_name) ==0)
2440 is_attr_units =
true;
2442 if (is_attr_units) {
2443 string val = attrs.get_attr(i,0);
2444 vector<string> unit_candidates;
2449 unit_candidates.push_back(
"degrees_east");
2450 has_axis_var_x = check_add_axis(d_a,val,unit_candidates,axisVar_x,
false);
2451 if (
true == has_axis_var_x) {
2453 if (axis_var_x_count ==2)
2456 unit_candidates.clear();
2459 unit_candidates.push_back(
"degrees_north");
2460 has_axis_var_y = check_add_axis(d_a,val,unit_candidates,axisVar_y,
false);
2461 if (
true == has_axis_var_y) {
2463 if (axis_var_y_count == 2)
2466 unit_candidates.clear();
2469 unit_candidates.push_back(
"hpa");
2470 unit_candidates.push_back(
"hPa");
2471 unit_candidates.push_back(
"meter");
2472 unit_candidates.push_back(
"m");
2473 unit_candidates.push_back(
"km");
2474 has_axis_var_z = check_add_axis(d_a,val,unit_candidates,axisVar_z,
false);
2475 if (
true == has_axis_var_z) {
2477 if (axis_var_z_count == 2)
2480 unit_candidates.clear();
2482for(
int i = 0; i <unit_candidates.size(); i++)
2483 cerr<<
"unit_candidates[i] is "<<unit_candidates[i] <<endl;
2487 unit_candidates.push_back(
"seconds since ");
2488 unit_candidates.push_back(
"minutes since ");
2489 unit_candidates.push_back(
"hours since ");
2490 unit_candidates.push_back(
"days since ");
2492for(
int i = 0; i <unit_candidates.size(); i++)
2493cerr<<
"unit_candidates[i] again is "<<unit_candidates[i] <<endl;
2496 has_axis_var_t = check_add_axis(d_a,val,unit_candidates,axisVar_t,
true);
2497 if (
true == has_axis_var_t) {
2499 if (axis_var_t_count == 2)
2502 unit_candidates.clear();
2514cerr<<
"axis_var_x_count is "<< axis_var_x_count <<endl;
2515cerr<<
"axis_var_y_count is "<< axis_var_y_count <<endl;
2516cerr<<
"axis_var_z_count is "<< axis_var_z_count <<endl;
2517cerr<<
"axis_var_t_count is "<< axis_var_t_count <<endl;
2519 bool is_simple_geo_candidate =
true;
2520 if(axis_var_x_count !=1 || axis_var_y_count !=1)
2521 is_simple_geo_candidate =
false;
2524 if(axis_var_z_count > 1) {
2526 axisVar_z.dim_name =
"";
2527 axisVar_z.bound_name =
"";
2529 if(axis_var_t_count > 1) {
2531 axisVar_t.dim_name =
"";
2532 axisVar_t.bound_name =
"";
2534 if(is_simple_geo_candidate ==
true) {
2540 map<string, string> vname_bname;
2542 check_bounds(dds,vname_bname);
2544 map<string, string>::iterator it;
2546for(it = vname_bname.begin(); it != vname_bname.end(); it++) {
2547cerr<<it->first <<endl;
2548cerr<<it->second <<endl;
2552 for(it = vname_bname.begin(); it != vname_bname.end(); it++) {
2555 if(axisVar_x.name == it->first)
2556 axisVar_x.bound_name = it->second;
2557 else if(axisVar_y.name == it->first)
2558 axisVar_y.bound_name = it->second;
2559 else if(axisVar_z.name == it->first)
2560 axisVar_z.bound_name = it->second;
2561 else if(axisVar_t.name == it->first)
2562 axisVar_t.bound_name = it->second;
2565cerr<<
"axisVar_x.name is "<<axisVar_x.name <<endl;
2566cerr<<
"axisVar_x.dim_name is "<<axisVar_x.dim_name <<endl;
2567cerr<<
"axisVar_x.dim_size is "<<axisVar_x.dim_size <<endl;
2568cerr<<
"axisVar_x.bound_name is "<<axisVar_x.bound_name <<endl;
2570cerr<<
"axisVar_y.name is "<<axisVar_y.name <<endl;
2571cerr<<
"axisVar_y.dim_name is "<<axisVar_y.dim_name <<endl;
2572cerr<<
"axisVar_y.dim_size is "<<axisVar_y.dim_size <<endl;
2573cerr<<
"axisVar_y.bound_name is "<<axisVar_y.bound_name <<endl;
2575cerr<<
"axisVar_z.name is "<<axisVar_z.name <<endl;
2576cerr<<
"axisVar_z.dim_name is "<<axisVar_z.dim_name <<endl;
2577cerr<<
"axisVar_z.dim_size is "<<axisVar_z.dim_size <<endl;
2578cerr<<
"axisVar_z.bound_name is "<<axisVar_z.bound_name <<endl;
2580cerr<<
"axisVar_t.name is "<<axisVar_t.name <<endl;
2581cerr<<
"axisVar_t.dim_name is "<<axisVar_t.dim_name <<endl;
2582cerr<<
"axisVar_t.dim_size is "<<axisVar_t.dim_size <<endl;
2583cerr<<
"axisVar_t.bound_name is "<<axisVar_t.bound_name <<endl;
2587 is_simple_cf_geographic = obtain_valid_vars(dds,axis_var_z_count,axis_var_t_count);
2589 if(
true == is_simple_cf_geographic) {
2598 string x_bnd_dim_name;
2599 string y_bnd_dim_name;
2600 string z_bnd_dim_name;
2601 string t_bnd_dim_name;
2603 obtain_bound_values(dds,axisVar_x,axisVar_x_bnd_val, x_bnd_dim_name,sendData);
2604 obtain_bound_values(dds,axisVar_y,axisVar_y_bnd_val, y_bnd_dim_name,sendData);
2605 obtain_bound_values(dds,axisVar_z,axisVar_z_bnd_val, z_bnd_dim_name,sendData);
2606 obtain_bound_values(dds,axisVar_t,axisVar_t_bnd_val, t_bnd_dim_name,sendData);
2608 if(x_bnd_dim_name!=
"")
2609 bnd_dim_names.push_back(x_bnd_dim_name);
2610 else if(y_bnd_dim_name!=
"")
2611 bnd_dim_names.push_back(y_bnd_dim_name);
2612 else if(z_bnd_dim_name!=
"")
2613 bnd_dim_names.push_back(z_bnd_dim_name);
2614 else if(t_bnd_dim_name!=
"")
2615 bnd_dim_names.push_back(t_bnd_dim_name);
2621void FoDapCovJsonTransform::check_update_simple_geo_dap4(libdap::D4Group *d4g) {
2625 bool has_axis_var_x =
false;
2626 short axis_var_x_count = 0;
2627 bool has_axis_var_y =
false;
2628 short axis_var_y_count = 0;
2629 bool has_axis_var_z =
false;
2630 short axis_var_z_count = 0;
2631 bool has_axis_var_t =
false;
2632 short axis_var_t_count = 0;
2634 string units_name =
"units";
2635 for (
auto vi = d4g->var_begin(), ve = d4g->var_end(); vi != ve; ++vi) {
2639 if((*vi)->send_p()) {
2641 libdap::BaseType *v = *vi;
2642 libdap::Type type = v->type();
2646 if(type == libdap::dods_array_c) {
2647 auto d_a =
dynamic_cast<libdap::Array *
>(v);
2648 int d_ndims = d_a->dimensions();
2656 libdap::D4Attributes *d4_attrs = d_a->attributes();
2657 for (libdap::D4Attributes::D4AttributesIter ii = d4_attrs->attribute_begin(), ee = d4_attrs->attribute_end();
2660 string attr_name = (*ii)->name();
2661 unsigned int num_vals = (*ii)->num_values();
2663 if (num_vals == 1) {
2666 bool is_attr_units =
false;
2667 if ((attr_name.size() == units_name.size())
2668 && (attr_name.compare(units_name) == 0))
2669 is_attr_units =
true;
2670 if (is_attr_units ==
false &&
2671 (attr_name.size() == (units_name.size()+1) &&
2672 attr_name[units_name.size()] ==
'\0' &&
2673 attr_name.compare(0,units_name.size(),units_name) ==0))
2674 is_attr_units =
true;
2676 if (is_attr_units) {
2677 string val = (*ii)->value(0);
2678 vector<string> unit_candidates;
2683 unit_candidates.emplace_back(
"degrees_east");
2684 has_axis_var_x = check_add_axis(d_a,val,unit_candidates,axisVar_x,
false);
2685 if (
true == has_axis_var_x) {
2687 if (axis_var_x_count == 2)
2690 unit_candidates.clear();
2693 unit_candidates.emplace_back(
"degrees_north");
2694 has_axis_var_y = check_add_axis(d_a,val,unit_candidates,axisVar_y,
false);
2695 if (
true == has_axis_var_y) {
2697 if (axis_var_y_count == 2)
2700 unit_candidates.clear();
2703 unit_candidates.emplace_back(
"hpa");
2704 unit_candidates.emplace_back(
"hPa");
2705 unit_candidates.emplace_back(
"meter");
2706 unit_candidates.emplace_back(
"m");
2707 unit_candidates.emplace_back(
"km");
2708 has_axis_var_z = check_add_axis(d_a,val,unit_candidates,axisVar_z,
false);
2709 if (
true == has_axis_var_z) {
2711 if (axis_var_z_count == 2)
2714 unit_candidates.clear();
2716for(
int i = 0; i <unit_candidates.size(); i++)
2717 cerr<<
"unit_candidates[i] is "<<unit_candidates[i] <<endl;
2721 unit_candidates.emplace_back(
"seconds since ");
2722 unit_candidates.emplace_back(
"minutes since ");
2723 unit_candidates.emplace_back(
"hours since ");
2724 unit_candidates.emplace_back(
"days since ");
2726for(
int i = 0; i <unit_candidates.size(); i++)
2727cerr<<
"unit_candidates[i] again is "<<unit_candidates[i] <<endl;
2730 has_axis_var_t = check_add_axis(d_a,val,unit_candidates,axisVar_t,
true);
2731 if (
true == has_axis_var_t) {
2733 if (axis_var_t_count == 2)
2736 unit_candidates.clear();
2746cerr<<
"axis_var_x_count is "<< axis_var_x_count <<endl;
2747cerr<<
"axis_var_y_count is "<< axis_var_y_count <<endl;
2748cerr<<
"axis_var_z_count is "<< axis_var_z_count <<endl;
2749cerr<<
"axis_var_t_count is "<< axis_var_t_count <<endl;
2752 bool is_simple_geo_candidate =
true;
2753 if(axis_var_x_count != 1 || axis_var_y_count != 1)
2754 is_simple_geo_candidate =
false;
2758 if(axis_var_z_count > 1) {
2760 axisVar_z.dim_name =
"";
2761 axisVar_z.bound_name =
"";
2763 if(axis_var_t_count > 1) {
2765 axisVar_t.dim_name =
"";
2766 axisVar_t.bound_name =
"";
2768 if (is_simple_geo_candidate ==
true) {
2771cerr<<
"axisVar_x.name is "<<axisVar_x.name <<endl;
2772cerr<<
"axisVar_x.dim_name is "<<axisVar_x.dim_name <<endl;
2773cerr<<
"axisVar_x.dim_size is "<<axisVar_x.dim_size <<endl;
2774cerr<<
"axisVar_x.bound_name is "<<axisVar_x.bound_name <<endl;
2776cerr<<
"axisVar_y.name is "<<axisVar_y.name <<endl;
2777cerr<<
"axisVar_y.dim_name is "<<axisVar_y.dim_name <<endl;
2778cerr<<
"axisVar_y.dim_size is "<<axisVar_y.dim_size <<endl;
2779cerr<<
"axisVar_y.bound_name is "<<axisVar_y.bound_name <<endl;
2781cerr<<
"axisVar_z.name is "<<axisVar_z.name <<endl;
2782cerr<<
"axisVar_z.dim_name is "<<axisVar_z.dim_name <<endl;
2783cerr<<
"axisVar_z.dim_size is "<<axisVar_z.dim_size <<endl;
2784cerr<<
"axisVar_z.bound_name is "<<axisVar_z.bound_name <<endl;
2786cerr<<
"axisVar_t.name is "<<axisVar_t.name <<endl;
2787cerr<<
"axisVar_t.dim_name is "<<axisVar_t.dim_name <<endl;
2788cerr<<
"axisVar_t.dim_size is "<<axisVar_t.dim_size <<endl;
2789cerr<<
"axisVar_t.bound_name is "<<axisVar_t.bound_name <<endl;
2792 is_simple_cf_geographic = obtain_valid_vars_dap4(d4g,axis_var_z_count,axis_var_t_count);
2797bool FoDapCovJsonTransform::check_add_axis(libdap::Array *d_a,
const string & unit_value,
const vector<string> & CF_unit_values, axisVar & this_axisVar,
bool is_t_axis) {
2799 bool ret_value =
false;
2800 for (
unsigned i = 0; i < CF_unit_values.size(); i++) {
2804 bool is_cf_units =
false;
2805 if(is_t_axis ==
false) {
2806 if((unit_value.size() == CF_unit_values[i].size() || unit_value.size() == (CF_unit_values[i].size() +1)) && unit_value.compare(0,CF_unit_values[i].size(),CF_unit_values[i])==0)
2810 if(unit_value.compare(0,CF_unit_values[i].size(),CF_unit_values[i])==0)
2815 libdap::Array::Dim_iter di = d_a->dim_begin();
2816 this_axisVar.dim_size = d_a->dimension_size(di,
true);
2817 this_axisVar.name = d_a->name();
2818 this_axisVar.dim_name = d_a->dimension_name(di);
2819 this_axisVar.bound_name=
"";
2822cerr<<
"axis size "<< this_axisVar.dim_size <<endl;
2823cerr<<
"axis name "<< this_axisVar.name <<endl;
2824cerr<<
"axis dim_name "<< this_axisVar.dim_name <<endl;
2835void FoDapCovJsonTransform::check_bounds(libdap::DDS *dds, map<string,string>& vname_bname) {
2837 string bound_name =
"bounds";
2838 libdap::DDS::Vars_iter vi = dds->var_begin();
2839 libdap::DDS::Vars_iter ve = dds->var_end();
2841 for(; vi != ve; vi++) {
2845 if((*vi)->send_p()) {
2846 libdap::BaseType *v = *vi;
2847 libdap::Type type = v->type();
2850 if(type == libdap::dods_array_c) {
2851 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
2852 int d_ndims = d_a->dimensions();
2857 libdap::AttrTable &attrs = d_a->get_attr_table();
2858 unsigned int num_attrs = attrs.get_size();
2860 libdap::AttrTable::Attr_iter i = attrs.attr_begin();
2861 libdap::AttrTable::Attr_iter e = attrs.attr_end();
2862 for (; i != e; i++) {
2863 string attr_name = attrs.get_name(i);
2867 unsigned int num_vals = attrs.get_attr_num(i);
2868 if (num_vals == 1) {
2870 bool is_attr_bounds =
false;
2871 if((attr_name.size() == bound_name.size())
2872 && (attr_name.compare(bound_name) == 0))
2873 is_attr_bounds =
true;
2874 if(is_attr_bounds ==
false)
2875 if(attr_name.size() == (bound_name.size()+1) &&
2876 attr_name[bound_name.size()] ==
'\0' &&
2877 attr_name.compare(0,bound_name.size(),bound_name) ==0)
2878 is_attr_bounds =
true;
2880 if (is_attr_bounds) {
2881 string val = attrs.get_attr(i,0);
2882 vname_bname[d_a->name()] = val;
2893void FoDapCovJsonTransform::obtain_bound_values(libdap::DDS *dds,
const axisVar & av, std::vector<float>& av_bnd_val, std::string& bnd_dim_name,
bool sendData) {
2896 libdap::Array* d_a = obtain_bound_values_worker(dds, av.bound_name,bnd_dim_name);
2902 if(d_a->var()->type_name() ==
"Float64") {
2904 int num_lengths = d_a->length();
2905 vector<double>temp_val;
2906 temp_val.resize(num_lengths);
2907 d_a->value(temp_val.data());
2909 av_bnd_val.resize(num_lengths);
2910 for (
unsigned i = 0; i <av_bnd_val.size();i++)
2911 av_bnd_val[i] =(
float)temp_val[i];
2914for (
int i = 0; i <av_bnd_val.size();i++)
2915cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2919 else if(d_a->var()->type_name() ==
"Float32") {
2921 int num_lengths = d_a->length();
2922 av_bnd_val.resize(num_lengths);
2923 d_a->value(av_bnd_val.data());
2925for (
int i = 0; i <av_bnd_val.size();i++)
2926cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2935void FoDapCovJsonTransform::obtain_bound_values(libdap::DDS *dds,
const axisVar & av, std::vector<double>& av_bnd_val, std::string& bnd_dim_name,
bool sendData) {
2937 libdap::Array* d_a = obtain_bound_values_worker(dds, av.bound_name,bnd_dim_name);
2940cerr<<
"d_a->name in obtain_bound_values is "<<d_a->name() <<endl;
2941cerr<<
"in obtain_bound_values bnd_dim_name is "<<bnd_dim_name <<endl;
2943 if(d_a->var()->type_name() ==
"Float64") {
2945 int num_lengths = d_a->length();
2946 av_bnd_val.resize(num_lengths);
2947 d_a->value(av_bnd_val.data());
2949for (
int i = 0; i <av_bnd_val.size();i++)
2950cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2954 else if(d_a->var()->type_name() ==
"Float32") {
2956 int num_lengths = d_a->length();
2957 vector<float>temp_val;
2958 temp_val.resize(num_lengths);
2959 d_a->value(temp_val.data());
2960 av_bnd_val.resize(num_lengths);
2961 for (
unsigned i = 0; i <av_bnd_val.size();i++)
2962 av_bnd_val[i] =(
double)temp_val[i];
2964for (
int i = 0; i <av_bnd_val.size();i++)
2965cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2972libdap::Array* FoDapCovJsonTransform::obtain_bound_values_worker(libdap::DDS *dds,
const string& bnd_name,
string & bnd_dim_name) {
2974 libdap::Array* d_a =
nullptr;
2977 libdap::DDS::Vars_iter vi = dds->var_begin();
2978 libdap::DDS::Vars_iter ve = dds->var_end();
2980 for(; vi != ve; vi++) {
2984 if((*vi)->send_p()) {
2985 libdap::BaseType *v = *vi;
2986 libdap::Type type = v->type();
2989 if(type == libdap::dods_array_c) {
2990 libdap::Array * td_a =
dynamic_cast<libdap::Array *
>(v);
2991 int d_ndims = td_a->dimensions();
2996 string tmp_bnd_dim_name;
2997 int bound_dim_size = 0;
2999 libdap::Array::Dim_iter di = td_a->dim_begin();
3000 libdap::Array::Dim_iter de = td_a->dim_end();
3001 for (; di != de; di++) {
3002 if(dim_count == 1) {
3003 bound_dim_size = td_a->dimension_size(di,
true);
3004 tmp_bnd_dim_name = td_a->dimension_name(di);
3013 if((bound_dim_size == 2) && (td_a->name() == bnd_name)) {
3015 bnd_dim_name = tmp_bnd_dim_name;
3031bool FoDapCovJsonTransform::obtain_valid_vars(libdap::DDS *dds,
short axis_var_z_count,
short axis_var_t_count ) {
3036 bool ret_value =
true;
3037 std::vector<std::string> temp_x_y_vars;
3038 std::vector<std::string> temp_x_y_z_vars;
3039 std::vector<std::string> temp_x_y_t_vars;
3040 std::vector<std::string> temp_x_y_z_t_vars;
3042 libdap::DDS::Vars_iter vi = dds->var_begin();
3043 libdap::DDS::Vars_iter ve = dds->var_end();
3044 for(; vi != ve; vi++) {
3045 if((*vi)->send_p()) {
3046 libdap::BaseType *v = *vi;
3047 libdap::Type type = v->type();
3048 if(type == libdap::dods_array_c) {
3049 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
3050 int d_ndims = d_a->dimensions();
3054 short axis_x_count = 0;
3055 short axis_y_count = 0;
3056 short axis_z_count = 0;
3057 short axis_t_count = 0;
3058 bool non_xyzt_dim =
false;
3059 bool supported_var =
true;
3061 libdap::Array::Dim_iter di = d_a->dim_begin();
3062 libdap::Array::Dim_iter de = d_a->dim_end();
3064 for (; di != de; di++) {
3066 if((d_a->dimension_size(di,
true) == axisVar_x.dim_size) &&
3067 (d_a->dimension_name(di) == axisVar_x.dim_name))
3069 else if((d_a->dimension_size(di,
true) == axisVar_y.dim_size) &&
3070 (d_a->dimension_name(di) == axisVar_y.dim_name))
3072 else if((d_a->dimension_size(di,
true) == axisVar_z.dim_size) &&
3073 (d_a->dimension_name(di) == axisVar_z.dim_name))
3075 else if((d_a->dimension_size(di,
true) == axisVar_t.dim_size) &&
3076 (d_a->dimension_name(di) == axisVar_t.dim_name))
3079 non_xyzt_dim =
true;
3084 if(non_xyzt_dim || axis_x_count >1 || axis_y_count >1 || axis_z_count >1 || axis_t_count >1) {
3085 supported_var =
false;
3087cerr<<
"Obtain: d_a->name() is "<<d_a->name() <<endl;
3089 if (FoCovJsonRequestHandler::get_may_ignore_z_axis() ==
false) {
3090 if(d_a->name()!=axisVar_x.bound_name && d_a->name()!=axisVar_y.bound_name &&
3091 d_a->name()!=axisVar_z.bound_name && d_a->name()!=axisVar_t.bound_name)
3100 if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 0)
3101 temp_x_y_vars.emplace_back(d_a->name());
3102 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 0)
3103 temp_x_y_z_vars.emplace_back(d_a->name());
3104 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 1)
3105 temp_x_y_t_vars.emplace_back(d_a->name());
3106 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 1)
3107 temp_x_y_z_t_vars.emplace_back(d_a->name());
3109 else if(ret_value ==
false)
3119 if (ret_value ==
true) {
3120 if(FoCovJsonRequestHandler::get_may_ignore_z_axis()==
true) {
3123cerr<<
"coming to ignore mode "<<endl;
3124cerr<<
"axis_var_z_count: "<<axis_var_z_count <<endl;
3125cerr<<
"axis_var_t_count: "<<axis_var_t_count <<endl;
3130 if(axis_var_z_count <=1 && axis_var_t_count <=1) {
3132 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
3133 par_vars.emplace_back(temp_x_y_vars[i]);
3134 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
3135 par_vars.emplace_back(temp_x_y_t_vars[i]);
3137 if (temp_x_y_vars.empty()) {
3138 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
3139 par_vars.emplace_back(temp_x_y_z_vars[i]);
3140 for (
unsigned i = 0; i <temp_x_y_z_t_vars.size(); i++)
3141 par_vars.emplace_back(temp_x_y_z_t_vars[i]);
3147 if (axis_var_z_count == 1) {
3149 axisVar_z.dim_name =
"";
3150 axisVar_z.bound_name =
"";
3154 else if (axis_var_z_count >1 && axis_var_t_count <=1) {
3156 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
3157 par_vars.emplace_back(temp_x_y_vars[i]);
3158 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
3159 par_vars.emplace_back(temp_x_y_t_vars[i]);
3161 else if (axis_var_z_count <=1 && axis_var_t_count >1) {
3163 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
3164 par_vars.emplace_back(temp_x_y_vars[i]);
3165 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
3166 par_vars.emplace_back(temp_x_y_z_vars[i]);
3171 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
3172 par_vars.emplace_back(temp_x_y_vars[i]);
3177cerr<<
"coming to strict mode "<<endl;
3179 if(axis_var_z_count >1 || axis_var_t_count >1)
3183 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
3184 par_vars.emplace_back(temp_x_y_vars[i]);
3185 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
3186 par_vars.emplace_back(temp_x_y_z_vars[i]);
3187 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
3188 par_vars.emplace_back(temp_x_y_t_vars[i]);
3189 for (
unsigned i = 0; i <temp_x_y_z_t_vars.size(); i++)
3190 par_vars.emplace_back(temp_x_y_z_t_vars[i]);
3195cerr<<
"Parameter Names: "<<endl;
3196for(
unsigned i = 0; i <par_vars.size(); i++)
3197 cerr<<par_vars[i]<<endl;
3201 if(par_vars.size() == 0)
3209bool FoDapCovJsonTransform::obtain_valid_vars_dap4(libdap::D4Group *d4g,
short axis_var_z_count,
short axis_var_t_count ) {
3214 bool ret_value =
true;
3215 std::vector<std::string> temp_x_y_vars;
3216 std::vector<std::string> temp_x_y_z_vars;
3217 std::vector<std::string> temp_x_y_t_vars;
3218 std::vector<std::string> temp_x_y_z_t_vars;
3220 for (
auto vi = d4g->var_begin(), ve = d4g->var_end(); vi != ve; ++vi) {
3222 if ((*vi)->send_p()) {
3224 libdap::BaseType *v = *vi;
3225 libdap::Type type = v->type();
3227 if (type == libdap::dods_array_c) {
3229 auto d_a =
dynamic_cast<libdap::Array *
>(v);
3230 int d_ndims = d_a->dimensions();
3234 short axis_x_count = 0;
3235 short axis_y_count = 0;
3236 short axis_z_count = 0;
3237 short axis_t_count = 0;
3238 bool non_xyzt_dim =
false;
3239 bool supported_var =
true;
3241 libdap::Array::Dim_iter di = d_a->dim_begin();
3242 libdap::Array::Dim_iter de = d_a->dim_end();
3244 for (; di != de; di++) {
3246 if((d_a->dimension_size(di,
true) == axisVar_x.dim_size) &&
3247 (d_a->dimension_name(di) == axisVar_x.dim_name))
3249 else if((d_a->dimension_size(di,
true) == axisVar_y.dim_size) &&
3250 (d_a->dimension_name(di) == axisVar_y.dim_name))
3252 else if((d_a->dimension_size(di,
true) == axisVar_z.dim_size) &&
3253 (d_a->dimension_name(di) == axisVar_z.dim_name))
3255 else if((d_a->dimension_size(di,
true) == axisVar_t.dim_size) &&
3256 (d_a->dimension_name(di) == axisVar_t.dim_name))
3259 non_xyzt_dim =
true;
3264 if(non_xyzt_dim || axis_x_count >1 || axis_y_count >1 || axis_z_count >1 || axis_t_count >1) {
3265 supported_var =
false;
3267cerr<<
"Obtain: d_a->name() is "<<d_a->name() <<endl;
3269 if (FoCovJsonRequestHandler::get_may_ignore_z_axis() ==
false) {
3270 if(d_a->name()!=axisVar_x.bound_name && d_a->name()!=axisVar_y.bound_name &&
3271 d_a->name()!=axisVar_z.bound_name && d_a->name()!=axisVar_t.bound_name)
3280 if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 0)
3281 temp_x_y_vars.emplace_back(d_a->name());
3282 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 0)
3283 temp_x_y_z_vars.emplace_back(d_a->name());
3284 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 1)
3285 temp_x_y_t_vars.emplace_back(d_a->name());
3286 else if(axis_x_count == 1 && axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 1)
3287 temp_x_y_z_t_vars.emplace_back(d_a->name());
3289 else if(ret_value ==
false)
3299 if (ret_value ==
true) {
3300 if(FoCovJsonRequestHandler::get_may_ignore_z_axis()==
true) {
3303cerr<<
"coming to ignore mode "<<endl;
3304cerr<<
"axis_var_z_count: "<<axis_var_z_count <<endl;
3305cerr<<
"axis_var_t_count: "<<axis_var_t_count <<endl;
3310 if(axis_var_z_count <=1 && axis_var_t_count <=1) {
3312 for (
const auto &txy_var:temp_x_y_vars)
3313 par_vars.emplace_back(txy_var);
3314 for (
const auto &txyt_var:temp_x_y_t_vars)
3315 par_vars.emplace_back(txyt_var);
3317 if (temp_x_y_vars.empty()) {
3318 for (
const auto &txyz_var:temp_x_y_z_vars)
3319 par_vars.emplace_back(txyz_var);
3320 for (
const auto &txyzt_var:temp_x_y_z_t_vars)
3321 par_vars.emplace_back(txyzt_var);
3327 if (axis_var_z_count == 1) {
3329 axisVar_z.dim_name =
"";
3330 axisVar_z.bound_name =
"";
3334 else if (axis_var_z_count >1 && axis_var_t_count <=1) {
3336 for (
const auto &txy_var:temp_x_y_vars)
3337 par_vars.emplace_back(txy_var);
3338 for (
const auto &txyt_var:temp_x_y_t_vars)
3339 par_vars.emplace_back(txyt_var);
3341 else if (axis_var_z_count <=1 && axis_var_t_count >1) {
3343 for (
const auto &txy_var:temp_x_y_vars)
3344 par_vars.emplace_back(txy_var);
3345 for (
const auto &txyz_var:temp_x_y_z_vars)
3346 par_vars.emplace_back(txyz_var);
3351 for (
const auto &txy_var:temp_x_y_vars)
3352 par_vars.emplace_back(txy_var);
3357cerr<<
"coming to strict mode "<<endl;
3359 if(axis_var_z_count >1 || axis_var_t_count >1)
3363 for (
const auto &txy_var:temp_x_y_vars)
3364 par_vars.emplace_back(txy_var);
3365 for (
const auto &txyz_var:temp_x_y_z_vars)
3366 par_vars.emplace_back(txyz_var);
3367 for (
const auto &txyt_var:temp_x_y_t_vars)
3368 par_vars.emplace_back(txyt_var);
3369 for (
const auto &txyzt_var:temp_x_y_z_t_vars)
3370 par_vars.emplace_back(txyzt_var);
3375cerr<<
"Parameter Names: "<<endl;
3376for(
unsigned i = 0; i <par_vars.size(); i++)
3377 cerr<<par_vars[i]<<endl;
3381 if (par_vars.empty() ==
true)
3390std::string FoDapCovJsonTransform::cf_time_to_greg(
long long time_val) {
3395 string cf_time= axis_t_units ;
3398 short time_unit_length = -1;
3399 if(cf_time.compare(0,3,
"day") == 0)
3400 time_unit_length = 0;
3401 else if(cf_time.compare(0,4,
"hour") == 0)
3402 time_unit_length = 1;
3403 else if(cf_time.compare(0,6,
"minute") == 0)
3404 time_unit_length = 2;
3405 else if(cf_time.compare(0,6,
"second") == 0)
3406 time_unit_length = 3;
3413 vector<string> subStrs = {
"days",
"day",
"hours",
"hour",
"minutes",
"minute",
3414 "seconds",
"second",
"since",
" " };
3416 for(
unsigned int i = 0; i < subStrs.size(); i++)
3417 focovjson::removeSubstring(cf_time, subStrs[i]);
3424 size_t cf_time_space_pos = cf_time.find(
' ');
3425 string cf_date,cf_hms;
3427 if(cf_time_space_pos!=string::npos) {
3428 cf_date= cf_time.substr(0,cf_time_space_pos);
3429 cf_hms = cf_time.substr(cf_time_space_pos+1);
3432 if(cf_hms==
" " || cf_hms==
"")
3436cerr<<
"cf_date is "<<cf_date <<endl;
3437cerr<<
"cf_hms is "<<cf_hms <<endl;
3443 string cf_y,cf_mo,cf_d;
3444 size_t cf_date_dash_pos = cf_date.find(
'-');
3445 if(cf_date_dash_pos !=string::npos) {
3447 cf_y = cf_date.substr(0,cf_date_dash_pos);
3448 cf_md = cf_date.substr(cf_date_dash_pos+1);
3449 size_t cf_md_dash_pos = cf_md.find(
"-");
3450 if(cf_md_dash_pos !=string::npos) {
3451 cf_mo = cf_md.substr(0,cf_md_dash_pos);
3452 cf_d = cf_md.substr(cf_md_dash_pos+1);
3456 string cf_h,cf_ms,cf_m,cf_s;
3457 size_t cf_hms_colon_pos = cf_hms.find(
':');
3458 if(cf_hms_colon_pos !=string::npos) {
3459 cf_h = cf_hms.substr(0,cf_hms_colon_pos);
3460 cf_ms = cf_hms.substr(cf_hms_colon_pos+1);
3461 size_t cf_ms_colon_pos = cf_ms.find(
":");
3462 if(cf_ms_colon_pos !=string::npos) {
3463 cf_m = cf_ms.substr(0,cf_ms_colon_pos);
3464 cf_s = cf_ms.substr(cf_ms_colon_pos+1);
3470cerr<<
"cf_y is "<<cf_y <<endl;
3471cerr<<
"cf_mo is "<<cf_mo <<endl;
3472cerr<<
"cf_d is "<<cf_d <<endl;
3474cerr<<
"cf_h is "<<cf_h <<endl;
3475cerr<<
"cf_m is "<<cf_m <<endl;
3476cerr<<
"cf_s is "<<cf_s <<endl;
3480 int cf_y_i,cf_mo_i,cf_d_i,cf_h_i,cf_m_i,cf_s_i;
3481 cf_y_i = stoi(cf_y);
3482 cf_mo_i = stoi(cf_mo);
3483 cf_d_i = stoi(cf_d);
3484 cf_h_i = stoi(cf_h);
3485 cf_m_i = stoi(cf_m);
3486 cf_s_i = stoi(cf_s);
3489cerr<<
"cf_y_i " <<cf_y_i <<endl;
3490cerr<<
"cf_mo_i " <<cf_mo_i <<endl;
3491cerr<<
"cf_d_i " <<cf_d_i <<endl;
3492cerr<<
"cf_h_i " <<cf_h_i <<endl;
3493cerr<<
"cf_m_i " <<cf_m_i <<endl;
3494cerr<<
"cf_s_i " <<cf_s_i <<endl;
3500 ycf_1.tm_hour = cf_h_i; ycf_1.tm_min = cf_m_i; ycf_1.tm_sec = cf_s_i;
3501 ycf_1.tm_year = cf_y_i-1900; ycf_1.tm_mon = cf_mo_i; ycf_1.tm_mday = cf_d_i;
3505 time_t t_ycf_1 = timegm(&ycf_1);
3508cerr<<
"t_ycf_1 is "<<t_ycf_1 <<endl;
3509cerr<<
"time_val is "<<time_val <<endl;
3517 if(time_unit_length == 0)
3518 t_ycf_2 = t_ycf_1 + 86400*time_val;
3519 else if (time_unit_length == 1)
3520 t_ycf_2 = t_ycf_1 + 3600*time_val;
3521 else if (time_unit_length == 2)
3522 t_ycf_2 = t_ycf_1 + 60*time_val;
3523 else if (time_unit_length == 3)
3524 t_ycf_2 = t_ycf_1 + time_val;
3532 struct tm temp_new_ycf{};
3541 auto t_new_ycf = gmtime_r(&t_ycf_2, &temp_new_ycf);
3544cerr<<
"t_new_ycf.tm_year is " <<t_new_ycf->tm_year <<endl;
3545cerr<<
"t_new_ycf.tm_mon is " <<t_new_ycf->tm_mon <<endl;
3546cerr<<
"t_new_ycf.tm_day is " <<t_new_ycf->tm_mday <<endl;
3547cerr<<
"t_new_ycf.tm_hour is " <<t_new_ycf->tm_hour <<endl;
3548cerr<<
"t_new_ycf.tm_min is " <<t_new_ycf->tm_min <<endl;
3549cerr<<
"t_new_ycf.tm_sec is " <<t_new_ycf->tm_sec <<endl;
3551 if(t_new_ycf->tm_mon == 0) {
3552 t_new_ycf->tm_year--;
3553 t_new_ycf->tm_mon = 12;
3556 string covjson_mon = (t_new_ycf->tm_mon<10)?
3557 (
"0"+to_string(t_new_ycf->tm_mon)):
3558 to_string(t_new_ycf->tm_mon);
3559 string covjson_mday = (t_new_ycf->tm_mday<10)?
3560 (
"0"+to_string(t_new_ycf->tm_mday)):
3561 to_string(t_new_ycf->tm_mday);
3563 string covjson_hour = (t_new_ycf->tm_hour<10)?
3564 (
"0"+to_string(t_new_ycf->tm_hour)):
3565 to_string(t_new_ycf->tm_hour);
3567 string covjson_min = (t_new_ycf->tm_min<10)?
3568 (
"0"+to_string(t_new_ycf->tm_min)):
3569 to_string(t_new_ycf->tm_min);
3571 string covjson_sec = (t_new_ycf->tm_sec<10)?
3572 (
"0"+to_string(t_new_ycf->tm_sec)):
3573 to_string(t_new_ycf->tm_sec);
3577 string covjson_time = to_string(1900+t_new_ycf->tm_year)+
"-"+
3578 covjson_mon+
"-"+covjson_mday+
"T"+
3579 covjson_hour+
":"+covjson_min+
":"+
3582 return covjson_time;
3585void FoDapCovJsonTransform::print_bound(
ostream *strm,
const std::vector<std::string> & t_bnd_val,
const std::string & indent,
bool is_t_axis)
const {
3587 if(axisVar_t.bound_name !=
"") {
3588 std::string print_values;
3589 if(t_bnd_val.size() >0) {
3590 print_values =
"\"bounds\": [";
3591 for(
unsigned i = 0; i <t_bnd_val.size(); i++) {
3592 string tmpString = t_bnd_val[i];
3595 print_values +=
"\"";
3596 print_values +=focovjson::escape_for_covjson(tmpString);
3597 print_values +=
"\"";
3600 print_values +=tmpString;
3602 if(i !=(t_bnd_val.size()-1))
3603 print_values +=
", ";
3607 print_values +=
"]";
3610 print_values=
"\"bounds\": []";
3611 *strm << indent << print_values <<endl;
3616bool FoDapCovJsonTransform::check_geo_dap2_grid(libdap::DDS *dds,
const vector<string> &dap2_grid_map_names)
const {
3618 libdap::DDS::Vars_iter vi = dds->var_begin();
3619 libdap::DDS::Vars_iter ve = dds->var_end();
3621 bool has_lat =
false;
3622 bool has_lon =
false;
3623 bool ret_value =
false;
3625 for (; vi != ve; vi++) {
3627 if ((*vi)->send_p()) {
3629 libdap::BaseType *v = *vi;
3630 libdap::Type type = v->type();
3632 if (type == libdap::dods_array_c) {
3634 for (
const auto &map_name:dap2_grid_map_names) {
3635 if (v->name() == map_name) {
3636 auto d_a =
dynamic_cast<libdap::Array *
>(v);
3637 short lat_or_lon = check_cf_unit_attr(d_a);
3638 if (lat_or_lon == 1)
3640 else if (lat_or_lon == 2)
3647 if (has_lat && has_lon) {
3658short FoDapCovJsonTransform::check_cf_unit_attr(libdap::Array *d_a)
const {
3660 short ret_value = 0;
3663 if (d_a->dimensions() == 1) {
3665 libdap::AttrTable &attrs = d_a->get_attr_table();
3666 unsigned int num_attrs = attrs.get_size();
3670 string lat_unit =
"degrees_north";
3671 string lon_unit =
"degrees_east";
3673 libdap::AttrTable::Attr_iter i = attrs.attr_begin();
3674 libdap::AttrTable::Attr_iter e = attrs.attr_end();
3676 for (; i != e; i++) {
3678 string attr_name = attrs.get_name(i);
3682 unsigned int num_vals = attrs.get_attr_num(i);
3684 if (num_vals == 1) {
3686 string units_name =
"units";
3688 bool is_attr_units =
false;
3689 if ((attr_name.size() == units_name.size())
3690 && (attr_name.compare(units_name) == 0))
3691 is_attr_units =
true;
3692 if ((is_attr_units ==
false) &&
3693 (attr_name.size() == (units_name.size()+1) &&
3694 attr_name[units_name.size()] ==
'\0' &&
3695 attr_name.compare(0,units_name.size(),units_name) ==0))
3696 is_attr_units =
true;
3698 if (is_attr_units) {
3700 string val = attrs.get_attr(i,0);
3701 if (val.compare(0,lat_unit.size(),lat_unit) == 0)
3703 else if (val.compare(0,lon_unit.size(),lon_unit) == 0)
exception thrown if internal error encountered
static bool endsWith(std::string const &fullString, std::string const &ending)
static void conditional_timeout_cancel()
Checks if the timeout alarm should be canceled based on the value of the BES key BES....
static RequestServiceTimer * TheTimer()
Return a pointer to a singleton timer instance. If an instance does not exist it will create and init...
void throw_if_timeout_expired(const std::string &message, const std::string &file, const int line)
Checks the RequestServiceTimer to determine if the time spent servicing the request at this point has...