OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
gdal_dds.cc
Go to the documentation of this file.
1 
2 // This file is part of the GDAL OPeNDAP Adapter
3 
4 // Copyright (c) 2004 OPeNDAP, Inc.
5 // Author: Frank Warmerdam <warmerdam@pobox.com>
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
22 
23 #include "config.h"
24 
25 //#define DODS_DEBUG 1
26 
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 
31 #include <gdal.h>
32 
33 #include <DDS.h>
34 #include <DAS.h>
35 #include <debug.h>
36 
37 #include "GDALTypes.h"
38 
39 using namespace libdap;
40 
41 extern void gdal_read_dataset_attributes(DAS &dds, const string &filename);
42 
43 /************************************************************************/
44 /* read_descriptors() */
45 /************************************************************************/
46 
47 GDALDatasetH gdal_read_dataset_variables(DDS *dds, const string &filename)
48 {
49  GDALDatasetH hDS;
50 /* -------------------------------------------------------------------- */
51 /* Open the dataset. */
52 /* -------------------------------------------------------------------- */
53 
54  // TODO Since this code no longer closes the dataset, it would be
55  // better to move the open operation outside it, to the caller.
56  // jhrg 7/26/12
57  GDALAllRegister();
58  hDS = GDALOpen(filename.c_str(), GA_ReadOnly);
59 
60  if (hDS == NULL)
61  throw Error(string(CPLGetLastErrorMsg()));
62 
63 
64 /* -------------------------------------------------------------------- */
65 /* Create the basic matrix for each band. */
66 /* -------------------------------------------------------------------- */
67  GDALDataType eBufType;
68 
69  for( int iBand = 0; iBand < GDALGetRasterCount( hDS ); iBand++ )
70  {
71  DBG(cerr << "In dgal_dds.cc iBand" << endl);
72 
73  GDALRasterBandH hBand = GDALGetRasterBand( hDS, iBand+1 );
74 #if 0
75  //BaseType *bt;
76  // TODO ostringstream
77  char szName[32];
78  // nsprintf if not ostringstream
79  sprintf( szName, "band_%d", iBand+1 );
80 #endif
81  ostringstream oss;
82  oss << "band_" << iBand+1;
83 
84  eBufType = GDALGetRasterDataType( hBand );
85 
86  BaseType *bt;
87  switch( GDALGetRasterDataType( hBand ) )
88  {
89  case GDT_Byte:
90  bt = new Byte( oss.str() );
91  break;
92 
93  case GDT_UInt16:
94  bt = new UInt16( oss.str() );
95  break;
96 
97  case GDT_Int16:
98  bt = new Int16( oss.str() );
99  break;
100 
101  case GDT_UInt32:
102  bt = new UInt32( oss.str() );
103  break;
104 
105  case GDT_Int32:
106  bt = new Int32( oss.str() );
107  break;
108 
109  case GDT_Float32:
110  bt = new Float32( oss.str() );
111  break;
112 
113  case GDT_Float64:
114  bt = new Float64( oss.str() );
115  break;
116 
117  case GDT_CFloat32:
118  case GDT_CFloat64:
119  case GDT_CInt16:
120  case GDT_CInt32:
121  default:
122  // TODO eventually we need to preserve complex info
123  bt = new Float64( oss.str() );
124  eBufType = GDT_Float64;
125  break;
126  }
127 
128 /* -------------------------------------------------------------------- */
129 /* Create a grid to hold the raster. */
130 /* -------------------------------------------------------------------- */
131  Grid *grid;
132  grid = new GDALGrid( filename, oss.str(), hBand, eBufType );
133 
134 /* -------------------------------------------------------------------- */
135 /* Make into an Array for the raster data with appropriate */
136 /* dimensions. */
137 /* -------------------------------------------------------------------- */
138  Array *ar;
139  // A 'feature' of Array is that it copies the variable passed to
140  // its ctor. To get around that, pass null and use add_var_nocopy().
141 #if 0
142  ar = new GDALArray( oss.str(), 0 );
143 #endif
144  // Added for the DAP4 response.
145  ar = new GDALArray( oss.str(), 0, filename, hBand, eBufType );
146  ar->add_var_nocopy( bt );
147  ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );
148  ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );
149 
150  grid->add_var_nocopy( ar, array );
151 
152 /* -------------------------------------------------------------------- */
153 /* Add the dimension map arrays. */
154 /* -------------------------------------------------------------------- */
155  bt = new GDALFloat64( "northing" );
156  ar = new GDALArray( "northing", 0, filename, hBand, eBufType );
157  ar->add_var_nocopy( bt );
158  ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );
159 
160  grid->add_var_nocopy( ar, maps );
161 
162  bt = new GDALFloat64( "easting" );
163  ar = new GDALArray( "easting", 0, filename, hBand, eBufType );
164  ar->add_var_nocopy( bt );
165  ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );
166 
167  grid->add_var_nocopy( ar, maps );
168 
169  DBG(cerr << "Type of grid: " << typeid(grid).name() << endl);
170 
171  dds->add_var_nocopy( grid );
172  }
173 
174  return hDS;
175 }
176 
191 void read_data_array(GDALArray *array, GDALRasterBandH hBand, GDALDataType eBufType) {
192  /* -------------------------------------------------------------------- */
193  /* Collect the x and y sampling values from the constraint. */
194  /* -------------------------------------------------------------------- */
195  Array::Dim_iter p = array->dim_begin();
196  int start = array->dimension_start(p, true);
197  int stride = array->dimension_stride(p, true);
198  int stop = array->dimension_stop(p, true);
199 
200  p++;
201  int start_2 = array->dimension_start(p, true);
202  int stride_2 = array->dimension_stride(p, true);
203  int stop_2 = array->dimension_stop(p, true);
204 
205  if (start + stop + stride == 0) { //default rows
206  start = 0;
207  stride = 1;
208  stop = GDALGetRasterBandYSize(hBand) - 1;
209  }
210  if (start_2 + stop_2 + stride_2 == 0) { //default columns
211  start_2 = 0;
212  stride_2 = 1;
213  stop_2 = GDALGetRasterBandXSize(hBand) - 1;
214  }
215 
216  /* -------------------------------------------------------------------- */
217  /* Build a window and buf size from this. */
218  /* -------------------------------------------------------------------- */
219  int nWinXOff, nWinYOff, nWinXSize, nWinYSize, nBufXSize, nBufYSize;
220 
221  nWinXOff = start_2;
222  nWinYOff = start;
223  nWinXSize = stop_2 + 1 - start_2;
224  nWinYSize = stop + 1 - start;
225 
226  nBufXSize = (stop_2 - start_2) / stride_2 + 1;
227  nBufYSize = (stop - start) / stride + 1;
228 
229  /* -------------------------------------------------------------------- */
230  /* Allocate buffer. */
231  /* -------------------------------------------------------------------- */
232  int nPixelSize = GDALGetDataTypeSize(eBufType) / 8;
233  vector<char> pData(nBufXSize * nBufYSize * nPixelSize);
234 
235  /* -------------------------------------------------------------------- */
236  /* Read request into buffer. */
237  /* -------------------------------------------------------------------- */
238  CPLErr eErr = GDALRasterIO(hBand, GF_Read, nWinXOff, nWinYOff, nWinXSize, nWinYSize,
239  &pData[0], nBufXSize, nBufYSize, eBufType, 0, 0);
240  if (eErr != CE_None)
241  throw Error("Error reading: " + array->name());
242 
243  array->val2buf(&pData[0]);
244 }
245 
254 void read_map_array(Array *map, GDALRasterBandH hBand, string filename)
255 {
256  Array::Dim_iter p = map->dim_begin();
257  int start = map->dimension_start(p, true);
258  int stride = map->dimension_stride(p, true);
259  int stop = map->dimension_stop(p, true);
260 
261  if (start + stop + stride == 0) { //default rows
262  start = 0;
263  stride = 1;
264  if (map->name() == "northing")
265  stop = GDALGetRasterBandYSize(hBand) - 1;
266  else if (map->name() == "easting")
267  stop = GDALGetRasterBandXSize(hBand) - 1;
268  else
269  throw Error("Expected a map named 'northing' or 'easting' but got: " + map->name());
270  }
271 
272  int nBufSize = (stop - start) / stride + 1;
273 
274  /* -------------------------------------------------------------------- */
275  /* Read or default the geotransform used to generate the */
276  /* georeferencing maps. */
277  /* -------------------------------------------------------------------- */
278 
279  // Move this into the gdal_dds.cc code so that it store this in the
280  // Grid or maybe in the GDALDDS instance? Then we can avoid a second
281  // open/read operation on the file. jhrg
282  GDALDatasetH hDS;
283  GDALAllRegister(); // even though the calling function called this.
284 
285  hDS = GDALOpen(filename.c_str(), GA_ReadOnly);
286 
287  if (hDS == NULL) throw Error(string(CPLGetLastErrorMsg()));
288 
289  double adfGeoTransform[6];
290 
291  if (GDALGetGeoTransform(hDS, adfGeoTransform) != CE_None) {
292  adfGeoTransform[0] = 0.0;
293  adfGeoTransform[1] = 1.0;
294  adfGeoTransform[2] = 0.0;
295  adfGeoTransform[3] = 0.0;
296  adfGeoTransform[4] = 0.0;
297  adfGeoTransform[5] = 1.0;
298  }
299 
300  GDALClose(hDS);
301 
302  /* -------------------------------------------------------------------- */
303  /* Set the map array. */
304  /* -------------------------------------------------------------------- */
305  vector<double> padfMap(nBufSize);
306 
307  if (map->name() == "northing") {
308  for (int i = 0, iLine = start; iLine <= stop; iLine += stride) {
309  padfMap[i++] = adfGeoTransform[3] + adfGeoTransform[5] * iLine;
310  }
311  }
312  else if (map->name() == "easting") {
313  for (int i = 0, iPixel = start; iPixel <= stop; iPixel += stride) {
314  padfMap[i++] = adfGeoTransform[0] + iPixel * adfGeoTransform[1];
315  }
316  }
317  else
318  throw Error("Expected a map named 'northing' or 'easting' but got: " + map->name());
319 
320  map->val2buf((void *) &padfMap[0]);
321 }
void gdal_read_dataset_attributes(DAS &dds, const string &filename)
Definition: gdal_das.cc:43
static class NCMLUtil overview
void read_map_array(Array *map, GDALRasterBandH hBand, string filename)
Read one of the Map arrays.
Definition: gdal_dds.cc:254
#define NULL
Definition: wcsUtil.h:65
void read_data_array(GDALArray *array, GDALRasterBandH hBand, GDALDataType eBufType)
Read the data array of a DAP2 Grid.
Definition: gdal_dds.cc:191
GDALDatasetH gdal_read_dataset_variables(DDS *dds, const string &filename)
Definition: gdal_dds.cc:47