libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
GeoGridFunction.cc
Go to the documentation of this file.
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) 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 <Array.h>
30#include <BaseType.h>
31#include <DDS.h>
32#include <Error.h>
33#include <Grid.h>
34#include <Str.h>
35#include <debug.h>
36#include <util.h>
37
38#include "GeoGridFunction.h"
39#include "GridGeoConstraint.h"
40#include "grid_utils.h"
41#include "gse_parser.h"
42
43using namespace libdap;
44
45namespace functions {
46
81void function_geogrid(int argc, BaseType *argv[], DDS &, BaseType **btpp) {
82 string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
83 "<function name=\"geogrid\" version=\"1.2\" "
84 "href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geogrid\">\n" +
85 "</function>";
86
87 if (argc == 0) {
88 Str *response = new Str("version");
89 response->set_value(info);
90 *btpp = response;
91 return;
92 }
93
94 // There are two main forms of this function, one that takes a Grid and one
95 // that takes a Grid and two Arrays. The latter provides a way to explicitly
96 // tell the function which maps contain lat and lon data. The remaining
97 // arguments are the same for both versions, although that includes a
98 // varying argument list.
99
100 // Look at the types of the first three arguments to determine which of the
101 // two forms were used to call this function.
102 Grid *l_grid = 0;
103 if (argc < 1 || !(l_grid = dynamic_cast<Grid *>(argv[0]->ptr_duplicate())))
104 throw Error(malformed_expr, "The first argument to geogrid() must be a Grid variable!");
105
106 // Both forms require at least this many args
107 if (argc < 5)
108 throw Error(
110 "Wrong number of arguments to geogrid() (expected at least 5 args). See geogrid() for more information.");
111
112 bool grid_lat_lon_form;
113 Array *l_lat = 0;
114 Array *l_lon = 0;
115 if (!(l_lat = dynamic_cast<Array *>(argv[1]))) //->ptr_duplicate())))
116 grid_lat_lon_form = false;
117 else if (!(l_lon = dynamic_cast<Array *>(argv[2]))) //->ptr_duplicate())))
118 throw Error(malformed_expr, "When using the Grid, Lat, Lon form of geogrid() both the lat and lon maps must be "
119 "given (lon map missing)!");
120 else
121 grid_lat_lon_form = true;
122
123 if (grid_lat_lon_form && argc < 7)
124 throw Error(
126 "Wrong number of arguments to geogrid() (expected at least 7 args). See geogrid() for more information.");
127
128#if 0
129 Grid *l_grid = dynamic_cast < Grid * >(argv[0]->ptr_duplicate());
130 if (!l_grid)
131 throw Error(malformed_expr,"The first argument to geogrid() must be a Grid variable!");
132#endif
133 // Read the maps. Do this before calling parse_gse_expression(). Avoid
134 // reading the array until the constraints have been applied because it
135 // might be really large.
136 //
137 // Trick: Some handlers build Grids from a combination of Array
138 // variables and attributes. Those handlers (e.g., hdf4) use the send_p
139 // property to determine which parts of the Grid to read *but they can
140 // only read the maps from within Grid::read(), not the map's read()*.
141 // Since the Grid's array does not have send_p set, it will not be read
142 // by the call below to Grid::read().
143 Grid::Map_iter i = l_grid->map_begin();
144 while (i != l_grid->map_end())
145 (*i++)->set_send_p(true);
146
147 l_grid->read();
148 // Calling read() above sets the read_p flag for the entire grid; clear it
149 // for the grid's array so that later on the code will be sure to read it
150 // under all circumstances.
151 l_grid->get_array()->set_read_p(false);
152
153 // Look for Grid Selection Expressions tacked onto the end of the BB
154 // specification. If there are any, evaluate them before evaluating the BB.
155 int min_arg_count = (grid_lat_lon_form) ? 7 : 5;
156 if (argc > min_arg_count) {
157 // argv[5..n] holds strings; each are little Grid Selection Expressions
158 // to be parsed and evaluated.
159 vector<GSEClause *> clauses;
160 gse_arg *arg = new gse_arg(l_grid);
161 for (int i = min_arg_count; i < argc; ++i) {
162 parse_gse_expression(arg, argv[i]);
163 clauses.push_back(arg->get_gsec());
164 }
165 delete arg;
166 arg = 0;
167
168 apply_grid_selection_expressions(l_grid, clauses);
169 }
170
171 try {
172 // Build a GeoConstraint object. If there are no longitude/latitude
173 // maps then this constructor throws Error.
174 GridGeoConstraint gc(l_grid);
175
176 // This sets the bounding box and modifies the maps to match the
177 // notation of the box (0/359 or -180/179)
178 int box_index_offset = (grid_lat_lon_form) ? 3 : 1;
179 double top = extract_double_value(argv[box_index_offset]);
180 double left = extract_double_value(argv[box_index_offset + 1]);
181 double bottom = extract_double_value(argv[box_index_offset + 2]);
182 double right = extract_double_value(argv[box_index_offset + 3]);
183 gc.set_bounding_box(top, left, bottom, right);
184 DBG(cerr << "geogrid: past bounding box set" << endl);
185
186 // This also reads all of the data into the grid variable
188 DBG(cerr << "geogrid: past apply constraint" << endl);
189
190 // In this function the l_grid pointer is the same as the pointer returned
191 // by this call. The caller of the function must free the pointer.
192 *btpp = gc.get_constrained_grid();
193 return;
194 } catch (Error &e) {
195 throw e;
196 } catch (exception &e) {
197 throw InternalErr(string("A C++ exception was thrown from inside geogrid(): ") + e.what());
198 }
199}
200
208 bool usable = false;
209
210 // Go find all the Grid variables.
211 // vector<Grid *> *grids = new vector<Grid *>();
212 vector<Grid *> grids;
213 get_grids(dds, &grids);
214
215 // Were there any?
216 if (!grids.empty()) {
217 // Apparently so...
218
219 // See if any one of them looks like suitable GeoGrid
221 for (git = grids.begin(); !usable && git != grids.end(); git++) {
222 Grid *grid = *git;
223 usable = is_geo_grid(grid);
224 }
225 }
226 // delete grids;
227
228 return usable;
229}
230
231} // namespace functions
#define malformed_expr
(400)
Definition Error.h:66
void set_bounding_box(double top, double left, double bottom, double right)
bool canOperateOn(libdap::DDS &dds)
virtual libdap::Grid * get_constrained_grid() const
A multidimensional array of identical data types.
Definition Array.h:121
The basic data type for the DODS DAP types.
Definition BaseType.h:118
virtual BaseType * ptr_duplicate()=0
bool read() override
Read the elements of Constructor marked for transmission.
A class for error processing.
Definition Error.h:92
const char * what() const noexcept override
The pointer is valid only for the lifetime of the Error instance. jhrg 9/22/20.
Definition Error.h:152
Holds the Grid data type.
Definition Grid.h:121
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Definition Grid.cc:448
std::vector< BaseType * >::iterator Map_iter
Definition Grid.h:136
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required.
Definition Grid.cc:445
Map_iter map_end()
Definition Grid.cc:458
A class for software fault reporting.
Definition InternalErr.h:61
Holds character string data.
Definition Str.h:61
virtual bool set_value(const string &value)
Definition Str.cc:219
void set_read_p(bool state) override
Indicates that the data is ready to send.
Definition Vector.cc:389
STL iterator class.
#define DBG(x)
Definition debug.h:58
void get_grids(BaseType *bt, vector< Grid * > *grids)
Definition grid_utils.cc:60
void function_geogrid(int argc, BaseType *argv[], DDS &, BaseType **btpp)
void parse_gse_expression(gse_arg *arg, BaseType *expr)
void apply_grid_selection_expressions(Grid *grid, vector< GSEClause * > clauses)
top level DAP object to house generic methods
Definition AISConnect.cc:30
double extract_double_value(BaseType *arg)
Definition util.cc:395
GSEClause * get_gsec()
Definition gse_parser.h:56