40#include <InternalErr.h>
42#include <dods-datatypes.h>
45#include "GridGeoConstraint.h"
58GridGeoConstraint::GridGeoConstraint(Grid *grid) :
GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0) {
59 if (d_grid->get_array()->dimensions() < 2 || d_grid->get_array()->dimensions() > 3)
60 throw Error(
"The geogrid() function works only with Grids of two or three dimensions.");
63 if (!build_lat_lon_maps())
64 throw Error(
string(
"The grid '") + d_grid->name() +
65 "' does not have identifiable latitude/longitude map vectors.");
67 if (!lat_lon_dimensions_ok())
68 throw Error(
"The geogrid() function will only work when the Grid's Longitude and Latitude maps are the "
69 "rightmost dimensions (grid: " +
70 grid->name() +
", 1).");
73GridGeoConstraint::GridGeoConstraint(Grid *grid,
Array *lat,
Array *lon)
74 : GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0) {
75 if (d_grid->get_array()->dimensions() < 2 || d_grid->get_array()->dimensions() > 3)
76 throw Error(
"The geogrid() function works only with Grids of two or three dimensions.");
79 if (!build_lat_lon_maps(lat, lon))
80 throw Error(
string(
"The grid '") + d_grid->name() +
"' does not have valid latitude/longitude map vectors.");
82 if (!lat_lon_dimensions_ok())
83 throw Error(
"The geogrid() function will only work when the Grid's Longitude and Latitude maps are the "
84 "rightmost dimensions (grid: " +
85 grid->name() +
", 2).");
103bool GridGeoConstraint::build_lat_lon_maps() {
104 Grid::Map_iter m = d_grid->map_begin();
116 while (m != d_grid->map_end() && (!d_latitude || !d_longitude)) {
117 string units_value = (*m)->get_attr_table().get_attr(
"units");
119 string map_name = (*m)->name();
123 if (!d_latitude && unit_or_name_match(get_coards_lat_units(), get_lat_names(), units_value, map_name)) {
131 d_latitude =
dynamic_cast<Array *
>(*m);
133 throw InternalErr(__FILE__, __LINE__,
"Expected an array.");
134 if (!d_latitude->read_p())
138 set_lat_length(d_latitude->length());
144 && unit_or_name_match(get_coards_lon_units(), get_lon_names(), units_value, map_name)) {
146 d_longitude =
dynamic_cast<Array *
>(*m);
148 throw InternalErr(__FILE__, __LINE__,
"Expected an array.");
149 if (!d_longitude->read_p())
153 set_lon_length(d_longitude->length());
157 if (m + 1 == d_grid->map_end())
158 set_longitude_rightmost(
true);
165 return get_lat() && get_lon();
175bool GridGeoConstraint::build_lat_lon_maps(
Array *lat,
Array *lon) {
176 Grid::Map_iter m = d_grid->map_begin();
180 while (m != d_grid->map_end() && (!d_latitude || !d_longitude)) {
182 if (!d_latitude && *m == lat) {
186 if (!d_latitude->read_p())
190 set_lat_length(d_latitude->length());
195 if (!d_longitude && *m == lon) {
199 if (!d_longitude->read_p())
203 set_lon_length(d_longitude->length());
207 if (m + 1 == d_grid->map_end())
208 set_longitude_rightmost(
true);
215 return get_lat() && get_lon();
228bool GridGeoConstraint::lat_lon_dimensions_ok() {
230 Grid::Map_riter rightmost = d_grid->map_rbegin();
231 Grid::Map_riter next_rightmost = rightmost + 1;
233 if (*rightmost == d_longitude && *next_rightmost == d_latitude)
234 set_longitude_rightmost(
true);
235 else if (*rightmost == d_latitude && *next_rightmost == d_longitude)
236 set_longitude_rightmost(
false);
265 if (!is_bounding_box_set())
267 "The Latitude and Longitude constraints must be set before calling apply_constraint_to_data().");
271 if (get_latitude_sense() == inverted) {
272 int tmp = get_latitude_index_top();
273 set_latitude_index_top(get_latitude_index_bottom());
274 set_latitude_index_bottom(tmp);
279 if (get_latitude_index_top() > get_latitude_index_bottom())
280 throw Error(
"The upper and lower latitude indices appear to be reversed. Please provide the latitude bounding "
281 "box numbers giving the northern-most latitude first.");
284 d_latitude->add_constraint(fd, get_latitude_index_top(), 1, get_latitude_index_bottom());
285 d_grid->get_array()->add_constraint(get_lat_dim(), get_latitude_index_top(), 1, get_latitude_index_bottom());
290 if (get_longitude_index_left() > get_longitude_index_right()) {
306 set_longitude_index_right(get_lon_length() - get_longitude_index_left() + get_longitude_index_right());
307 set_longitude_index_left(0);
321 if (get_longitude_notation() == neg_pos) {
326 fd = d_longitude->dim_begin();
327 d_longitude->add_constraint(fd, get_longitude_index_left(), 1, get_longitude_index_right());
329 d_grid->get_array()->add_constraint(get_lon_dim(), get_longitude_index_left(), 1, get_longitude_index_right());
334 if (get_latitude_sense() == inverted) {
335 DBG(cerr <<
"Inverted latitude sense" << endl);
337 get_latitude_index_bottom() - get_latitude_index_top() + 1);
339 flip_latitude_within_array(*d_grid->get_array(), get_latitude_index_bottom() - get_latitude_index_top() + 1,
340 get_longitude_index_right() - get_longitude_index_left() + 1);
344 get_latitude_index_bottom() - get_latitude_index_top() + 1);
347 get_longitude_index_right() - get_longitude_index_left() + 1);
350 Grid::Map_iter i = d_grid->map_begin();
351 Grid::Map_iter end = d_grid->map_end();
353 if (*i != d_latitude && *i != d_longitude) {
354 if ((*i)->send_p()) {
355 DBG(cerr <<
"reading grid map: " << (*i)->name() << endl);
364 if (get_array_data()) {
365 int size = d_grid->get_array()->val2buf(get_array_data());
367 if (size != get_array_data_size())
368 throw InternalErr(__FILE__, __LINE__,
"Expected data size not copied to the Grid's buffer.");
370 d_grid->set_read_p(
true);
372 d_grid->get_array()->read();
virtual void reorder_longitude_map(int longitude_index_left)
virtual void transform_longitude_to_neg_pos_notation()
virtual void reorder_data_longitude_axis(libdap::Array &a, libdap::Array::Dim_iter lon_dim)
virtual void transpose_vector(double *src, const int length)
virtual void apply_constraint_to_data()
A multidimensional array of identical data types.
std::vector< dimension >::iterator Dim_iter
A class for error processing.
A class for software fault reporting.
top level DAP object to house generic methods
string remove_quotes(const string &s)
void set_array_using_double(Array *dest, double *src, int src_len)
double * extract_double_array(Array *a)