29#include <libdap/BaseType.h>
30#include <libdap/Str.h>
31#include <libdap/Array.h>
32#include <libdap/Grid.h>
33#include <libdap/Structure.h>
34#include <libdap/D4RValue.h>
35#include <libdap/D4Maps.h>
36#include <libdap/Error.h>
37#include <libdap/DDS.h>
38#include <libdap/DMR.h>
39#include <libdap/D4Group.h>
40#include <libdap/debug.h>
41#include <libdap/util.h>
45#include "GeoGridFunction.h"
46#include "GridGeoConstraint.h"
47#include "gse_parser.h"
48#include "grid_utils.h"
55 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
56 "<function name=\"geogrid\" version=\"1.2\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geogrid\">\n"+
94function_dap2_geogrid(
int argc, BaseType *argv[], DDS &, BaseType **btpp)
97 Str *response =
new Str(
"version");
98 response->set_value(geogrid_info);
112 if (argc < 1 || !(l_grid =
dynamic_cast < Grid *
>(argv[0]->ptr_duplicate())))
113 throw Error(malformed_expr,
"The first argument to geogrid() must be a Grid variable!");
117 throw Error(malformed_expr,
"Wrong number of arguments to geogrid() (expected at least 5 args). See geogrid() for more information.");
119 bool grid_lat_lon_form;
122 if (!(l_lat =
dynamic_cast < Array *
>(argv[1])))
123 grid_lat_lon_form =
false;
124 else if (!(l_lon =
dynamic_cast < Array *
>(argv[2])))
125 throw Error(malformed_expr,
"When using the Grid, Lat, Lon form of geogrid() both the lat and lon maps must be given (lon map missing)!");
127 grid_lat_lon_form =
true;
129 if (grid_lat_lon_form && argc < 7)
130 throw Error(malformed_expr,
"Wrong number of arguments to geogrid() (expected at least 7 args). See geogrid() for more information.");
133 Grid *l_grid =
dynamic_cast < Grid *
>(argv[0]->ptr_duplicate());
135 throw Error(malformed_expr,
"The first argument to geogrid() must be a Grid variable!");
147 Grid::Map_iter i = l_grid->map_begin();
148 while (i != l_grid->map_end())
149 (*i++)->set_send_p(
true);
155 l_grid->get_array()->set_read_p(
false);
159 int min_arg_count = (grid_lat_lon_form) ? 7 : 5;
160 if (argc > min_arg_count) {
163 vector < GSEClause * > clauses;
165 for (
int i = min_arg_count; i < argc; ++i) {
166 parse_gse_expression(arg, argv[i]);
167 clauses.push_back(arg->get_gsec());
172 apply_grid_selection_expressions(l_grid, clauses);
182 int box_index_offset = (grid_lat_lon_form) ? 3 : 1;
183 double top = extract_double_value(argv[box_index_offset]);
184 double left = extract_double_value(argv[box_index_offset + 1]);
185 double bottom = extract_double_value(argv[box_index_offset + 2]);
186 double right = extract_double_value(argv[box_index_offset + 3]);
187 gc.set_bounding_box(top, left, bottom, right);
188 DBG(cerr <<
"geogrid: past bounding box set" << endl);
191 gc.apply_constraint_to_data();
192 DBG(cerr <<
"geogrid: past apply constraint" << endl);
196 *btpp = gc.get_constrained_grid();
202 catch (exception & e) {
205 (
"A C++ exception was thrown from inside geogrid(): ")
223 get_grids(dds, &grids);
231 for(git=grids.begin(); !usable && git!=grids.end() ; git++){
233 usable = is_geo_grid(grid);
241BaseType *function_dap4_geogrid(D4RValueList *args, DMR &dmr)
243 BESDEBUG(
"function",
"function_dap4_geogrid() BEGIN " << endl);
256 if (args == 0 || args->size() < 5) {
257 Str *response =
new Str(
"info");
258 response->set_value(geogrid_info);
263 BaseType *a_btp = args->get_rvalue(0)->value(dmr);
264 Array *original_array =
dynamic_cast < Array *
>(a_btp);
265 if (!original_array) {
267 throw Error(malformed_expr,
"The first argument to geogrid() must be a Dap4 array variable!");
273 BaseType *btp = original_array->ptr_duplicate();
274 Array *l_array =
dynamic_cast < Array *
>(btp);
277 throw InternalErr(__FILE__, __LINE__,
"Expected an Array.");
280 DBG(cerr <<
"array: past initialization code" << endl);
282 bool grid_lat_lon_form =
false;
284 BaseType *lat_btp = args->get_rvalue(1)->value(dmr);
285 Array *l_lat =
dynamic_cast < Array *
>(lat_btp);
286 BaseType *lon_btp = args->get_rvalue(2)->value(dmr);
287 Array *l_lon =
dynamic_cast < Array *
>(lon_btp);
290 grid_lat_lon_form =
false;
293 throw Error(malformed_expr,
294 "When using the Grid, Lat, Lon form of geogrid() both the lat and lon maps must be given (lon map missing)!");
297 grid_lat_lon_form =
true;
300 if (grid_lat_lon_form && args->size() < 7) {
301 throw Error(malformed_expr,
302 "Wrong number of arguments to geogrid() (expected at least 7 args). See geogrid() for more information.");
310 BESDEBUG(
"functions",
"original_array: read_p: " << original_array->read_p() << endl);
311 BESDEBUG(
"functions",
"l_array: read_p: " << l_array->read_p() << endl);
314 D4Maps *d4_maps = l_array->maps();
315 D4Maps::D4MapsIter miter = d4_maps->map_begin();
316 while (miter != d4_maps->map_end()) {
317 D4Map *d4_map = (*miter);
318 Array *map =
const_cast<Array *
>(d4_map->array());
319 map->set_send_p(
true);
324 DBG(cerr <<
"array: past map read" << endl);
328 unsigned int min_arg_count = (grid_lat_lon_form) ? 7 : 5;
330 if (args->size() > min_arg_count) {
333 vector < GSEClause * > clauses;
335 for (
unsigned int i = min_arg_count; i < args->size(); ++i) {
336 parse_gse_expression(arg, args->get_rvalue(i)->value(dmr));
337 clauses.push_back(arg->get_gsec());
342 apply_grid_selection_expressions(l_array, clauses);
344 DBG(cerr <<
"array: past gse application" << endl);
353 int box_index_offset = (grid_lat_lon_form) ? 3 : 1;
354 double top = extract_double_value(args->get_rvalue(box_index_offset)->value(dmr));
355 double left = extract_double_value(args->get_rvalue(box_index_offset + 1)->value(dmr));
356 double bottom = extract_double_value(args->get_rvalue(box_index_offset + 2)->value(dmr));
357 double right = extract_double_value(args->get_rvalue(box_index_offset + 3)->value(dmr));
358 gc.set_bounding_box(top, left, bottom, right);
359 DBG(cerr <<
"geogrid: past bounding box set" << endl);
362 gc.apply_constraint_to_data();
363 DBG(cerr <<
"geogrid: past apply constraint" << endl);
366 D4Group *dapResult =
new D4Group(
"geogrid_result");
369 dapResult->set_parent(dmr.root());
372 l_array->set_read_p(
false);
373 dapResult->add_var_nocopy(l_array);
376 D4Dimensions *grp_d4_dims = dapResult->dims();
378 Array *g_array =
dynamic_cast<Array *
>(dapResult->find_var(l_array->name()));
380 Array::Dim_iter dim_i = g_array->dim_begin();
381 while (dim_i != g_array->dim_end()) {
382 D4Dimension *d4_dim = g_array->dimension_D4dim(dim_i);
383 grp_d4_dims->add_dim_nocopy(d4_dim);
388 d4_maps = l_array->maps();
389 miter = d4_maps->map_begin();
390 while (miter != d4_maps->map_end()) {
391 D4Map *d4_map = (*miter);
392 Array *map =
const_cast<Array *
>(d4_map->array());
393 map->set_read_p(
false);
394 dapResult->add_var_nocopy(map);
398 dapResult->set_send_p(
true);
406 catch (exception & e) {
409 (
"A C++ exception was thrown from inside geogrid(): ")
423 get_coverages(dmr, &coverages);
425 return !coverages.empty();
bool canOperateOn(libdap::DDS &dds)