29 namespace mio {
template <
class T>
class Array2D; }
40 template <
class T>
class Array2DProxy {
43 T& operator[](
const size_t& j) {
44 return array2D(anx, j);
48 Array2DProxy(Array2D<T>& i_array2D,
const size_t& i_anx) : array2D(i_array2D), anx(i_anx){}
62 template<
class T>
class Array2D {
71 Array2D(
const size_t& anx,
const size_t& any);
79 Array2D(
const size_t& anx,
const size_t& any,
const T& init);
93 Array2D(
const Array2D<T>& i_array2D,
const size_t& i_nx,
const size_t& i_ny,
94 const size_t& i_ncols,
const size_t& i_nrows);
101 Array2D(
const Array3D<T>& array3D,
const size_t& depth);
113 void subset(
const Array2D<T>& i_array2D,
const size_t& i_nx,
const size_t& i_ny,
114 const size_t& i_ncols,
const size_t& i_nrows);
126 void fill(
const Array2D<T>& i_array2D,
const size_t& i_nx,
const size_t& i_ny,
127 const size_t& i_ncols,
const size_t& i_nrows);
129 void fill(
const Array2D<T>& i_array2D,
const size_t& i_nx,
const size_t& i_ny);
144 void resize(
const size_t&
nx,
const size_t&
ny);
145 void resize(
const size_t&
nx,
const size_t&
ny,
const T& init);
146 void size(
size_t&
nx,
size_t&
ny)
const;
148 size_t getNx()
const;
149 size_t getNy()
const;
180 const Array2D<T>
getAbs()
const;
184 template<
class P>
friend std::iostream& operator<<(std::iostream& os, const Array2D<P>&
array);
185 template<
class P>
friend std::iostream&
operator>>(std::iostream& is, Array2D<P>&
array);
188 static bool checkEpsilonEquality(
const Array2D<double>& rhs1,
const Array2D<double>& rhs2,
const double& epsilon);
191 const T
operator ()(
const size_t& x,
const size_t& y)
const;
200 const Array2D<T>
operator+(
const T& rhs)
const;
201 Array2D<T>&
operator+=(
const Array2D<T>& rhs);
202 const Array2D<T>
operator+(
const Array2D<T>& rhs)
const;
205 const Array2D<T>
operator-(
const T& rhs)
const;
206 Array2D<T>&
operator-=(
const Array2D<T>& rhs);
207 const Array2D<T>
operator-(
const Array2D<T>& rhs)
const;
210 const Array2D<T>
operator*(
const T& rhs)
const;
211 Array2D<T>&
operator*=(
const Array2D<T>& rhs);
212 const Array2D<T>
operator*(
const Array2D<T>& rhs)
const;
215 const Array2D<T>
operator/(
const T& rhs)
const;
216 Array2D<T>&
operator/=(
const Array2D<T>& rhs);
217 const Array2D<T>
operator/(
const Array2D<T>& rhs)
const;
231 return vecData.at(i);
239 return vecData.at(i);
246 if ((x >= nx) || (y >= ny)) {
247 std::stringstream ss;
248 ss <<
"Trying to access array(" << x <<
"," << y <<
")";
249 ss <<
" while array is (" << nx <<
"," << ny <<
")";
254 return vecData[x + y*nx];
259 if ((x >= nx) || (y >= ny)) {
260 std::stringstream ss;
261 ss <<
"Trying to access array(" << x <<
"," << y <<
")";
262 ss <<
" while array is (" << nx <<
"," << ny <<
")";
266 return vecData[x + y*nx];
270 return Array2DProxy<T>(*
this, i);
280 const size_t& i_ncols,
const size_t& i_nrows) :
281 vecData(i_ncols*i_nrows), nx(i_ncols), ny(i_nrows), keep_nodata(true)
283 subset(i_array2D, i_nx, i_ny, i_ncols, i_nrows);
287 : vecData(array3D.getNx()*array3D.getNy()), nx(array3D.getNx()), ny(array3D.getNy()), keep_nodata(array3D.getKeepNodata())
290 for (
size_t jj=0; jj<
ny; jj++) {
291 for (
size_t ii=0; ii<
nx; ii++) {
298 const size_t& i_ncols,
const size_t& i_nrows)
300 if (((i_nx+i_ncols) > i_array2D.nx) || ((i_ny+i_nrows) > i_array2D.ny)) {
301 std::stringstream ss;
302 ss <<
"Trying to cut an array of size (" << i_array2D.nx <<
"," << i_array2D.ny <<
") ";
303 ss <<
"to size (" << i_ncols <<
"," << i_nrows <<
") starting at (" << i_nx <<
"," << i_ny <<
")";
307 if ((i_ncols == 0) || (i_nrows == 0))
310 resize(i_ncols, i_nrows);
312 for (
size_t jj=0; jj<ny; jj++) {
313 for (
size_t ii=0; ii<nx; ii++) {
314 operator()(ii,jj) = i_array2D(i_nx+ii, i_ny+jj);
321 size_t i_ncols, i_nrows;
322 i_array2D.size(i_ncols, i_nrows);
323 fill(i_array2D, i_nx, i_ny, i_ncols, i_nrows);
327 const size_t& i_ncols,
const size_t& i_nrows)
329 if (((i_nx+i_ncols) > nx) || ((i_ny+i_nrows) > ny)) {
330 std::stringstream ss;
331 ss <<
"Filling an array of size (" << nx <<
"," << ny <<
") ";
332 ss <<
"with an array of size (" << i_ncols <<
"," << i_nrows <<
") ";
333 ss <<
"starting at (" << i_nx <<
"," << i_ny <<
")";
337 if ((i_ncols == 0) || (i_nrows == 0))
340 for (
size_t jj=i_ny; jj<(i_ny+i_nrows); jj++) {
341 for (
size_t ii=i_nx; ii<(i_nx+i_ncols); ii++) {
342 const size_t ix = ii-i_nx;
343 const size_t iy = jj-i_ny;
344 operator()(ii,jj) = i_array2D(ix, iy);
350 vecData(anx*any, init), nx(anx), ny(any), keep_nodata(true) {}
353 vecData(anx*any), nx(anx), ny(any), keep_nodata(true) {}
356 keep_nodata = i_keep_nodata;
365 vecData.resize(anx*any);
372 vecData.resize(anx*any, init);
400 return (nx==0 && ny==0);
404 std::ostringstream os;
406 for (
size_t jj=0; jj<ny; jj++) {
407 const size_t jnx = jj*nx;
408 for (
size_t ii=0; ii<nx; ii++) {
409 os << vecData[ii+jnx] <<
" ";
413 os <<
"</array2d>\n";
417 template<
class P> std::iostream& operator<<(std::iostream& os, const Array2D<P>&
array) {
418 os.write(reinterpret_cast<const char*>(&
array.keep_nodata),
sizeof(
array.keep_nodata));
419 os.write(reinterpret_cast<const char*>(&
array.nx),
sizeof(
array.nx));
420 os.write(reinterpret_cast<const char*>(&
array.ny),
sizeof(
array.ny));
421 os.write(reinterpret_cast<const char*>(&
array.vecData[0]), static_cast<std::streamsize>(
array.nx*
array.ny*
sizeof(P)));
426 is.read(reinterpret_cast<char*>(&array.keep_nodata),
sizeof(array.keep_nodata));
427 is.read(reinterpret_cast<char*>(&array.nx),
sizeof(array.nx));
428 is.read(reinterpret_cast<char*>(&array.ny),
sizeof(array.ny));
429 array.vecData.resize(array.nx*array.ny);
430 is.read(reinterpret_cast<char*>(&array.vecData[0]), static_cast<std::streamsize>(array.nx*array.ny*
sizeof(P)));
436 T min = std::numeric_limits<T>::max();
438 const size_t nxy = ny*nx;
439 if (keep_nodata==
false) {
440 for (
size_t jj=0; jj<nxy; jj++) {
441 const T val = vecData[jj];
442 if (val<min) min=val;
446 for (
size_t jj=0; jj<nxy; jj++) {
447 const T val = vecData[jj];
450 if (min!=std::numeric_limits<T>::max())
return min;
457 T max = -std::numeric_limits<T>::max();
459 const size_t nxy = ny*nx;
460 if (keep_nodata==
false) {
461 for (
size_t jj=0; jj<nxy; jj++) {
462 const T val = vecData[jj];
463 if (val>max) max=val;
467 for (
size_t jj=0; jj<nxy; jj++) {
468 const T val = vecData[jj];
471 if (max!=-std::numeric_limits<T>::max())
return max;
479 const size_t nxy = nx*ny;
481 if (keep_nodata==
false) {
482 for (
size_t jj=0; jj<nxy; jj++) {
483 const T val = vecData[jj];
486 if (nxy>0)
return mean/(T)(nxy);
490 for (
size_t jj=0; jj<nxy; jj++) {
491 const T val = vecData[jj];
497 if (count>0)
return mean/(T)(count);
504 const size_t nxy = nx*ny;
506 if (keep_nodata==
false) {
510 for (
size_t ii=0; ii<nxy; ii++) {
518 if (std::numeric_limits<T>::is_signed) {
519 const size_t nxy = nx*ny;
520 if (keep_nodata==
false) {
521 for (
size_t ii=0; ii<nxy; ii++) {
522 T& val = vecData[ii];
526 for (
size_t ii=0; ii<nxy; ii++) {
527 T& val = vecData[ii];
544 if (nx!=rhs.
nx || ny!=rhs.
ny)
return false;
546 const size_t nxy = nx*ny;
547 for (
size_t jj=0; jj<nxy; jj++)
558 if (
this != &source) {
559 keep_nodata = source.keep_nodata;
562 vecData = source.vecData;
568 std::fill(vecData.begin(), vecData.end(), value);
575 if ((rhs.nx != nx) || (rhs.ny != ny)) {
576 std::stringstream ss;
577 ss <<
"Trying to add two Array2D objects with different dimensions: ";
578 ss <<
"(" << nx <<
"," << ny <<
") + (" << rhs.nx <<
"," << rhs.ny <<
")";
582 const size_t nxy = nx*ny;
584 if (keep_nodata==
false) {
585 for (
size_t jj=0; jj<nxy; jj++)
586 vecData[jj] += rhs(jj);
588 for (
size_t jj=0; jj<nxy; jj++) {
592 vecData[jj] += rhs(jj);
609 if (rhs==0.)
return *
this;
612 const size_t nxy = nx*ny;
614 if (keep_nodata==
false) {
615 for (
size_t jj=0; jj<nxy; jj++)
618 for (
size_t jj=0; jj<nxy; jj++) {
638 if ((rhs.nx != nx) || (rhs.ny != ny)){
639 std::stringstream ss;
640 ss <<
"Trying to substract two Array2D objects with different dimensions: ";
641 ss <<
"(" << nx <<
"," << ny <<
") - (" << rhs.nx <<
"," << rhs.ny <<
")";
645 const size_t nxy = nx*ny;
647 if (keep_nodata==
false) {
648 for (
size_t jj=0; jj<nxy; jj++)
649 vecData[jj] -= rhs(jj);
651 for (
size_t jj=0; jj<nxy; jj++) {
655 vecData[jj] -= rhs(jj);
687 if ((rhs.nx != nx) || (rhs.ny != ny)){
688 std::stringstream ss;
689 ss <<
"Trying to multiply two Array2D objects with different dimensions: ";
690 ss <<
"(" << nx <<
"," << ny <<
") * (" << rhs.nx <<
"," << rhs.ny <<
")";
694 const size_t nxy = nx*ny;
696 if (keep_nodata==
false) {
697 for (
size_t jj=0; jj<nxy; jj++)
698 vecData[jj] *= rhs(jj);
700 for (
size_t jj=0; jj<nxy; jj++) {
704 vecData[jj] *= rhs(jj);
721 if (rhs==1.)
return *
this;
724 const size_t nxy = nx*ny;
726 if (keep_nodata==
false) {
727 for (
size_t jj=0; jj<nxy; jj++)
730 for (
size_t jj=0; jj<nxy; jj++) {
750 if ((rhs.nx != nx) || (rhs.ny != ny)){
751 std::stringstream ss;
752 ss <<
"Trying to divide two Array2D objects with different dimensions: ";
753 ss <<
"(" << nx <<
"," << ny <<
") / (" << rhs.nx <<
"," << rhs.ny <<
")";
757 const size_t nxy = nx*ny;
759 if (keep_nodata==
false) {
760 for (
size_t jj=0; jj<nxy; jj++)
761 vecData[jj] /= rhs(jj);
763 for (
size_t jj=0; jj<nxy; jj++) {
767 vecData[jj] /= rhs(jj);
797 const size_t in_nx=in.getNx(), in_ny=in.getNy();
799 if (nx!=in_nx || ny!=in_ny)
802 const size_t nxy = nx*ny;
803 for (
size_t jj=0; jj<nxy; jj++)
T & operator()(const size_t &x, const size_t &y)
Definition: Array2D.h:244
bool operator==(const Array2D< T > &) const
Operator that tests for equality.
Definition: Array2D.h:796
Array2D()
Definition: Array2D.h:273
size_t getNx() const
Definition: Array2D.h:386
friend std::iostream & operator>>(std::iostream &is, Array2D< P > &array)
Definition: Array2D.h:425
void subset(const Array2D< T > &i_array2D, const size_t &i_nx, const size_t &i_ny, const size_t &i_ncols, const size_t &i_nrows)
A method that can be used to cut out a subplane of an existing Array2D object that is passed as i_arr...
Definition: Array2D.h:297
const Array2D< T > operator+(const T &rhs) const
Definition: Array2D.h:627
void resize(const size_t &nx, const size_t &ny)
Definition: Array2D.h:363
T getMax() const
returns the maximum value contained in the grid
Definition: Array2D.h:455
const Array2D< T > operator/(const T &rhs) const
Definition: Array2D.h:788
bool checkEpsilonEquality(const Array2D< double > &rhs, const double &epsilon) const
Definition: Array2D.h:543
bool getKeepNodata() const
get how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array2D.h:359
size_t nx
Definition: Array2D.h:224
void setKeepNodata(const bool i_keep_nodata)
set how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array2D.h:355
The template class Array2D is a 2D Array (Matrix) able to hold any type of object as datatype...
Definition: Array2D.h:29
std::vector< T > vecData
Definition: Array2D.h:223
bool checkEpsilonEquality(const double &val1, const double &val2, const double &epsilon)
Check whether two values are equal regarding a certain epsilon environment (within certain radius of ...
Definition: IOUtils.h:81
const Array2D< T > operator*(const T &rhs) const
Definition: Array2D.h:739
void clear()
Definition: Array2D.h:394
Array2D< T > & operator+=(const T &rhs)
Definition: Array2D.h:607
T getMin() const
returns the minimum value contained in the grid
Definition: Array2D.h:434
const std::string toString() const
Definition: Array2D.h:403
void abs()
Definition: Array2D.h:517
bool keep_nodata
Definition: Array2D.h:226
Array2D< T > & operator-=(const T &rhs)
Definition: Array2D.h:670
bool empty() const
Definition: Array2D.h:399
#define AT
Definition: IOExceptions.h:29
bool operator!=(const Array2D< T > &) const
Operator that tests for inequality.
Definition: Array2D.h:809
const double nodata
This is the internal nodata value.
Definition: IOUtils.h:60
size_t size() const
Definition: Array2D.h:382
T getMean() const
returns the mean value contained in the grid
Definition: Array2D.h:476
virtual ~Array2D()
Definition: Array2D.h:277
Array2DProxy< T > operator[](const size_t &i)
Definition: Array2D.h:269
Array2D< T > & operator*=(const T &rhs)
Definition: Array2D.h:719
size_t ny
Definition: Array2D.h:225
void fill(const Array2D< T > &i_array2D, const size_t &i_nx, const size_t &i_ny, const size_t &i_ncols, const size_t &i_nrows)
A method that can be used to insert a subplane into an existing Array2D object that is passed as i_ar...
Definition: Array2D.h:326
thrown when an index is out of bounds
Definition: IOExceptions.h:108
const double e
Definition: Meteoconst.h:66
Array2D< T > & operator=(const Array2D< T > &)
Definition: Array2D.h:557
The template class Array3D is a 3D Array (Tensor) able to hold any type of object as datatype...
Definition: Array3D.h:29
size_t getCount() const
returns the number of points contained in the grid. If setNodataHandling(IOUtils::RAW_NODATA), then the number of points is the size of the grid. If setNodataHandling(IOUtils::PARSE_NODATA), then it is the number of non-nodata values in the grid
Definition: Array2D.h:502
const Array2D< T > operator-(const T &rhs) const
Definition: Array2D.h:676
The basic exception class adjusted for the needs of SLF software.
Definition: IOExceptions.h:41
size_t getNy() const
Definition: Array2D.h:390
std::iostream & operator>>(std::iostream &is, Config &cfg)
Definition: Config.cc:141
value::array array
Definition: picojson.h:194
Array2D< T > & operator/=(const T &rhs)
Definition: Array2D.h:782
const Array2D< T > getAbs() const
returns the grid of the absolute value of values contained in the grid
Definition: Array2D.h:534