40 #include <dods-datatypes.h> 42 #include <InternalErr.h> 46 #include "GridGeoConstraint.h" 59 GridGeoConstraint::GridGeoConstraint(
Grid *grid)
60 :
GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0)
64 throw Error(
"The geogrid() function works only with Grids of two or three dimensions.");
67 if (!build_lat_lon_maps())
68 throw Error(
string(
"The grid '") + d_grid->
name()
69 +
"' does not have identifiable latitude/longitude map vectors.");
71 if (!lat_lon_dimensions_ok())
72 throw Error(
"The geogrid() function will only work when the Grid's Longitude and Latitude maps are the rightmost dimensions (grid: " + grid->
name() +
", 1).");
76 :
GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0)
80 throw Error(
"The geogrid() function works only with Grids of two or three dimensions.");
83 if (!build_lat_lon_maps(lat, lon))
84 throw Error(
string(
"The grid '") + d_grid->
name()
85 +
"' does not have valid latitude/longitude map vectors.");
88 if (!lat_lon_dimensions_ok())
89 throw Error(
"The geogrid() function will only work when the Grid's Longitude and Latitude maps are the rightmost dimensions (grid: " + grid->
name() +
", 2).");
107 bool GridGeoConstraint::build_lat_lon_maps()
121 while (m != d_grid->
map_end() && (!d_latitude || !d_longitude)) {
122 string units_value = (*m)->get_attr_table().get_attr(
"units");
124 string map_name = (*m)->name();
129 && unit_or_name_match(get_coards_lat_units(), get_lat_names(),
130 units_value, map_name)) {
138 d_latitude = dynamic_cast <
Array * >(*m);
140 throw InternalErr(__FILE__, __LINE__,
"Expected an array.");
141 if (!d_latitude->
read_p())
145 set_lat_length(d_latitude->
length());
151 && unit_or_name_match(get_coards_lon_units(), get_lon_names(),
152 units_value, map_name)) {
154 d_longitude = dynamic_cast <
Array * >(*m);
156 throw InternalErr(__FILE__, __LINE__,
"Expected an array.");
157 if (!d_longitude->
read_p())
161 set_lon_length(d_longitude->
length());
165 if (m + 1 == d_grid->
map_end())
166 set_longitude_rightmost(
true);
173 return get_lat() && get_lon();
183 bool GridGeoConstraint::build_lat_lon_maps(
Array *lat,
Array *lon)
189 while (m != d_grid->
map_end() && (!d_latitude || !d_longitude)) {
191 if (!d_latitude && *m == lat) {
195 if (!d_latitude->
read_p())
199 set_lat_length(d_latitude->
length());
204 if (!d_longitude && *m == lon) {
208 if (!d_longitude->
read_p())
212 set_lon_length(d_longitude->
length());
216 if (m + 1 == d_grid->
map_end())
217 set_longitude_rightmost(
true);
224 return get_lat() && get_lon();
238 GridGeoConstraint::lat_lon_dimensions_ok()
241 Grid::Map_riter rightmost = d_grid->
map_rbegin();
242 Grid::Map_riter next_rightmost = rightmost + 1;
244 if (*rightmost == d_longitude && *next_rightmost == d_latitude)
245 set_longitude_rightmost(
true);
246 else if (*rightmost == d_latitude && *next_rightmost == d_longitude)
247 set_longitude_rightmost(
false);
277 if (!is_bounding_box_set())
278 throw InternalErr(
"The Latitude and Longitude constraints must be set before calling apply_constraint_to_data().");
282 if (get_latitude_sense() == inverted) {
283 int tmp = get_latitude_index_top();
284 set_latitude_index_top(get_latitude_index_bottom());
285 set_latitude_index_bottom(tmp);
290 if (get_latitude_index_top() > get_latitude_index_bottom())
291 throw Error(
"The upper and lower latitude indices appear to be reversed. Please provide the latitude bounding box numbers giving the northern-most latitude first.");
295 get_latitude_index_bottom());
297 get_latitude_index_top(), 1,
298 get_latitude_index_bottom());
303 if (get_longitude_index_left() > get_longitude_index_right()) {
319 set_longitude_index_right(get_lon_length() - get_longitude_index_left()
320 + get_longitude_index_right());
321 set_longitude_index_left(0);
335 if (get_longitude_notation() == neg_pos) {
342 get_longitude_index_right());
345 get_longitude_index_left(),
346 1, get_longitude_index_right());
351 if (get_latitude_sense() == inverted) {
352 DBG(cerr <<
"Inverted latitude sense" << endl);
354 get_latitude_index_bottom() - get_latitude_index_top() + 1);
356 flip_latitude_within_array(*d_grid->
get_array(),
357 get_latitude_index_bottom() - get_latitude_index_top() + 1,
358 get_longitude_index_right() - get_longitude_index_left() + 1);
362 get_latitude_index_bottom() - get_latitude_index_top() + 1);
364 set_array_using_double(d_longitude, get_lon() + get_longitude_index_left(),
365 get_longitude_index_right() - get_longitude_index_left() + 1);
369 Grid::Map_iter end = d_grid->
map_end();
371 if (*i != d_latitude && *i != d_longitude) {
372 if ((*i)->send_p()) {
373 DBG(cerr <<
"reading grid map: " << (*i)->name() << endl);
382 if (get_array_data()) {
385 if (size != get_array_data_size())
386 throw InternalErr(__FILE__, __LINE__,
"Expected data size not copied to the Grid's buffer.");
GridGeoConstraint(libdap::Grid *grid)
Initialize GeoConstraint with a Grid.
virtual bool read()
Read data into a local buffer.
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
virtual bool read_p()
Has this variable been read?
virtual string name() const
Returns the name of the class instance.
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
virtual void apply_constraint_to_data()
top level DAP object to house generic methods
A class for software fault reporting.
Map_riter map_rbegin()
Returns an iterator referencing the first Map vector.
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
void set_array_using_double(Array *dest, double *src, int src_len)
double * extract_double_array(Array *a)
std::vector< dimension >::iterator Dim_iter
Holds the Grid data type.
virtual unsigned int val2buf(void *val, bool reuse=false)
Reads data into the Vector buffer.
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required...
GeoConstraint()
Initialize GeoConstraint.
virtual void reorder_longitude_map(int longitude_index_left)
string remove_quotes(const string &s)
virtual void transpose_vector(double *src, const int length)
virtual int length() const
virtual void transform_longitude_to_neg_pos_notation()
A class for error processing.
A multidimensional array of identical data types.
virtual void reorder_data_longitude_axis(libdap::Array &a, libdap::Array::Dim_iter lon_dim)
virtual void set_read_p(bool state)
Sets the value of the read_p property.