bes  Updated for version 3.17.0
GridFunction.cc
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2003,2013 OPeNDAP, Inc.
8 // Authors: Nathan Potter <npotter@opendap.org>
9 // James Gallagher <jgallagher@opendap.org>
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 #include "config.h"
28 
29 #include <BaseType.h>
30 #include <Str.h>
31 #include <Array.h>
32 #include <Grid.h>
33 #include <Error.h>
34 #include <DDS.h>
35 #include <debug.h>
36 #include <util.h>
37 
38 #include "GridFunction.h"
39 #include "gse_parser.h"
40 #include "grid_utils.h"
41 
42 using namespace libdap;
43 
44 namespace functions {
45 
75 void
76 function_grid(int argc, BaseType *argv[], DDS &, BaseType **btpp)
77 {
78  DBG(cerr << "Entering function_grid..." << endl);
79 
80  string info =
81  string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
82  "<function name=\"grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#grid\">\n" +
83  "</function>\n";
84 
85  if (argc == 0) {
86  Str *response = new Str("info");
87  response->set_value(info);
88  *btpp = response;
89  return;
90  }
91 
92  Grid *original_grid = dynamic_cast < Grid * >(argv[0]);
93  if (!original_grid)
94  throw Error(malformed_expr,"The first argument to grid() must be a Grid variable!");
95 
96  // Duplicate the grid; ResponseBuilder::send_data() will delete the variable
97  // after serializing it.
98  BaseType *btp = original_grid->ptr_duplicate();
99  Grid *l_grid = dynamic_cast < Grid * >(btp);
100  if (!l_grid) {
101  delete btp;
102  throw InternalErr(__FILE__, __LINE__, "Expected a Grid.");
103  }
104 
105  DBG(cerr << "grid: past initialization code" << endl);
106 
107  // Read the maps. Do this before calling parse_gse_expression(). Avoid
108  // reading the array until the constraints have been applied because it
109  // might be really large.
110 
111  // This version makes sure to set the send_p flags which is needed for
112  // the hdf4 handler (and is what should be done in general).
113  Grid::Map_iter i = l_grid->map_begin();
114  while (i != l_grid->map_end())
115  (*i++)->set_send_p(true);
116 
117  l_grid->read();
118 
119  DBG(cerr << "grid: past map read" << endl);
120 
121  // argv[1..n] holds strings; each are little expressions to be parsed.
122  // When each expression is parsed, the parser makes a new instance of
123  // GSEClause. GSEClause checks to make sure the named map really exists
124  // in the Grid and that the range of values given makes sense.
125  vector < GSEClause * > clauses;
126  gse_arg *arg = new gse_arg(l_grid);
127  for (int i = 1; i < argc; ++i) {
128  parse_gse_expression(arg, argv[i]);
129  clauses.push_back(arg->get_gsec());
130  }
131  delete arg;
132  arg = 0;
133 
134  apply_grid_selection_expressions(l_grid, clauses);
135 
136  DBG(cerr << "grid: past gse application" << endl);
137 
138  l_grid->get_array()->set_send_p(true);
139 
140  l_grid->read();
141 
142  // Make a new grid here and copy just the parts of the Grid
143  // that are in the current projection - this means reading
144  // the array slicing information, extracting the correct
145  // values and building destination arrays with just those
146  // values.
147 
148  *btpp = l_grid;
149  return;
150 }
151 
157 bool GridFunction::canOperateOn(DDS &dds) {
158  //vector<Grid *> *grids = new vector<Grid *>();
159  vector<Grid *> grids;
160  getGrids(dds, &grids);
161 
162  return !grids.empty();
163 }
164 
165 } // namesspace functions