libdap++  Updated for version 3.11.7
ArrayGeoConstraint.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2003 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 // The Grid Selection Expression Clause class.
27 
28 
29 #include "config.h"
30 
31 static char id[] not_used =
32  { "$Id: ArrayGeoConstraint.cc 21922 2010-01-07 18:23:57Z jimg $"
33  };
34 
35 #include <cmath>
36 #include <iostream>
37 #include <sstream>
38 
39 //#define DODS_DEBUG
40 
41 #include "debug.h"
42 #include "dods-datatypes.h"
43 #include "ArrayGeoConstraint.h"
44 #include "Float64.h"
45 
46 #include "Error.h"
47 #include "InternalErr.h"
48 #include "ce_functions.h"
49 
50 using namespace std;
51 
52 namespace libdap {
53 
55 void ArrayGeoConstraint::m_init()
56 {
57  if (d_array->dimensions() < 2 || d_array->dimensions() > 3)
58  throw Error("The geoarray() function works only with Arrays of two or three dimensions.");
59 
60  build_lat_lon_maps();
61 }
62 
63 // In the other methods the ds_name parameter defaults to "" but that's not
64 // possible here. Remove ds_name
65 ArrayGeoConstraint::ArrayGeoConstraint(Array *array, double top, double left,
66  double bottom, double right)
67  : GeoConstraint(), d_array(array),
68  d_extent(top, left, bottom, right), d_projection("plat-carre", "wgs84")
69 
70 {
71  m_init();
72 }
73 
75  double top, double left, double bottom, double right,
76  const string &projection, const string &datum)
77  : GeoConstraint(), d_array(array),
78  d_extent(top, left, bottom, right), d_projection(projection, datum)
79 
80 {
81  m_init();
82 }
83 
95 bool ArrayGeoConstraint::build_lat_lon_maps()
96 {
97  // Find the longitude dimension: Assume it is the rightmost
99  set_lon_dim(d_array->dim_begin() + (d_array->dimensions() - 1));
100 
101  int number_elements_longitude = d_array->dimension_size(get_lon_dim());
102  double *lon_map = new double[number_elements_longitude];
103  for (int i = 0; i < number_elements_longitude; ++i) {
104  lon_map[i] = ((d_extent.d_right - d_extent.d_left) / (number_elements_longitude - 1)) * i + d_extent.d_left;
105  }
106  set_lon(lon_map);
107  set_lon_length(number_elements_longitude);
108 
109  // Find the latitude dimension: Assume it is the next-rightmost
110  set_lat_dim(d_array->dim_begin() + (d_array->dimensions() - 2));
111 
112  int number_elements_latitude = d_array->dimension_size(get_lat_dim());
113  double *lat_map = new double[number_elements_latitude];
114  for (int i = 0; i < number_elements_latitude; ++i) {
115  lat_map[i] = ((d_extent.d_bottom - d_extent.d_top) / (number_elements_latitude - 1)) * i + d_extent.d_top;
116  }
117  set_lat(lat_map);
118  set_lat_length(number_elements_latitude);
119 
120  return get_lat() && get_lon();
121 }
122 
130 bool
131 ArrayGeoConstraint::lat_lon_dimensions_ok()
132 {
133  return true;
134 }
135 
151 {
152  if (!is_bounding_box_set())
153  throw InternalErr(
154  "The Latitude and Longitude constraints must be set before calling\n\
155  apply_constraint_to_data().");
156 
157  if (get_latitude_sense() == inverted) {
158  int tmp = get_latitude_index_top();
161  }
162 
163  // It's easy to flip the Latitude values; if the bottom index value
164  // is before/above the top index, return an error explaining that.
166  throw Error("The upper and lower latitude indexes appear to be reversed. Please provide\nthe latitude bounding box numbers giving the northern-most latitude first.");
167 
168  d_array->add_constraint(get_lat_dim(),
171 
172  // Does the longitude constraint cross the edge of the longitude vector?
173  // If so, reorder the data (array).
176 
177  // Now the data are all in local storage
178 
179  // alter the indexes; the left index has now been moved to 0, and the right
180  // index is now at lon_vector_length-left+right.
184  }
185  // If the constraint used the -180/179 (neg_pos) notation, transform
186  // the longitude map s it uses the -180/179 notation. Note that at this
187  // point, d_longitude always uses the pos notation because of the earlier
188  // conditional transformation.
189 
190  // Apply constraint; stride is always one
191  d_array->add_constraint(get_lon_dim(),
194 
195  // Load the array if it has been read, which will be the case if
196  // reorder_data_longitude_axis() has been called.
197  if (get_array_data()) {
198 
199  int size = d_array->val2buf(get_array_data());
200 
201  if (size != get_array_data_size())
202  throw InternalErr
203  ("Expected data size not copied to the Grid's buffer.");
204  d_array->set_read_p(true);
205  }
206  else {
207  d_array->read();
208  }
209 }
210 
211 } // namespace libdap
212 
void set_lat_dim(Array::Dim_iter lat)
virtual bool read()
Read data into a local buffer.
Definition: BaseType.cc:788
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
Definition: Array.cc:333
char * get_array_data() const
void set_latitude_index_bottom(int bottom)
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
Definition: Array.cc:382
void set_lon(double *lon)
#define not_used
Definition: config.h:853
virtual void reorder_data_longitude_axis(Array &a, Array::Dim_iter lon_dim)
void set_latitude_index_top(int top)
virtual void set_read_p(bool state)
Indicates that the data is ready to send.
Definition: Vector.cc:341
void set_longitude_rightmost(bool state)
int get_longitude_index_left() const
Array::Dim_iter get_lon_dim() const
void set_lat(double *lat)
void set_lat_length(int len)
A class for software fault reporting.
Definition: InternalErr.h:64
int get_longitude_index_right() const
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
Definition: Array.cc:410
int get_array_data_size() const
int get_latitude_index_bottom() const
virtual unsigned int val2buf(void *val, bool reuse=false)
Reads data into the Vector buffer. Thrown if called for Structure, Sequence or Grid.
Definition: Vector.cc:819
LatitudeSense get_latitude_sense() const
void set_longitude_index_right(int right)
Dim_iter dim_begin()
Definition: Array.cc:360
int get_lon_length() const
void set_longitude_index_left(int left)
double * get_lon() const
A class for error processing.
Definition: Error.h:90
Array::Dim_iter get_lat_dim() const
A multidimensional array of identical data types.
Definition: Array.h:105
bool is_bounding_box_set() const
void set_lon_dim(Array::Dim_iter lon)
int get_latitude_index_top() const
double * get_lat() const
void set_lon_length(int len)