// // C++ Implementation: %{MODULE} // // Description: // // // Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR} // // Copyright: See COPYING file that comes with this distribution // // #include <stdio.h> #include <string.h> #include "merisfiledata.h" #include "epr_record.h" #include "epr_band.h" #include "epr_field.h" #include "epr_core.h" #include <sstream> #include <cfloat> MerisFileData::MerisFileData(const string &filename, const string &mode) :FileData(filename,mode),FileDataReader(filename,mode) { this->filename=filename; if (!exists_file(filename)) { bad_file e(filename); throw e; } /* Initialize the API. Set log-level to DEBUG and use default log-output (stdout) */ epr_init_api(e_log_warning, epr_log_message, NULL); /* Open the product; an argument is a path to product data file */ product_id = epr_open_product(filename.c_str()); const EPR_SField* field_start = epr_get_field(epr_get_mph(product_id), "SENSING_START"); const EPR_SField* field_stop = epr_get_field(epr_get_mph(product_id), "SENSING_STOP"); string start = epr_get_field_elem_as_str(field_start); string stop = epr_get_field_elem_as_str(field_stop); string sdate; Date bdate; if(start.substr(0,1)=="\"") { start = start.substr(1,20); } sdate=start.substr(7,4)+getMonth(start.substr(3,3))+start.substr(0,2)+start.substr(12,2)+start.substr(15,2)+start.substr(18,2); bdate.set_date_str(sdate,(const char *) "%Y%m%d%H%M%S"); Date edate; if(stop.substr(0,1)=="\"") { stop = stop.substr(1,20); } sdate=stop.substr(7,4)+getMonth(stop.substr(3,3))+stop.substr(0,2)+stop.substr(12,2)+stop.substr(15,2)+stop.substr(18,2); edate.set_date_str(sdate,(const char *) "%Y%m%d%H%M%S"); this->set_date(bdate); this->time_coverage=edate.get_epoch_time()-bdate.get_epoch_time(); } MerisFileData::~MerisFileData() { /* Close product_id and release rest of the allocated memory */ epr_close_product(product_id); /* Closes product reader API, release all allocated resources */ epr_close_api(); product_id=NULL; } void MerisFileData::open_data_file() { } void MerisFileData::close_data_file() { } void* MerisFileData::read_data(void* data, const char* sds_name, int * start, int * stride, int *edges, int rank) { EPR_SBandId* band_id = NULL; int err_code; EPR_SRaster* raster = NULL; uint source_w, source_h; uint source_step_x, source_step_y; uint start_step_x, start_step_y; band_id = epr_get_band_id(product_id, sds_name); // if (band_id == NULL) { // printf("Error: band '%s' not found\n", band_name); // return 1; // } if(start==NULL){ start_step_x = 0; start_step_y = 0; }else{ start_step_x = start[0]; start_step_y = start[1]; } if(edges==NULL){ source_w = epr_get_scene_width(product_id); source_h = epr_get_scene_height(product_id); }else{ source_w = edges[0]; source_h = edges[1]; } if(stride == NULL) { source_step_x = 1; source_step_y = 1; }else{ source_step_x = stride[0]; source_step_y = stride[1]; } raster = epr_create_compatible_raster(band_id, source_w, source_h, source_step_x, source_step_y); EPR_EDataTypeId band_id_data_type = band_id->data_type; EPR_ESampleModel band_smod = band_id->sample_model; if(sds_name!=string("latitude") && sds_name!=string("longitude") && sds_name!=string("atm_press") ){ if(band_id->sample_model != e_smod_3TOI && band_id->sample_model != e_smod_2TOF){ EPR_SDatasetId* dataset_id = band_id->dataset_ref.dataset_id; EPR_SRecord* record = epr_create_record(dataset_id); EPR_SFieldInfo* field_info = (EPR_SFieldInfo*)epr_get_ptr_array_elem_at(record->info->field_infos, band_id->dataset_ref.field_index - 1); raster->data_type = field_info->data_type_id; band_id->data_type = field_info->data_type_id; } } err_code = epr_read_band_raster(band_id, start_step_x, start_step_y, raster); band_id->data_type = band_id_data_type; band_id->sample_model = band_smod; if(data==NULL) { data = raster->buffer; }else{ int size = 0; switch (get_dataset_data_type(sds_name)) { case DFNT_UINT8:{ size=1; break; } case DFNT_INT8:{ size=1; break; } case DFNT_UINT16:{ size=2; break; } case DFNT_INT16:{ size=2; break; } case DFNT_UINT32:{ size=4; break; } case DFNT_INT32:{ size=4; break; } case DFNT_FLOAT32:{ size=4; break; } case DFNT_FLOAT64:{ size=8; break; } default:{ bad_file e("bad type data"); throw e; break; } } memcpy (data,raster->buffer,size*(raster->raster_width)*(raster->raster_height)); free(raster->buffer); } return data; } vector<int> MerisFileData::get_dataset_dimension(const string &sds_name) { vector<int> v; int source_w = epr_get_scene_width(product_id); int source_h = epr_get_scene_height(product_id); v.push_back(source_h); v.push_back(source_w); return v; } void MerisFileData::get_dataset_fill_value(const string &sds_name, void* fill_value) { switch(get_dataset_data_type(sds_name)){ case DFNT_UCHAR8:{ uchar8 x; getFillValues(x); uchar8 **y; y = (uchar8**)&fill_value; (**y) = x; break; } case DFNT_CHAR8:{ char8 x; getFillValues(x); char8 **y; y = (char8**)&fill_value; (**y) = x; break; } case DFNT_UINT16:{ uint16 x; getFillValues(x); uint16 **y; y = (uint16**)&fill_value; (**y) = x; break; } case DFNT_INT16:{ int16 x; getFillValues(x); int16 **y; y = (int16**)&fill_value; (**y) = x; break; } case DFNT_UINT32:{ uint32 x; getFillValues(x); uint32 **y; y = (uint32**)&fill_value; (**y) = x; break; } case DFNT_INT32:{ int32 x; getFillValues(x); int32 **y; y = (int32**)&fill_value; (**y) = x; break; } case DFNT_FLOAT32:{ float32 x; getFillValues(x); float32 **y; y = (float32**)&fill_value; (**y) = x; break; } case DFNT_FLOAT64:{ float64 x; getFillValues(x); float64 **y; y = (float64**)&fill_value; (**y) = x; break; } } } int MerisFileData::get_n_dataset() { return epr_get_num_bands(product_id); }; string MerisFileData::get_dataset_name(int i) { EPR_SBandId* band_id = epr_get_band_id_at(product_id, i); return epr_get_band_name(band_id); }; int MerisFileData::get_dataset_data_type(string sds_name) { EPR_SBandId* band_id = epr_get_band_id(product_id, sds_name.c_str()); EPR_EDataTypeId datatype_id; if(sds_name!="latitude" && sds_name!="longitude" && sds_name!=string("atm_press") && band_id->sample_model != e_smod_3TOI && band_id->sample_model != e_smod_2TOF){ EPR_SDatasetId* dataset_id = band_id->dataset_ref.dataset_id; EPR_SRecord* record = epr_create_record(dataset_id); EPR_SFieldInfo* field_info = (EPR_SFieldInfo*)epr_get_ptr_array_elem_at(record->info->field_infos, band_id->dataset_ref.field_index - 1); datatype_id = field_info->data_type_id; } else{ datatype_id = band_id->data_type; } switch (datatype_id) { case e_tid_string: case e_tid_time: case e_tid_spare:{ bad_file e("bad type data"); throw e; break; } case e_tid_uchar:{ return DFNT_UINT8; } case e_tid_char:{ return DFNT_INT8; } case e_tid_ushort:{ return DFNT_UINT16; } case e_tid_short:{ return DFNT_INT16; } case e_tid_ulong:{ return DFNT_UINT32; } case e_tid_long:{ return DFNT_INT32; } case e_tid_float:{ return DFNT_FLOAT32; } case e_tid_double:{ return DFNT_FLOAT64; } default:{ bad_file e("bad type data"); throw e; break; } } } string MerisFileData::get_values_attr_dataset(string sds_name,string attr_name) { EPR_SDatasetId* dataset_id = epr_get_band_id(product_id, sds_name.c_str())->dataset_ref.dataset_id; const EPR_SRecord* record = epr_create_record_from_info(epr_get_record_info(dataset_id)); const EPR_SField* field = epr_get_field(record,attr_name.c_str()); if(field==NULL) return ""; string str=epr_get_field_elem_as_str(field); return str.c_str(); } bool MerisFileData::has_attr_dataset(string sds_name,string attr_name) { EPR_SDatasetId* dataset_id = epr_get_band_id(product_id, sds_name.c_str())->dataset_ref.dataset_id; const EPR_SRecord* record = epr_create_record_from_info(epr_get_record_info(dataset_id)); const char *field_name = attr_name.c_str(); EPR_SField* field; for (uint field_index = 0; field_index < record->num_fields; field_index++) { field = record->fields[field_index]; if (strcmp(field_name, field->info->name) == 0) { return true; } } return false; } string MerisFileData::get_values_attr(string attr_name) { const EPR_SRecord* record_mph = epr_get_mph(product_id); const EPR_SRecord* record_sph = epr_get_sph(product_id); const EPR_SField* field = NULL; for (uint field_index = 0; field_index < record_mph->num_fields; field_index++) { field = record_mph->fields[field_index]; const char *field_name = attr_name.c_str(); if (strcmp(field_name, field->info->name) == 0) { field = epr_get_field(record_mph,attr_name.c_str()); string str=epr_get_field_elem_as_str(field); return str.c_str(); } } field = epr_get_field(record_sph,attr_name.c_str()); if(field==NULL) return ""; string str=epr_get_field_elem_as_str(field); return str.c_str(); } bool MerisFileData::has_attr(string attr_name) { const EPR_SRecord* record_mph = epr_get_mph(product_id); const EPR_SRecord* record_sph = epr_get_sph(product_id); const char *field_name = attr_name.c_str(); EPR_SField* field; for (uint field_index = 0; field_index < record_mph->num_fields; field_index++) { field = record_mph->fields[field_index]; if (strcmp(field_name, field->info->name) == 0) { return true; } } for (uint field_index = 0; field_index < record_sph->num_fields; field_index++) { field = record_sph->fields[field_index]; if (strcmp(field_name, field->info->name) == 0) { return true; } } return false; } string MerisFileData::getMonth(const string &month) { if(month=="JAN") return "01"; else if(month=="FEB") return "02"; else if(month=="MAR") return "03"; else if(month=="APR") return "04"; else if(month=="MAY") return "05"; else if(month=="JUN") return "06"; else if(month=="JUL") return "07"; else if(month=="AUG") return "08"; else if(month=="SEP") return "09"; else if(month=="OCT") return "10"; else if(month=="NOV") return "11"; else if(month=="DEC") return "12"; bad_file e(month); throw e; } void MerisFileData::get_fillValue(const string &sds_name, void *fillValue) { if(sds_name=="surf_press") { uint8 *fv = (uint8*)fillValue; fv=0; return; } get_dataset_fill_value(sds_name, (void*) &fillValue); } void MerisFileData::getFillValues(char8 &fillvalue) { fillvalue = static_cast<int8 >((int8 )SCHAR_MIN); } void MerisFileData::getFillValues(uchar8 &fillvalue) { fillvalue = static_cast<uint8 >((uint8 )UCHAR_MAX); } void MerisFileData::getFillValues(int16 &fillvalue) { fillvalue = static_cast<int16 >((int16 )SHRT_MIN); } void MerisFileData::getFillValues(uint16 &fillvalue) { fillvalue = static_cast<uint16 >((uint16 )USHRT_MAX); } void MerisFileData::getFillValues(int32 &fillvalue) { fillvalue = static_cast<int32 >((int32 )LONG_MIN); } void MerisFileData::getFillValues(uint32 &fillvalue) { fillvalue = static_cast<uint32 >((uint32 )ULONG_MAX); } void MerisFileData::getFillValues(float32 &fillvalue) { fillvalue = static_cast<float32 >((float32 )-DBL_MAX); } void MerisFileData::getFillValues(float64 &fillvalue) { fillvalue = static_cast<float64 >((float64 )-LDBL_MAX); } /** * Interprates a memory data as a string. * * @param field the pointer at the array to convert * * @return the <code>char</code> typed element * or <code>NULL</code> if an error occured. */ string MerisFileData::epr_get_field_elem_as_str(const EPR_SField* field) { char *str = new char[field->info->num_elems * 128]; epr_clear_err(); if (field == NULL) { epr_set_err(e_err_invalid_field_name, "epr_get_field_elem_as_str: invalid field name"); return NULL; } if (field->info->data_type_id == e_tid_string) { sprintf(str, "\"%s\"", (const char*) field->elems); /* sprintf(ostream, "\""); for (i = 0; i < field->info->num_elems; i++) { sprintf(ostream, "%c", ((char*) field->elems)[i]); } sprintf(ostream, "\""); */ } else if (field->info->data_type_id == e_tid_time) { EPR_STime* time = (EPR_STime*) field->elems; sprintf(str, "{d=%ld, j=%ld, m=%ld}", time->days, time->seconds, time->microseconds); } else { if (field->info->num_elems > 1) { sprintf(str, "{"); } for (uint i = 0; i < field->info->num_elems; i++) { if (i > 0) sprintf(str, ", "); switch (field->info->data_type_id) { case e_tid_uchar: sprintf(str, "%u", ((uchar*) field->elems)[i]); break; case e_tid_char: sprintf(str, "%d", ((char*) field->elems)[i]); break; case e_tid_ushort: sprintf(str, "%u", ((ushort*) field->elems)[i]); break; case e_tid_short: sprintf(str, "%d", ((short*) field->elems)[i]); break; case e_tid_ulong: sprintf(str, "%lu", ((ulong*) field->elems)[i]); break; case e_tid_long: sprintf(str, "%d", ((int*) field->elems)[i]); break; case e_tid_float: sprintf(str, "%f", ((float*) field->elems)[i]); break; case e_tid_double: sprintf(str, "%f", ((double*) field->elems)[i]); break; default: sprintf(str, "<<unknown data type>>"); } } if (field->info->num_elems > 1) { sprintf(str, "}"); } } return str; } void MerisFileData::get_scaling(const string &sds_name, float64 &scale, float64 &offset) { if(sds_name==string("latitude") || sds_name==string("longitude") || sds_name==string("atm_press") ){ scale = 1.0; offset = 0.0; }else{ EPR_SBandId *band_id=epr_get_band_id(product_id, sds_name.c_str()); scale = band_id->scaling_factor; offset = band_id->scaling_offset; } };