OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
AsciiGrid.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of asciival, software which can return an ASCII
4 // representation of the data read from a DAP server.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 // (c) COPYRIGHT URI/MIT 1998,2000
26 // Please read the full copyright statement in the file COPYRIGHT_URI.
27 //
28 // Authors:
29 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
30 
31 // implementation for AsciiGrid. See AsciiByte.
32 //
33 // 3/12/98 jhrg
34 
35 #include "config.h"
36 
37 #include <iostream>
38 #include <string>
39 
40 using namespace std;
41 
42 #include <InternalErr.h>
43 
44 #include <BESDebug.h>
45 
46 // #define DODS_DEBUG
47 
48 #include "AsciiGrid.h"
49 #include "AsciiArray.h"
50 #include "debug.h"
51 #include "get_ascii.h"
52 
53 using namespace dap_asciival;
54 
55 BaseType *
57 {
58  return new AsciiGrid(*this);
59 }
60 
61 AsciiGrid::AsciiGrid(const string &n) :
62  Grid(n)
63 {
64 }
65 
66 AsciiGrid::AsciiGrid(Grid *grid) :
67  Grid(grid->name()), AsciiOutput(grid)
68 {
69  BaseType *bt = basetype_to_asciitype(grid->array_var());
70  add_var(bt, array);
71  // add_var makes a copy of the base type passed to it, so delete it here
72  delete bt;
73  bt = 0;
74 
75  Grid::Map_iter i = grid->map_begin();
76  Grid::Map_iter e = grid->map_end();
77  while (i != e) {
78  bt = basetype_to_asciitype(*i);
79  add_var(bt, maps);
80  // add_var makes a copy of the base type passed to it, so delete it here
81  delete bt;
82  ++i;
83  }
84 
85  BaseType::set_send_p(grid->send_p());
86 }
87 
89 {
90 }
91 
92 void AsciiGrid::print_ascii(ostream &strm, bool print_name)
93  throw(InternalErr)
94 {
95  BESDEBUG("ascii", "In AsciiGrid::print_ascii" << endl);
96 
97  Grid *g = dynamic_cast<Grid *> (_redirect);
98  if (!g)
99  g = this;
100 
101  // If the 'array' part of the Grid is not projected, then only maps are
102  // to be printed and those should be printed like arrays in a structure.
103  // Similarly, if any of the maps are not projected, then the maps and
104  // array in the grid should be printed like arrays in a structure. The
105  // general rule is that if everything in the Grid (all maps plus the array)
106  // are projected, then print as a Grid, else print as if the Gird is a
107  // Structure.
108  if (projection_yields_grid()) {
109  if (dynamic_cast<Array &> (*g->array_var()).dimensions(true) > 1)
110  print_grid(strm, print_name);
111  else
112  print_vector(strm, print_name);
113  }
114  else {
115  Map_iter m = map_begin();
116  while (m != map_end()) {
117  if ((*m)->send_p()) {
118  dynamic_cast<AsciiArray&>(**m).print_ascii(strm, print_name);
119  strm << "\n";
120  }
121  ++m;
122  }
123 
124  if (array_var()->send_p()) {
125  dynamic_cast<AsciiArray&>(*array_var()).print_ascii(strm, print_name);
126  strm << "\n";
127  }
128  }
129 }
130 
131 // Similar to AsciiArray's print_vector. Print a Grid that has only one
132 // dimension. To fit the spec we can call print_ascii() on the map vector and
133 // then the array (which has only one dimension). This is a special case; if
134 // a grid has two or more dimensions then we can't use the AsciiArray code.
135 //
136 // Note that for the variable to be considered a Grid, it has to have all its
137 // parts projected so there's no need to test send_p(). If anything is not part
138 // of the current projection, then the variable is sent as a Structure.
139 void AsciiGrid::print_vector(ostream &strm, bool print_name)
140 {
141  BESDEBUG("ascii", "In AsciiGrid::print_vector" << endl);
142 
143  dynamic_cast<AsciiArray&> (**map_begin()).print_ascii(strm, print_name);
144 
145  strm << "\n";
146 
147  dynamic_cast<AsciiArray&> (*array_var()).print_ascii(strm, print_name);
148 }
149 
150 void AsciiGrid::print_grid(ostream &strm, bool print_name)
151 {
152  BESDEBUG("ascii", "In AsciiGrid::print_grid" << endl);
153 
154  Grid *g = dynamic_cast<Grid *> (_redirect);
155  if (!g) {
156  g = this;
157  }
158  // Grab the Grid's array
159  Array *grid_array = dynamic_cast<Array *> (g->array_var());
160  AsciiArray *a_grid_array = dynamic_cast<AsciiArray *> (array_var());
161  AsciiOutput *ao_grid_array = dynamic_cast<AsciiOutput *> (a_grid_array);
162 
163  // Set up the shape and state vectors. Shape holds the shape of this
164  // array, state holds the index of the current vector to print.
165  int dims = grid_array->dimensions(true);
166  if (dims <= 1)
167  throw InternalErr(__FILE__, __LINE__,
168  "Dimension count is <= 1 while printing multidimensional array.");
169 
170  // shape holds the maximum index value of each dimension of the array
171  // (not the size; each value is one less that the size).
172  vector<int> shape = a_grid_array->get_shape_vector(dims - 1);
173  int rightmost_dim_size = a_grid_array->get_nth_dim_size(dims - 1);
174 
175  // state holds the indexes of the current row being printed. For an N-dim
176  // array, there are N-1 dims that are iterated over when printing (the
177  // Nth dim is not printed explicitly. Instead it's the number of values
178  // on the row.
179  vector<int> state(dims - 1, 0);
180 
181  // Now that we have the number of dims, get and print the rightmost map.
182  // This is cumbersome; if we used the STL it would be much less so.
183  // We are now using STL, so it isn't so cumbersome. pcw
184  // By definition, a map is a vector. Print the rightmost map.
185  dynamic_cast<AsciiArray &> (**(map_begin() + dims - 1)) .print_ascii(
186  strm, print_name);
187  strm << "\n";
188 
189  bool more_indices;
190  int index = 0;
191  do {
192  // Print indices for all dimensions except the last one. Include the
193  // name of the corresponding map vector and the *value* of this
194  // index. Note that the successive elements of state give the indices
195  // of each of the N-1 dimensions for the current row.
196  string n = ao_grid_array->get_full_name();
197 
198  strm << n;
199 
200  vector<int>::iterator state_iter = state.begin();
201  Grid::Map_iter p = g->map_begin();
202  Grid::Map_iter ap = map_begin();
203  while (state_iter != state.end()) {
204  Array *map = dynamic_cast<Array *> (*p);
205  AsciiArray *amap = dynamic_cast<AsciiArray *> (*ap);
206  AsciiOutput *aomap = dynamic_cast<AsciiOutput *> (amap);
207 
208  strm << "[" << aomap->get_full_name() << "=";
209  BaseType *avar = basetype_to_asciitype(map->var(*state_iter));
210  AsciiOutput *aovar = dynamic_cast<AsciiOutput *> (avar);
211  aovar->print_ascii(strm, false);
212  // we aren't saving a var for future reference so need to delete
213  delete avar;
214  strm << "]";
215 
216  state_iter++;
217  p++;
218  ap++;
219  }
220  strm << ", ";
221 
222  index = a_grid_array->print_row(strm, index, rightmost_dim_size - 1);
223 
224  more_indices = increment_state(&state, shape);
225  if (more_indices)
226  strm << "\n";
227 
228  } while (more_indices);
229 }
virtual ~AsciiGrid()
Definition: AsciiGrid.cc:88
bool increment_state(vector< int > *state, const vector< int > &shape)
Increment #state# to the next value given #shape#.
Definition: AsciiOutput.cc:98
BaseType * _redirect
Definition: AsciiOutput.h:52
STL namespace.
virtual void print_ascii(ostream &strm, bool print_name=true)
Print an ASCII representation for an instance of BaseType's children.
Definition: AsciiOutput.cc:73
virtual BaseType * ptr_duplicate()
Definition: AsciiGrid.cc:56
int get_nth_dim_size(size_t n)
Get the size of dimension #n#.
Definition: AsciiArray.cc:241
BaseType * basetype_to_asciitype(BaseType *bt)
Definition: get_ascii.cc:116
int print_row(ostream &strm, int index, int number)
Print a single row of values for a N-dimensional array.
Definition: AsciiArray.cc:150
vector< int > get_shape_vector(size_t n)
Get the sizes of the first N dimensions of this array.
Definition: AsciiArray.cc:218
virtual void print_ascii(ostream &strm, bool print_name=true)
Print an ASCII representation for an instance of BaseType's children.
Definition: AsciiGrid.cc:92
virtual void print_ascii(ostream &strm, bool print_name=true)
Print an ASCII representation for an instance of BaseType's children.
Definition: AsciiArray.cc:94
AsciiGrid(const string &n)
Definition: AsciiGrid.cc:61
string get_full_name()
Get the fully qualified name of this object.
Definition: AsciiOutput.cc:49
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64