29#include <cpl_string.h>
33#include <libdap/Byte.h>
34#include <libdap/UInt16.h>
35#include <libdap/Int16.h>
36#include <libdap/UInt32.h>
37#include <libdap/Int32.h>
38#include <libdap/Float32.h>
39#include <libdap/Float64.h>
41#include <libdap/DDS.h>
42#include <libdap/DAS.h>
43#include <libdap/BaseTypeFactory.h>
45#include <libdap/DMR.h>
46#include <libdap/D4Group.h>
47#include <libdap/D4Dimensions.h>
48#include <libdap/D4Maps.h>
49#include <libdap/D4Attributes.h>
50#include <libdap/D4BaseTypeFactory.h>
51#include <libdap/debug.h>
65static void attach_str_attr_item(AttrTable *parent_table,
const char *pszKey,
const char *pszValue)
69 char *pszEscapedText = CPLEscapeString(pszValue, -1,
70 CPLES_BackslashQuotable);
74 parent_table->append_attr(pszKey,
"String", pszValue );
77 CPLFree(pszEscapedText);
88static void translate_metadata(
char **md, AttrTable *parent_table)
93 md_table = parent_table->append_container(
string(
"Metadata"));
95 for (i = 0; md != NULL && md[i] != NULL; i++) {
99 pszValue = CPLParseNameValue(md[i], &pszKey);
101 attach_str_attr_item(md_table, pszKey, pszValue);
113static void build_global_attributes(
const GDALDatasetH& hDS, AttrTable* attr_table)
118 double adfGeoTransform[6];
119 if (GDALGetGeoTransform(hDS, adfGeoTransform) == CE_None
120 && (adfGeoTransform[0] != 0.0 || adfGeoTransform[1] != 1.0 || adfGeoTransform[2] != 0.0
121 || adfGeoTransform[3] != 0.0 || adfGeoTransform[4] != 0.0 || fabs(adfGeoTransform[5]) != 1.0)) {
123 char szGeoTransform[200];
124 double dfMaxX, dfMinX, dfMaxY, dfMinY;
125 int nXSize = GDALGetRasterXSize(hDS);
126 int nYSize = GDALGetRasterYSize(hDS);
129 MAX(MAX(adfGeoTransform[0], adfGeoTransform[0] + adfGeoTransform[1] * nXSize),
130 MAX(adfGeoTransform[0] + adfGeoTransform[2] * nYSize, adfGeoTransform[0] + adfGeoTransform[2] * nYSize + adfGeoTransform[1] * nXSize));
132 MIN(MIN(adfGeoTransform[0], adfGeoTransform[0] + adfGeoTransform[1] * nXSize),
133 MIN(adfGeoTransform[0] + adfGeoTransform[2] * nYSize, adfGeoTransform[0] + adfGeoTransform[2] * nYSize + adfGeoTransform[1] * nXSize));
135 MAX(MAX(adfGeoTransform[3], adfGeoTransform[3] + adfGeoTransform[4] * nXSize),
136 MAX(adfGeoTransform[3] + adfGeoTransform[5] * nYSize, adfGeoTransform[3] + adfGeoTransform[5] * nYSize + adfGeoTransform[4] * nXSize));
138 MIN(MIN(adfGeoTransform[3], adfGeoTransform[3] + adfGeoTransform[4] * nXSize),
139 MIN(adfGeoTransform[3] + adfGeoTransform[5] * nYSize, adfGeoTransform[3] + adfGeoTransform[5] * nYSize + adfGeoTransform[4] * nXSize));
141 attr_table->append_attr(
"Northernmost_Northing",
"Float64", CPLSPrintf(
"%.16g", dfMaxY));
142 attr_table->append_attr(
"Southernmost_Northing",
"Float64", CPLSPrintf(
"%.16g", dfMinY));
143 attr_table->append_attr(
"Easternmost_Easting",
"Float64", CPLSPrintf(
"%.16g", dfMaxX));
146 attr_table->append_attr(
"Westernmost_Northing",
"Float64", CPLSPrintf(
"%.16g", dfMinX));
148 attr_table->append_attr(
"Westernmost_Easting",
"Float64", CPLSPrintf(
"%.16g", dfMinX));
150 snprintf(szGeoTransform, 200,
"%.16g %.16g %.16g %.16g %.16g %.16g", adfGeoTransform[0], adfGeoTransform[1],
151 adfGeoTransform[2], adfGeoTransform[3], adfGeoTransform[4], adfGeoTransform[5]);
153 attach_str_attr_item(attr_table,
"GeoTransform", szGeoTransform);
160 md = GDALGetMetadata(hDS, NULL);
161 if (md != NULL) translate_metadata(md, attr_table);
166 const char* pszWKT = GDALGetProjectionRef(hDS);
167 if (pszWKT != NULL && strlen(pszWKT) > 0) attach_str_attr_item(attr_table,
"spatial_ref", pszWKT);
177static void build_variable_attributes(
const GDALDatasetH &hDS, AttrTable *band_attr,
const int iBand)
185 GDALRasterBandH hBand = GDALGetRasterBand(hDS, iBand + 1);
187 dfValue = GDALGetRasterOffset(hBand, &bSuccess);
189 snprintf(szValue, 128,
"%.16g", dfValue);
190 band_attr->append_attr(
"add_offset",
"Float64", szValue);
196 dfValue = GDALGetRasterScale(hBand, &bSuccess);
198 snprintf(szValue, 128,
"%.16g", dfValue);
199 band_attr->append_attr(
"scale_factor",
"Float64", szValue);
205 dfValue = GDALGetRasterNoDataValue(hBand, &bSuccess);
207 snprintf(szValue, 128,
"%.16g", dfValue);
208 band_attr->append_attr(
"missing_value",
"Float64", szValue);
214 if (GDALGetDescription(hBand) != NULL && strlen(GDALGetDescription(hBand)) > 0) {
215 attach_str_attr_item(band_attr,
"Description", GDALGetDescription(hBand));
221 if (GDALGetRasterColorInterpretation(hBand) != GCI_Undefined) {
222 attach_str_attr_item(band_attr,
"PhotometricInterpretation",
223 GDALGetColorInterpretationName(GDALGetRasterColorInterpretation(hBand)));
229 char **md = GDALGetMetadata(hBand, NULL);
230 if (md != NULL) translate_metadata(md, band_attr);
237 hCT = GDALGetRasterColorTable(hBand);
240 int iColor, nColorCount = GDALGetColorEntryCount(hCT);
242 ct_attr = band_attr->append_container(
string(
"Colormap"));
244 for (iColor = 0; iColor < nColorCount; iColor++) {
246 AttrTable *color_attr;
248 color_attr = ct_attr->append_container(
string(CPLSPrintf(
"color_%d", iColor)));
250 GDALGetColorEntryAsRGB(hCT, iColor, &sRGB);
252 color_attr->append_attr(
"red",
"byte", CPLSPrintf(
"%d", sRGB.c1));
253 color_attr->append_attr(
"green",
"byte", CPLSPrintf(
"%d", sRGB.c2));
254 color_attr->append_attr(
"blue",
"byte", CPLSPrintf(
"%d", sRGB.c3));
255 color_attr->append_attr(
"alpha",
"byte", CPLSPrintf(
"%d", sRGB.c4));
273void gdal_read_dataset_attributes(DAS &das,
const GDALDatasetH &hDS)
275 AttrTable *attr_table = das.add_table(
string(
"GLOBAL"),
new AttrTable);
277 build_global_attributes(hDS, attr_table);
282 for (
int iBand = 0; iBand < GDALGetRasterCount(hDS); iBand++) {
284 AttrTable *band_attr;
289 snprintf(szName, 128,
"band_%d", iBand + 1);
290 band_attr = das.add_table(
string(szName),
new AttrTable);
292 build_variable_attributes(hDS, band_attr, iBand);
306void gdal_read_dataset_variables(DDS *dds,
const GDALDatasetH &hDS,
const string &filename,
bool include_attrs)
309 if(
true == include_attrs) {
310 AttrTable *global_attr = dds->get_attr_table().append_container(
"GLOBAL");
311 build_global_attributes(hDS, global_attr);
318 GDALDataType eBufType;
320 for (
int iBand = 0; iBand < GDALGetRasterCount(hDS); iBand++) {
321 DBG(cerr <<
"In dgal_dds.cc iBand" << endl);
323 GDALRasterBandH hBand = GDALGetRasterBand(hDS, iBand + 1);
326 oss <<
"band_" << iBand + 1;
328 eBufType = GDALGetRasterDataType(hBand);
331 switch (GDALGetRasterDataType(hBand)) {
333 bt = factory.NewByte(oss.str());
337 bt = factory.NewUInt16(oss.str());
341 bt = factory.NewInt16(oss.str());
345 bt = factory.NewUInt32(oss.str());
349 bt = factory.NewInt32(oss.str());
353 bt = factory.NewFloat32(oss.str());
357 bt = factory.NewFloat64(oss.str());
366 bt = factory.NewFloat64(oss.str());
367 eBufType = GDT_Float64;
375 grid =
new GDALGrid(filename, oss.str());
385 ar =
new GDALArray(oss.str(), 0, filename, eBufType, iBand + 1);
386 ar->add_var_nocopy(bt);
387 ar->append_dim(GDALGetRasterYSize(hDS),
"northing");
388 ar->append_dim(GDALGetRasterXSize(hDS),
"easting");
390 grid->add_var_nocopy(ar, libdap::array);
396 bt = factory.NewFloat64(
"northing");
397 ar =
new GDALArray(
"northing", 0, filename, GDT_Float64, iBand + 1);
398 ar->add_var_nocopy(bt);
399 ar->append_dim(GDALGetRasterYSize(hDS),
"northing");
401 grid->add_var_nocopy(ar, maps);
404 bt = factory.NewFloat64(
"easting");
405 ar =
new GDALArray(
"easting", 0, filename, GDT_Float64, iBand + 1);
406 ar->add_var_nocopy(bt);
407 ar->append_dim(GDALGetRasterXSize(hDS),
"easting");
409 grid->add_var_nocopy(ar, maps);
411 DBG(cerr <<
"Type of grid: " <<
typeid(grid).name() << endl);
414 if(
true == include_attrs) {
415 AttrTable &band_attr = grid->get_attr_table();
416 build_variable_attributes(hDS, &band_attr, iBand);
419 dds->add_var_nocopy(grid);
436void gdal_read_dataset_variables(DMR *dmr,
const GDALDatasetH &hDS,
const string &filename)
447 AttrTable *attr =
new AttrTable();
448 AttrTable *global_attr = attr->append_container(
"GLOBAL");
450 build_global_attributes(hDS, global_attr);
452 dmr->root()->attributes()->transform_to_dap4(*attr);
453 delete attr; attr = 0;
455 D4BaseTypeFactory factory;
470 int sdim_band_num = 1;
471 for (; sdim_band_num <= GDALGetRasterCount(hDS); ++sdim_band_num) {
472 if (GDALGetRasterBandYSize(GDALGetRasterBand(hDS, sdim_band_num)) == GDALGetRasterYSize(hDS)
473 && GDALGetRasterBandXSize(GDALGetRasterBand(hDS, sdim_band_num)) == GDALGetRasterXSize(hDS)) {
479 const string northing =
"northing";
481 D4Dimension *northing_dim =
new D4Dimension(northing, GDALGetRasterYSize(hDS));
482 dmr->root()->dims()->add_dim_nocopy(northing_dim);
484 Array *northing_map =
new GDALArray(northing, 0, filename, GDT_Float64, sdim_band_num);
485 northing_map->add_var_nocopy(factory.NewFloat64(northing));
486 northing_map->append_dim(northing_dim);
488 dmr->root()->add_var_nocopy(northing_map);
490 const string easting =
"easting";
491 D4Dimension *easting_dim =
new D4Dimension(easting, GDALGetRasterXSize(hDS));
492 dmr->root()->dims()->add_dim_nocopy(easting_dim);
493 Array *easting_map =
new GDALArray(easting, 0, filename, GDT_Float64, sdim_band_num);
494 easting_map->add_var_nocopy(factory.NewFloat64(easting));
495 easting_map->append_dim(easting_dim);
496 dmr->root()->add_var_nocopy(easting_map);
502 GDALDataType eBufType;
504 for (
int iBand = 0; iBand < GDALGetRasterCount(hDS); iBand++) {
505 DBG(cerr <<
"In dgal_dds.cc iBand" << endl);
507 GDALRasterBandH hBand = GDALGetRasterBand(hDS, iBand + 1);
510 oss <<
"band_" << iBand + 1;
512 eBufType = GDALGetRasterDataType(hBand);
515 switch (GDALGetRasterDataType(hBand)) {
517 bt = factory.NewByte(oss.str());
521 bt = factory.NewUInt16(oss.str());
525 bt = factory.NewInt16(oss.str());
529 bt = factory.NewUInt32(oss.str());
533 bt = factory.NewInt32(oss.str());
537 bt = factory.NewFloat32(oss.str());
541 bt = factory.NewFloat64(oss.str());
551 bt = factory.NewFloat64(oss.str());
552 eBufType = GDT_Float64;
558 Array *ar =
new GDALArray(oss.str(), 0, filename, eBufType, iBand + 1);
559 ar->add_var_nocopy(bt);
565 if (GDALGetRasterBandYSize(hBand) == GDALGetRasterYSize(hDS)
566 && GDALGetRasterBandXSize(hBand) == GDALGetRasterXSize(hDS)) {
568 ar->append_dim(northing_dim);
569 ar->append_dim(easting_dim);
572 ar->maps()->add_map(
new D4Map(
string(
"/") + northing, northing_map, ar));
573 ar->maps()->add_map(
new D4Map(
string(
"/") + easting, easting_map, ar));
577 ar->append_dim(GDALGetRasterBandYSize(hBand), northing);
578 ar->append_dim(GDALGetRasterBandXSize(hBand), easting);
583 AttrTable &band_attr = ar->get_attr_table();
584 build_variable_attributes(hDS, &band_attr, iBand);
585 ar->attributes()->transform_to_dap4(band_attr);
587 dmr->root()->add_var_nocopy(ar);
608void read_data_array(
GDALArray *array,
const GDALRasterBandH &hBand)
613 Array::Dim_iter p = array->dim_begin();
614 int start = array->dimension_start(p,
true);
615 int stride = array->dimension_stride(p,
true);
616 int stop = array->dimension_stop(p,
true);
619 if (array->dimension_size(p,
true) == 0) {
622 stop = GDALGetRasterBandYSize(hBand) - 1;
626 int start_2 = array->dimension_start(p,
true);
627 int stride_2 = array->dimension_stride(p,
true);
628 int stop_2 = array->dimension_stop(p,
true);
630 if (array->dimension_size(p,
true) == 0) {
633 stop_2 = GDALGetRasterBandXSize(hBand) - 1;
639 int nWinXOff, nWinYOff, nWinXSize, nWinYSize, nBufXSize, nBufYSize;
643 nWinXSize = stop_2 + 1 - start_2;
644 nWinYSize = stop + 1 - start;
646 nBufXSize = (stop_2 - start_2) / stride_2 + 1;
647 nBufYSize = (stop - start) / stride + 1;
652 int nPixelSize = GDALGetDataTypeSize(array->get_gdal_buf_type()) / 8;
658 CPLErr eErr = GDALRasterIO(hBand, GF_Read, nWinXOff, nWinYOff, nWinXSize, nWinYSize, pData.data(), nBufXSize,
659 nBufYSize, array->get_gdal_buf_type(), 0, 0);
660 if (eErr != CE_None)
throw Error(
"Error reading: " + array->name());
662 array->val2buf(pData.data());
683void read_map_array(Array *
map,
const GDALRasterBandH &hBand,
const GDALDatasetH &hDS)
685 Array::Dim_iter p =
map->dim_begin();
686 int start =
map->dimension_start(p,
true);
687 int stride =
map->dimension_stride(p,
true);
688 int stop =
map->dimension_stop(p,
true);
690 if (start + stop + stride == 0) {
693 if (
map->name() ==
"northing")
694 stop = GDALGetRasterBandYSize(hBand) - 1;
695 else if (
map->name() ==
"easting")
696 stop = GDALGetRasterBandXSize(hBand) - 1;
698 throw Error(
"Expected a map named 'northing' or 'easting' but got: " +
map->name());
701 int nBufSize = (stop - start) / stride + 1;
708 double adfGeoTransform[6];
710 if (GDALGetGeoTransform(hDS, adfGeoTransform) != CE_None) {
711 adfGeoTransform[0] = 0.0;
712 adfGeoTransform[1] = 1.0;
713 adfGeoTransform[2] = 0.0;
714 adfGeoTransform[3] = 0.0;
715 adfGeoTransform[4] = 0.0;
716 adfGeoTransform[5] = 1.0;
724 if (
map->name() ==
"northing") {
725 for (
int i = 0, iLine = start; iLine <= stop; iLine += stride) {
726 padfMap[i++] = adfGeoTransform[3] + adfGeoTransform[5] * iLine;
729 else if (
map->name() ==
"easting") {
730 for (
int i = 0, iPixel = start; iPixel <= stop; iPixel += stride) {
731 padfMap[i++] = adfGeoTransform[0] + iPixel * adfGeoTransform[1];
735 throw Error(
"Expected a map named 'northing' or 'easting' but got: " +
map->name());
737 map->val2buf((
void *) padfMap.data());