bes Updated for version 3.20.13
grid_utils.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// This file is part of libdap, A C++ implementation of the OPeNDAP Data
4// Access Protocol.
5
6// Copyright (c) 2002,2003 OPeNDAP, Inc.
7// Author: Nathan Potter <npotter@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#include "config.h"
26
27#include <libdap/BaseType.h>
28#include <libdap/Structure.h>
29#include <libdap/Grid.h>
30#include <libdap/util.h>
31
32#include <BESDebug.h>
33
34#include "grid_utils.h"
35#include "gse_parser.h"
36#include "GSEClause.h"
37#include "GridGeoConstraint.h"
38
39using namespace libdap;
40
41int gse_parse(functions::gse_arg *arg);
42void gse_restart(FILE * in);
43
44// Glue routines declared in gse.lex
45void gse_delete_buffer(void *buffer);
46void *gse_string(const char *yy_str);
47
48namespace functions {
49
56void get_grids(BaseType *bt, vector<Grid *> *grids)
57{
58 switch (bt->type()) {
59
60 case dods_grid_c: {
61 // Yay! It's a Grid!
62 grids->push_back(static_cast<Grid*>(bt));
63 break;
64 }
65 case dods_structure_c: {
66 // It's an Structure - but of what? Check each variable in the Structure.
67 Structure &s = static_cast<Structure&>(*bt);
68 for (Structure::Vars_iter i = s.var_begin(); i != s.var_begin(); i++) {
69 get_grids(*i, grids);
70 }
71 break;
72 }
73 // Grids cannot be members of Array or Sequence in DAP2. jhrg 6/10/13
74 case dods_array_c:
75 case dods_sequence_c:
76 default:
77 break;
78 }
79}
80
87void get_grids(DDS &dds, vector<Grid *> *grids)
88{
89 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
90 get_grids(*i, grids);
91 }
92}
93
103bool is_geo_grid(Grid *grid)
104{
105 try {
106 GridGeoConstraint gc(grid);
107 }
108 catch (Error *e) {
109 return false;
110 }
111
112 return true;
113}
114
115void parse_gse_expression(gse_arg *arg, BaseType *expr)
116{
117 gse_restart(0); // Restart the scanner.
118 void *cls = gse_string(extract_string_argument(expr).c_str());
119 // gse_switch_to_buffer(cls); // Get set to scan the string.
120 bool status = gse_parse(arg) == 0;
121 gse_delete_buffer(cls);
122 if (!status)
123 throw Error(malformed_expr, "Error parsing grid selection.");
124}
125
126static void apply_grid_selection_expr(Grid *grid, GSEClause *clause)
127{
128 // Basic plan: For each map, look at each clause and set start and stop
129 // to be the intersection of the ranges in those clauses.
130 Grid::Map_iter map_i = grid->map_begin();
131 while (map_i != grid->map_end() && (*map_i)->name() != clause->get_map_name())
132 ++map_i;
133
134 if (map_i == grid->map_end())
135 throw Error(malformed_expr,"The map vector '" + clause->get_map_name()
136 + "' is not in the grid '" + grid->name() + "'.");
137
138 // Use pointer arith & the rule that map order must match array dim order
139 Array::Dim_iter grid_dim = (grid->get_array()->dim_begin() + (map_i - grid->map_begin()));
140
141 Array *map = dynamic_cast < Array * >((*map_i));
142 if (!map)
143 throw InternalErr(__FILE__, __LINE__, "Expected an Array");
144 int start = max(map->dimension_start(map->dim_begin()), clause->get_start());
145 int stop = min(map->dimension_stop(map->dim_begin()), clause->get_stop());
146
147 if (start > stop) {
148 ostringstream msg;
149 msg
150 << "The expressions passed to grid() do not result in an inclusive \n"
151 << "subset of '" << clause->get_map_name()
152 << "'. The map's values range " << "from "
153 << clause->get_map_min_value() << " to "
154 << clause->get_map_max_value() << ".";
155 throw Error(malformed_expr,msg.str());
156 }
157
158 BESDEBUG("GeoGrid", "Setting constraint on " << map->name() << "[" << start << ":" << stop << "]" << endl);
159
160 // Stride is always one.
161 map->add_constraint(map->dim_begin(), start, 1, stop);
162 grid->get_array()->add_constraint(grid_dim, start, 1, stop);
163}
164
165void apply_grid_selection_expressions(Grid * grid, vector < GSEClause * >clauses)
166{
167 vector < GSEClause * >::iterator clause_i = clauses.begin();
168 while (clause_i != clauses.end())
169 apply_grid_selection_expr(grid, *clause_i++);
170
171 grid->set_read_p(false);
172}
173
174} //namespace libdap