40#include <gdal_utils.h>
41#include <ogr_spatialref.h>
42#include <gdalwarper.h>
44#include <libdap/Str.h>
45#include <libdap/Float32.h>
46#include <libdap/Int16.h>
47#include <libdap/Array.h>
48#include <libdap/Grid.h>
50#include <libdap/util.h>
51#include <libdap/Error.h>
54#include <BESDapError.h>
58#define DEBUG_KEY "geo"
69inline static int is_valid_lat(
const double lat)
71 return (lat >= -90 && lat <= 90);
74inline static int is_valid_lon(
const double lon)
76 return (lon >= -180 && lon <= 180);
86SizeBox get_size_box(Array *x, Array *y)
88 int src_x_size = x->dimension_size(x->dim_begin(),
true);
89 int src_y_size = y->dimension_size(y->dim_begin(),
true);
91 return SizeBox(src_x_size, src_y_size);
101static bool same_as(
const double a,
const double b)
104 return fabs(a - b) <= numeric_limits<float>::epsilon();
113bool monotonic_and_uniform(
const vector<double> &values,
double res)
115 vector<double>::size_type end_index = values.size() - 1;
116 for (vector<double>::size_type i = 0; i < end_index; ++i) {
119 if (!same_as((values[i+1] - values[i]), res))
137vector<double> get_geotransform_data(Array *x, Array *y,
bool test_maps )
143 SizeBox size = get_size_box(x, y);
146 vector<double> y_values(size.y_size);
147 extract_double_array(y, y_values);
149 double res_y = (y_values[y_values.size()-1] - y_values[0]) / (y_values.size() -1);
151 if (test_maps && !monotonic_and_uniform(y_values, res_y)){
152 string msg =
"The grids maps/dimensions must be monotonic and uniform (" + y->name() +
").";
153 BESDEBUG(DEBUG_KEY,
"ERROR get_geotransform_data(): " << msg << endl);
154 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
157 vector<double> x_values(size.x_size);
158 extract_double_array(x, x_values);
160 double res_x = (x_values[x_values.size()-1] - x_values[0]) / (x_values.size() -1);
162 if (test_maps && !monotonic_and_uniform(x_values, res_x)){
163 string msg =
"The grids maps/dimensions must be monotonic and uniform (" + x->name() +
").";
164 BESDEBUG(DEBUG_KEY,
"ERROR get_geotransform_data(): " << msg << endl);
165 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
181 vector<double> geo_transform(6);
182 geo_transform[0] = x_values[0];
183 geo_transform[1] = res_x;
184 geo_transform[2] = 0;
185 geo_transform[3] = y_values[0];
186 geo_transform[4] = 0;
187 geo_transform[5] = res_y;
189 return geo_transform;
203vector<GDAL_GCP> get_gcp_data(Array *x, Array *y,
int sample_x,
int sample_y)
205 SizeBox size = get_size_box(x, y);
208 vector<double> y_values(size.y_size);
209 extract_double_array(y, y_values);
212 vector<double> x_values(size.x_size);
213 extract_double_array(x, x_values);
222 unsigned long n_gcps = (size.x_size/sample_x) * (size.y_size/sample_y);
224 vector<GDAL_GCP> gcp_list(n_gcps);
225 GDALInitGCPs(n_gcps, gcp_list.data());
227 unsigned long count = 0;
228 for (
int i = 0; i < size.x_size; i += sample_x) {
231 for (
int j = 0; count < n_gcps && j < size.y_size; j += sample_y) {
232 gcp_list[count].dfGCPLine = j;
233 gcp_list[count].dfGCPPixel = i;
234 gcp_list[count].dfGCPX = x_values[i];
235 gcp_list[count].dfGCPY = y_values[j];
244GDALDataType get_array_type(
const Array *a)
246 switch (
const_cast<Array*
>(a)->var()->type()) {
276 string msg =
"Cannot perform geo-spatial operations on "
277 +
const_cast<Array*
>(a)->var()->type_name() +
" data.";
278 BESDEBUG(DEBUG_KEY,
"ERROR get_array_type(): " << msg << endl);
279 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
294static Array *transfer_values_helper(GDALRasterBand *band,
const unsigned long x,
const unsigned long y, Array *a)
297 vector<T> buf(x * y);
298 CPLErr error = band->RasterIO(GF_Read, 0, 0, x, y, buf.data(), x, y, get_array_type(a), 0, 0);
300 if (error != CPLE_None){
301 string msg = string(
"Could not extract data for array.") + CPLGetLastErrorMsg();
302 BESDEBUG(DEBUG_KEY,
"ERROR transfer_values_helper(): " << msg << endl);
303 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
305 a->set_value(buf, buf.size());
320static Vector *transfer_values_helper_vec(GDALRasterBand *band,
const int x,
const int y, Vector *a)
323 vector<T> buf(x * y);
324 CPLErr error = band->RasterIO(GF_Read, 0, 0, x, y, buf.data(), x, y, a->type(), 0, 0);
326 if (error != CPLE_None){
327 string msg = string(
"Could not extract data for array.") + CPLGetLastErrorMsg();
328 BESDEBUG(DEBUG_KEY,
"ERROR transfer_values_helper(): " << msg << endl);
329 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
331 a->set_value(buf, buf.size());
343Array *build_array_from_gdal_dataset(GDALDataset *source,
const Array *dest)
346 GDALRasterBand *band = source->GetRasterBand(1);
347 unsigned long x = band->GetXSize();
348 unsigned long y = band->GetYSize();
351 Array *result =
new Array(
"result",
const_cast<Array*
>(dest)->var()->ptr_duplicate());
352 result->append_dim(y);
353 result->append_dim(x);
356 switch (result->var()->type()) {
358 return transfer_values_helper<dods_byte>(source->GetRasterBand(1), x, y, result);
361 return transfer_values_helper<dods_uint16>(source->GetRasterBand(1), x, y, result);
364 return transfer_values_helper<dods_int16>(source->GetRasterBand(1), x, y, result);
367 return transfer_values_helper<dods_uint32>(source->GetRasterBand(1), x, y, result);
370 return transfer_values_helper<dods_int32>(source->GetRasterBand(1), x, y, result);
373 return transfer_values_helper<dods_float32>(source->GetRasterBand(1), x, y, result);
376 return transfer_values_helper<dods_float64>(source->GetRasterBand(1), x, y, result);
379 return transfer_values_helper<dods_byte>(source->GetRasterBand(1), x, y, result);
382 return transfer_values_helper<dods_int8>(source->GetRasterBand(1), x, y, result);
387 string msg =
"The source array to a geo-function contained an unsupported numeric type.";
388 BESDEBUG(DEBUG_KEY,
"ERROR build_array_from_gdal_dataset(): " << msg << endl);
389 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
400Array *build_array_from_gdal_dataset_3D(GDALDataset *source3D,
const Array *dest){
403 int t_size = source3D->GetRasterCount();
404 int x_size = source3D->GetRasterBand(1)->GetXSize();
405 int y_size = source3D->GetRasterBand(1)->GetYSize();
406 Array *result =
new Array(
"result",
const_cast<Array*
>(dest)->var()->ptr_duplicate());
407 result->append_dim(t_size);
408 result->append_dim(y_size);
409 result->append_dim(x_size);
411 vector<dods_float32> res(t_size * x_size * y_size);
412 for(
int i=0; i< t_size; i++) {
414 GDALRasterBand *band = source3D->GetRasterBand(i+1);
416 throw Error(
string(
"Could not get the GDALRasterBand for the GDALDataset: ") + CPLGetLastErrorMsg());
417 vector<double> gt(6);
418 source3D->GetGeoTransform(gt.data());
420 vector<dods_float32> buf(x_size * y_size);
421 CPLErr error = band->RasterIO(GF_Read, 0, 0, x_size, y_size, buf.data(), x_size, y_size, get_array_type(dest),
423 if (error != CPLE_None)
424 throw Error(
string(
"Could not extract data for translated GDAL Dataset.") + CPLGetLastErrorMsg());
428 res.insert(res.end(), buf.begin(), buf.end());
431 result->set_value(res, res.size());
458void build_maps_from_gdal_dataset(GDALDataset *dst, Array *x_map, Array *y_map,
bool name_maps )
461 vector<double> gt(6);
462 dst->GetGeoTransform(gt.data());
465 GDALRasterBand *band = dst->GetRasterBand(1);
468 unsigned long x = band->GetXSize();
471 x_map->append_dim(x,
"Longitude");
474 x_map->append_dim(x);
478 vector<dods_float32> x_map_vals(x);
479 dods_float32 *cur_x = x_map_vals.data();
480 dods_float32 *prev_x = cur_x;
483 for (
unsigned long i = 1; i < x; ++i) {
486 *cur_x++ = *prev_x++ + gt[1];
489 x_map->set_value(x_map_vals.data(), x);
492 unsigned long y = band->GetYSize();
495 y_map->append_dim(y,
"Latitude");
498 y_map->append_dim(y);
502 vector<dods_float32> y_map_vals(y);
503 dods_float32 *cur_y = y_map_vals.data();
504 dods_float32 *prev_y = cur_y;
507 for (
unsigned long i = 1; i < y; ++i) {
510 *cur_y++ = *prev_y++ + gt[5];
513 y_map->set_value(y_map_vals.data(), y);
539void build_maps_from_gdal_dataset_3D(GDALDataset *dst, Array *t, Array *t_map, Array *x_map, Array *y_map,
bool name_maps )
542 vector<double> gt(6);
543 dst->GetGeoTransform(gt.data());
546 GDALRasterBand *band = dst->GetRasterBand(1);
549 int t_size = t->size();
552 t_map->append_dim(t_size,
"Time");
555 t_map->append_dim(t_size);
558 vector<dods_float32> t_buf(t_size);
559 t->value(t_buf.data());
561 t_map->set_value(t_buf.data(), t_size);
564 unsigned long x = band->GetXSize();
567 x_map->append_dim(x,
"Longitude");
570 x_map->append_dim(x);
574 vector<dods_float32> x_map_vals(x);
575 dods_float32 *cur_x = x_map_vals.data();
576 dods_float32 *prev_x = cur_x;
579 for (
unsigned long i = 1; i < x; ++i) {
582 *cur_x++ = *prev_x++ + gt[1];
585 x_map->set_value(x_map_vals.data(), x);
588 unsigned long y = band->GetYSize();
591 y_map->append_dim(y,
"Latitude");
594 y_map->append_dim(y);
598 vector<dods_float32> y_map_vals(y);
599 dods_float32 *cur_y = y_map_vals.data();
600 dods_float32 *prev_y = cur_y;
603 for (
unsigned long i = 1; i < y; ++i) {
606 *cur_y++ = *prev_y++ + gt[5];
609 y_map->set_value(y_map_vals.data(), y);
620double get_missing_data_value(
const Array *src)
622 Array *a =
const_cast<Array*
>(src);
625 string mv_attr = a->get_attr_table().get_attr(
"missing_value");
626 if (mv_attr.empty()) mv_attr = a->get_attr_table().get_attr(
"_FillValue");
628 double missing_data = numeric_limits<double>::quiet_NaN();
629 if (!mv_attr.empty()) {
631 missing_data = strtod(mv_attr.c_str(), &endptr);
632 if (missing_data == 0.0 && endptr == mv_attr.c_str())
633 missing_data = numeric_limits<double>::quiet_NaN();
645Array::Dim_iter get_x_dim(
const libdap::Array *src)
647 Array *a =
const_cast<Array*
>(src);
648 int numDims = a->dimensions();
651 ss <<
"Ouch! Retrieving the 'x' dimension for the array ";
652 a->print_decl(ss,
"",
false,
true,
true);
653 ss <<
" FAILED Because it has less than 2 dimensions" << endl;
654 BESDEBUG(DEBUG_KEY, ss.str());
655 throw BESError(ss.str(),BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
657 Array::Dim_iter start = a->dim_begin();
658 Array::Dim_iter xDim = start + numDims - 1;
669Array::Dim_iter get_y_dim(
const libdap::Array *src)
671 Array *a =
const_cast<Array*
>(src);
672 int numDims = a->dimensions();
675 ss <<
"Ouch! Retrieving the 'y' dimension for the array ";
676 a->print_decl(ss,
"",
false,
true,
true);
677 ss <<
" FAILED Because it has less than 2 dimensions" << endl;
678 BESDEBUG(DEBUG_KEY, ss.str());
679 throw BESError(ss.str(),BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
681 Array::Dim_iter start = a->dim_begin();
682 Array::Dim_iter yDim = start + numDims - 2;
697bool array_is_effectively_2D(
const libdap::Array *src)
699 Array *a =
const_cast<Array*
>(src);
700 int numDims = a->dimensions();
701 if (numDims == 2)
return true;
702 if (numDims < 2)
return false;
704 Array::Dim_iter xDim = get_x_dim(a);
705 for (Array::Dim_iter thisDim = a->dim_begin(); thisDim < xDim; thisDim++) {
706 unsigned long size = a->dimension_size(thisDim,
true);
725void read_band_data(
const Array *src, GDALRasterBand* band)
727 Array *a =
const_cast<Array*
>(src);
729 if (!array_is_effectively_2D(src)) {
731 ss <<
"Cannot perform geo-spatial operations on an Array (";
732 ss << a->name() <<
") with " << a->dimensions() <<
" dimensions.";
733 ss <<
"Because the constrained shape of the array: ";
734 a->print_decl(ss,
"",
false,
true,
true);
735 ss <<
" is not a two-dimensional array." << endl;
736 BESDEBUG(DEBUG_KEY, ss.str());
737 throw BESError(ss.str(), BES_SYNTAX_USER_ERROR, __FILE__, __LINE__);
743 unsigned long x = a->dimension_size(get_x_dim(a),
true);
744 unsigned long y = a->dimension_size(get_y_dim(a),
true);
751 CPLErr error = band->RasterIO(GF_Write, 0, 0, x, y, a->get_buf(), x, y, get_array_type(a), 0, 0);
753 if (error != CPLE_None){
754 string msg =
"Could not load data for grid '" + a->name() +
"' msg: '" + CPLGetLastErrorMsg() +
"'";
755 BESDEBUG(DEBUG_KEY,
"ERROR read_band_data(): " << msg << endl);
756 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
770void add_band_data(
const Array *src, GDALDataset* ds)
772 Array *a =
const_cast<Array*
>(src);
779 char **options = NULL;
781 oss << reinterpret_cast<unsigned long>(a->get_buf());
782 options = CSLSetNameValue(options,
"DATAPOINTER", oss.str().c_str());
784 CPLErr error = ds->AddBand(get_array_type(a), options);
788 if (error != CPLE_None){
789 string msg =
"Could not add data for grid '" + a->name() +
"': " + CPLGetLastErrorMsg();
790 BESDEBUG(DEBUG_KEY,
"ERROR add_band_data(): " << msg << endl);
791 throw BESError(msg,BES_INTERNAL_ERROR,__FILE__,__LINE__);
814unique_ptr<GDALDataset> build_src_dataset(Array *data, Array *x, Array *y,
const string &srs)
816 GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(
"MEM");
818 string msg = string(
"Could not get the Memory driver for GDAL: ") + CPLGetLastErrorMsg();
819 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
820 throw BESError(msg,BES_INTERNAL_ERROR,__FILE__,__LINE__);
823 SizeBox array_size = get_size_box(x, y);
826 unique_ptr<GDALDataset> ds(driver->Create(
"result", array_size.x_size, array_size.y_size,
827 1 , get_array_type(data), NULL ));
830 add_band_data(data, ds.get());
834 GDALRasterBand *band = ds->GetRasterBand(1);
836 string msg =
"Could not get the GDAL RasterBand for Array '" + data->name() +
"': " + CPLGetLastErrorMsg();
837 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
838 throw BESError(msg,BES_INTERNAL_ERROR,__FILE__,__LINE__);
842 double no_data = get_missing_data_value(data);
843 band->SetNoDataValue(no_data);
846 read_band_data(data, band);
849 vector<double> geo_transform = get_geotransform_data(x, y);
850 ds->SetGeoTransform(geo_transform.data());
852 OGRSpatialReference native_srs;
853 if (CE_None != native_srs.SetWellKnownGeogCS(srs.c_str())){
854 string msg =
"Could not set '" + srs +
"' as the dataset native CRS.";
855 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
856 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
862 char *pszSRS_WKT = NULL;
863 native_srs.exportToWkt( &pszSRS_WKT );
864 ds->SetProjection( pszSRS_WKT );
865 CPLFree( pszSRS_WKT );
880unique_ptr<GDALDataset> scale_dataset(unique_ptr<GDALDataset>& src,
const SizeBox &size,
const string &crs ,
881 const string &interp )
884 argv = CSLAddString(argv,
"-of");
885 argv = CSLAddString(argv,
"MEM");
887 argv = CSLAddString(argv,
"-outsize");
890 argv = CSLAddString(argv, oss.str().c_str());
893 argv = CSLAddString(argv, oss.str().c_str());
895 argv = CSLAddString(argv,
"-b");
896 argv = CSLAddString(argv,
"1");
898 argv = CSLAddString(argv,
"-r");
899 argv = CSLAddString(argv, interp.c_str());
902 argv = CSLAddString(argv,
"-a_srs");
903 argv = CSLAddString(argv, crs.c_str());
906 if (BESISDEBUG(DEBUG_KEY)) {
909 BESDEBUG(DEBUG_KEY,
"argv: " << *local++ << endl);
916 cerr <<
"argv: " << *local++ << endl;
920 GDALTranslateOptions *options = GDALTranslateOptionsNew(argv, NULL );
922 int usage_error = CE_None;
923 GDALDatasetH dst_handle = GDALTranslate(
"warped_dst", src.get(), options, &usage_error);
924 if (!dst_handle || usage_error != CE_None) {
925 GDALClose(dst_handle);
926 GDALTranslateOptionsFree(options);
927 string msg = string(
"Error calling GDAL translate: ") + CPLGetLastErrorMsg();
928 BESDEBUG(DEBUG_KEY,
"ERROR scale_dataset(): " << msg << endl);
929 throw BESError(msg, BES_INTERNAL_ERROR, __FILE__, __LINE__);
932 unique_ptr<GDALDataset> dst(
static_cast<GDALDataset*
>(dst_handle));
934 GDALTranslateOptionsFree(options);
940unique_ptr<GDALDataset> scale_dataset_3D(unique_ptr<GDALDataset>& src,
const SizeBox &size,
const string &crs ,
941 const string &interp )
944 argv = CSLAddString(argv,
"-of");
945 argv = CSLAddString(argv,
"MEM");
947 argv = CSLAddString(argv,
"-outsize");
950 argv = CSLAddString(argv, oss.str().c_str());
953 argv = CSLAddString(argv, oss.str().c_str());
956 int n_bands = src.get()->GetRasterCount();
957 for(
int i=0; i < n_bands; i++){
960 argv = CSLAddString(argv,
"-b");
961 argv = CSLAddString(argv, oss.str().c_str());
964 argv = CSLAddString(argv,
"-r");
965 argv = CSLAddString(argv, interp.c_str());
968 argv = CSLAddString(argv,
"-a_srs");
969 argv = CSLAddString(argv, crs.c_str());
972 if (BESISDEBUG(DEBUG_KEY)) {
975 BESDEBUG(DEBUG_KEY,
"argv: " << *local++ << endl);
982 cerr <<
"argv: " << *local++ << endl;
986 GDALTranslateOptions *options = GDALTranslateOptionsNew(argv, NULL );
987 int usage_error = CE_None;
988 GDALDatasetH dst_handle = GDALTranslate(
"warped_dst", src.get(), options, &usage_error);
989 if (!dst_handle || usage_error != CE_None) {
990 GDALClose(dst_handle);
991 GDALTranslateOptionsFree(options);
992 string msg = string(
"Error calling GDAL translate: ") + CPLGetLastErrorMsg();
993 BESDEBUG(DEBUG_KEY,
"ERROR scale_dataset(): " << msg << endl);
994 throw BESError(msg, BES_INTERNAL_ERROR, __FILE__, __LINE__);
997 unique_ptr<GDALDataset> dst(
static_cast<GDALDataset*
>(dst_handle));
999 GDALTranslateOptionsFree(options);
1017Grid *scale_dap_array(
const Array *data,
const Array *x,
const Array *y,
const SizeBox &size,
1018 const string &crs,
const string &interp)
1021 Array *d =
const_cast<Array*
>(data);
1023 unique_ptr<GDALDataset> src = build_src_dataset(d,
const_cast<Array*
>(x),
const_cast<Array*
>(y));
1026 unique_ptr<GDALDataset> dst = scale_dataset(src, size, crs, interp);
1029 unique_ptr<Array> built_data(build_array_from_gdal_dataset(dst.get(), d));
1031 unique_ptr<Array> built_lat(
new Array(y->name(),
new Float32(y->name())));
1032 unique_ptr<Array> built_lon(
new Array(x->name(),
new Float32(x->name())));
1034 build_maps_from_gdal_dataset(dst.get(), built_lon.get(), built_lat.get());
1036 unique_ptr<Grid> result(
new Grid(d->name()));
1037 result->set_array(built_data.release());
1038 result->add_map(built_lat.release(),
false);
1039 result->add_map(built_lon.release(),
false);
1041 return result.release();
1054Grid *scale_dap_grid(
const Grid *g,
const SizeBox &size,
const string &crs,
const string &interp)
1056 string func(__func__);
1060 throw BESError(func+
"The Grid object is null.",BES_INTERNAL_ERROR,__FILE__,__LINE__);
1063 Array *data =
dynamic_cast<Array*
>(
const_cast<Grid*
>(g)->array_var());
1065 throw BESError(func+
"Unable to obtain data array from Grid '"+g->name()+
"'",BES_INTERNAL_ERROR,__FILE__,__LINE__);
1068 Grid::Map_riter ritr =
const_cast<Grid*
>(g)->map_rbegin();
1069 Array *x =
dynamic_cast<Array*
>(*ritr);
1070 Array *y =
dynamic_cast<Array*
>(*++ritr);
1073 throw BESError(func+
"Unable to obtain 2 Map arrays from Grid '"+g->name()+
"'",BES_INTERNAL_ERROR,__FILE__,__LINE__);
1076 return scale_dap_array(data, x, y, size, crs, interp);
1099unique_ptr<GDALDataset> build_src_dataset_3D(Array *data, Array *t, Array *x, Array *y,
const string &srs)
1101 Array *d =
dynamic_cast<Array*
>(data);
1103 GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(
"MEM");
1105 string msg = string(
"Could not get the Memory driver for GDAL: ") + CPLGetLastErrorMsg();
1106 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
1107 throw BESError(msg,BES_INTERNAL_ERROR,__FILE__,__LINE__);
1110 SizeBox array_size = get_size_box(x, y);
1111 int nBands = t->size();
1112 BESDEBUG(DEBUG_KEY,
"nBands = " << nBands << endl);
1113 int nBytes = data->prototype()->width();
1114 const int data_size = x->size() * y->size();
1115 unsigned int dsize = data_size * nBytes;
1117 unique_ptr<GDALDataset> ds(driver->Create(
"result", array_size.x_size, array_size.y_size, nBands, get_array_type(d),
1121 for(
int i=1; i<=nBands; i++){
1123 GDALRasterBand *band = ds->GetRasterBand(i);
1125 string msg =
"Could not get the GDAL RasterBand for Array '" + data->name() +
"': " + CPLGetLastErrorMsg();
1126 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
1127 throw BESError(msg,BES_INTERNAL_ERROR,__FILE__,__LINE__);
1130 double no_data = get_missing_data_value(data);
1131 band->SetNoDataValue(no_data);
1134 CPLErr error = band->RasterIO(GF_Write, 0, 0, x->size(), y->size(), data->get_buf() + dsize*(i-1), x->size(), y->size(), get_array_type(data), 0, 0);
1135 if (error != CPLE_None)
1136 throw Error(
"Could not write data for band: " + long_to_string(i) +
": " +
string(CPLGetLastErrorMsg()));
1141 vector<double> geo_transform = get_geotransform_data(x, y);
1142 ds->SetGeoTransform(geo_transform.data());
1144 OGRSpatialReference native_srs;
1145 if (CE_None != native_srs.SetWellKnownGeogCS(srs.c_str())){
1146 string msg =
"Could not set '" + srs +
"' as the dataset native CRS.";
1147 BESDEBUG(DEBUG_KEY,
"ERROR build_src_dataset(): " << msg << endl);
1148 throw BESError(msg,BES_SYNTAX_USER_ERROR,__FILE__,__LINE__);
1152 char *pszSRS_WKT = NULL;
1153 native_srs.exportToWkt( &pszSRS_WKT );
1154 ds->SetProjection( pszSRS_WKT );
1155 CPLFree( pszSRS_WKT );
1173Grid *scale_dap_array_3D(
const Array *data,
const Array *time,
const Array *lon,
const Array *lat,
const SizeBox &size,
1174 const string &crs,
const string &interp)
1177 Array *d =
const_cast<Array*
>(data);
1178 Array *t =
const_cast<Array*
>(time);
1179 Array *x =
const_cast<Array*
>(lon);
1180 Array *y =
const_cast<Array*
>(lat);
1183 unique_ptr<GDALDataset> src = build_src_dataset_3D(d,
const_cast<Array*
>(t),
const_cast<Array*
>(x),
const_cast<Array*
>(y));
1186 unique_ptr<GDALDataset> dst = scale_dataset_3D(src, size, crs, interp);
1189 unique_ptr<Array> built_data(build_array_from_gdal_dataset_3D(dst.get(), d));
1190 unique_ptr<Array> built_time(
new Array(t->name(),
new Float32(t->name())));
1191 unique_ptr<Array> built_lat(
new Array(y->name(),
new Float32(y->name())));
1192 unique_ptr<Array> built_lon(
new Array(x->name(),
new Float32(x->name())));
1195 build_maps_from_gdal_dataset_3D(dst.get(), t, built_time.get(), built_lon.get(), built_lat.get());
1198 unique_ptr<Grid> result(
new Grid(d->name()));
1199 result->set_array(built_data.release());
1200 result->add_map(built_time.release(),
false);
1201 result->add_map(built_lat.release(),
false);
1202 result->add_map(built_lon.release(),
false);
1204 return result.release();