bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
40using namespace std;
41
42#include <libdap/InternalErr.h>
43
44#include <BESDebug.h>
45
46// #define DODS_DEBUG
47
48#include "AsciiGrid.h"
49#include "AsciiArray.h"
50#include <libdap/debug.h>
51#include "get_ascii.h"
52
53using namespace dap_asciival;
54
55BaseType *
56AsciiGrid::ptr_duplicate()
57{
58 return new AsciiGrid(*this);
59}
60
61AsciiGrid::AsciiGrid(const string &n) :
62 Grid(n)
63{
64}
65
66AsciiGrid::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
92AsciiGrid::~AsciiGrid()
93{
94}
95
96void 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.
143void 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
154void 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}
virtual void print_ascii(ostream &strm, bool print_name=true)
Definition AsciiArray.cc:94
int get_nth_dim_size(size_t n)
vector< int > get_shape_vector(size_t n)
int print_row(ostream &strm, int index, int number)
virtual void print_ascii(ostream &strm, bool print_name=true)
Definition AsciiGrid.cc:96
virtual void print_ascii(ostream &strm, bool print_name=true)
bool increment_state(vector< int > *state, const vector< int > &shape)
string get_full_name()