45using std::ostringstream;
46using std::istringstream;
49#define prolog string("FoDapCovJsonTransform::").append(__func__).append("() - ")
51#include <libdap/DDS.h>
52#include <libdap/Structure.h>
53#include <libdap/Constructor.h>
54#include <libdap/Array.h>
55#include <libdap/Grid.h>
56#include <libdap/Sequence.h>
57#include <libdap/Float64.h>
58#include <libdap/Str.h>
59#include <libdap/Url.h>
62#include <BESInternalError.h>
63#include <DapFunctionUtils.h>
64#include <RequestServiceTimer.h>
65#include "FoDapCovJsonTransform.h"
66#include "focovjson_utils.h"
67#include "FoCovJsonRequestHandler.h"
70#define FoDapCovJsonTransform_debug_key "focovjson"
73bool FoDapCovJsonTransform::canConvert()
82cerr<<
"Before X and Y and Z and T"<<endl;
83cerr<<
"Number of parameters is "<<this->parameters.size() <<endl;
84cerr<<
"shapeVals is "<<shapeVals.size() <<endl;
85cerr<<
"Number of Axis is "<<this->axes.size() <<endl;
86for (
int i = 0; i <this->axes.size(); i++) {
87cerr<<
"Axis name is "<<this->axes[i]->name << endl;
88cerr<<
"Axis value is "<<this->axes[i]->values << endl;
94 if(
true == is_simple_cf_geographic) {
106 if(xExists && yExists && zExists && tExists) {
108 if (shapeVals.size() < 4)
113 if((shapeVals[0] > 1) && (shapeVals[1] > 1) && (shapeVals[2] >= 1) && (shapeVals[3] >= 0)) {
120 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] >= 1) && ((shapeVals[3] <= 1) && (shapeVals[3] >= 0))) {
121 domainType =
"Vertical Profile";
129 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1) && (shapeVals[3] >= 0)) {
130 domainType =
"Point Series";
136 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1) && (shapeVals[3] == 1)) {
137 domainType =
"Point";
148 else if(xExists && yExists && !zExists && tExists) {
150 if (shapeVals.size() < 3)
162 if((shapeVals[0] >= 1) && (shapeVals[1] >= 1) && (shapeVals[2] >= 0)) {
171 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] >= 0)) {
172 domainType =
"Point Series";
178 else if((shapeVals[0] == 1) && (shapeVals[1] == 1) && (shapeVals[2] == 1)) {
179 domainType =
"Point";
189 else if(xExists && yExists && !zExists && !tExists) {
191 if (shapeVals.size() < 2)
196 if((shapeVals[0] > 1) && (shapeVals[1] > 1)) {
203 else if((shapeVals[0] == 1) && (shapeVals[1] == 1)) {
204 domainType =
"Point";
216unsigned int FoDapCovJsonTransform::covjsonSimpleTypeArrayWorker(ostream *strm, T *values,
unsigned int indx,
217 vector<unsigned int> *shape,
unsigned int currentDim,
bool is_axis_t_sgeo,libdap::Type a_type)
219 unsigned int currentDimSize = (*shape)[currentDim];
225 for(
unsigned int i = 0; i < currentDimSize; i++) {
226 if(currentDim < shape->size() - 1) {
227 BESDEBUG(FoDapCovJsonTransform_debug_key,
228 "covjsonSimpleTypeArrayWorker() - Recursing! indx: " << indx <<
" currentDim: " << currentDim <<
" currentDimSize: " << currentDimSize << endl);
229 indx = covjsonSimpleTypeArrayWorker<T>(strm, values, indx, shape, currentDim + 1,is_axis_t_sgeo,a_type);
230 if(i + 1 != currentDimSize) {
238 if(
typeid(T) ==
typeid(
string)) {
240 string val =
reinterpret_cast<string*
>(values)[indx++];
241 *strm <<
"\"" << focovjson::escape_for_covjson(val) <<
"\"";
247 std::ostringstream tmp_stream;
248 long long tmp_value = 0;
250 case libdap::dods_byte_c: {
251 unsigned char tmp_byte_value =
reinterpret_cast<unsigned char *
>(values)[indx++];
252 tmp_value = (
long long) tmp_byte_value;
256 case libdap::dods_uint16_c: {
257 unsigned short tmp_uint16_value =
reinterpret_cast<unsigned short *
>(values)[indx++];
258 tmp_value = (
long long) tmp_uint16_value;
262 case libdap::dods_int16_c: {
263 short tmp_int16_value =
reinterpret_cast<short *
>(values)[indx++];
264 tmp_value = (
long long) tmp_int16_value;
268 case libdap::dods_uint32_c: {
269 unsigned int tmp_uint_value =
reinterpret_cast<unsigned int *
>(values)[indx++];
270 tmp_value = (
long long) tmp_uint_value;
274 case libdap::dods_int32_c: {
275 int tmp_int_value =
reinterpret_cast<int *
>(values)[indx++];
276 tmp_value = (
long long) tmp_int_value;
280 case libdap::dods_float32_c: {
281 float tmp_float_value =
reinterpret_cast<float *
>(values)[indx++];
283 tmp_value = (
long long) tmp_float_value;
287 case libdap::dods_float64_c: {
288 double tmp_double_value =
reinterpret_cast<double *
>(values)[indx++];
290 tmp_value = (
long long) tmp_double_value;
295 throw BESInternalError(
"Attempt to extract CF time information from an invalid source", __FILE__, __LINE__);
299 axis_t_value = cf_time_to_greg(tmp_value);
301 cerr<<
"time value is " <<axis_t_value <<endl;
302 cerr<<
"CF time unit is "<<axis_t_units <<endl;
304 *strm <<
"\"" << focovjson::escape_for_covjson(axis_t_value) <<
"\"";
307 *strm << values[indx++];
316void FoDapCovJsonTransform::covjsonSimpleTypeArray(ostream *strm, libdap::Array *a,
string indent,
bool sendData)
318 string childindent = indent + _indent_increment;
319 bool axisRetrieved =
false;
320 bool parameterRetrieved =
false;
322 currDataType = a->var()->type_name();
328 getAttributes(strm, a->get_attr_table(), a->name(), &axisRetrieved, ¶meterRetrieved);
335 if((axisRetrieved ==
true) && (parameterRetrieved ==
false)) {
336 struct Axis *currAxis;
337 currAxis = axes[axisCount - 1];
339 int numDim = a->dimensions(
true);
340 vector<unsigned int> shape(numDim);
341 long length = focovjson::computeConstrainedShape(a, &shape);
347 bool handle_axis_t_here =
true;
348 if(!is_simple_cf_geographic && currAxis->name.compare(
"t") == 0)
349 handle_axis_t_here =
false;
350 if (handle_axis_t_here) {
353 currAxis->values +=
"\"values\": [";
354 unsigned int indx = 0;
355 vector<T> src(length);
356 a->value(src.data());
359 bool is_time_axis_for_sgeo =
false;
360 if(is_simple_cf_geographic && currAxis->name.compare(
"t") == 0)
361 is_time_axis_for_sgeo =
true;
364 indx = covjsonSimpleTypeArrayWorker(&astrm, src.data(), 0, &shape, 0,is_time_axis_for_sgeo,a->var()->type());
365 currAxis->values += astrm.str();
367 currAxis->values +=
"]";
370 if (length != indx) {
371 BESDEBUG(FoDapCovJsonTransform_debug_key,
372 "covjsonSimpleTypeArray(Axis) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
374 assert(length == indx);
377 currAxis->values +=
"\"values\": []";
383 else if(axisRetrieved ==
false && parameterRetrieved ==
true) {
384 struct Parameter *currParameter;
385 currParameter = parameters[parameterCount - 1];
388 int numDim = a->dimensions(
true);
389 vector<unsigned int> shape(numDim);
390 long length = focovjson::computeConstrainedShape(a, &shape);
396 currParameter->shape +=
"\"shape\": [";
397 for(vector<unsigned int>::size_type i = 0; i < shape.size(); i++) {
399 currParameter->shape +=
", ";
408 istringstream (otemp.str());
409 istringstream (otemp.str()) >> tempVal;
411 shapeVals.push_back(tempVal);
415 if((i == 0) && tExists && is_simple_cf_geographic ==
false) {
417 currParameter->shape +=
"1";
420 currParameter->shape += otemp.str();
423 currParameter->shape +=
"],";
426 currParameter->values +=
"\"values\": [";
427 unsigned int indx = 0;
428 vector<T> src(length);
429 a->value(src.data());
432 indx = covjsonSimpleTypeArrayWorker(&pstrm, src.data(), 0, &shape, 0,
false,a->var()->type());
433 currParameter->values += pstrm.str();
435 currParameter->values +=
"]";
437 if (length != indx) {
438 BESDEBUG(FoDapCovJsonTransform_debug_key,
439 "covjsonSimpleTypeArray(Parameter) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
441 assert(length == indx);
444 currParameter->values +=
"\"values\": []";
449void FoDapCovJsonTransform::covjsonStringArray(ostream *strm, libdap::Array *a,
string indent,
bool sendData)
451 string childindent = indent + _indent_increment;
452 bool axisRetrieved =
false;
453 bool parameterRetrieved =
false;
455 currDataType = a->var()->type_name();
463 getAttributes(strm, a->get_attr_table(), a->name(), &axisRetrieved, ¶meterRetrieved);
470 if((axisRetrieved ==
true) && (parameterRetrieved ==
false)) {
471 struct Axis *currAxis;
472 currAxis = axes[axisCount - 1];
474 int numDim = a->dimensions(
true);
475 vector<unsigned int> shape(numDim);
476 long length = focovjson::computeConstrainedShape(a, &shape);
478 bool handle_axis_t_here =
true;
479 if(!is_simple_cf_geographic && currAxis->name.compare(
"t") == 0)
480 handle_axis_t_here =
false;
481 if (handle_axis_t_here) {
484 currAxis->values +=
"\"values\": ";
485 unsigned int indx = 0;
487 vector<string> sourceValues;
488 a->value(sourceValues);
491 indx = covjsonSimpleTypeArrayWorker(&astrm, (
string *) (sourceValues.data()), 0, &shape, 0,
false,a->var()->type());
492 currAxis->values += astrm.str();
494 if (length != indx) {
495 BESDEBUG(FoDapCovJsonTransform_debug_key,
496 "covjsonStringArray(Axis) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
498 assert(length == indx);
501 currAxis->values +=
"\"values\": []";
507 else if(axisRetrieved ==
false && parameterRetrieved ==
true) {
508 struct Parameter *currParameter;
509 currParameter = parameters[parameterCount - 1];
511 int numDim = a->dimensions(
true);
512 vector<unsigned int> shape(numDim);
513 long length = focovjson::computeConstrainedShape(a, &shape);
515 currParameter->shape +=
"\"shape\": [";
516 for(vector<unsigned int>::size_type i = 0; i < shape.size(); i++) {
518 currParameter->shape +=
", ";
527 istringstream (otemp.str());
528 istringstream (otemp.str()) >> tempVal;
529 shapeVals.push_back(tempVal);
533 if((i == 0) && tExists && is_simple_cf_geographic ==
false) {
535 currParameter->shape +=
"1";
538 currParameter->shape += otemp.str();
541 currParameter->shape +=
"],";
544 currParameter->values +=
"\"values\": ";
545 unsigned int indx = 0;
547 vector<string> sourceValues;
548 a->value(sourceValues);
551 indx = covjsonSimpleTypeArrayWorker(&pstrm, (
string *) (sourceValues.data()), 0, &shape, 0,
false,a->var()->type());
552 currParameter->values += pstrm.str();
554 if (length != indx) {
555 BESDEBUG(FoDapCovJsonTransform_debug_key,
556 "covjsonStringArray(Parameter) - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
558 assert(length == indx);
561 currParameter->values +=
"\"values\": []";
566void FoDapCovJsonTransform::addAxis(
string name,
string values)
568 struct Axis *newAxis =
new Axis;
570 newAxis->name = name;
571 newAxis->values = values;
573cerr <<
"axis name is "<< name <<endl;
574cerr <<
"axis value is "<< values <<endl;
576 this->axes.push_back(newAxis);
580void FoDapCovJsonTransform::addParameter(
string id,
string name,
string type,
string dataType,
string unit,
581 string longName,
string standardName,
string shape,
string values)
583 struct Parameter *newParameter =
new Parameter;
585 newParameter->id = id;
586 newParameter->name = name;
587 newParameter->type = type;
588 newParameter->dataType = dataType;
589 newParameter->unit = unit;
590 newParameter->longName = longName;
591 newParameter->standardName = standardName;
592 newParameter->shape = shape;
593 newParameter->values = values;
595 this->parameters.push_back(newParameter);
596 this->parameterCount++;
599void FoDapCovJsonTransform::getAttributes(ostream *strm, libdap::AttrTable &attr_table,
string name,
600 bool *axisRetrieved,
bool *parameterRetrieved)
603 string currAxisTimeOrigin;
606 string currStandardName;
611 *axisRetrieved =
false;
612 *parameterRetrieved =
false;
618 if(is_simple_cf_geographic) {
619 getAttributes_simple_cf_geographic(strm,attr_table,name,axisRetrieved,parameterRetrieved);
625 if((name.compare(
"lon") == 0) || (name.compare(
"LON") == 0)
626 || (name.compare(
"longitude") == 0) || (name.compare(
"LONGITUDE") == 0)
627 || (name.compare(
"COADSX") == 0)) {
638 else if((name.compare(
"lat") == 0) || (name.compare(
"LAT") == 0)
639 || (name.compare(
"latitude") == 0) || (name.compare(
"LATITUDE") == 0)
640 || (name.compare(
"COADSY") == 0)) {
651 else if((name.compare(
"lev") == 0) || (name.compare(
"LEV") == 0)
652 || (name.compare(
"height") == 0) || (name.compare(
"HEIGHT") == 0)
653 || (name.compare(
"depth") == 0) || (name.compare(
"DEPTH") == 0)
654 || (name.compare(
"pres") == 0) || (name.compare(
"PRES") == 0)) {
665 else if((name.compare(
"time") == 0) || (name.compare(
"TIME") == 0)) {
681 if(attr_table.get_size() != 0) {
682 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
683 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
685 for(libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
689 switch (attr_table.get_attr_type(at_iter)) {
690 case libdap::Attr_container: {
691 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
693 getAttributes(strm, *atbl, name, axisRetrieved, parameterRetrieved);
697 vector<string> *values = attr_table.get_attr_vector(at_iter);
699 for(vector<string>::size_type i = 0; i < values->size(); i++) {
700 string currName = attr_table.get_name(at_iter);
701 string currValue = (*values)[i];
720 if(currName.compare(
"units") == 0) {
721 currUnit = currValue;
724 if(currAxisName.compare(
"t") == 0) {
725 currAxisTimeOrigin = currValue;
736 else if(currName.compare(
"long_name") == 0) {
737 currLongName = currValue;
740 else if(currName.compare(
"standard_name") == 0) {
741 currStandardName = currValue;
755 if(currAxisName.compare(
"t") == 0) {
756 addAxis(currAxisName,
"\"values\": [\"" + sanitizeTimeOriginString(currAxisTimeOrigin) +
"\"]");
760 addAxis(currAxisName,
"");
769 if((currUnit.find(
"east") != string::npos) || (currUnit.find(
"East") != string::npos) ||
770 (currUnit.find(
"north") != string::npos) || (currUnit.find(
"North") != string::npos)) {
771 coordRefType =
"ProjectedCRS";
774 *axisRetrieved =
true;
777 addParameter(
"", name,
"", currDataType, currUnit, currLongName, currStandardName,
"",
"");
778 *parameterRetrieved =
true;
786void FoDapCovJsonTransform::
787 getAttributes_simple_cf_geographic(ostream *strm, libdap::AttrTable &attr_table,
string name,
788 bool *axisRetrieved,
bool *parameterRetrieved)
793 string currStandardName;
798 *axisRetrieved =
false;
799 *parameterRetrieved =
false;
804 if(axisVar_x.name == name) {
814 else if(axisVar_y.name == name) {
824 else if(axisVar_z.name == name) {
834 else if(axisVar_t.name == name) {
846 for (
unsigned int i = 0; i <par_vars.size(); i++) {
847 if(par_vars[i] == name){
855 if(attr_table.get_size() != 0) {
856 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
857 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
859 for(libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
863 switch (attr_table.get_attr_type(at_iter)) {
864 case libdap::Attr_container: {
865 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
867 getAttributes_simple_cf_geographic(strm, *atbl, name, axisRetrieved, parameterRetrieved);
871 vector<string> *values = attr_table.get_attr_vector(at_iter);
873 for(vector<string>::size_type i = 0; i < values->size(); i++) {
874 string currName = attr_table.get_name(at_iter);
875 string currValue = (*values)[i];
894 if(currName.compare(
"units") == 0)
895 currUnit = currValue;
903 else if(currName.compare(
"long_name") == 0) {
904 currLongName = currValue;
907 else if(currName.compare(
"standard_name") == 0) {
908 currStandardName = currValue;
919 addAxis(currAxisName,
"");
922 if(currAxisName.compare(
"t") == 0)
923 axis_t_units = currUnit;
924 *axisRetrieved =
true;
927 addParameter(
"", name,
"", currDataType, currUnit, currLongName, currStandardName,
"",
"");
928 *parameterRetrieved =
true;
939string FoDapCovJsonTransform::sanitizeTimeOriginString(
string timeOrigin)
959 vector<string> subStrs = {
"hours",
"hour",
"minutes",
"minute",
960 "seconds",
"second",
"since",
" " };
962 string cleanTimeOrigin = timeOrigin;
965 if(timeOrigin.find(
"base_time") != string::npos) {
966 cleanTimeOrigin =
"2020-01-01T12:00:00Z";
969 for(
unsigned int i = 0; i < subStrs.size(); i++)
970 focovjson::removeSubstring(cleanTimeOrigin, subStrs[i]);
973 return cleanTimeOrigin;
977 _dds(dds), _returnAs(
""), _indent_increment(
" "), atomicVals(
""), currDataType(
""), domainType(
"Unknown"),
978 coordRefType(
"GeographicCRS"), xExists(false), yExists(false), zExists(false), tExists(false), isParam(false),
979 isAxis(false), canConvertToCovJson(false), axisCount(0), parameterCount(0),is_simple_cf_geographic(false)
981 if (!_dds)
throw BESInternalError(
"File out COVJSON, null DDS passed to constructor", __FILE__, __LINE__);
986 strm << BESIndent::LMarg <<
"FoDapCovJsonTransform::dump - (" << (
void *)
this <<
")" << endl;
991 BESIndent::UnIndent();
994void FoDapCovJsonTransform::transform(ostream &ostrm,
bool sendData,
bool testOverride)
996 transform(&ostrm, _dds,
"", sendData, testOverride);
999void FoDapCovJsonTransform::transform(ostream *strm, libdap::Constructor *cnstrctr,
string indent,
bool sendData)
1001 vector<libdap::BaseType *> leaves;
1002 vector<libdap::BaseType *> nodes;
1004 libdap::DDS::Vars_iter vi = cnstrctr->var_begin();
1005 libdap::DDS::Vars_iter ve = cnstrctr->var_end();
1009 for(; vi != ve; vi++) {
1010 if((*vi)->send_p()) {
1011 libdap::BaseType *v = *vi;
1012 libdap::Type type = v->type();
1014 if(type == libdap::dods_array_c) {
1015 type = v->var()->type();
1017 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type())) {
1021 leaves.push_back(v);
1026 transformNodeWorker(strm, leaves, nodes, indent, sendData);
1029void FoDapCovJsonTransform::transformNodeWorker(ostream *strm, vector<libdap::BaseType *> leaves,
1030 vector<libdap::BaseType *> nodes,
string indent,
bool sendData)
1033 for(vector<libdap::BaseType *>::size_type l = 0; l < leaves.size(); l++) {
1034 libdap::BaseType *v = leaves[l];
1035 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Processing LEAF: " << v->name() << endl);
1040 transform(strm, v, indent + _indent_increment, sendData);
1044 for(vector<libdap::BaseType *>::size_type n = 0; n < nodes.size(); n++) {
1045 libdap::BaseType *v = nodes[n];
1046 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Processing NODE: " << v->name() << endl);
1051 transform(strm, v, indent + _indent_increment, sendData);
1055void FoDapCovJsonTransform::printCoverageJSON(ostream *strm,
string indent,
bool testOverride)
1061 canConvertToCovJson =
true;
1064 canConvertToCovJson = canConvert();
1068 if(canConvertToCovJson) {
1071 printCoverage(strm, indent);
1075 throw BESInternalError(
"File cannot be converted to CovJSON format due to missing or incompatible spatial dimensions", __FILE__, __LINE__);
1079void FoDapCovJsonTransform::printCoverage(ostream *strm,
string indent)
1081 string child_indent1 = indent + _indent_increment;
1082 string child_indent2 = child_indent1 + _indent_increment;
1084 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing COVERAGE" << endl);
1086 *strm << indent <<
"{" << endl;
1087 *strm << child_indent1 <<
"\"type\": \"Coverage\"," << endl;
1089 printDomain(strm, child_indent1);
1091 printParameters(strm, child_indent1);
1093 printRanges(strm, child_indent1);
1095 *strm << indent <<
"}" << endl;
1098void FoDapCovJsonTransform::printDomain(ostream *strm,
string indent)
1100 string child_indent1 = indent + _indent_increment;
1102 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing DOMAIN" << endl);
1104 *strm << indent <<
"\"domain\": {" << endl;
1105 *strm << child_indent1 <<
"\"type\" : \"Domain\"," << endl;
1106 *strm << child_indent1 <<
"\"domainType\": \"" + domainType +
"\"," << endl;
1109 printAxes(strm, child_indent1);
1112 printReference(strm, child_indent1);
1114 *strm << indent <<
"}," << endl;
1117void FoDapCovJsonTransform::printAxes(ostream *strm,
string indent)
1119 string child_indent1 = indent + _indent_increment;
1120 string child_indent2 = child_indent1 + _indent_increment;
1122 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing AXES" << endl);
1126 std::vector<std::string> t_bnd_val;
1127 if(axisVar_t_bnd_val.size() >0) {
1128 t_bnd_val.resize(axisVar_t_bnd_val.size());
1129 for (
unsigned i = 0; i < axisVar_t_bnd_val.size();i++) {
1130 t_bnd_val[i] = cf_time_to_greg((
long long)(axisVar_t_bnd_val[i]));
1138 std::vector<std::string> x_bnd_val;
1139 if(axisVar_x_bnd_val.empty() ==
false) {
1140 x_bnd_val.resize(axisVar_x_bnd_val.size());
1141 for (
unsigned i = 0; i < axisVar_x_bnd_val.size();i++) {
1142 ostringstream temp_strm;
1143 temp_strm<<axisVar_x_bnd_val[i];
1144 x_bnd_val[i] = temp_strm.str();
1152 std::vector<std::string> y_bnd_val;
1153 if(axisVar_y_bnd_val.empty() ==
false) {
1154 y_bnd_val.resize(axisVar_y_bnd_val.size());
1155 for (
unsigned i = 0; i < axisVar_y_bnd_val.size();i++) {
1156 ostringstream temp_strm;
1157 temp_strm<<axisVar_y_bnd_val[i];
1158 y_bnd_val[i] = temp_strm.str();
1166 std::vector<std::string> z_bnd_val;
1167 if(axisVar_z_bnd_val.empty() ==
false) {
1168 z_bnd_val.resize(axisVar_z_bnd_val.size());
1169 for (
unsigned i = 0; i < axisVar_z_bnd_val.size();i++) {
1170 ostringstream temp_strm;
1171 temp_strm<<axisVar_z_bnd_val[i];
1172 z_bnd_val[i] = temp_strm.str();
1183 *strm << indent <<
"\"axes\": {" << endl;
1184 for(
unsigned int i = 0; i < axisCount; i++) {
1185 for(
unsigned int j = 0; j < axisCount; j++) {
1189 if(xExists && yExists && zExists && tExists) {
1190 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1191 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1192 *strm << child_indent2 << axes[j]->values << endl;
1193 print_bound(strm, x_bnd_val,child_indent2,
false);
1195 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1196 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1197 *strm << child_indent2 << axes[j]->values << endl;
1198 print_bound(strm, y_bnd_val,child_indent2,
false);
1200 else if((i == 2) && (axes[j]->name.compare(
"z") == 0)) {
1201 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1202 *strm << child_indent2 << axes[j]->values << endl;
1203 print_bound(strm, z_bnd_val,child_indent2,
false);
1205 else if((i == 3) && (axes[j]->name.compare(
"t") == 0)) {
1206 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1207 *strm << child_indent2 << axes[j]->values << endl;
1208 print_bound(strm, t_bnd_val,child_indent2,
true);
1212 else if(xExists && yExists && !zExists && tExists) {
1213 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1214 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1215 *strm << child_indent2 << axes[j]->values << endl;
1216 print_bound(strm, x_bnd_val,child_indent2,
false);
1218 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1219 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1220 *strm << child_indent2 << axes[j]->values << endl;
1221 print_bound(strm, y_bnd_val,child_indent2,
false);
1223 else if((i == 2) && (axes[j]->name.compare(
"t") == 0)) {
1224 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1225 *strm << child_indent2 << axes[j]->values << endl;
1226 print_bound(strm, t_bnd_val,child_indent2,
true);
1230 else if(xExists && yExists && !zExists && !tExists) {
1231 if((i == 0) && (axes[j]->name.compare(
"x") == 0)) {
1232 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1233 *strm << child_indent2 << axes[j]->values << endl;
1234 print_bound(strm, x_bnd_val,child_indent2,
false);
1236 else if((i == 1) && (axes[j]->name.compare(
"y") == 0)) {
1237 *strm << child_indent1 <<
"\"" << axes[j]->name <<
"\": {" << endl;
1238 *strm << child_indent2 << axes[j]->values << endl;
1239 print_bound(strm, y_bnd_val,child_indent2,
false);
1243 if(i == axisCount - 1) {
1244 *strm << child_indent1 <<
"}" << endl;
1247 *strm << child_indent1 <<
"}," << endl;
1250 *strm << indent <<
"}," << endl;
1253void FoDapCovJsonTransform::printReference(ostream *strm,
string indent)
1255 string child_indent1 = indent + _indent_increment;
1256 string child_indent2 = child_indent1 + _indent_increment;
1259 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing REFERENCES" << endl);
1262 coordVars +=
"\"x\"";
1266 if(!coordVars.empty()) {
1269 coordVars +=
"\"y\"";
1273 if(!coordVars.empty()) {
1276 coordVars +=
"\"z\"";
1279 *strm << indent <<
"\"referencing\": [{" << endl;
1283 *strm << child_indent1 <<
"\"coordinates\": [\"t\"]," << endl;
1284 *strm << child_indent1 <<
"\"system\": {" << endl;
1285 *strm << child_indent2 <<
"\"type\": \"TemporalRS\"," << endl;
1286 *strm << child_indent2 <<
"\"calendar\": \"Gregorian\"" << endl;
1287 *strm << child_indent1 <<
"}" << endl;
1288 *strm << indent <<
"}," << endl;
1289 *strm << indent <<
"{" << endl;
1293 *strm << child_indent1 <<
"\"coordinates\": [" << coordVars <<
"]," << endl;
1294 *strm << child_indent1 <<
"\"system\": {" << endl;
1295 *strm << child_indent2 <<
"\"type\": \"" + coordRefType +
"\"," << endl;
1299 if(coordRefType.compare(
"ProjectedCRS") == 0) {
1301 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/EPSG/0/27700\"" << endl;
1304 if(xExists && yExists && zExists) {
1306 if(!is_simple_cf_geographic)
1307 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/EPSG/0/4979\"" << endl;
1311 if(!is_simple_cf_geographic)
1312 *strm << child_indent2 <<
"\"id\": \"http://www.opengis.net/def/crs/OGC/1.3/CRS84\"" << endl;
1316 *strm << child_indent1 <<
"}" << endl;
1317 *strm << indent <<
"}]" << endl;
1320void FoDapCovJsonTransform::printParameters(ostream *strm,
string indent)
1322 string child_indent1 = indent + _indent_increment;
1323 string child_indent2 = child_indent1 + _indent_increment;
1324 string child_indent3 = child_indent2 + _indent_increment;
1325 string child_indent4 = child_indent3 + _indent_increment;
1327 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing PARAMETERS" << endl);
1330 *strm << indent <<
"\"parameters\": {" << endl;
1331 for(
unsigned int i = 0; i < parameterCount; i++) {
1332 *strm << child_indent1 <<
"\"" << parameters[i]->name <<
"\": {" << endl;
1333 *strm << child_indent2 <<
"\"type\": \"Parameter\"," << endl;
1334 *strm << child_indent2 <<
"\"description\": {" << endl;
1336 if(parameters[i]->longName.compare(
"") != 0) {
1337 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->longName <<
"\"" << endl;
1339 else if(parameters[i]->standardName.compare(
"") != 0) {
1340 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->standardName <<
"\"" << endl;
1343 *strm << child_indent3 <<
"\"en\": \"" << parameters[i]->name <<
"\"" << endl;
1346 *strm << child_indent2 <<
"}," << endl;
1347 *strm << child_indent2 <<
"\"unit\": {" << endl;
1348 *strm << child_indent3 <<
"\"label\": {" << endl;
1349 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->unit <<
"\"" << endl;
1350 *strm << child_indent3 <<
"}," << endl;
1351 *strm << child_indent3 <<
"\"symbol\": {" << endl;
1352 *strm << child_indent4 <<
"\"value\": \"" << parameters[i]->unit <<
"\"," << endl;
1353 *strm << child_indent4 <<
"\"type\": \"http://www.opengis.net/def/uom/UCUM/\"" << endl;
1354 *strm << child_indent3 <<
"}" << endl;
1355 *strm << child_indent2 <<
"}," << endl;
1356 *strm << child_indent2 <<
"\"observedProperty\": {" << endl;
1362 if(parameters[i]->standardName.compare(
"") != 0) {
1363 *strm << child_indent3 <<
"\"id\": \"http://vocab.nerc.ac.uk/standard_name/" << parameters[i]->standardName <<
"/\"," << endl;
1371 *strm << child_indent3 <<
"\"label\": {" << endl;
1373 if(parameters[i]->longName.compare(
"") != 0) {
1374 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->longName <<
"\"" << endl;
1376 else if(parameters[i]->standardName.compare(
"") != 0) {
1377 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->standardName <<
"\"" << endl;
1380 *strm << child_indent4 <<
"\"en\": \"" << parameters[i]->name <<
"\"" << endl;
1383 *strm << child_indent3 <<
"}" << endl;
1384 *strm << child_indent2 <<
"}" << endl;
1386 if(i == parameterCount - 1) {
1387 *strm << child_indent1 <<
"}" << endl;
1390 *strm << child_indent1 <<
"}," << endl;
1394 *strm << indent <<
"}," << endl;
1397void FoDapCovJsonTransform::printRanges(ostream *strm,
string indent)
1399 string child_indent1 = indent + _indent_increment;
1400 string child_indent2 = child_indent1 + _indent_increment;
1401 string child_indent3 = child_indent2 + _indent_increment;
1404 BESDEBUG(FoDapCovJsonTransform_debug_key,
"Printing RANGES" << endl);
1407 axisNames +=
"\"t\"";
1411 if(!axisNames.empty()) {
1414 axisNames +=
"\"z\"";
1418 if(!axisNames.empty()) {
1421 axisNames +=
"\"y\"";
1425 if(!axisNames.empty()) {
1428 axisNames +=
"\"x\"";
1432 *strm << indent <<
"\"ranges\": {" << endl;
1433 for(
unsigned int i = 0; i < parameterCount; i++) {
1436 if(parameters[i]->dataType.find(
"int") == 0 || parameters[i]->dataType.find(
"Int") == 0
1437 || parameters[i]->dataType.find(
"integer") == 0 || parameters[i]->dataType.find(
"Integer") == 0) {
1438 dataType =
"integer";
1440 else if(parameters[i]->dataType.find(
"float") == 0 || parameters[i]->dataType.find(
"Float") == 0) {
1443 else if(parameters[i]->dataType.find(
"string") == 0 || parameters[i]->dataType.find(
"String") == 0) {
1444 dataType =
"string";
1447 dataType =
"string";
1452 *strm << child_indent1 <<
"\"" << parameters[i]->name <<
"\": {" << endl;
1453 *strm << child_indent2 <<
"\"type\": \"NdArray\"," << endl;
1454 *strm << child_indent2 <<
"\"dataType\": \"" << dataType <<
"\", " << endl;
1455 *strm << child_indent2 <<
"\"axisNames\": [" << axisNames <<
"]," << endl;
1456 *strm << child_indent2 << parameters[i]->shape << endl;
1457 *strm << child_indent2 << parameters[i]->values << endl;
1459 if(i == parameterCount - 1) {
1460 *strm << child_indent1 <<
"}" << endl;
1463 *strm << child_indent1 <<
"}," << endl;
1467 *strm << indent <<
"}" << endl;
1470void FoDapCovJsonTransform::transform(ostream *strm, libdap::DDS *dds,
string indent,
bool sendData,
bool testOverride)
1473 vector<libdap::BaseType *> leaves;
1474 vector<libdap::BaseType *> nodes;
1476 libdap::DDS::Vars_iter vi = dds->var_begin();
1477 libdap::DDS::Vars_iter ve = dds->var_end();
1478 for(; vi != ve; vi++) {
1479 if((*vi)->send_p()) {
1480 libdap::BaseType *v = *vi;
1481 libdap::Type type = v->type();
1482 if(type == libdap::dods_array_c) {
1483 type = v->var()->type();
1485 if(v->is_constructor_type() || (v->is_vector_type() && v->var()->is_constructor_type())) {
1489 leaves.push_back(v);
1494 if(FoCovJsonRequestHandler::get_simple_geo()) {
1496 vi = dds->var_begin();
1497 ve = dds->var_end();
1502 bool has_axis_var_x =
false;
1503 short axis_var_x_count = 0;
1504 bool has_axis_var_y =
false;
1505 short axis_var_y_count = 0;
1506 bool has_axis_var_z =
false;
1507 short axis_var_z_count = 0;
1508 bool has_axis_var_t =
false;
1509 short axis_var_t_count = 0;
1511 string units_name =
"units";
1512 for(; vi != ve; vi++) {
1514 if((*vi)->send_p()) {
1515 libdap::BaseType *v = *vi;
1516 libdap::Type type = v->type();
1519 if(type == libdap::dods_array_c) {
1520 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
1521 int d_ndims = d_a->dimensions();
1525 libdap::AttrTable &attrs = d_a->get_attr_table();
1526 unsigned int num_attrs = attrs.get_size();
1528 libdap::AttrTable::Attr_iter i = attrs.attr_begin();
1529 libdap::AttrTable::Attr_iter e = attrs.attr_end();
1530 for (; i != e; i++) {
1531 string attr_name = attrs.get_name(i);
1533 unsigned int num_vals = attrs.get_attr_num(i);
1534 if (num_vals == 1) {
1536 bool is_attr_units =
false;
1537 if((attr_name.size() == units_name.size())
1538 && (attr_name.compare(units_name) == 0))
1539 is_attr_units =
true;
1540 if(is_attr_units ==
false)
1541 if(attr_name.size() == (units_name.size()+1) &&
1542 attr_name[units_name.size()] ==
'\0' &&
1543 attr_name.compare(0,units_name.size(),units_name) ==0)
1544 is_attr_units =
true;
1546 if (is_attr_units) {
1547 string val = attrs.get_attr(i,0);
1548 vector<string> unit_candidates;
1553 unit_candidates.push_back(
"degrees_east");
1554 has_axis_var_x = check_add_axis(d_a,val,unit_candidates,axisVar_x,
false);
1555 if (
true == has_axis_var_x) {
1557 if (axis_var_x_count ==2)
1560 unit_candidates.clear();
1563 unit_candidates.push_back(
"degrees_north");
1564 has_axis_var_y = check_add_axis(d_a,val,unit_candidates,axisVar_y,
false);
1565 if (
true == has_axis_var_y) {
1567 if (axis_var_y_count == 2)
1570 unit_candidates.clear();
1573 unit_candidates.push_back(
"hpa");
1574 unit_candidates.push_back(
"hPa");
1575 unit_candidates.push_back(
"meter");
1576 unit_candidates.push_back(
"m");
1577 unit_candidates.push_back(
"km");
1578 has_axis_var_z = check_add_axis(d_a,val,unit_candidates,axisVar_z,
false);
1579 if (
true == has_axis_var_z) {
1581 if (axis_var_z_count == 2)
1584 unit_candidates.clear();
1586for(
int i = 0; i <unit_candidates.size(); i++)
1587 cerr<<
"unit_candidates[i] is "<<unit_candidates[i] <<endl;
1591 unit_candidates.push_back(
"seconds since ");
1592 unit_candidates.push_back(
"minutes since ");
1593 unit_candidates.push_back(
"hours since ");
1594 unit_candidates.push_back(
"days since ");
1596for(
int i = 0; i <unit_candidates.size(); i++)
1597cerr<<
"unit_candidates[i] again is "<<unit_candidates[i] <<endl;
1600 has_axis_var_t = check_add_axis(d_a,val,unit_candidates,axisVar_t,
true);
1602 if (
true == has_axis_var_t) {
1604 if (axis_var_t_count == 2)
1607 unit_candidates.clear();
1619cerr<<
"axis_var_x_count is "<< axis_var_x_count <<endl;
1620cerr<<
"axis_var_y_count is "<< axis_var_y_count <<endl;
1621cerr<<
"axis_var_z_count is "<< axis_var_z_count <<endl;
1622cerr<<
"axis_var_t_count is "<< axis_var_t_count <<endl;
1624 bool is_simple_geo_candidate =
true;
1625 if(axis_var_x_count !=1 || axis_var_y_count !=1)
1626 is_simple_geo_candidate =
false;
1629 if(axis_var_z_count > 1) {
1631 axisVar_z.dim_name =
"";
1632 axisVar_z.bound_name =
"";
1634 if(axis_var_t_count > 1) {
1636 axisVar_t.dim_name =
"";
1637 axisVar_t.bound_name =
"";
1639 if(is_simple_geo_candidate ==
true) {
1645 map<string, string> vname_bname;
1647 check_bounds(dds,vname_bname);
1649 map<string, string>::iterator it;
1651for(it = vname_bname.begin(); it != vname_bname.end(); it++) {
1652cerr<<it->first <<endl;
1653cerr<<it->second <<endl;
1657 for(it = vname_bname.begin(); it != vname_bname.end(); it++) {
1660 if(axisVar_x.name == it->first)
1661 axisVar_x.bound_name = it->second;
1662 else if(axisVar_y.name == it->first)
1663 axisVar_y.bound_name = it->second;
1664 else if(axisVar_z.name == it->first)
1665 axisVar_z.bound_name = it->second;
1666 else if(axisVar_t.name == it->first)
1667 axisVar_t.bound_name = it->second;
1670cerr<<
"axisVar_x.name is "<<axisVar_x.name <<endl;
1671cerr<<
"axisVar_x.dim_name is "<<axisVar_x.dim_name <<endl;
1672cerr<<
"axisVar_x.dim_size is "<<axisVar_x.dim_size <<endl;
1673cerr<<
"axisVar_x.bound_name is "<<axisVar_x.bound_name <<endl;
1675cerr<<
"axisVar_y.name is "<<axisVar_y.name <<endl;
1676cerr<<
"axisVar_y.dim_name is "<<axisVar_y.dim_name <<endl;
1677cerr<<
"axisVar_y.dim_size is "<<axisVar_y.dim_size <<endl;
1678cerr<<
"axisVar_y.bound_name is "<<axisVar_y.bound_name <<endl;
1680cerr<<
"axisVar_z.name is "<<axisVar_z.name <<endl;
1681cerr<<
"axisVar_z.dim_name is "<<axisVar_z.dim_name <<endl;
1682cerr<<
"axisVar_z.dim_size is "<<axisVar_z.dim_size <<endl;
1683cerr<<
"axisVar_z.bound_name is "<<axisVar_z.bound_name <<endl;
1685cerr<<
"axisVar_t.name is "<<axisVar_t.name <<endl;
1686cerr<<
"axisVar_t.dim_name is "<<axisVar_t.dim_name <<endl;
1687cerr<<
"axisVar_t.dim_size is "<<axisVar_t.dim_size <<endl;
1688cerr<<
"axisVar_t.bound_name is "<<axisVar_t.bound_name <<endl;
1692 is_simple_cf_geographic = obtain_valid_vars(dds,axis_var_z_count,axis_var_t_count);
1694 if(
true == is_simple_cf_geographic) {
1702 string x_bnd_dim_name;
1703 string y_bnd_dim_name;
1704 string z_bnd_dim_name;
1705 string t_bnd_dim_name;
1707 obtain_bound_values(dds,axisVar_x,axisVar_x_bnd_val, x_bnd_dim_name,sendData);
1708 obtain_bound_values(dds,axisVar_y,axisVar_y_bnd_val, y_bnd_dim_name,sendData);
1709 obtain_bound_values(dds,axisVar_z,axisVar_z_bnd_val, z_bnd_dim_name,sendData);
1710 obtain_bound_values(dds,axisVar_t,axisVar_t_bnd_val, t_bnd_dim_name,sendData);
1712 if(x_bnd_dim_name!=
"")
1713 bnd_dim_names.push_back(x_bnd_dim_name);
1714 else if(y_bnd_dim_name!=
"")
1715 bnd_dim_names.push_back(y_bnd_dim_name);
1716 else if(z_bnd_dim_name!=
"")
1717 bnd_dim_names.push_back(z_bnd_dim_name);
1718 else if(t_bnd_dim_name!=
"")
1719 bnd_dim_names.push_back(t_bnd_dim_name);
1727 transformNodeWorker(strm, leaves, nodes, indent + _indent_increment + _indent_increment, sendData);
1734 printCoverageJSON(strm, indent, testOverride);
1737void FoDapCovJsonTransform::transform(ostream *strm, libdap::BaseType *bt,
string indent,
bool sendData)
1739 switch(bt->type()) {
1741 case libdap::dods_byte_c:
1742 case libdap::dods_int16_c:
1743 case libdap::dods_uint16_c:
1744 case libdap::dods_int32_c:
1745 case libdap::dods_uint32_c:
1746 case libdap::dods_float32_c:
1747 case libdap::dods_float64_c:
1748 case libdap::dods_str_c:
1749 case libdap::dods_url_c:
1750 transformAtomic(bt, indent, sendData);
1753 case libdap::dods_structure_c:
1754 transform(strm, (libdap::Structure *) bt, indent, sendData);
1757 case libdap::dods_grid_c:
1758 transform(strm, (libdap::Grid *) bt, indent, sendData);
1761 case libdap::dods_sequence_c:
1762 transform(strm, (libdap::Sequence *) bt, indent, sendData);
1765 case libdap::dods_array_c:
1766 transform(strm, (libdap::Array *) bt, indent, sendData);
1769 case libdap::dods_int8_c:
1770 case libdap::dods_uint8_c:
1771 case libdap::dods_int64_c:
1772 case libdap::dods_uint64_c:
1773 case libdap::dods_enum_c:
1774 case libdap::dods_group_c: {
1775 string s = (string)
"File out COVJSON, DAP4 types not yet supported.";
1781 string s = (string)
"File out COVJSON, Unrecognized type.";
1788void FoDapCovJsonTransform::transformAtomic(libdap::BaseType *b,
string indent,
bool sendData)
1790 string childindent = indent + _indent_increment;
1791 struct Axis *newAxis =
new Axis;
1794 newAxis->name =
"test";
1796 newAxis->values +=
"\"values\": [";
1797 if(b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c) {
1798 libdap::Str *strVar = (libdap::Str *) b;
1799 string tmpString = strVar->value();
1800 newAxis->values +=
"\"";
1801 newAxis->values += focovjson::escape_for_covjson(tmpString);
1802 newAxis->values +=
"\"";
1805 ostringstream otemp;
1806 istringstream itemp;
1808 b->print_val(otemp,
"",
false);
1809 istringstream (otemp.str());
1810 istringstream (otemp.str()) >> tempVal;
1811 newAxis->values += otemp.str();
1813 newAxis->values +=
"]";
1816 newAxis->values +=
"\"values\": []";
1819 axes.push_back(newAxis);
1823void FoDapCovJsonTransform::transform(ostream *strm, libdap::Array *a,
string indent,
bool sendData)
1825 BESDEBUG(FoDapCovJsonTransform_debug_key,
1826 "FoCovJsonTransform::transform() - Processing Array. " <<
" a->type(): " << a->type() <<
" a->var()->type(): " << a->var()->type() << endl);
1828 switch(a->var()->type()) {
1830 case libdap::dods_byte_c:
1831 covjsonSimpleTypeArray<libdap::dods_byte>(strm, a, indent, sendData);
1834 case libdap::dods_int16_c:
1835 covjsonSimpleTypeArray<libdap::dods_int16>(strm, a, indent, sendData);
1838 case libdap::dods_uint16_c:
1839 covjsonSimpleTypeArray<libdap::dods_uint16>(strm, a, indent, sendData);
1842 case libdap::dods_int32_c:
1843 covjsonSimpleTypeArray<libdap::dods_int32>(strm, a, indent, sendData);
1846 case libdap::dods_uint32_c:
1847 covjsonSimpleTypeArray<libdap::dods_uint32>(strm, a, indent, sendData);
1850 case libdap::dods_float32_c:
1851 covjsonSimpleTypeArray<libdap::dods_float32>(strm, a, indent, sendData);
1854 case libdap::dods_float64_c:
1855 covjsonSimpleTypeArray<libdap::dods_float64>(strm, a, indent, sendData);
1858 case libdap::dods_str_c: {
1859 covjsonStringArray(strm, a, indent, sendData);
1863 case libdap::dods_url_c: {
1864 covjsonStringArray(strm, a, indent, sendData);
1868 case libdap::dods_structure_c:
1869 throw BESInternalError(
"File out COVJSON, Arrays of Structure objects not a supported return type.", __FILE__, __LINE__);
1871 case libdap::dods_grid_c:
1872 throw BESInternalError(
"File out COVJSON, Arrays of Grid objects not a supported return type.", __FILE__, __LINE__);
1874 case libdap::dods_sequence_c:
1875 throw BESInternalError(
"File out COVJSON, Arrays of Sequence objects not a supported return type.", __FILE__, __LINE__);
1877 case libdap::dods_array_c:
1878 throw BESInternalError(
"File out COVJSON, Arrays of Array objects not a supported return type.", __FILE__, __LINE__);
1880 case libdap::dods_int8_c:
1881 case libdap::dods_uint8_c:
1882 case libdap::dods_int64_c:
1883 case libdap::dods_uint64_c:
1884 case libdap::dods_enum_c:
1885 case libdap::dods_group_c:
1886 throw BESInternalError(
"File out COVJSON, DAP4 types not yet supported.", __FILE__, __LINE__);
1889 throw BESInternalError(
"File out COVJSON, Unrecognized type.", __FILE__, __LINE__);
1893bool 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) {
1895 bool ret_value =
false;
1896 for (
unsigned i = 0; i < CF_unit_values.size(); i++) {
1898 bool is_cf_units =
false;
1899 if(is_t_axis ==
false) {
1900 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)
1904 if(unit_value.compare(0,CF_unit_values[i].size(),CF_unit_values[i])==0)
1909 libdap::Array::Dim_iter di = d_a->dim_begin();
1910 this_axisVar.dim_size = d_a->dimension_size(di,
true);
1911 this_axisVar.name = d_a->name();
1912 this_axisVar.dim_name = d_a->dimension_name(di);
1913 this_axisVar.bound_name=
"";
1916cerr<<
"axis size "<< this_axisVar.dim_size <<endl;
1917cerr<<
"axis name "<< this_axisVar.name <<endl;
1918cerr<<
"axis dim_name "<< this_axisVar.dim_name <<endl;
1929void FoDapCovJsonTransform::check_bounds(libdap::DDS *dds, map<string,string>& vname_bname) {
1931 string bound_name =
"bounds";
1932 libdap::DDS::Vars_iter vi = dds->var_begin();
1933 libdap::DDS::Vars_iter ve = dds->var_end();
1935 for(; vi != ve; vi++) {
1937 if((*vi)->send_p()) {
1938 libdap::BaseType *v = *vi;
1939 libdap::Type type = v->type();
1942 if(type == libdap::dods_array_c) {
1943 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
1944 int d_ndims = d_a->dimensions();
1947 libdap::AttrTable &attrs = d_a->get_attr_table();
1948 unsigned int num_attrs = attrs.get_size();
1950 libdap::AttrTable::Attr_iter i = attrs.attr_begin();
1951 libdap::AttrTable::Attr_iter e = attrs.attr_end();
1952 for (; i != e; i++) {
1953 string attr_name = attrs.get_name(i);
1955 unsigned int num_vals = attrs.get_attr_num(i);
1956 if (num_vals == 1) {
1958 bool is_attr_bounds =
false;
1959 if((attr_name.size() == bound_name.size())
1960 && (attr_name.compare(bound_name) == 0))
1961 is_attr_bounds =
true;
1962 if(is_attr_bounds ==
false)
1963 if(attr_name.size() == (bound_name.size()+1) &&
1964 attr_name[bound_name.size()] ==
'\0' &&
1965 attr_name.compare(0,bound_name.size(),bound_name) ==0)
1966 is_attr_bounds =
true;
1968 if (is_attr_bounds) {
1969 string val = attrs.get_attr(i,0);
1970 vname_bname[d_a->name()] = val;
1981void FoDapCovJsonTransform::obtain_bound_values(libdap::DDS *dds,
const axisVar & av, std::vector<float>& av_bnd_val, std::string& bnd_dim_name,
bool sendData) {
1984 libdap::Array* d_a = obtain_bound_values_worker(dds, av.bound_name,bnd_dim_name);
1990 if(d_a->var()->type_name() ==
"Float64") {
1992 int num_lengths = d_a->length();
1993 vector<double>temp_val;
1994 temp_val.resize(num_lengths);
1995 d_a->value(temp_val.data());
1997 av_bnd_val.resize(num_lengths);
1998 for (
unsigned i = 0; i <av_bnd_val.size();i++)
1999 av_bnd_val[i] =(
float)temp_val[i];
2002for (
int i = 0; i <av_bnd_val.size();i++)
2003cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2007 else if(d_a->var()->type_name() ==
"Float32") {
2009 int num_lengths = d_a->length();
2010 av_bnd_val.resize(num_lengths);
2011 d_a->value(av_bnd_val.data());
2013for (
int i = 0; i <av_bnd_val.size();i++)
2014cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2023void FoDapCovJsonTransform::obtain_bound_values(libdap::DDS *dds,
const axisVar & av, std::vector<double>& av_bnd_val, std::string& bnd_dim_name,
bool sendData) {
2025 libdap::Array* d_a = obtain_bound_values_worker(dds, av.bound_name,bnd_dim_name);
2028cerr<<
"d_a->name in obtain_bound_values is "<<d_a->name() <<endl;
2029cerr<<
"in obtain_bound_values bnd_dim_name is "<<bnd_dim_name <<endl;
2031 if(d_a->var()->type_name() ==
"Float64") {
2033 int num_lengths = d_a->length();
2034 av_bnd_val.resize(num_lengths);
2035 d_a->value(av_bnd_val.data());
2037for (
int i = 0; i <av_bnd_val.size();i++)
2038cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2042 else if(d_a->var()->type_name() ==
"Float32") {
2044 int num_lengths = d_a->length();
2045 vector<float>temp_val;
2046 temp_val.resize(num_lengths);
2047 d_a->value(temp_val.data());
2048 av_bnd_val.resize(num_lengths);
2049 for (
unsigned i = 0; i <av_bnd_val.size();i++)
2050 av_bnd_val[i] =(
double)temp_val[i];
2052for (
int i = 0; i <av_bnd_val.size();i++)
2053cerr<<
"av_bnd_val["<<i<<
"] = "<<av_bnd_val[i] <<endl;
2060libdap::Array* FoDapCovJsonTransform::obtain_bound_values_worker(libdap::DDS *dds,
const string& bnd_name,
string & bnd_dim_name) {
2062 libdap::Array* d_a =
nullptr;
2065 libdap::DDS::Vars_iter vi = dds->var_begin();
2066 libdap::DDS::Vars_iter ve = dds->var_end();
2068 for(; vi != ve; vi++) {
2070 if((*vi)->send_p()) {
2071 libdap::BaseType *v = *vi;
2072 libdap::Type type = v->type();
2075 if(type == libdap::dods_array_c) {
2076 libdap::Array * td_a =
dynamic_cast<libdap::Array *
>(v);
2077 int d_ndims = td_a->dimensions();
2080 string tmp_bnd_dim_name;
2081 int bound_dim_size = 0;
2083 libdap::Array::Dim_iter di = td_a->dim_begin();
2084 libdap::Array::Dim_iter de = td_a->dim_end();
2085 for (; di != de; di++) {
2086 if(dim_count == 1) {
2087 bound_dim_size = td_a->dimension_size(di,
true);
2088 tmp_bnd_dim_name = td_a->dimension_name(di);
2095 if((bound_dim_size == 2) && (td_a->name() == bnd_name)) {
2097 bnd_dim_name = tmp_bnd_dim_name;
2111bool FoDapCovJsonTransform::obtain_valid_vars(libdap::DDS *dds,
short axis_var_z_count,
short axis_var_t_count ) {
2114 bool ret_value =
true;
2115 std::vector<std::string> temp_x_y_vars;
2116 std::vector<std::string> temp_x_y_z_vars;
2117 std::vector<std::string> temp_x_y_t_vars;
2118 std::vector<std::string> temp_x_y_z_t_vars;
2120 libdap::DDS::Vars_iter vi = dds->var_begin();
2121 libdap::DDS::Vars_iter ve = dds->var_end();
2122 for(; vi != ve; vi++) {
2123 if((*vi)->send_p()) {
2124 libdap::BaseType *v = *vi;
2125 libdap::Type type = v->type();
2126 if(type == libdap::dods_array_c) {
2127 libdap::Array * d_a =
dynamic_cast<libdap::Array *
>(v);
2128 int d_ndims = d_a->dimensions();
2132 short axis_x_count = 0;
2133 short axis_y_count = 0;
2134 short axis_z_count = 0;
2135 short axis_t_count = 0;
2136 bool non_xyzt_dim =
false;
2137 bool supported_var =
true;
2139 libdap::Array::Dim_iter di = d_a->dim_begin();
2140 libdap::Array::Dim_iter de = d_a->dim_end();
2142 for (; di != de; di++) {
2144 if((d_a->dimension_size(di,
true) == axisVar_x.dim_size) &&
2145 (d_a->dimension_name(di) == axisVar_x.dim_name))
2147 else if((d_a->dimension_size(di,
true) == axisVar_y.dim_size) &&
2148 (d_a->dimension_name(di) == axisVar_y.dim_name))
2150 else if((d_a->dimension_size(di,
true) == axisVar_z.dim_size) &&
2151 (d_a->dimension_name(di) == axisVar_z.dim_name))
2153 else if((d_a->dimension_size(di,
true) == axisVar_t.dim_size) &&
2154 (d_a->dimension_name(di) == axisVar_t.dim_name))
2157 non_xyzt_dim =
true;
2162 if(non_xyzt_dim || axis_x_count >1 || axis_y_count >1 || axis_z_count >1 || axis_t_count >1) {
2163 supported_var =
false;
2165 if (FoCovJsonRequestHandler::get_may_ignore_z_axis() ==
false) {
2166 if(d_a->name()!=axisVar_x.bound_name && d_a->name()!=axisVar_y.bound_name &&
2167 d_a->name()!=axisVar_z.bound_name && d_a->name()!=axisVar_t.bound_name)
2176 if(axis_x_count == 1 & axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 0)
2177 temp_x_y_vars.push_back(d_a->name());
2178 else if(axis_x_count == 1 & axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 0)
2179 temp_x_y_z_vars.push_back(d_a->name());
2180 else if(axis_x_count == 1 & axis_y_count == 1 && axis_z_count == 0 && axis_t_count == 1)
2181 temp_x_y_t_vars.push_back(d_a->name());
2182 else if(axis_x_count == 1 & axis_y_count == 1 && axis_z_count == 1 && axis_t_count == 1)
2183 temp_x_y_z_t_vars.push_back(d_a->name());
2185 else if(ret_value ==
false)
2193 if (ret_value ==
true) {
2194 if(FoCovJsonRequestHandler::get_may_ignore_z_axis()==
true) {
2197cerr<<
"coming to ignore mode "<<endl;
2198cerr<<
"axis_var_z_count: "<<axis_var_z_count <<endl;
2199cerr<<
"axis_var_t_count: "<<axis_var_t_count <<endl;
2204 if(axis_var_z_count <=1 && axis_var_t_count <=1) {
2206 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
2207 par_vars.push_back(temp_x_y_vars[i]);
2208 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
2209 par_vars.push_back(temp_x_y_t_vars[i]);
2211 if (temp_x_y_vars.empty()) {
2212 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
2213 par_vars.push_back(temp_x_y_z_vars[i]);
2214 for (
unsigned i = 0; i <temp_x_y_z_t_vars.size(); i++)
2215 par_vars.push_back(temp_x_y_z_t_vars[i]);
2221 if (axis_var_z_count == 1) {
2223 axisVar_z.dim_name =
"";
2224 axisVar_z.bound_name =
"";
2228 else if (axis_var_z_count >1 && axis_var_t_count <=1) {
2230 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
2231 par_vars.push_back(temp_x_y_vars[i]);
2232 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
2233 par_vars.push_back(temp_x_y_t_vars[i]);
2235 else if (axis_var_z_count <=1 && axis_var_t_count >1) {
2237 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
2238 par_vars.push_back(temp_x_y_vars[i]);
2239 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
2240 par_vars.push_back(temp_x_y_z_vars[i]);
2245 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
2246 par_vars.push_back(temp_x_y_vars[i]);
2251 if(axis_var_z_count >1 || axis_var_t_count >1)
2255 for (
unsigned i = 0; i <temp_x_y_vars.size(); i++)
2256 par_vars.push_back(temp_x_y_vars[i]);
2257 for (
unsigned i = 0; i <temp_x_y_z_vars.size(); i++)
2258 par_vars.push_back(temp_x_y_z_vars[i]);
2259 for (
unsigned i = 0; i <temp_x_y_t_vars.size(); i++)
2260 par_vars.push_back(temp_x_y_t_vars[i]);
2261 for (
unsigned i = 0; i <temp_x_y_z_t_vars.size(); i++)
2262 par_vars.push_back(temp_x_y_z_t_vars[i]);
2267cerr<<
"Parameter Names: "<<endl;
2268for(
unsigned i = 0; i <par_vars.size(); i++)
2269 cerr<<par_vars[i]<<endl;
2273 if(par_vars.size() == 0)
2281std::string FoDapCovJsonTransform::cf_time_to_greg(
long long time_val) {
2286 string cf_time= axis_t_units ;
2289 short time_unit_length = -1;
2290 if(cf_time.compare(0,3,
"day") == 0)
2291 time_unit_length = 0;
2292 else if(cf_time.compare(0,4,
"hour") == 0)
2293 time_unit_length = 1;
2294 else if(cf_time.compare(0,6,
"minute") == 0)
2295 time_unit_length = 2;
2296 else if(cf_time.compare(0,6,
"second") == 0)
2297 time_unit_length = 3;
2302 vector<string> subStrs = {
"days",
"day",
"hours",
"hour",
"minutes",
"minute",
2303 "seconds",
"second",
"since",
" " };
2305 for(
unsigned int i = 0; i < subStrs.size(); i++)
2306 focovjson::removeSubstring(cf_time, subStrs[i]);
2311 size_t cf_time_space_pos = cf_time.find(
' ');
2312 string cf_date,cf_hms;
2314 if(cf_time_space_pos!=string::npos) {
2315 cf_date= cf_time.substr(0,cf_time_space_pos);
2316 cf_hms = cf_time.substr(cf_time_space_pos+1);
2319 if(cf_hms==
" " || cf_hms==
"")
2323cerr<<
"cf_date is "<<cf_date <<endl;
2324cerr<<
"cf_hms is "<<cf_hms <<endl;
2330 string cf_y,cf_mo,cf_d;
2331 size_t cf_date_dash_pos = cf_date.find(
'-');
2332 if(cf_date_dash_pos !=string::npos) {
2334 cf_y = cf_date.substr(0,cf_date_dash_pos);
2335 cf_md = cf_date.substr(cf_date_dash_pos+1);
2336 size_t cf_md_dash_pos = cf_md.find(
"-");
2337 if(cf_md_dash_pos !=string::npos) {
2338 cf_mo = cf_md.substr(0,cf_md_dash_pos);
2339 cf_d = cf_md.substr(cf_md_dash_pos+1);
2343 string cf_h,cf_ms,cf_m,cf_s;
2344 size_t cf_hms_colon_pos = cf_hms.find(
':');
2345 if(cf_hms_colon_pos !=string::npos) {
2346 cf_h = cf_hms.substr(0,cf_hms_colon_pos);
2347 cf_ms = cf_hms.substr(cf_hms_colon_pos+1);
2348 size_t cf_ms_colon_pos = cf_ms.find(
":");
2349 if(cf_ms_colon_pos !=string::npos) {
2350 cf_m = cf_ms.substr(0,cf_ms_colon_pos);
2351 cf_s = cf_ms.substr(cf_ms_colon_pos+1);
2357cerr<<
"cf_y is "<<cf_y <<endl;
2358cerr<<
"cf_mo is "<<cf_mo <<endl;
2359cerr<<
"cf_d is "<<cf_d <<endl;
2361cerr<<
"cf_h is "<<cf_h <<endl;
2362cerr<<
"cf_m is "<<cf_m <<endl;
2363cerr<<
"cf_s is "<<cf_s <<endl;
2367 int cf_y_i,cf_mo_i,cf_d_i,cf_h_i,cf_m_i,cf_s_i;
2368 cf_y_i = stoi(cf_y);
2369 cf_mo_i = stoi(cf_mo);
2370 cf_d_i = stoi(cf_d);
2371 cf_h_i = stoi(cf_h);
2372 cf_m_i = stoi(cf_m);
2373 cf_s_i = stoi(cf_s);
2376cerr<<
"cf_y_i " <<cf_y_i <<endl;
2377cerr<<
"cf_mo_i " <<cf_mo_i <<endl;
2378cerr<<
"cf_d_i " <<cf_d_i <<endl;
2379cerr<<
"cf_h_i " <<cf_h_i <<endl;
2380cerr<<
"cf_m_i " <<cf_m_i <<endl;
2381cerr<<
"cf_s_i " <<cf_s_i <<endl;
2387 ycf_1.tm_hour = cf_h_i; ycf_1.tm_min = cf_m_i; ycf_1.tm_sec = cf_s_i;
2388 ycf_1.tm_year = cf_y_i-1900; ycf_1.tm_mon = cf_mo_i; ycf_1.tm_mday = cf_d_i;
2392 time_t t_ycf_1 = timegm(&ycf_1);
2395cerr<<
"t_ycf_1 is "<<t_ycf_1 <<endl;
2396cerr<<
"time_val is "<<time_val <<endl;
2404 if(time_unit_length == 0)
2405 t_ycf_2 = t_ycf_1 + 86400*time_val;
2406 else if (time_unit_length == 1)
2407 t_ycf_2 = t_ycf_1 + 3600*time_val;
2408 else if (time_unit_length == 2)
2409 t_ycf_2 = t_ycf_1 + 60*time_val;
2410 else if (time_unit_length == 3)
2411 t_ycf_2 = t_ycf_1 + time_val;
2416 struct tm *t_new_ycf;
2417 struct tm temp_new_ycf;
2426 t_new_ycf = gmtime_r(&t_ycf_2,&temp_new_ycf);
2429cerr<<
"t_new_ycf.tm_year is " <<t_new_ycf->tm_year <<endl;
2430cerr<<
"t_new_ycf.tm_mon is " <<t_new_ycf->tm_mon <<endl;
2431cerr<<
"t_new_ycf.tm_day is " <<t_new_ycf->tm_mday <<endl;
2432cerr<<
"t_new_ycf.tm_hour is " <<t_new_ycf->tm_hour <<endl;
2433cerr<<
"t_new_ycf.tm_min is " <<t_new_ycf->tm_min <<endl;
2434cerr<<
"t_new_ycf.tm_sec is " <<t_new_ycf->tm_sec <<endl;
2436 if(t_new_ycf->tm_mon == 0) {
2437 t_new_ycf->tm_year--;
2438 t_new_ycf->tm_mon = 12;
2441 string covjson_mon = (t_new_ycf->tm_mon<10)?
2442 (
"0"+to_string(t_new_ycf->tm_mon)):
2443 to_string(t_new_ycf->tm_mon);
2444 string covjson_mday = (t_new_ycf->tm_mday<10)?
2445 (
"0"+to_string(t_new_ycf->tm_mday)):
2446 to_string(t_new_ycf->tm_mday);
2448 string covjson_hour = (t_new_ycf->tm_hour<10)?
2449 (
"0"+to_string(t_new_ycf->tm_hour)):
2450 to_string(t_new_ycf->tm_hour);
2452 string covjson_min = (t_new_ycf->tm_min<10)?
2453 (
"0"+to_string(t_new_ycf->tm_min)):
2454 to_string(t_new_ycf->tm_min);
2456 string covjson_sec = (t_new_ycf->tm_sec<10)?
2457 (
"0"+to_string(t_new_ycf->tm_sec)):
2458 to_string(t_new_ycf->tm_sec);
2462 string covjson_time = to_string(1900+t_new_ycf->tm_year)+
"-"+
2463 covjson_mon+
"-"+covjson_mday+
"T"+
2464 covjson_hour+
":"+covjson_min+
":"+
2467 return covjson_time;
2470void FoDapCovJsonTransform::print_bound(ostream *strm,
const std::vector<std::string> & t_bnd_val,
const std::string & indent,
bool is_t_axis)
const {
2472 if(axisVar_t.bound_name !=
"") {
2473 std::string print_values;
2474 if(t_bnd_val.size() >0) {
2475 print_values =
"\"bounds\": [";
2476 for(
unsigned i = 0; i <t_bnd_val.size(); i++) {
2477 string tmpString = t_bnd_val[i];
2480 print_values +=
"\"";
2481 print_values +=focovjson::escape_for_covjson(tmpString);
2482 print_values +=
"\"";
2485 print_values +=tmpString;
2487 if(i !=(t_bnd_val.size()-1))
2488 print_values +=
", ";
2492 print_values +=
"]";
2495 print_values=
"\"bounds\": []";
2496 *strm << indent << print_values <<endl;
exception thrown if internal error encountered
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...