bes  Updated for version 3.20.6
AsciiGrid.cc
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 *
56 AsciiGrid::ptr_duplicate()
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  // Added qualification for 'array' which is libdap::Part::array, but adding
71  // the full qualification results in a warning about the code being c++-11
72  // specific. The line with no qualification on 'array' does not compile on
73  // gcc 6. jhrg 2/4/16
74  add_var(bt, libdap::array);
75  // add_var makes a copy of the base type passed to it, so delete it here
76  delete bt;
77  bt = 0;
78 
79  Grid::Map_iter i = grid->map_begin();
80  Grid::Map_iter e = grid->map_end();
81  while (i != e) {
82  bt = basetype_to_asciitype(*i);
83  add_var(bt, maps);
84  // add_var makes a copy of the base type passed to it, so delete it here
85  delete bt;
86  ++i;
87  }
88 
89  BaseType::set_send_p(grid->send_p());
90 }
91 
92 AsciiGrid::~AsciiGrid()
93 {
94 }
95 
96 void AsciiGrid::print_ascii(ostream &strm, bool print_name)
97  throw(InternalErr)
98 {
99  BESDEBUG("ascii", "In AsciiGrid::print_ascii" << endl);
100 
101  Grid *g = dynamic_cast<Grid *> (_redirect);
102  if (!g)
103  g = this;
104 
105  // If the 'array' part of the Grid is not projected, then only maps are
106  // to be printed and those should be printed like arrays in a structure.
107  // Similarly, if any of the maps are not projected, then the maps and
108  // array in the grid should be printed like arrays in a structure. The
109  // general rule is that if everything in the Grid (all maps plus the array)
110  // are projected, then print as a Grid, else print as if the Gird is a
111  // Structure.
112  if (projection_yields_grid()) {
113  if (dynamic_cast<Array &> (*g->array_var()).dimensions(true) > 1)
114  print_grid(strm, print_name);
115  else
116  print_vector(strm, print_name);
117  }
118  else {
119  Map_iter m = map_begin();
120  while (m != map_end()) {
121  if ((*m)->send_p()) {
122  dynamic_cast<AsciiArray&>(**m).print_ascii(strm, print_name);
123  strm << "\n";
124  }
125  ++m;
126  }
127 
128  if (array_var()->send_p()) {
129  dynamic_cast<AsciiArray&>(*array_var()).print_ascii(strm, print_name);
130  strm << "\n";
131  }
132  }
133 }
134 
135 // Similar to AsciiArray's print_vector. Print a Grid that has only one
136 // dimension. To fit the spec we can call print_ascii() on the map vector and
137 // then the array (which has only one dimension). This is a special case; if
138 // a grid has two or more dimensions then we can't use the AsciiArray code.
139 //
140 // Note that for the variable to be considered a Grid, it has to have all its
141 // parts projected so there's no need to test send_p(). If anything is not part
142 // of the current projection, then the variable is sent as a Structure.
143 void AsciiGrid::print_vector(ostream &strm, bool print_name)
144 {
145  BESDEBUG("ascii", "In AsciiGrid::print_vector" << endl);
146 
147  dynamic_cast<AsciiArray&> (**map_begin()).print_ascii(strm, print_name);
148 
149  strm << "\n";
150 
151  dynamic_cast<AsciiArray&> (*array_var()).print_ascii(strm, print_name);
152 }
153 
154 void AsciiGrid::print_grid(ostream &strm, bool print_name)
155 {
156  BESDEBUG("ascii", "In AsciiGrid::print_grid" << endl);
157 
158  Grid *g = dynamic_cast<Grid *> (_redirect);
159  if (!g) {
160  g = this;
161  }
162  // Grab the Grid's array
163  Array *grid_array = dynamic_cast<Array *> (g->array_var());
164  if (!grid_array) throw InternalErr(__FILE__, __LINE__, "Expected an Array");
165 
166  AsciiArray *a_grid_array = dynamic_cast<AsciiArray *> (array_var());
167  if (!a_grid_array) throw InternalErr(__FILE__, __LINE__, "Expected an AsciiArray");
168 
169  AsciiOutput *ao_grid_array = dynamic_cast<AsciiOutput *> (a_grid_array);
170  if (!ao_grid_array) throw InternalErr(__FILE__, __LINE__, "Expected an AsciiOutput");
171 
172  // Set up the shape and state vectors. Shape holds the shape of this
173  // array, state holds the index of the current vector to print.
174  int dims = grid_array->dimensions(true);
175  if (dims <= 1)
176  throw InternalErr(__FILE__, __LINE__,
177  "Dimension count is <= 1 while printing multidimensional array.");
178 
179  // shape holds the maximum index value of each dimension of the array
180  // (not the size; each value is one less that the size).
181  vector<int> shape = a_grid_array->get_shape_vector(dims - 1);
182  int rightmost_dim_size = a_grid_array->get_nth_dim_size(dims - 1);
183 
184  // state holds the indexes of the current row being printed. For an N-dim
185  // array, there are N-1 dims that are iterated over when printing (the
186  // Nth dim is not printed explicitly. Instead it's the number of values
187  // on the row.
188  vector<int> state(dims - 1, 0);
189 
190  // Now that we have the number of dims, get and print the rightmost map.
191  // This is cumbersome; if we used the STL it would be much less so.
192  // We are now using STL, so it isn't so cumbersome. pcw
193  // By definition, a map is a vector. Print the rightmost map.
194  dynamic_cast<AsciiArray &> (**(map_begin() + dims - 1)) .print_ascii(
195  strm, print_name);
196  strm << "\n";
197 
198  bool more_indices;
199  int index = 0;
200  do {
201  // Print indices for all dimensions except the last one. Include the
202  // name of the corresponding map vector and the *value* of this
203  // index. Note that the successive elements of state give the indices
204  // of each of the N-1 dimensions for the current row.
205  string n = ao_grid_array->get_full_name();
206 
207  strm << n;
208 
209  vector<int>::iterator state_iter = state.begin();
210  Grid::Map_iter p = g->map_begin();
211  Grid::Map_iter ap = map_begin();
212  while (state_iter != state.end()) {
213  Array *map = dynamic_cast<Array *> (*p);
214  if (!map) throw InternalErr(__FILE__, __LINE__, "Expected an Array");
215 
216  AsciiArray *amap = dynamic_cast<AsciiArray *> (*ap);
217  if (!amap) throw InternalErr(__FILE__, __LINE__, "Expected an AsciiArray");
218 
219  AsciiOutput *aomap = dynamic_cast<AsciiOutput *> (amap);
220  if (!aomap) throw InternalErr(__FILE__, __LINE__, "Expected an AsciiOutput");
221 
222  strm << "[" << aomap->get_full_name() << "=";
223  BaseType *avar = basetype_to_asciitype(map->var(*state_iter));
224  AsciiOutput &aovar = dynamic_cast<AsciiOutput &> (*avar);
225  aovar.print_ascii(strm, false);
226  // we aren't saving a var for future reference so need to delete
227  delete avar;
228  strm << "]";
229 
230  state_iter++;
231  p++;
232  ap++;
233  }
234  strm << ", ";
235 
236  index = a_grid_array->print_row(strm, index, rightmost_dim_size - 1);
237 
238  more_indices = increment_state(&state, shape);
239  if (more_indices)
240  strm << "\n";
241 
242  } while (more_indices);
243 }
AsciiArray::print_row
int print_row(ostream &strm, int index, int number)
Definition: AsciiArray.cc:154
AsciiArray::get_shape_vector
vector< int > get_shape_vector(size_t n)
Definition: AsciiArray.cc:216
AsciiOutput::print_ascii
virtual void print_ascii(ostream &strm, bool print_name=true)
Print values as ASCII Prints the values of this in ASCII suitable for import into a spreadsheet....
Definition: AsciiOutput.cc:73
AsciiArray::print_ascii
virtual void print_ascii(ostream &strm, bool print_name=true)
Print values as ASCII Prints the values of this in ASCII suitable for import into a spreadsheet....
Definition: AsciiArray.cc:94
AsciiOutput::increment_state
bool increment_state(vector< int > *state, const vector< int > &shape)
Definition: AsciiOutput.cc:97
AsciiArray
Definition: AsciiArray.h:44
AsciiGrid
Definition: AsciiGrid.h:42
AsciiGrid::print_ascii
virtual void print_ascii(ostream &strm, bool print_name=true)
Print values as ASCII Prints the values of this in ASCII suitable for import into a spreadsheet....
Definition: AsciiGrid.cc:96
AsciiOutput
Definition: AsciiOutput.h:46
AsciiOutput::get_full_name
string get_full_name()
Definition: AsciiOutput.cc:49
AsciiArray::get_nth_dim_size
int get_nth_dim_size(size_t n)
Definition: AsciiArray.cc:239