00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037
00038 static char rcsid[]not_used =
00039 { "$Id: ce_functions.cc 21923 2010-01-07 20:05:48Z jimg $"
00040 };
00041
00042 #include <limits.h>
00043
00044 #include <cstdlib>
00045 #include <cerrno>
00046 #include <cmath>
00047 #include <iostream>
00048 #include <vector>
00049 #include <algorithm>
00050
00051
00052
00053 #include "BaseType.h"
00054 #include "Byte.h"
00055 #include "Int16.h"
00056 #include "UInt16.h"
00057 #include "Int32.h"
00058 #include "UInt32.h"
00059 #include "Float32.h"
00060 #include "Float64.h"
00061 #include "Str.h"
00062 #include "Url.h"
00063 #include "Array.h"
00064 #include "Structure.h"
00065 #include "Sequence.h"
00066 #include "Grid.h"
00067 #include "Error.h"
00068 #include "RValue.h"
00069
00070 #include "GSEClause.h"
00071 #include "GridGeoConstraint.h"
00072 #include "ArrayGeoConstraint.h"
00073
00074 #include "ce_functions.h"
00075 #include "gse_parser.h"
00076 #include "gse.tab.hh"
00077 #include "debug.h"
00078 #include "util.h"
00079
00080
00081
00082
00083
00084 #ifdef WIN32
00085 #include <limits>
00086 double w32strtod(const char *, char **);
00087 #endif
00088
00089 using namespace std;
00090
00091 int gse_parse(void *arg);
00092 void gse_restart(FILE * in);
00093
00094
00095 void gse_switch_to_buffer(void *new_buffer);
00096 void gse_delete_buffer(void *buffer);
00097 void *gse_string(const char *yy_str);
00098
00099 namespace libdap {
00100
00102 inline bool double_eq(double lhs, double rhs, double epsilon = 1.0e-5)
00103 {
00104 if (lhs > rhs)
00105 return (lhs - rhs) < ((lhs + rhs) / epsilon);
00106 else
00107 return (rhs - lhs) < ((lhs + rhs) / epsilon);
00108 }
00109
00117 string extract_string_argument(BaseType * arg)
00118 {
00119 if (arg->type() != dods_str_c)
00120 throw Error(malformed_expr,
00121 "The function requires a DAP string argument.");
00122
00123 if (!arg->read_p())
00124 throw InternalErr(__FILE__, __LINE__,
00125 "The CE Evaluator built an argument list where some constants held no values.");
00126
00127 string s = dynamic_cast<Str&>(*arg).value();
00128
00129 DBG(cerr << "s: " << s << endl);
00130
00131 return s;
00132 }
00133 template<class T> static void set_array_using_double_helper(Array * a,
00134 double *src, int src_len)
00135 {
00136 T *values = new T[src_len];
00137 for (int i = 0; i < src_len; ++i)
00138 values[i] = (T) src[i];
00139
00140 #ifdef VAL2BUF
00141 a->val2buf(values, true);
00142 #else
00143 a->set_value(values, src_len);
00144 #endif
00145
00146 delete[]values;
00147 }
00148
00166 void set_array_using_double(Array * dest, double *src, int src_len)
00167 {
00168
00169 if ((dest->type() == dods_array_c && !dest->var()->is_simple_type())
00170 || dest->var()->type() == dods_str_c
00171 || dest->var()->type() == dods_url_c)
00172 throw InternalErr(__FILE__, __LINE__,
00173 "The function requires a DAP numeric-type array argument.");
00174
00175
00176
00177
00178
00179 if (dest->length() != src_len)
00180 throw InternalErr(__FILE__, __LINE__,
00181 "The source and destination array sizes don't match ("
00182 + long_to_string(src_len) + " versus "
00183 + long_to_string(dest->length()) + ").");
00184
00185
00186
00187
00188
00189 switch (dest->var()->type()) {
00190 case dods_byte_c:
00191 set_array_using_double_helper<dods_byte>(dest, src, src_len);
00192 break;
00193 case dods_uint16_c:
00194 set_array_using_double_helper<dods_uint16>(dest, src, src_len);
00195 break;
00196 case dods_int16_c:
00197 set_array_using_double_helper<dods_int16>(dest, src, src_len);
00198 break;
00199 case dods_uint32_c:
00200 set_array_using_double_helper<dods_uint32>(dest, src, src_len);
00201 break;
00202 case dods_int32_c:
00203 set_array_using_double_helper<dods_int32>(dest, src, src_len);
00204 break;
00205 case dods_float32_c:
00206 set_array_using_double_helper<dods_float32>(dest, src, src_len);
00207 break;
00208 case dods_float64_c:
00209 set_array_using_double_helper<dods_float64>(dest, src, src_len);
00210 break;
00211 default:
00212 throw InternalErr(__FILE__, __LINE__,
00213 "The argument list built by the CE parser contained an unsupported numeric type.");
00214 }
00215
00216
00217 dest->set_read_p(true);
00218 }
00219
00220 template<class T> static double *extract_double_array_helper(Array * a)
00221 {
00222 int length = a->length();
00223
00224 T *b = new T[length];
00225 a->value(b);
00226
00227 double *dest = new double[length];
00228 for (int i = 0; i < length; ++i)
00229 dest[i] = (double) b[i];
00230 delete[]b;
00231
00232 return dest;
00233 }
00234
00239 double *extract_double_array(Array * a)
00240 {
00241
00242 if ((a->type() == dods_array_c && !a->var()->is_simple_type())
00243 || a->var()->type() == dods_str_c || a->var()->type() == dods_url_c)
00244 throw Error(malformed_expr,
00245 "The function requires a DAP numeric-type array argument.");
00246
00247 if (!a->read_p())
00248 throw InternalErr(__FILE__, __LINE__,
00249 string("The Array '") + a->name() +
00250 "'does not contain values.");
00251
00252
00253
00254
00255
00256 switch (a->var()->type()) {
00257 case dods_byte_c:
00258 return extract_double_array_helper<dods_byte>(a);
00259 case dods_uint16_c:
00260 return extract_double_array_helper<dods_uint16>(a);
00261 case dods_int16_c:
00262 return extract_double_array_helper<dods_int16>(a);
00263 case dods_uint32_c:
00264 return extract_double_array_helper<dods_uint32>(a);
00265 case dods_int32_c:
00266 return extract_double_array_helper<dods_int32>(a);
00267 case dods_float32_c:
00268 return extract_double_array_helper<dods_float32>(a);
00269 case dods_float64_c:
00270 return extract_double_array_helper<dods_float64>(a);
00271 default:
00272 throw InternalErr(__FILE__, __LINE__,
00273 "The argument list built by the CE parser contained an unsupported numeric type.");
00274 }
00275 }
00276
00284 double extract_double_value(BaseType * arg)
00285 {
00286
00287 if (!arg->is_simple_type() || arg->type() == dods_str_c || arg->type()
00288 == dods_url_c)
00289 throw Error(malformed_expr,
00290 "The function requires a DAP numeric-type argument.");
00291
00292 if (!arg->read_p())
00293 throw InternalErr(__FILE__, __LINE__,
00294 "The CE Evaluator built an argument list where some constants held no values.");
00295
00296
00297
00298
00299
00300 switch (arg->type()) {
00301 case dods_byte_c:
00302 return (double)(dynamic_cast<Byte&>(*arg).value());
00303 case dods_uint16_c:
00304 return (double)(dynamic_cast<UInt16&>(*arg).value());
00305 case dods_int16_c:
00306 return (double)(dynamic_cast<Int16&>(*arg).value());
00307 case dods_uint32_c:
00308 return (double)(dynamic_cast<UInt32&>(*arg).value());
00309 case dods_int32_c:
00310 return (double)(dynamic_cast<Int32&>(*arg).value());
00311 case dods_float32_c:
00312 return (double)(dynamic_cast<Float32&>(*arg).value());
00313 case dods_float64_c:
00314 return dynamic_cast<Float64&>(*arg).value();
00315 default:
00316 throw InternalErr(__FILE__, __LINE__,
00317 "The argument list built by the CE parser contained an unsupported numeric type.");
00318 }
00319 }
00320
00323 void
00324 function_version(int, BaseType *[], DDS &, BaseType **btpp)
00325 {
00326 string
00327 xml_value =
00328 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
00329 <functions>\
00330 <function name=\"geogrid\" version=\"1.1\"/>\
00331 <function name=\"grid\" version=\"1.0\"/>\
00332 <function name=\"linear_scale\" version=\"1.0b1\"/>\
00333 <function name=\"version\" version=\"1.0\"/>\
00334 </functions>";
00335
00336
00337
00338 Str *response = new Str("version");
00339
00340 response->set_value(xml_value);
00341 *btpp = response;
00342 return;
00343 }
00344
00345 static void parse_gse_expression(gse_arg * arg, BaseType * expr)
00346 {
00347 gse_restart(0);
00348 void *cls = gse_string(extract_string_argument(expr).c_str());
00349
00350 bool status = gse_parse((void *) arg) == 0;
00351 gse_delete_buffer(cls);
00352 if (!status)
00353 throw Error(malformed_expr, "Error parsing grid selection.");
00354 }
00355
00356 static void apply_grid_selection_expr(Grid * grid, GSEClause * clause)
00357 {
00358
00359
00360 Grid::Map_iter map_i = grid->map_begin();
00361 while (map_i != grid->map_end() && (*map_i)->name() != clause->get_map_name())
00362 ++map_i;
00363
00364 if (map_i == grid->map_end())
00365 throw Error(malformed_expr,"The map vector '" + clause->get_map_name()
00366 + "' is not in the grid '" + grid->name() + "'.");
00367
00368
00369 Array::Dim_iter grid_dim = (grid->get_array()->dim_begin() + (map_i - grid->map_begin()));
00370
00371 Array *map = dynamic_cast < Array * >((*map_i));
00372 if (!map)
00373 throw InternalErr(__FILE__, __LINE__, "Expected an Array");
00374 int start = max(map->dimension_start(map->dim_begin()), clause->get_start());
00375 int stop = min(map->dimension_stop(map->dim_begin()), clause->get_stop());
00376
00377 if (start > stop) {
00378 ostringstream msg;
00379 msg
00380 << "The expressions passed to grid() do not result in an inclusive \n"
00381 << "subset of '" << clause->get_map_name()
00382 << "'. The map's values range " << "from "
00383 << clause->get_map_min_value() << " to "
00384 << clause->get_map_max_value() << ".";
00385 throw Error(malformed_expr,msg.str());
00386 }
00387
00388 DBG(cerr << "Setting constraint on " << map->name()
00389 << "[" << start << ":" << stop << "]" << endl);
00390
00391
00392 map->add_constraint(map->dim_begin(), start, 1, stop);
00393 grid->get_array()->add_constraint(grid_dim, start, 1, stop);
00394 }
00395
00396 static void apply_grid_selection_expressions(Grid * grid,
00397 vector < GSEClause * >clauses)
00398 {
00399 vector < GSEClause * >::iterator clause_i = clauses.begin();
00400 while (clause_i != clauses.end())
00401 apply_grid_selection_expr(grid, *clause_i++);
00402
00403 grid->set_read_p(false);
00404 }
00405
00442 void
00443 function_grid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
00444 {
00445 DBG(cerr << "Entering function_grid..." << endl);
00446
00447 string info =
00448 string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
00449 "<function name=\"grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#grid\">\n" +
00450 "</function>\n";
00451
00452 if (argc == 0) {
00453 Str *response = new Str("info");
00454 response->set_value(info);
00455 *btpp = response;
00456 return;
00457 }
00458
00459 Grid *original_grid = dynamic_cast < Grid * >(argv[0]);
00460 if (!original_grid)
00461 throw Error(malformed_expr,"The first argument to grid() must be a Grid variable!");
00462
00463
00464
00465 Grid *l_grid = dynamic_cast < Grid * >(original_grid->ptr_duplicate());
00466 if (!l_grid)
00467 throw InternalErr(__FILE__, __LINE__, "Expected a Grid.");
00468
00469 DBG(cerr << "grid: past initialization code" << endl);
00470
00471
00472
00473
00474
00475
00476
00477 Grid::Map_iter i = l_grid->map_begin();
00478 while (i != l_grid->map_end())
00479 (*i++)->set_send_p(true);
00480 l_grid->read();
00481
00482 DBG(cerr << "grid: past map read" << endl);
00483
00484
00485
00486
00487
00488 vector < GSEClause * > clauses;
00489 gse_arg *arg = new gse_arg(l_grid);
00490 for (int i = 1; i < argc; ++i) {
00491 parse_gse_expression(arg, argv[i]);
00492 clauses.push_back(arg->get_gsec());
00493 }
00494 delete arg;
00495 arg = 0;
00496
00497 apply_grid_selection_expressions(l_grid, clauses);
00498
00499 DBG(cerr << "grid: past gse application" << endl);
00500
00501 l_grid->get_array()->set_send_p(true);
00502
00503 l_grid->read();
00504
00505 *btpp = l_grid;
00506 return;
00507 }
00508
00544 void
00545 function_geogrid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
00546 {
00547 string info =
00548 string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
00549 "<function name=\"geogrid\" version=\"1.1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geogrid\">\n"+
00550 "</function>";
00551
00552 if (argc == 0) {
00553 Str *response = new Str("version");
00554 response->set_value(info);
00555 *btpp = response;
00556 return ;
00557 }
00558
00559 if (argc < 5)
00560 throw Error(malformed_expr,"Wrong number of arguments to geogrid(). See geogrid() for more information.");
00561
00562 Grid *l_grid = dynamic_cast < Grid * >(argv[0]->ptr_duplicate());
00563 if (!l_grid)
00564 throw Error(malformed_expr,"The first argument to geogrid() must be a Grid variable!");
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 Grid::Map_iter i = l_grid->map_begin();
00577 while (i != l_grid->map_end())
00578 (*i++)->set_send_p(true);
00579
00580 l_grid->read();
00581
00582
00583
00584 l_grid->get_array()->set_read_p(false);
00585 DBG(cerr << "geogrid: past map read" << endl);
00586
00587
00588
00589 if (argc > 5) {
00590
00591
00592 vector < GSEClause * > clauses;
00593 gse_arg *arg = new gse_arg(l_grid);
00594 for (int i = 5; i < argc; ++i) {
00595 parse_gse_expression(arg, argv[i]);
00596 clauses.push_back(arg->get_gsec());
00597 }
00598 delete arg;
00599 arg = 0;
00600
00601 apply_grid_selection_expressions(l_grid, clauses);
00602 }
00603
00604 try {
00605
00606
00607 GridGeoConstraint gc(l_grid);
00608
00609
00610
00611 double top = extract_double_value(argv[1]);
00612 double left = extract_double_value(argv[2]);
00613 double bottom = extract_double_value(argv[3]);
00614 double right = extract_double_value(argv[4]);
00615 gc.set_bounding_box(top, left, bottom, right);
00616 DBG(cerr << "geogrid: past bounding box set" << endl);
00617
00618
00619 gc.apply_constraint_to_data();
00620 DBG(cerr << "geogrid: past apply constraint" << endl);
00621
00622
00623
00624 *btpp = gc.get_constrained_grid();
00625 return;
00626 }
00627 catch (Error &e) {
00628 throw e;
00629 }
00630 catch (exception & e) {
00631 throw
00632 InternalErr(string
00633 ("A C++ exception was thrown from inside geogrid(): ")
00634 + e.what());
00635 }
00636 }
00637
00638
00639
00640
00641
00642
00643 static double string_to_double(const char *val)
00644 {
00645 char *ptr;
00646 errno = 0;
00647
00648
00649 #ifdef WIN32
00650 double v = w32strtod(val, &ptr);
00651 #else
00652 double v = strtod(val, &ptr);
00653 #endif
00654
00655 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
00656 || *ptr != '\0') {
00657 throw Error(malformed_expr,string("Could not convert the string '") + val + "' to a double.");
00658 }
00659
00660 double abs_val = fabs(v);
00661 if (abs_val > DODS_DBL_MAX || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
00662 throw Error(malformed_expr,string("Could not convert the string '") + val + "' to a double.");
00663
00664 return v;
00665 }
00666
00670 static double get_attribute_double_value(BaseType *var,
00671 vector<string> &attributes)
00672 {
00673 AttrTable &attr = var->get_attr_table();
00674 string attribute_value = "";
00675 string values = "";
00676 vector<string>::iterator i = attributes.begin();
00677 while (attribute_value == "" && i != attributes.end()) {
00678 values += *i;
00679 if (!values.empty())
00680 values += ", ";
00681 attribute_value = attr.get_attr(*i++);
00682 }
00683
00684
00685
00686 if (attribute_value.empty()) {
00687 if (var->type() == dods_grid_c)
00688 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attributes);
00689 else
00690 throw Error(malformed_expr,string("No COARDS '") + values.substr(0, values.length() - 2)
00691 + "' attribute was found for the variable '"
00692 + var->name() + "'.");
00693 }
00694
00695 return string_to_double(remove_quotes(attribute_value).c_str());
00696 }
00697
00698 static double get_attribute_double_value(BaseType *var, const string &attribute)
00699 {
00700 AttrTable &attr = var->get_attr_table();
00701 string attribute_value = attr.get_attr(attribute);
00702
00703
00704
00705 if (attribute_value.empty()) {
00706 if (var->type() == dods_grid_c)
00707 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attribute);
00708 else
00709 throw Error(malformed_expr,string("No COARDS '") + attribute
00710 + "' attribute was found for the variable '"
00711 + var->name() + "'.");
00712 }
00713
00714 return string_to_double(remove_quotes(attribute_value).c_str());
00715 }
00716
00717 static double get_y_intercept(BaseType *var)
00718 {
00719 vector<string> attributes;
00720 attributes.push_back("add_offset");
00721 attributes.push_back("add_off");
00722 return get_attribute_double_value(var, attributes);
00723 }
00724
00725 static double get_slope(BaseType *var)
00726 {
00727 return get_attribute_double_value(var, "scale_factor");
00728 }
00729
00730 static double get_missing_value(BaseType *var)
00731 {
00732 return get_attribute_double_value(var, "missing_value");
00733 }
00734
00747 void
00748 function_linear_scale(int argc, BaseType * argv[], DDS &, BaseType **btpp)
00749 {
00750 string info =
00751 string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
00752 "<function name=\"linear_scale\" version=\"1.0b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#linear_scale\">\n" +
00753 "</function>";
00754
00755 if (argc == 0) {
00756 Str *response = new Str("info");
00757 response->set_value(info);
00758 *btpp = response;
00759 return;
00760 }
00761
00762
00763 DBG(cerr << "argc = " << argc << endl);
00764 if (!(argc == 1 || argc == 3 || argc == 4))
00765 throw Error(malformed_expr,"Wrong number of arguments to linear_scale(). See linear_scale() for more information");
00766
00767
00768 bool use_missing = false;
00769 double m, b, missing = 0.0;
00770 if (argc == 4) {
00771 m = extract_double_value(argv[1]);
00772 b = extract_double_value(argv[2]);
00773 missing = extract_double_value(argv[3]);
00774 use_missing = true;
00775 } else if (argc == 3) {
00776 m = extract_double_value(argv[1]);
00777 b = extract_double_value(argv[2]);
00778 use_missing = false;
00779 } else {
00780 m = get_slope(argv[0]);
00781
00782
00783
00784
00785 try {
00786 b = get_y_intercept(argv[0]);
00787 }
00788 catch (Error &e) {
00789 b = 0.0;
00790 }
00791
00792
00793
00794
00795 try {
00796 missing = get_missing_value(argv[0]);
00797 use_missing = true;
00798 }
00799 catch (Error &e) {
00800 use_missing = false;
00801 }
00802 }
00803
00804 DBG(cerr << "m: " << m << ", b: " << b << endl);DBG(cerr << "use_missing: " << use_missing << ", missing: " << missing << endl);
00805
00806
00807
00808 BaseType *dest = 0;
00809 double *data;
00810 if (argv[0]->type() == dods_grid_c) {
00811 Array &source = *dynamic_cast<Grid&>(*argv[0]).get_array();
00812 source.set_send_p(true);
00813 source.read();
00814 data = extract_double_array(&source);
00815 int length = source.length();
00816 int i = 0;
00817 while (i < length) {
00818 DBG2(cerr << "data[" << i << "]: " << data[i] << endl);
00819 if (!use_missing || !double_eq(data[i], missing))
00820 data[i] = data[i] * m + b;
00821 DBG2(cerr << " >> data[" << i << "]: " << data[i] << endl);
00822 ++i;
00823 }
00824
00825
00826 Float64 *temp_f = new Float64(source.name());
00827 source.add_var(temp_f);
00828 #ifdef VAL2BUF
00829 source.val2buf(static_cast<void*>(data), false);
00830 #else
00831 source.set_value(data, i);
00832 #endif
00833 delete [] data;
00834 delete temp_f;
00835 dest = argv[0];
00836 } else if (argv[0]->is_vector_type()) {
00837 Array &source = dynamic_cast<Array&>(*argv[0]);
00838 source.set_send_p(true);
00839
00840
00841 if (source.get_parent() && source.get_parent()->type() == dods_grid_c)
00842 source.get_parent()->read();
00843 else
00844 source.read();
00845
00846 data = extract_double_array(&source);
00847 int length = source.length();
00848 int i = 0;
00849 while (i < length) {
00850 if (!use_missing || !double_eq(data[i], missing))
00851 data[i] = data[i] * m + b;
00852 ++i;
00853 }
00854
00855 Float64 *temp_f = new Float64(source.name());
00856 source.add_var(temp_f);
00857
00858 source.val2buf(static_cast<void*>(data), false);
00859
00860 delete [] data;
00861 delete temp_f;
00862
00863 dest = argv[0];
00864 } else if (argv[0]->is_simple_type() && !(argv[0]->type() == dods_str_c
00865 || argv[0]->type() == dods_url_c)) {
00866 double data = extract_double_value(argv[0]);
00867 if (!use_missing || !double_eq(data, missing))
00868 data = data * m + b;
00869
00870 dest = new Float64(argv[0]->name());
00871
00872 dest->val2buf(static_cast<void*>(&data));
00873
00874 } else {
00875 throw Error(malformed_expr,"The linear_scale() function works only for numeric Grids, Arrays and scalars.");
00876 }
00877
00878 *btpp = dest;
00879 return;
00880 }
00881 #if 0
00882
00898 void
00899 function_geoarray(int argc, BaseType * argv[], DDS &, BaseType **btpp)
00900 {
00901 string info =
00902 string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
00903 "<function name=\"geoarray\" version=\"0.9b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geoarray\">\n" +
00904 "</function>";
00905
00906 if (argc == 0) {
00907 Str *response = new Str("version");
00908 response->set_value(info);
00909 *btpp = response;
00910 return;
00911 }
00912
00913 DBG(cerr << "argc = " << argc << endl);
00914 if (!(argc == 5 || argc == 9 || argc == 11))
00915 throw Error(malformed_expr,"Wrong number of arguments to geoarray(). See geoarray() for more information.");
00916
00917
00918 Array *l_array = dynamic_cast < Array * >(argv[0]->ptr_duplicate());
00919 if (!l_array)
00920 throw Error(malformed_expr,"The first argument to geoarray() must be an Array variable!");
00921
00922 try {
00923
00924
00925 double bb_top = extract_double_value(argv[1]);
00926 double bb_left = extract_double_value(argv[2]);
00927 double bb_bottom = extract_double_value(argv[3]);
00928 double bb_right = extract_double_value(argv[4]);
00929
00930 switch (argc) {
00931 case 5: {
00932 ArrayGeoConstraint agc(l_array);
00933
00934 agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
00935
00936 agc.apply_constraint_to_data();
00937 *btpp = agc.get_constrained_array();
00938 return;
00939 break;
00940 }
00941 case 9: {
00942 double var_top = extract_double_value(argv[5]);
00943 double var_left = extract_double_value(argv[6]);
00944 double var_bottom = extract_double_value(argv[7]);
00945 double var_right = extract_double_value(argv[8]);
00946 ArrayGeoConstraint agc (l_array, var_left, var_top, var_right, var_bottom);
00947
00948 agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
00949
00950 agc.apply_constraint_to_data();
00951 *btpp = agc.get_constrained_array();
00952 return;
00953 break;
00954 }
00955 case 11: {
00956 double var_top = extract_double_value(argv[5]);
00957 double var_left = extract_double_value(argv[6]);
00958 double var_bottom = extract_double_value(argv[7]);
00959 double var_right = extract_double_value(argv[8]);
00960 string projection = extract_string_argument(argv[9]);
00961 string datum = extract_string_argument(argv[10]);
00962 ArrayGeoConstraint agc(l_array,
00963 var_left, var_top, var_right, var_bottom,
00964 projection, datum);
00965
00966 agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
00967
00968 agc.apply_constraint_to_data();
00969 *btpp = agc.get_constrained_array();
00970 return;
00971 break;
00972 }
00973 default:
00974 throw InternalErr(__FILE__, __LINE__, "Wrong number of args to geoarray.");
00975 }
00976 }
00977 catch (Error & e) {
00978 throw e;
00979 }
00980 catch (exception & e) {
00981 throw
00982 InternalErr(string
00983 ("A C++ exception was thrown from inside geoarray(): ")
00984 + e.what());
00985
00986 }
00987
00988 throw InternalErr(__FILE__, __LINE__, "Impossible condition in geoarray.");
00989 }
00990 #endif
00991 void register_functions(ConstraintEvaluator & ce)
00992 {
00993 ce.add_function("grid", function_grid);
00994 ce.add_function("geogrid", function_geogrid);
00995 ce.add_function("linear_scale", function_linear_scale);
00996 #if 0
00997 ce.add_function("geoarray", function_geoarray);
00998 #endif
00999 ce.add_function("version", function_version);
01000 }
01001
01002 }