36#include <unordered_map>
37#include <unordered_set>
39#include <libdap/InternalErr.h>
57#include "HDF5CFGeoCF1D.h"
58#include "HDF5CFGeoCFProj.h"
64using namespace HDF5CF;
68void gen_dap_onevar_dds(DDS &dds,
const HDF5CF::Var* var, hid_t file_id,
const string & filename)
70 BESDEBUG(
"h5",
"Coming to gen_dap_onevar_dds() "<<endl);
71 const vector<HDF5CF::Dimension *>& dims = var->
getDimensions();
77 gen_dap_onevar_dds_sca_64bit_int(var, filename);
78 else if (H5FSTRING == var->
getType() || H5VSTRING == var->
getType()) {
82 auto sca_str = sca_str_unique.get();
86 gen_dap_onevar_dds_sca_atomic(dds, var, filename) ;
89 gen_dap_onevar_dds_array(dds, var, file_id, filename,dims);
93void gen_dap_onevar_dds_sca_64bit_int(
const HDF5CF::Var *var,
const string &filename) {
95 DMR * dmr = HDF5RequestHandler::get_dmr_64bit_int();
99 D4Group* root_grp = dmr->root();
100 if (H5INT64 == var->
getType()) {
101 auto sca_int64_unique =
104 auto sca_int64 = sca_int64_unique.release();
105 sca_int64->set_is_dap4(
true);
106 map_cfh5_var_attrs_to_dap4_int64(var,sca_int64);
107 root_grp->add_var_nocopy(sca_int64);
109 else if(H5UINT64 == var->
getType()) {
110 auto sca_uint64_unique =
112 auto sca_uint64 = sca_uint64_unique.release();
113 sca_uint64->set_is_dap4(
true);
114 map_cfh5_var_attrs_to_dap4_int64(var,sca_uint64);
115 root_grp->add_var_nocopy(sca_uint64);
121void gen_dap_onevar_dds_sca_atomic(DDS &dds,
const HDF5CF::Var *var,
const string &filename) {
126 auto sca_uchar_unique =
128 auto sca_uchar = sca_uchar_unique.get();
129 dds.add_var(sca_uchar);
134 auto sca_int16_unique =
136 auto sca_int16 = sca_int16_unique.get();
137 dds.add_var(sca_int16);
141 auto sca_uint16_unique =
143 auto sca_uint16 = sca_uint16_unique.get();
144 dds.add_var(sca_uint16);
148 auto sca_int32_unique =
150 auto sca_int32 = sca_int32_unique.get();
151 dds.add_var(sca_int32);
156 auto sca_uint32_unique =
158 auto sca_uint32 = sca_uint32_unique.get();
159 dds.add_var(sca_uint32);
163 auto sca_float32_unique =
165 auto sca_float32 = sca_float32_unique.get();
166 dds.add_var(sca_float32);
170 auto sca_float64_unique =
172 auto sca_float64 = sca_float64_unique.get();
173 dds.add_var(sca_float64);
177 throw InternalErr(__FILE__, __LINE__,
"unsupported data type.");
181void gen_dap_onevar_dds_array(DDS &dds,
const HDF5CF::Var *var, hid_t file_id,
const string &filename,
182 const vector<HDF5CF::Dimension *>& dims) {
186 bool dap4_int64 =
false;
188 const DMR *dmr = HDF5RequestHandler::get_dmr_64bit_int();
195 BaseType *bt =
nullptr;
197 if (
true == dap4_int64) {
198 if (var->
getType() == H5INT64) {
200 bt = int64_unique.release();
201 }
else if (var->
getType() == H5UINT64) {
203 bt = uint64_unique.release();
209#define HANDLE_CASE(tid, type) \
211 auto type_unique = make_unique<type>(var->getNewName(),var->getFullPath()); bt = type_unique.release(); \
214#define HANDLE_CASE(tid, type) \
216 bt = new (type)(var->getNewName(),var->getFullPath()); \
226 HANDLE_CASE(H5FSTRING,
Str)
227 HANDLE_CASE(H5VSTRING,
Str)
229 throw InternalErr(__FILE__, __LINE__,
"unsupported data type.");
234 vector<size_t> dimsizes;
235 dimsizes.resize(var->
getRank());
236 for (
int i = 0; i < var->
getRank(); i++)
237 dimsizes[i] = (dims[i])->getSize();
239 auto ar_unique = make_unique<HDF5CFArray>(var->
getRank(), file_id,
240 filename, var->
getType(), dimsizes,
244 auto ar = ar_unique.get();
246 for (
const auto &dim: dims) {
247 if ((dim->getNewName()).empty())
248 ar->append_dim((
int) (dim->getSize()));
250 ar->append_dim((
int) (dim->getSize()), dim->getNewName());
254 if (dap4_int64 ==
true) {
256 DMR *dmr = HDF5RequestHandler::get_dmr_64bit_int();
257 D4Group *root_grp = dmr->root();
259 BaseType *d4_var = ar->h5cfdims_transform_to_dap4_int64(root_grp);
261 map_cfh5_var_attrs_to_dap4_int64(var, d4_var);
262 root_grp->add_var_nocopy(d4_var);
272 return (((
"_FillValue" == attr->getNewName()) && (var->
getType() != attr->getType())) ?
true :
false);
279 BESDEBUG(
"h5",
"Coming to gen_dap_special_oneobj_das() "<<endl);
280 if (attr->getCount() != 1)
281 throw InternalErr(__FILE__, __LINE__,
"FillValue attribute can only have one element.");
283 H5DataType var_dtype = var->
getType();
284 if ((
true == HDF5RequestHandler::get_fillvalue_check())
285 && (
false == is_fvalue_valid(var_dtype, attr))) {
286 string msg =
"The attribute value is out of the range.\n";
287 msg +=
"The variable name: " + var->
getNewName() +
"\n";
288 msg +=
"The attribute name: " + attr->getNewName() +
"\n";
289 msg +=
"The error occurs inside the gen_dap_special_oneobj_das function in h5commoncfdap.cc.";
290 throw InternalErr(msg);
292 string print_rep = HDF5CFDAPUtil::print_attr(attr->getType(), 0, (
void*) (&(attr->getValue()[0])));
293 at->append_attr(attr->getNewName(), HDF5CFDAPUtil::print_type(var_dtype), print_rep);
300 BESDEBUG(
"h5",
"Coming to is_fvalue_valid() "<<endl);
301 bool ret_value =
true;
304 switch (attr->getType()) {
306 signed char final_fill_value = *((
signed char*) ((
void*) (&(attr->getValue()[0]))));
307 if ((var_dtype == H5UCHAR) && (final_fill_value<0))
313 short final_fill_value = *((
short*) ((
void*) (&(attr->getValue()[0]))));
314 if ((var_dtype == H5UCHAR) &&(final_fill_value > 255 || final_fill_value < 0))
318 else if ((var_dtype == H5UINT16) && (final_fill_value < 0))
323 unsigned short final_fill_value = *((
unsigned short*) ((
void*) (&(attr->getValue()[0]))));
324 if ((var_dtype == H5UCHAR) &&(final_fill_value > 255)) {
327 else if ((var_dtype == H5INT16) && (final_fill_value >32767)){
340 unsigned char final_fill_value = *((
unsigned char*)((
void*)(&(attr->getValue()[0]))));
341 if(var_dtype == H5CHAR) {
342 if(final_fill_value >127)
360 BESDEBUG(
"h5",
"Coming to gen_dap_oneobj_das() "<<endl);
362 if (H5INT64 == attr->getType() || H5UINT64 == attr->getType()) {
367 else if ((H5FSTRING == attr->getType()) || (H5VSTRING == attr->getType())) {
372 if (
nullptr == var) {
376 size_t mem_dtype_size = (attr->getBufSize()) / (attr->getCount());
377 H5DataType mem_dtype = HDF5CFDAPUtil::get_mem_dtype(attr->getType(), mem_dtype_size);
379 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
380 string print_rep = HDF5CFDAPUtil::print_attr(mem_dtype, loc, (
void*) &(attr->getValue()[0]));
381 at->append_attr(attr->getNewName(), HDF5CFDAPUtil::print_type(attr->getType()), print_rep);
391 bool special_attr_handling = need_special_attribute_handling(attr, var);
392 if (
true == special_attr_handling)
393 gen_dap_special_oneobj_das(at, attr, var);
398 size_t mem_dtype_size = (attr->getBufSize()) / (attr->getCount());
399 H5DataType mem_dtype = HDF5CFDAPUtil::get_mem_dtype(attr->getType(), mem_dtype_size);
401 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
402 string print_rep = HDF5CFDAPUtil::print_attr(mem_dtype, loc, (
void*) &(attr->getValue()[0]));
403 at->append_attr(attr->getNewName(), HDF5CFDAPUtil::print_type(attr->getType()), print_rep);
412void gen_dap_onevar_dmr(libdap::D4Group* d4_grp,
const HDF5CF::Var* var, hid_t file_id,
const string & filename) {
414 BESDEBUG(
"h5",
"Coming to gen_dap_onevar_dmr() "<<endl);
416 const vector<HDF5CF::Dimension *>& dims = var->
getDimensions();
419 gen_dap_onevar_dmr_sca(d4_grp, var, filename);
421 gen_dap_onevar_dmr_array(d4_grp, var, file_id, filename, dims);
425void gen_dap_onevar_dmr_sca(D4Group* d4_grp,
const HDF5CF::Var* var,
const string & filename) {
429 auto sca_str_unique =
431 auto sca_str = sca_str_unique.release();
432 sca_str->set_is_dap4(
true);
433 map_cfh5_var_attrs_to_dap4(var, sca_str);
434 d4_grp->add_var_nocopy(sca_str);
440 auto sca_uchar_unique =
442 auto sca_uchar = sca_uchar_unique.release();
443 sca_uchar->set_is_dap4(
true);
444 map_cfh5_var_attrs_to_dap4(var, sca_uchar);
445 d4_grp->add_var_nocopy(sca_uchar);
450 auto sca_char_unique =
452 auto sca_char = sca_char_unique.release();
453 sca_char->set_is_dap4(
true);
454 map_cfh5_var_attrs_to_dap4(var, sca_char);
455 d4_grp->add_var_nocopy(sca_char);
461 auto sca_int16_unique =
463 auto sca_int16 = sca_int16_unique.release();
464 sca_int16->set_is_dap4(
true);
465 map_cfh5_var_attrs_to_dap4(var, sca_int16);
466 d4_grp->add_var_nocopy(sca_int16);
471 auto sca_uint16_unique =
473 auto sca_uint16 = sca_uint16_unique.release();
474 sca_uint16->set_is_dap4(
true);
475 map_cfh5_var_attrs_to_dap4(var, sca_uint16);
476 d4_grp->add_var_nocopy(sca_uint16);
481 auto sca_int32_unique =
483 auto sca_int32 = sca_int32_unique.release();
484 sca_int32->set_is_dap4(
true);
485 map_cfh5_var_attrs_to_dap4(var, sca_int32);
486 d4_grp->add_var_nocopy(sca_int32);
491 auto sca_uint32_unique =
493 auto sca_uint32 = sca_uint32_unique.release();
494 sca_uint32->set_is_dap4(
true);
495 map_cfh5_var_attrs_to_dap4(var, sca_uint32);
496 d4_grp->add_var_nocopy(sca_uint32);
501 auto sca_int64_unique =
503 auto sca_int64 = sca_int64_unique.release();
504 sca_int64->set_is_dap4(
true);
505 map_cfh5_var_attrs_to_dap4(var, sca_int64);
506 d4_grp->add_var_nocopy(sca_int64);
511 auto sca_uint64_unique =
513 auto sca_uint64 = sca_uint64_unique.release();
514 sca_uint64->set_is_dap4(
true);
515 map_cfh5_var_attrs_to_dap4(var, sca_uint64);
516 d4_grp->add_var_nocopy(sca_uint64);
521 auto sca_float32_unique =
523 auto sca_float32 = sca_float32_unique.release();
524 sca_float32->set_is_dap4(
true);
525 map_cfh5_var_attrs_to_dap4(var, sca_float32);
526 d4_grp->add_var_nocopy(sca_float32);
531 auto sca_float64_unique =
533 auto sca_float64 = sca_float64_unique.release();
534 sca_float64->set_is_dap4(
true);
535 map_cfh5_var_attrs_to_dap4(var, sca_float64);
536 d4_grp->add_var_nocopy(sca_float64);
540 throw InternalErr(__FILE__, __LINE__,
"unsupported data type.");
545void gen_dap_onevar_dmr_array(D4Group* d4_grp,
const HDF5CF::Var* var, hid_t file_id,
const string &filename,
546 const vector<HDF5CF::Dimension *>& dims ) {
548 BaseType *bt =
nullptr;
551#define HANDLE_CASE(tid, type) \
553 bt = new (type)(var->getNewName(),var->getFullPath()); \
565 HANDLE_CASE(H5FSTRING,
Str)
566 HANDLE_CASE(H5VSTRING,
Str)
568 throw InternalErr(__FILE__, __LINE__,
"unsupported data type.");
572 vector<size_t> dimsizes;
573 dimsizes.resize(var->
getRank());
574 for (
int i = 0; i < var->
getRank(); i++)
575 dimsizes[i] = (dims[i])->getSize();
577 auto ar_unique = make_unique<HDF5CFArray>(var->
getRank(), file_id, filename,
579 var->getTotalElems(),CV_UNSUPPORTED,
false,
581 auto ar = ar_unique.get();
583 for (
const auto &dim: dims) {
584 if ((dim->getNewName()).empty())
585 ar->append_dim_ll(dim->getSize());
587 ar->append_dim_ll(dim->getSize(), dim->getNewName());
591 ar->set_is_dap4(
true);
592 BaseType *d4_var = ar->h5cfdims_transform_to_dap4(d4_grp);
593 map_cfh5_var_attrs_to_dap4(var, d4_var);
594 d4_grp->add_var_nocopy(d4_var);
618 BESDEBUG(
"h5",
"Coming to gen_dap_str_attr() " << endl);
619 const vector<size_t>& strsize = attr->getStrSize();
621 unsigned int temp_start_pos = 0;
622 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
623 if (strsize[loc] != 0) {
624 string tempstring(attr->getValue().begin() + temp_start_pos, attr->getValue().begin() + temp_start_pos + strsize[loc]);
625 temp_start_pos += strsize[loc];
636 if (HDF5RequestHandler::get_escape_utf8_attr() ==
false && (
false == attr->getCsetType()))
637 at->append_attr(attr->getNewName(),
"String", tempstring,
true);
639 at->append_attr(attr->getNewName(),
"String", tempstring);
648void add_cf_grid_cvs(DDS & dds, EOS5GridPCType cv_proj_code,
float cv_point_lower,
float cv_point_upper,
649 float cv_point_left,
float cv_point_right,
const vector<HDF5CF::Dimension*>& dims)
654 if (HE5_GCTP_SNSOID == cv_proj_code || HE5_GCTP_LAMAZ == cv_proj_code || HE5_GCTP_PS == cv_proj_code) {
657 string dim0name = dims[0]->getNewName();
658 auto dim0size = (
int)(dims[0]->getSize());
659 string dim1name = dims[1]->getNewName();
660 auto dim1size = (
int)(dims[1]->getSize());
663 auto bt_dim0_unique = make_unique<HDF5CFFloat64>(dim0name, dim0name);
664 auto bt_dim0 = bt_dim0_unique.get();
665 auto bt_dim1_unique = make_unique<HDF5CFFloat64>(dim1name, dim1name);
666 auto bt_dim1 = bt_dim1_unique.get();
669 auto ar_dim0_unique = make_unique<HDF5CFGeoCF1D>
670 (HE5_GCTP_SNSOID, cv_point_upper, cv_point_lower, dim0size, dim0name, bt_dim0);
671 auto ar_dim0 = ar_dim0_unique.get();
672 ar_dim0->append_dim(dim0size, dim0name);
674 auto ar_dim1_unique = make_unique<HDF5CFGeoCF1D>
675 (HE5_GCTP_SNSOID, cv_point_left, cv_point_right, dim1size, dim1name, bt_dim1);
676 auto ar_dim1 = ar_dim1_unique.get();
677 ar_dim1->append_dim(dim1size, dim1name);
678 dds.add_var(ar_dim0);
679 dds.add_var(ar_dim1);
684void add_cf_grid_mapinfo_var(DDS & dds, EOS5GridPCType grid_proj_code,
unsigned short g_suffix)
689 string cf_projection_base =
"eos_cf_projection";
691 if (HE5_GCTP_SNSOID == grid_proj_code) {
694 auto dummy_proj_cf_unique =
695 make_unique<HDF5CFGeoCFProj>(cf_projection_base, cf_projection_base);
696 auto dummy_proj_cf = dummy_proj_cf_unique.get();
697 dds.add_var(dummy_proj_cf);
701 stringstream t_suffix_ss;
702 t_suffix_ss << g_suffix;
703 string cf_projection_name = cf_projection_base +
"_" + t_suffix_ss.str();
704 auto dummy_proj_cf_unique =
705 make_unique<HDF5CFGeoCFProj>(cf_projection_name, cf_projection_name);
706 auto dummy_proj_cf = dummy_proj_cf_unique.get();
707 dds.add_var(dummy_proj_cf);
713void add_cf_grid_cv_attrs(DAS & das,
const vector<HDF5CF::Var*>& vars, EOS5GridPCType cv_proj_code,
714 const vector<HDF5CF::Dimension*>& dims,
const vector<double> &eos5_proj_params,
unsigned short g_suffix)
718 if (HE5_GCTP_SNSOID == cv_proj_code || HE5_GCTP_PS == cv_proj_code || HE5_GCTP_LAMAZ== cv_proj_code) {
720 string dim0name = (dims[0])->getNewName();
721 auto dim0size = (
int)(dims[0]->getSize());
722 string dim1name = (dims[1])->getNewName();
723 auto dim1size = (
int)(dims[1]->getSize());
726 AttrTable *at = das.get_table(dim0name);
728 at = das.add_table(dim0name, obtain_new_attr_table());
729 at->append_attr(
"standard_name",
"String",
"projection_y_coordinate");
731 string long_name =
"y coordinate of projection ";
732 at->append_attr(
"long_name",
"String", long_name);
735 at->append_attr(
"units",
"string",
"meter");
737 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoY");
739 at = das.get_table(dim1name);
741 at = das.add_table(dim1name, obtain_new_attr_table());
743 at->append_attr(
"standard_name",
"String",
"projection_x_coordinate");
745 long_name =
"x coordinate of projection ";
746 at->append_attr(
"long_name",
"String", long_name);
749 at->append_attr(
"units",
"string",
"meter");
752 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoX");
755 string cf_projection_base =
"eos_cf_projection";
756 string cf_projection;
757 if (HE5_GCTP_SNSOID == cv_proj_code)
758 cf_projection = cf_projection_base;
760 stringstream t_suffix_ss;
761 t_suffix_ss << g_suffix;
762 cf_projection = cf_projection_base +
"_" + t_suffix_ss.str();
764 add_cf_projection_attrs(das,cv_proj_code,eos5_proj_params,cf_projection);
768 add_cf_grid_mapping_attr(das, vars, cf_projection, dim0name, dim0size, dim1name, dim1size);
773void add_cf_projection_attrs(DAS &das,EOS5GridPCType cv_proj_code,
const vector<double> &eos5_proj_params,
774 const string& cf_projection) {
776 AttrTable* at = das.get_table(cf_projection);
778 at = das.add_table(cf_projection, obtain_new_attr_table());
780 if (HE5_GCTP_SNSOID == cv_proj_code) {
781 at->append_attr(
"grid_mapping_name",
"String",
"sinusoidal");
782 at->append_attr(
"longitude_of_central_meridian",
"Float64",
"0.0");
783 at->append_attr(
"earth_radius",
"Float64",
"6371007.181");
784 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
786 else if (HE5_GCTP_PS == cv_proj_code) {
792 double vert_lon_pole = HE5_EHconvAng(eos5_proj_params[4],HE5_HDFE_DMS_DEG);
795 double lat_true_scale = HE5_EHconvAng(eos5_proj_params[5],HE5_HDFE_DMS_DEG);
798 double fe = eos5_proj_params[6];
801 double fn = eos5_proj_params[7];
803 at->append_attr(
"grid_mapping_name",
"String",
"polar_stereographic");
805 ostringstream s_vert_lon_pole;
806 s_vert_lon_pole << vert_lon_pole;
810 at->append_attr(
"straight_vertical_longitude_from_pole",
"Float64", s_vert_lon_pole.str());
811 ostringstream s_lat_true_scale;
812 s_lat_true_scale << lat_true_scale;
814 at->append_attr(
"standard_parallel",
"Float64", s_lat_true_scale.str());
817 at->append_attr(
"false_easting",
"Float64",
"0.0");
821 at->append_attr(
"false_easting",
"Float64",s_fe.str());
825 at->append_attr(
"false_northing",
"Float64",
"0.0");
829 at->append_attr(
"false_northing",
"Float64",s_fn.str());
832 if(lat_true_scale >0)
833 at->append_attr(
"latitude_of_projection_origin",
"Float64",
"+90.0");
835 at->append_attr(
"latitude_of_projection_origin",
"Float64",
"-90.0");
838 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
845 else if(HE5_GCTP_LAMAZ == cv_proj_code) {
846 double lon_proj_origin = HE5_EHconvAng(eos5_proj_params[4],HE5_HDFE_DMS_DEG);
847 double lat_proj_origin = HE5_EHconvAng(eos5_proj_params[5],HE5_HDFE_DMS_DEG);
848 double fe = eos5_proj_params[6];
849 double fn = eos5_proj_params[7];
851 at->append_attr(
"grid_mapping_name",
"String",
"lambert_azimuthal_equal_area");
853 ostringstream s_lon_proj_origin;
854 s_lon_proj_origin << lon_proj_origin;
855 at->append_attr(
"longitude_of_projection_origin",
"Float64", s_lon_proj_origin.str());
857 ostringstream s_lat_proj_origin;
858 s_lat_proj_origin << lat_proj_origin;
860 at->append_attr(
"latitude_of_projection_origin",
"Float64", s_lat_proj_origin.str());
863 at->append_attr(
"false_easting",
"Float64",
"0.0");
867 at->append_attr(
"false_easting",
"Float64",s_fe.str());
871 at->append_attr(
"false_northing",
"Float64",
"0.0");
875 at->append_attr(
"false_northing",
"Float64",s_fn.str());
877 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
886void add_cf_grid_mapping_attr(DAS &das,
const vector<HDF5CF::Var*>& vars,
const string& cf_projection,
887 const string & dim0name, hsize_t dim0size,
const string &dim1name, hsize_t dim1size)
891 for (
const auto &var:vars) {
894 bool has_dim0 =
false;
895 bool has_dim1 =
false;
896 const vector<HDF5CF::Dimension*>& dims = var->
getDimensions();
897 for (
const auto &dim:dims) {
898 if (dim->getNewName() == dim0name && dim->getSize() == dim0size)
900 else if (dim->getNewName() == dim1name && dim->getSize() == dim1size)
904 if (
true == has_dim0 &&
true == has_dim1) {
905 AttrTable *at = das.get_table(var->
getNewName());
907 at = das.add_table(var->
getNewName(), obtain_new_attr_table());
910 at->append_attr(
"grid_mapping",
"String", cf_projection);
918void add_ll_valid_range(AttrTable* at,
bool is_lat) {
920 at->append_attr(
"valid_min",
"Float64",
"-90.0");
921 at->append_attr(
"valid_max",
"Float64",
"90.0");
924 at->append_attr(
"valid_min",
"Float64",
"-180.0");
925 at->append_attr(
"valid_max",
"Float64",
"180.0");
931bool need_attr_values_for_dap4(
const HDF5CF::Var *var) {
932 bool ret_value =
false;
933 if((HDF5RequestHandler::get_dmr_64bit_int()!=
nullptr) &&
941void map_cfh5_var_attrs_to_dap4_int64(
const HDF5CF::Var *var,BaseType* d4_var) {
943 for (
const auto & attr:var->getAttributes()) {
946 size_t mem_dtype_size = (attr->getBufSize()) / (attr->getCount());
947 H5DataType mem_dtype = HDF5CFDAPUtil::get_mem_dtype(attr->getType(), mem_dtype_size);
949 string dap2_attrtype = HDF5CFDAPUtil::print_type(mem_dtype);
951 auto d4_attr_unique = make_unique<D4Attribute>(attr->getNewName(),dap4_attrtype);
952 auto d4_attr = d4_attr_unique.release();
953 if (dap4_attrtype == attr_str_c) {
954 if (
"coordinates" == attr->getNewName()) {
955 bool chg_coor_value =
false;
956 if ((
true == HDF5RequestHandler::get_enable_coord_attr_add_path())
957 &&(
true == var->getCoorAttrAddPath()))
958 chg_coor_value =
true;
960 handle_coor_attr_for_int64_var(attr,var->
getFullPath(),tempstring,chg_coor_value);
961 d4_attr->add_value(tempstring);
964 const vector<size_t>& strsize = attr->getStrSize();
965 unsigned int temp_start_pos = 0;
966 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
967 if (strsize[loc] != 0) {
968 string tempstring(attr->getValue().begin() + temp_start_pos,
969 attr->getValue().begin() + temp_start_pos + strsize[loc]);
970 temp_start_pos += strsize[loc];
971 d4_attr->add_value(tempstring);
977 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
978 string print_rep = HDF5CFDAPUtil::print_attr(mem_dtype, loc, (
void*) &(attr->getValue()[0]));
979 d4_attr->add_value(print_rep);
982 d4_var->attributes()->add_attribute_nocopy(d4_attr);
986 auto d4_attro_unique = make_unique<D4Attribute>(
"origname",attr_str_c);
987 auto d4_attro = d4_attro_unique.release();
988 d4_attro->add_value(var->
getName());
989 d4_var->attributes()->add_attribute_nocopy(d4_attro);
991 auto d4_attrf_unique = make_unique<D4Attribute>(
"fullnamepath",attr_str_c);
992 auto d4_attrf = d4_attrf_unique.release();
994 d4_var->attributes()->add_attribute_nocopy(d4_attrf);
999void check_update_int64_attr(
const string & obj_name,
const HDF5CF::Attribute * attr) {
1001 if (attr->getType() == H5INT64 || attr->getType() == H5UINT64) {
1003 DMR * dmr = HDF5RequestHandler::get_dmr_64bit_int();
1004 if (dmr !=
nullptr) {
1006 string dap2_attrtype = HDF5CFDAPUtil::print_type(attr->getType());
1009 auto d4_attr_unique = make_unique<D4Attribute>(attr->getNewName(),dap4_attrtype);
1010 auto d4_attr = d4_attr_unique.release();
1011 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
1012 string print_rep = HDF5CFDAPUtil::print_attr(attr->getType(), loc, (
void*) &(attr->getValue()[0]));
1013 d4_attr->add_value(print_rep);
1015 D4Group * root_grp = dmr->root();
1016 if (root_grp->attributes()->empty() ==
true) {
1017 auto d4_hg_container_unique = make_unique<D4Attribute>();
1018 auto d4_hg_container = d4_hg_container_unique.release();
1019 d4_hg_container->set_name(
"HDF5_GLOBAL_integer_64");
1020 d4_hg_container->set_type(attr_container_c);
1021 root_grp->attributes()->add_attribute_nocopy(d4_hg_container);
1024 D4Attribute *d4_hg_container = root_grp->attributes()->get(
"HDF5_GLOBAL_integer_64");
1025 if (obj_name.empty() ==
false) {
1026 string test_obj_name =
"HDF5_GLOBAL_integer_64."+obj_name;
1027 D4Attribute *d4_container = root_grp->attributes()->get(test_obj_name);
1028 if (d4_container ==
nullptr) {
1029 auto d4_container_unique = make_unique<D4Attribute>();
1030 d4_container = d4_container_unique.release();
1031 d4_container->set_name(obj_name);
1032 d4_container->set_type(attr_container_c);
1034 d4_container->attributes()->add_attribute_nocopy(d4_attr);
1035 if (d4_hg_container->attributes()->get(obj_name)==
nullptr)
1036 d4_hg_container->attributes()->add_attribute_nocopy(d4_container);
1039 d4_hg_container->attributes()->add_attribute_nocopy(d4_attr);
1046void handle_coor_attr_for_int64_var(
const HDF5CF::Attribute *attr,
const string &var_path,
string &tempstring,
1047 bool chg_coor_value) {
1049 string tempstring2(attr->getValue().begin(),attr->getValue().end());
1050 if(
true == chg_coor_value) {
1052 vector<string>cvalue_vec;
1053 HDF5CFUtil::Split_helper(cvalue_vec,tempstring2,sep);
1054 for (
unsigned int i = 0; i<cvalue_vec.size();i++) {
1055 HDF5CFUtil::cha_co(cvalue_vec[i],var_path);
1056 string t_str = get_cf_string(cvalue_vec[i]);
1060 tempstring += sep+t_str;
1064 tempstring = tempstring2;
1070void map_cfh5_var_attrs_to_dap4(
const HDF5CF::Var *var,BaseType* d4_var) {
1072 for (
const auto &attr:var->getAttributes()) {
1073 D4Attribute *d4_attr = gen_dap4_attr(attr);
1074 d4_var->attributes()->add_attribute_nocopy(d4_attr);
1079void map_cfh5_grp_attr_to_dap4(libdap::D4Group *d4_grp,
const HDF5CF::Attribute *attr) {
1081 D4Attribute *d4_attr = gen_dap4_attr(attr);
1082 d4_grp->attributes()->add_attribute_nocopy(d4_attr);
1087void map_cfh5_attr_container_to_dap4(libdap::D4Attribute *d4_con,
const HDF5CF::Attribute *attr) {
1089 D4Attribute *d4_attr = gen_dap4_attr(attr);
1090 d4_con->attributes()->add_attribute_nocopy(d4_attr);
1097 D4AttributeType dap4_attrtype = HDF5CFDAPUtil::print_type_dap4(attr->getType());
1098 auto d4_attr_unique = make_unique<D4Attribute>(attr->getNewName(),dap4_attrtype);
1099 auto d4_attr = d4_attr_unique.release();
1101 if (dap4_attrtype == attr_str_c) {
1103 const vector<size_t>& strsize = attr->getStrSize();
1105 unsigned int temp_start_pos = 0;
1106 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
1107 if (strsize[loc] != 0) {
1108 string tempstring(attr->getValue().begin() + temp_start_pos,
1109 attr->getValue().begin() + temp_start_pos + strsize[loc]);
1110 temp_start_pos += strsize[loc];
1111 d4_attr->add_value(tempstring);
1114 if (HDF5RequestHandler::get_escape_utf8_attr() ==
false && (
false == attr->getCsetType()))
1115 d4_attr->set_utf8_str_flag(
true);
1118 for (
unsigned int loc = 0; loc < attr->getCount(); loc++) {
1119 string print_rep = HDF5CFDAPUtil::print_attr(attr->getType(), loc, (
void*) &(attr->getValue()[0]));
1120 d4_attr->add_value(print_rep);
1129void add_gm_oneproj_var_dap4_attrs(BaseType *var,EOS5GridPCType cv_proj_code,
const vector<double> &eos5_proj_params) {
1131 if (HE5_GCTP_SNSOID == cv_proj_code) {
1133 add_var_dap4_attr(var,
"grid_mapping_name",attr_str_c,
"sinusoidal");
1134 add_var_dap4_attr(var,
"longitude_of_central_meridian",attr_float64_c,
"0.0");
1135 add_var_dap4_attr(var,
"earth_radius", attr_float64_c,
"6371007.181");
1136 add_var_dap4_attr(var,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
1139 else if (HE5_GCTP_PS == cv_proj_code) {
1145 double vert_lon_pole = HE5_EHconvAng(eos5_proj_params[4],HE5_HDFE_DMS_DEG);
1148 double lat_true_scale = HE5_EHconvAng(eos5_proj_params[5],HE5_HDFE_DMS_DEG);
1151 double fe = eos5_proj_params[6];
1154 double fn = eos5_proj_params[7];
1156 add_var_dap4_attr(var,
"grid_mapping_name",attr_str_c,
"polar_stereographic");
1158 ostringstream s_vert_lon_pole;
1159 s_vert_lon_pole << vert_lon_pole;
1163 add_var_dap4_attr(var,
"straight_vertical_longitude_from_pole", attr_float64_c, s_vert_lon_pole.str());
1165 ostringstream s_lat_true_scale;
1166 s_lat_true_scale << lat_true_scale;
1167 add_var_dap4_attr(var,
"standard_parallel", attr_float64_c, s_lat_true_scale.str());
1170 add_var_dap4_attr(var,
"false_easting",attr_float64_c,
"0.0");
1174 add_var_dap4_attr(var,
"false_easting",attr_float64_c,s_fe.str());
1178 add_var_dap4_attr(var,
"false_northing",attr_float64_c,
"0.0");
1182 add_var_dap4_attr(var,
"false_northing",attr_float64_c,s_fn.str());
1185 if (lat_true_scale >0)
1186 add_var_dap4_attr(var,
"latitude_of_projection_origin",attr_float64_c,
"+90.0");
1188 add_var_dap4_attr(var,
"latitude_of_projection_origin",attr_float64_c,
"-90.0");
1190 add_var_dap4_attr(var,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
1197 else if(HE5_GCTP_LAMAZ == cv_proj_code) {
1199 double lon_proj_origin = HE5_EHconvAng(eos5_proj_params[4],HE5_HDFE_DMS_DEG);
1200 double lat_proj_origin = HE5_EHconvAng(eos5_proj_params[5],HE5_HDFE_DMS_DEG);
1201 double fe = eos5_proj_params[6];
1202 double fn = eos5_proj_params[7];
1204 add_var_dap4_attr(var,
"grid_mapping_name", attr_str_c,
"lambert_azimuthal_equal_area");
1206 ostringstream s_lon_proj_origin;
1207 s_lon_proj_origin << lon_proj_origin;
1208 add_var_dap4_attr(var,
"longitude_of_projection_origin", attr_float64_c, s_lon_proj_origin.str());
1210 ostringstream s_lat_proj_origin;
1211 s_lat_proj_origin << lat_proj_origin;
1213 add_var_dap4_attr(var,
"latitude_of_projection_origin", attr_float64_c, s_lat_proj_origin.str());
1216 add_var_dap4_attr(var,
"false_easting",attr_float64_c,
"0.0");
1220 add_var_dap4_attr(var,
"false_easting",attr_float64_c,s_fe.str());
1224 add_var_dap4_attr(var,
"false_northing",attr_float64_c,
"0.0");
1228 add_var_dap4_attr(var,
"false_northing",attr_float64_c,s_fn.str());
1230 add_var_dap4_attr(var,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
1235void add_cf_grid_cv_dap4_attrs(D4Group *d4_root,
const string& cf_projection,
1236 const vector<HDF5CF::Dimension*>& dims,
const vector<string> & cvar_name)
1239 string dim0name = (dims[0])->getNewName();
1240 hsize_t dim0size = dims[0]->getSize();
1241 string dim1name = (dims[1])->getNewName();
1242 hsize_t dim1size = dims[1]->getSize();
1245 Constructor::Vars_iter vi = d4_root->var_begin();
1246 Constructor::Vars_iter ve = d4_root->var_end();
1247 for (; vi != ve; vi++) {
1249 if ((*vi)->is_vector_type() && (cvar_name.end() == find(cvar_name.begin(), cvar_name.end(),(*vi)->name()))) {
1250 auto t_a =
dynamic_cast<Array*
>(*vi);
1251 if (t_a->dimensions() >1) {
1253 bool has_dim0 =
false;
1254 bool has_dim1 =
false;
1255 add_cf_grid_cv_dap4_attrs_helper(t_a, dim0name, dim0size, has_dim0, dim1name, dim1size, has_dim1);
1256 if (
true == has_dim0 &&
true == has_dim1)
1257 add_var_dap4_attr((*vi),
"grid_mapping",attr_str_c,cf_projection);
1263void add_cf_grid_cv_dap4_attrs_helper(Array *t_a,
const string &dim0name, hsize_t dim0size,
bool &has_dim0,
1264 const string &dim1name, hsize_t dim1size,
bool &has_dim1){
1266 Array::Dim_iter dim_i = t_a->dim_begin();
1267 Array::Dim_iter dim_e = t_a->dim_end();
1269 for(;dim_i !=dim_e;dim_i++) {
1270 if ((*dim_i).name == dim0name && (*dim_i).size == (int64_t)dim0size)
1272 else if ((*dim_i).name == dim1name && (*dim_i).size == (int64_t)dim1size)
1280void add_gm_spcvs(libdap::D4Group *d4_root, EOS5GridPCType cv_proj_code,
float cv_point_lower,
float cv_point_upper,
1281 float cv_point_left,
float cv_point_right,
const std::vector<HDF5CF::Dimension*>& dims) {
1285 if (HE5_GCTP_SNSOID == cv_proj_code || HE5_GCTP_LAMAZ == cv_proj_code || HE5_GCTP_PS == cv_proj_code) {
1288 string dim0name = dims[0]->getNewName();
1289 auto dim0size = (
int)(dims[0]->getSize());
1290 string dim1name = dims[1]->getNewName();
1291 auto dim1size = (
int)(dims[1]->getSize());
1293 auto bt_dim0_unique = make_unique<HDF5CFFloat64>(dim0name, dim0name);
1294 auto bt_dim0 = bt_dim0_unique.get();
1295 auto bt_dim1_unique = make_unique<HDF5CFFloat64>(dim1name, dim1name);
1296 auto bt_dim1 = bt_dim1_unique.get();
1298 auto ar_dim0_unique = make_unique<HDF5CFGeoCF1D>
1299 (HE5_GCTP_SNSOID, cv_point_upper, cv_point_lower, dim0size, dim0name, bt_dim0);
1300 auto ar_dim0 = ar_dim0_unique.release();
1301 ar_dim0->append_dim(dim0size, dim0name);
1302 ar_dim0->set_is_dap4(
true);
1303 add_gm_spcvs_attrs(ar_dim0,
true);
1304 d4_root->add_var_nocopy(ar_dim0);
1306 auto ar_dim1_unique = make_unique<HDF5CFGeoCF1D>
1307 (HE5_GCTP_SNSOID, cv_point_left, cv_point_right, dim1size, dim1name, bt_dim1);
1308 auto ar_dim1 = ar_dim1_unique.release();
1309 ar_dim1->append_dim(dim1size, dim1name);
1310 ar_dim1->set_is_dap4(
true);
1311 add_gm_spcvs_attrs(ar_dim1,
false);
1312 d4_root->add_var_nocopy(ar_dim1);
1318void add_gm_spcvs_attrs(libdap::BaseType *var,
bool is_dim0) {
1320 string standard_name;
1322 string COORAxisTypes;
1324 if (
true == is_dim0) {
1325 standard_name =
"projection_y_coordinate";
1326 long_name =
"y coordinate of projection ";
1327 COORAxisTypes =
"GeoY";
1330 standard_name =
"projection_x_coordinate";
1331 long_name =
"x coordinate of projection ";
1332 COORAxisTypes =
"GeoX";
1335 add_var_dap4_attr(var,
"standard_name", attr_str_c, standard_name);
1336 add_var_dap4_attr(var,
"long_name", attr_str_c, long_name);
1337 add_var_dap4_attr(var,
"units", attr_str_c,
"meter");
1338 add_var_dap4_attr(var,
"_CoordinateAxisType", attr_str_c, COORAxisTypes);
1343void add_grp_dap4_attr(D4Group *d4_grp,
const string& attr_name, D4AttributeType attr_type,
const string& attr_value){
1345 auto d4_attr_unique = make_unique<D4Attribute>(attr_name,attr_type);
1346 auto d4_attr = d4_attr_unique.release();
1347 d4_attr->add_value(attr_value);
1348 d4_grp->attributes()->add_attribute_nocopy(d4_attr);
1352void add_var_dap4_attr(BaseType *var,
const string& attr_name, D4AttributeType attr_type,
const string& attr_value){
1354 auto d4_attr_unique = make_unique<D4Attribute>(attr_name,attr_type);
1355 auto d4_attr = d4_attr_unique.release();
1356 d4_attr->add_value(attr_value);
1357 var->attributes()->add_attribute_nocopy(d4_attr);
1362void add_dap4_coverage(libdap::D4Group* d4_root,
const vector<string>& coord_var_names,
bool is_coard) {
1365 unordered_map<string, Array*> d4map_array_maps;
1368 vector<Array*> has_map_arrays;
1370 Constructor::Vars_iter vi = d4_root->var_begin();
1371 Constructor::Vars_iter ve = d4_root->var_end();
1373 for (; vi != ve; vi++) {
1375 const BaseType *v = *vi;
1378 if (libdap::dods_array_c == v->type()) {
1379 auto t_a =
dynamic_cast<Array *
>(*vi);
1380 add_dap4_coverage_set_up(d4map_array_maps, has_map_arrays, t_a, coord_var_names, v->name());
1386 add_dap4_coverage_grid(d4map_array_maps,has_map_arrays);
1389 add_dap4_coverage_swath(d4map_array_maps,has_map_arrays);
1394 for (
auto& d4map_array_map:d4map_array_maps)
1395 d4map_array_map.second =
nullptr;
1399void add_dap4_coverage_set_up(unordered_map<string, Array*> &d4map_array_maps, vector<Array *> &has_map_arrays,
1400 Array *t_a,
const vector<string>& coord_var_names,
const string & vname) {
1409 for (
const auto &cvar_name: coord_var_names) {
1410 if (cvar_name == vname) {
1412 d4map_array_maps.emplace(vname, t_a);
1419 has_map_arrays.emplace_back(t_a);
1423void add_dap4_coverage_grid(unordered_map<string, Array*> &d4map_array_maps, vector<Array *> &has_map_arrays) {
1425 for (
auto &has_map_array: has_map_arrays) {
1427 Array::Dim_iter dim_i = has_map_array->dim_begin();
1428 Array::Dim_iter dim_e = has_map_array->dim_end();
1429 for (; dim_i != dim_e; dim_i++) {
1433 unordered_map<string, Array *>::const_iterator it_ma = d4map_array_maps.find(dim_i->name);
1434 if (it_ma != d4map_array_maps.end()) {
1435 auto d4_map_unique = make_unique<D4Map>((it_ma->second)->FQN(), it_ma->second);
1436 auto d4_map = d4_map_unique.release();
1437 has_map_array->maps()->add_map(d4_map);
1441 has_map_array =
nullptr;
1445void add_dap4_coverage_swath(unordered_map<std::string, libdap::Array*> &d4map_array_maps,
1446 const std::vector<libdap::Array *> &has_map_arrays) {
1448 for (
auto has_map_array: has_map_arrays) {
1451 vector<string> coord_names;
1454 unordered_set<string> coord_dim_names;
1456 D4Attributes *d4_attrs = has_map_array->attributes();
1457 const D4Attribute *d4_attr = d4_attrs->find(
"coordinates");
1458 if (d4_attr !=
nullptr) {
1461 if (d4_attr->type() == attr_str_c && d4_attr->num_values() == 1) {
1462 string tempstring = d4_attr->value(0);
1464 HDF5CFUtil::Split_helper(coord_names, tempstring, sep);
1468 add_dap4_coverage_swath_coords(d4map_array_maps, has_map_array, coord_names, coord_dim_names);
1471 has_map_array =
nullptr;
1475void add_dap4_coverage_swath_coords(unordered_map<string, Array*> &d4map_array_maps, Array *has_map_array,
1476 const vector<string> &coord_names, unordered_set<string> &coord_dim_names) {
1480 for (
const auto &cname: coord_names) {
1482 unordered_map<string, Array *>::const_iterator it_ma = d4map_array_maps.find(cname);
1483 if (it_ma != d4map_array_maps.end()) {
1485 auto d4_map_unique = make_unique<D4Map>((it_ma->second)->FQN(), it_ma->second);
1486 auto d4_map = d4_map_unique.release();
1487 has_map_array->maps()->add_map(d4_map);
1490 Array::Dim_iter dim_i = it_ma->second->dim_begin();
1491 Array::Dim_iter dim_e = it_ma->second->dim_end();
1492 for (; dim_i != dim_e; dim_i++)
1493 coord_dim_names.insert(dim_i->name);
1499 Array::Dim_iter dim_i = has_map_array->dim_begin();
1500 Array::Dim_iter dim_e = has_map_array->dim_end();
1501 for (; dim_i != dim_e; dim_i++) {
1504 if (coord_dim_names.find(dim_i->name) == coord_dim_names.end()) {
1505 unordered_map<string, Array *>::const_iterator it_ma = d4map_array_maps.find(dim_i->name);
1506 if (it_ma != d4map_array_maps.end()) {
1507 auto d4_map_unique = make_unique<D4Map>((it_ma->second)->FQN(), it_ma->second);
1508 auto d4_map = d4_map_unique.release();
1509 has_map_array->maps()->add_map(d4_map);
1517string get_cf_string(
string & s) {
1520 return get_cf_string_helper(s);
1524 return get_cf_string_helper(s);
1528string get_cf_string_helper(
string & s) {
1532 string insertString(1,
'_');
1535 if (
true == isdigit(s[0])) s.insert(0, insertString);
1537 for (
unsigned int i = 0; i < s.size(); i++)
1538 if ((
false == isalnum(s[i])) && (s[i] !=
'_')) s[i] =
'_';
This class includes the methods to read data array into DAP buffer from an HDF5 dataset for the CF op...
This class provides a way to map HDF5 byte to DAP byte for the CF option.
This class provides a way to map HDF5 float to DAP float for the CF option.
This class provides a way to map HDF5 64-bit floating-point(double) to DAP 64-bit floating-point for ...
This class provides a way to map HDF5 int16 to DAP int16 for the CF option.
This class provides a way to map HDF5 32-bit integer to DAP Int32 for the CF option.
This class provides a way to map HDF5 64-bit integer to DAP4 Int64 for the CF option.
This class provides a way to map HDF5 int8 to DAP int16 for the CF option.
This class provides a way to map HDF5 Str to DAP Str for the CF option.
This class provides a way to map HDF5 unsigned 16-bit integer to DAP uint16 for the CF option.
This class provides a way to map HDF5 unsigned 32-bit integer to DAP uint32 for the CF option.
This class provides a way to map HDF5 64-bit unsigned integer to DAP4 UInt64 for the CF option.
This file includes several helper functions for translating HDF5 to CF-compliant.
include the entry functions to execute the handlers
static D4AttributeType daptype_strrep_to_dap4_attrtype(const string &s)
This class represents one attribute.
This class represents one HDF5 dataset(CF variable)
float getCompRatio() const
Get the compression ratio of this dataset.
int getRank() const
Get the dimension rank of this variable.
const std::string & getFullPath() const
Get the full path of this variable.
const std::string & getName() const
Get the original name of this variable.
H5DataType getType() const
Get the data type of this variable(Not HDF5 datatype id)
const std::vector< Dimension * > & getDimensions() const
Get the list of the dimensions.
const std::string & getNewName() const
Get the new name of this variable.
Helper functions for generating DAS attributes and a function to check BES Key.
void gen_dap_str_attr(AttrTable *at, const HDF5CF::Attribute *attr)
Transfer string attributes to a DAP2 AttrTable.
Map and generate DDS and DAS for the CF option for generic HDF5 products.