12 #include "eckit/thread/ThreadSingleton.h"
14 using namespace eckit;
22 double mfmod(
double x,
double y) {
24 return (
a -
int(
a)) * y;
28 RegionCache::RegionCache() :
29 nboxes_(0), resol_(0), nbands_(0), latband_(0), midlat_(0), loncnt_(0), sum_loncnt_(0), stlon_(0), deltalon_(0) {}
45 const double& add,
const double& sign )
48 const double eps = 1.0e-7;
49 double Delta = delta ? *delta : 0;
50 bool wrap_around = (delta && add != 0) ?
true :
false;
51 double halfDelta = Delta / 2;
52 double x0 = x[0] + halfDelta;
53 double Key = wrap_around ? sign *
mfmod(
key + halfDelta + add, add) : sign * (
key + halfDelta);
54 int lo = 0, hi = n - 1;
56 int k = (lo + hi) / 2;
57 double xk = wrap_around ? sign *
mfmod(x0 + k * Delta + add, add) : sign * (x[k] + halfDelta);
58 if (wrap_around && k > 0 && std::abs(xk) < eps)
66 double xkp1 = wrap_around ? sign *
mfmod(x0 + kp1 * Delta + add, add) : sign * (x[kp1] + halfDelta);
67 if (wrap_around && std::abs(xkp1) < eps)
84 const double three_sixty = 360;
90 double Lon =
mfmod(
lon + three_sixty, three_sixty);
94 double startlon =
stlon_[jb] + k * deltalon;
95 double endlon =
stlon_[jb] + (k + 1) * deltalon;
96 startlon =
mfmod(startlon + three_sixty, three_sixty);
97 endlon =
mfmod(endlon + three_sixty, three_sixty);
98 if (endlon >= startlon) {
99 if (Lon >= startlon && Lon < endlon)
103 if ((Lon >= 0 && Lon < endlon) || (Lon >= startlon && Lon < three_sixty))
109 const double* stlon = &
stlon_[jb];
114 left = (*stlon) + k * deltalon;
115 mid = (*stlon) + (k + 0.5) * deltalon;
116 right = (*stlon) + (k + 1) * deltalon;
134 const double one_eighty = 180;
135 if (mid > one_eighty)
177 if (jb >= 0 && jb < *
nbands_) {
197 bool cache_save =
true;
200 VectorRegionCache::const_iterator it_cache =
instance().begin();
202 while (it_cache !=
instance().end() && cache_save) {
204 if (resol == *(cache->
resol_)) {
232 double midlat[],
double stlon[],
double deltalon[],
int loncnt[]) {
234 int nelm = p->size();
238 *(p->at(nelm)->kind_) = kind;
239 p->at(nelm)->resol_ =
new double;
240 *(p->at(nelm)->resol_) = resol;
241 p->at(nelm)->nbands_ =
new int;
242 *(p->at(nelm)->nbands_) = nb;
243 resol_ = p->at(nelm)->resol_;
244 nbands_ = p->at(nelm)->nbands_;
245 kind_ = p->at(nelm)->kind_;
246 p->at(nelm)->latband_ = latband;
247 p->at(nelm)->midlat_ = midlat;
248 p->at(nelm)->loncnt_ = loncnt;
249 p->at(nelm)->stlon_ = stlon;
250 p->at(nelm)->deltalon_ = deltalon;
259 p->at(nelm)->sum_loncnt_ =
new int[nb];
260 for (jb = 0; jb < nb; jb++) {
261 p->at(nelm)->sum_loncnt_[jb] = sum;
264 p->at(nelm)->nboxes_ =
new int;
265 *(p->at(nelm)->nboxes_) = sum;
266 nboxes_ = p->at(nelm)->nboxes_;
269 p->at(nelm)->last_ =
new Last;
270 p->at(nelm)->last_->
jb = -1;
271 p->at(nelm)->last_->lonbox = -1;
272 p->at(nelm)->last_->boxid = -1;
273 last_ = p->at(nelm)->last_;
double get_midlon(const double &, const double &, const double &)
static VectorRegionCache & instance()
virtual double get_resol(const double &val)
int interval_bsearch(const double &, const int &, const double[], const double *, const double &, const double &)
void get_cache(const double &)
void put_cache(const RegionCacheKind &kind, const double &, const int &, double[], double[], double[], double[], int[])
virtual void create_cache(const double &, const int &)
int find_latband(const double &)
double get_midlat(const double &, const double &)
int find_lonbox(const int &, const double &, double *, double *, double *)
double mfmod(double x, double y)
std::vector< RegionCache * > VectorRegionCache
static ThreadSingleton< VectorRegionCache > region_cache_