40#include <InternalErr.h>
42#include <dods-datatypes.h>
45#include "GridGeoConstraint.h"
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).");
74 :
GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0) {
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() {
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)
GridGeoConstraint(libdap::Grid *grid)
Initialize GeoConstraint with a Grid.
virtual void apply_constraint_to_data()
A multidimensional array of identical data types.
std::vector< dimension >::iterator Dim_iter
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
virtual bool read()
Read data into a local buffer.
virtual string name() const
Returns the name of the class instance.
virtual bool read_p()
Has this variable been read?
A class for error processing.
Holds the Grid data type.
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required.
A class for software fault reporting.
int length() const override
Returns the number of elements in the vector. Note that some child classes of Vector use the length o...
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)