00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_DATATYPE_REGULARDATA2D_H
00008 #define BALL_DATATYPE_REGULARDATA2D_H
00009
00010 #ifndef BALL_MATHS_VECTOR2_H
00011 # include <BALL/MATHS/vector2.h>
00012 #endif
00013
00014 #ifndef BALL_SYSTEM_FILE_H
00015 # include <BALL/SYSTEM/file.h>
00016 #endif
00017
00018 #include <iostream>
00019 #include <fstream>
00020 #include <iterator>
00021 #include <algorithm>
00022
00023 namespace BALL
00024 {
00034 template <typename ValueType>
00035 class TRegularData2D
00036 {
00037 public:
00038
00039 BALL_CREATE(TRegularData2D<ValueType>)
00040
00041
00044
00046 class IndexType
00047 {
00048 public:
00049 inline IndexType() : x(0), y(0) {}
00050 inline IndexType(Position p) : x(p), y(p) {}
00051 inline IndexType(Position p, Position q) : x(p), y(q) {}
00052
00054 Position x;
00056 Position y;
00057
00058 };
00059
00061 typedef std::vector<ValueType> VectorType;
00063 typedef TVector2<float> CoordinateType;
00065 typedef typename std::vector<ValueType>::iterator Iterator;
00067 typedef typename std::vector<ValueType>::const_iterator ConstIterator;
00069
00070
00071
00072 typedef ValueType value_type;
00073 typedef typename std::vector<ValueType>::iterator iterator;
00074 typedef typename std::vector<ValueType>::const_iterator const_iterator;
00075 typedef typename std::vector<ValueType>::reference reference;
00076 typedef typename std::vector<ValueType>::const_reference const_reference;
00077 typedef typename std::vector<ValueType>::pointer pointer;
00078 typedef typename std::vector<ValueType>::difference_type difference_type;
00079 typedef typename std::vector<ValueType>::size_type size_type;
00080
00084
00088 TRegularData2D();
00089
00091 TRegularData2D(const TRegularData2D<ValueType>& data)
00092 throw(Exception::OutOfMemory);
00093
00100 TRegularData2D(const CoordinateType& origin, const CoordinateType& dimension, const CoordinateType& spacing)
00101 throw(Exception::OutOfMemory);
00102
00103
00104
00105
00106
00107
00108 TRegularData2D(const IndexType& size,
00109 const CoordinateType& origin = CoordinateType(0.0),
00110 const CoordinateType& dimension = CoordinateType(1.0))
00111 throw(Exception::OutOfMemory);
00112
00115 virtual ~TRegularData2D();
00116
00120 virtual void clear();
00122
00126
00130 TRegularData2D& operator = (const TRegularData2D<ValueType>& data)
00131 throw(Exception::OutOfMemory);
00133
00134
00138
00143 bool operator == (const TRegularData2D<ValueType>& data) const;
00144
00146 BALL_INLINE bool operator != (const TRegularData2D<ValueType>& data) const { return !this->operator == (data); }
00147
00149 BALL_INLINE bool empty() const { return data_.empty(); }
00150
00152 bool isInside(const CoordinateType& x) const;
00154
00158
00159 BALL_INLINE ConstIterator begin() const { return data_.begin(); }
00161 BALL_INLINE ConstIterator end() const { return data_.end(); }
00163 BALL_INLINE Iterator begin() { return data_.begin(); }
00165 BALL_INLINE Iterator end() { return data_.end(); }
00167
00171
00172 BALL_INLINE size_type size() const { return data_.size(); }
00173 BALL_INLINE size_type max_size() const { return data_.max_size(); }
00174 BALL_INLINE void swap(TRegularData2D<ValueType>& data) { std::swap(*this, data); }
00175
00176
00180 const ValueType& getData(const IndexType& index) const
00181 throw(Exception::OutOfGrid);
00182
00186 ValueType& getData(const IndexType& index)
00187 throw(Exception::OutOfGrid);
00188
00192 const ValueType& getData(Position index) const
00193 throw(Exception::OutOfGrid);
00194
00198 ValueType& getData(Position index)
00199 throw(Exception::OutOfGrid);
00200
00205 const ValueType& operator [] (const IndexType& index) const { return data_[index.x + size_.x * index.y]; }
00206
00211 ValueType& operator [] (const IndexType& index) { return data_[index.x + size_.x * index.y]; }
00212
00217 const ValueType& operator [] (Position index) const { return data_[index]; }
00218
00223 ValueType& operator [] (Position index) { return data_[index]; }
00224
00233 ValueType operator () (const CoordinateType& x) const;
00234
00240 ValueType getInterpolatedValue(const CoordinateType& x) const
00241 throw(Exception::OutOfGrid);
00242
00248 const ValueType& getClosestValue(const CoordinateType& x) const
00249 throw(Exception::OutOfGrid);
00250
00256 ValueType& getClosestValue(const CoordinateType& x)
00257 throw(Exception::OutOfGrid);
00258
00262 IndexType getLowerIndex(const CoordinateType& v) const
00263 throw(Exception::OutOfGrid);
00264
00270 IndexType getClosestIndex(const CoordinateType& v) const
00271 throw(Exception::OutOfGrid);
00272
00278 inline const IndexType& getSize() const { return size_; }
00279
00284 inline const CoordinateType& getOrigin() const { return origin_; }
00285
00290 const CoordinateType& getSpacing() const { return spacing_; }
00291
00294 void setOrigin(const CoordinateType& origin);
00295
00301 const CoordinateType& getDimension() const { return dimension_; }
00302
00308 void setDimension(const CoordinateType& dimension) { dimension_ = dimension; }
00309
00321 void resize(const IndexType& new_size)
00322 throw(Exception::OutOfMemory);
00323
00332 void rescale(const IndexType& new_size)
00333 throw(Exception::OutOfMemory);
00334
00339 CoordinateType getCoordinates(const IndexType& index) const
00340 throw(Exception::OutOfGrid);
00341
00346 CoordinateType getCoordinates(Position index) const
00347 throw(Exception::OutOfGrid);
00348
00361 void getEnclosingIndices
00362 (const CoordinateType& r, Position& ll, Position& lr, Position& ul, Position& ur) const
00363 throw(Exception::OutOfGrid);
00364
00368 void getEnclosingValues
00369 (const CoordinateType& r, ValueType& ll, ValueType& lr, ValueType& ul, ValueType& ur) const
00370 throw(Exception::OutOfGrid);
00371
00375 void binaryWrite(const String& filename) const
00376 throw(Exception::FileNotFound);
00377
00381 void binaryRead(const String& filename)
00382 throw(Exception::FileNotFound);
00384
00385 protected:
00386
00388 VectorType data_;
00389
00391 CoordinateType origin_;
00392
00394 CoordinateType dimension_;
00395
00397 CoordinateType spacing_;
00398
00400 IndexType size_;
00401
00403 typedef struct { ValueType bt[1024]; } BlockValueType;
00404 };
00405
00408 typedef TRegularData2D<float> RegularData2D;
00409
00410
00411 template <class ValueType>
00412 TRegularData2D<ValueType>::TRegularData2D()
00413 : data_(),
00414 origin_(0.0),
00415 dimension_(0.0),
00416 spacing_(1.0),
00417 size_(0)
00418 {
00419 }
00420
00421
00422 template <class ValueType>
00423 TRegularData2D<ValueType>::TRegularData2D(const TRegularData2D<ValueType>& data)
00424 throw(Exception::OutOfMemory)
00425 : data_(),
00426 origin_(data.origin_),
00427 dimension_(data.dimension_),
00428 spacing_(data.spacing_),
00429 size_(data.size_)
00430 {
00431 try
00432 {
00433 data_ = data.data_;
00434 }
00435 catch (std::bad_alloc&)
00436 {
00437 data_.resize(0);
00438 throw Exception::OutOfMemory(__FILE__, __LINE__, data.data_.size() * sizeof(ValueType));
00439 }
00440 }
00441
00442 template <class ValueType>
00443 TRegularData2D<ValueType>::TRegularData2D
00444 (const typename TRegularData2D<ValueType>::IndexType& size,
00445 const typename TRegularData2D<ValueType>::CoordinateType& origin,
00446 const typename TRegularData2D<ValueType>::CoordinateType& dimension)
00447 throw(Exception::OutOfMemory)
00448 : data_(),
00449 origin_(origin),
00450 dimension_(dimension),
00451 spacing_(0.0, 0.0),
00452 size_(size)
00453 {
00454
00455 spacing_.x = dimension_.x / (double)(size_.x - 1);
00456 spacing_.y = dimension_.y / (double)(size_.y - 1);
00457
00458
00459 size_type number_of_points = size_.x * size_.y;
00460 try
00461 {
00462 data_.resize(number_of_points);
00463 }
00464 catch (std::bad_alloc&)
00465 {
00466 data_.resize(0);
00467 throw Exception::OutOfMemory(__FILE__, __LINE__, number_of_points * sizeof(ValueType));
00468 }
00469 }
00470
00471 template <class ValueType>
00472 TRegularData2D<ValueType>::TRegularData2D
00473 (const typename TRegularData2D<ValueType>::CoordinateType& origin,
00474 const typename TRegularData2D<ValueType>::CoordinateType& dimension,
00475 const typename TRegularData2D<ValueType>::CoordinateType& spacing)
00476 throw(Exception::OutOfMemory)
00477 : data_(),
00478 origin_(origin),
00479 dimension_(dimension),
00480 spacing_(spacing),
00481 size_(0)
00482 {
00483
00484 size_.x = (Size)(dimension_.x / spacing_.x + 0.5) + 1;
00485 size_.y = (Size)(dimension_.y / spacing_.y + 0.5) + 1;
00486
00487
00488 size_type size = size_.x * size_.y;
00489 try
00490 {
00491 data_ .resize(size);
00492 }
00493 catch (std::bad_alloc&)
00494 {
00495 data_.resize(0);
00496 throw Exception::OutOfMemory(__FILE__, __LINE__, size * sizeof(ValueType));
00497 }
00498
00499
00500 spacing_.x = dimension_.x / (double)(size_.x - 1);
00501 spacing_.y = dimension_.y / (double)(size_.y - 1);
00502 }
00503
00504 template <class ValueType>
00505 TRegularData2D<ValueType>::~TRegularData2D()
00506 {
00507 }
00508
00509
00510 template <typename ValueType>
00511 BALL_INLINE
00512 TRegularData2D<ValueType>& TRegularData2D<ValueType>::operator =
00513 (const TRegularData2D<ValueType>& rhs)
00514 throw(Exception::OutOfMemory)
00515 {
00516
00517 if (&rhs != this)
00518 {
00519
00520
00521 origin_ = rhs.origin_;
00522 dimension_ = rhs.dimension_;
00523 spacing_ = rhs.spacing_;
00524 size_ = rhs.size_;
00525
00526
00527 try
00528 {
00529 data_ = rhs.data_;
00530 }
00531 catch (std::bad_alloc&)
00532 {
00533 data_.resize(0);
00534 throw Exception::OutOfMemory(__FILE__, __LINE__, rhs.data_.size() * sizeof(ValueType));
00535 }
00536 }
00537
00538 return *this;
00539 }
00540
00541 template <typename ValueType>
00542 void TRegularData2D<ValueType>::rescale(const typename TRegularData2D<ValueType>::IndexType& size)
00543 throw(Exception::OutOfMemory)
00544 {
00545
00546 if ((size.x == size_.x) && (size_.y == size.y))
00547 {
00548 return;
00549 }
00550
00551
00552 if ((size.x == 0) || (size.y == 0))
00553 {
00554 data_.resize(0);
00555 dimension_.set(0.0);
00556 return;
00557 }
00558
00559
00560 size_type new_size = (size_type)(size.x * size.y);
00561
00562
00563 try
00564 {
00565
00566 TRegularData2D<ValueType> old_data(*this);
00567
00568
00569 data_.resize(new_size);
00570 spacing_.x = dimension_.x / (double)(size.x - 1);
00571 spacing_.y = dimension_.y / (double)(size.y - 1);
00572
00573
00574 CoordinateType v;
00575 for (size_type i = 0; i < new_size; i++)
00576 {
00577 Position x = i % size.x;
00578 Position y = i / size.x;
00579 v.x = origin_.x + x * spacing_.x;
00580 v.y = origin_.y + y * spacing_.y;
00581 data_[i] = old_data(v);
00582 }
00583
00584
00585 size_ = size;
00586 }
00587 catch (std::bad_alloc&)
00588 {
00589 throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * (Size)sizeof(ValueType));
00590 }
00591 }
00592
00593 template <typename ValueType>
00594 void TRegularData2D<ValueType>::resize(const typename TRegularData2D<ValueType>::IndexType& size)
00595 throw(Exception::OutOfMemory)
00596 {
00597
00598 if (size.x == size_.x && size_.y == size.y)
00599 {
00600 return;
00601 }
00602
00603
00604 if ((size.x == 0) || (size.y == 0))
00605 {
00606 data_.resize(0);
00607 dimension_.set(0.0, 0.0);
00608 return;
00609 }
00610
00611
00612 size_type new_size = (size_type)(size.x * size.y);
00613
00614
00615 try
00616 {
00617
00618 std::vector<ValueType> old_data(data_);
00619
00620
00621 data_.resize(new_size);
00622
00623
00624 static ValueType default_value = (ValueType)0;
00625 for (size_type i = 0; i < new_size; i++)
00626 {
00627 size_type x = i % size.x;
00628 size_type y = i / size.x;
00629 if (x >= size_.x || y >= size_.y)
00630 {
00631 data_[i] = default_value;
00632 }
00633 else
00634 {
00635 data_[i] = old_data[x + y * size_.x];
00636 }
00637 }
00638
00639
00640 dimension_.x *= (double)size.x / (double)size_.x;
00641 dimension_.y *= (double)size.y / (double)size_.y;
00642 size_ = size;
00643 }
00644 catch (std::bad_alloc&)
00645 {
00646 throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * (Size)sizeof(ValueType));
00647 }
00648 }
00649
00650 template <class ValueType>
00651 void TRegularData2D<ValueType>::setOrigin(const typename TRegularData2D<ValueType>::CoordinateType& origin)
00652 {
00653 origin_ = origin;
00654 }
00655
00656 template <class ValueType>
00657 BALL_INLINE
00658 bool TRegularData2D<ValueType>::isInside(const typename TRegularData2D<ValueType>::CoordinateType& r) const
00659 {
00660 return ((r.x >= origin_.x) && (r.x <= (origin_.x + dimension_.x))
00661 && (r.y >= origin_.y) && (r.y <= (origin_.y + dimension_.y)));
00662 }
00663
00664 template <class ValueType>
00665 BALL_INLINE
00666 const ValueType& TRegularData2D<ValueType>::getData
00667 (const typename TRegularData2D<ValueType>::IndexType& index) const
00668 throw(Exception::OutOfGrid)
00669 {
00670 size_type pos = index.x + index.y * size_.x;
00671 if (pos >= data_.size())
00672 {
00673 throw Exception::OutOfGrid(__FILE__, __LINE__);
00674 }
00675 return data_[pos];
00676 }
00677
00678 template <class ValueType>
00679 BALL_INLINE
00680 ValueType& TRegularData2D<ValueType>::getData(const typename TRegularData2D<ValueType>::IndexType& index)
00681 throw(Exception::OutOfGrid)
00682 {
00683 size_type pos = index.x + index.y * size_.x;
00684 if (pos >= data_.size())
00685 {
00686 throw Exception::OutOfGrid(__FILE__, __LINE__);
00687 }
00688 return data_[pos];
00689 }
00690
00691 template <class ValueType>
00692 BALL_INLINE
00693 const ValueType& TRegularData2D<ValueType>::getData(Position index) const
00694 throw(Exception::OutOfGrid)
00695 {
00696 if (index >= data_.size())
00697 {
00698 throw Exception::OutOfGrid(__FILE__, __LINE__);
00699 }
00700 return data_[index];
00701 }
00702
00703 template <class ValueType>
00704 BALL_INLINE
00705 ValueType& TRegularData2D<ValueType>::getData(Position index)
00706 throw(Exception::OutOfGrid)
00707 {
00708 if (index >= data_.size())
00709 {
00710 throw Exception::OutOfGrid(__FILE__, __LINE__);
00711 }
00712 return data_[index];
00713 }
00714
00715 template <class ValueType>
00716 BALL_INLINE
00717 typename TRegularData2D<ValueType>::CoordinateType TRegularData2D<ValueType>::getCoordinates
00718 (const typename TRegularData2D<ValueType>::IndexType& index) const
00719 throw(Exception::OutOfGrid)
00720 {
00721 if ((index.x >= size_.x) || (index.y >= size_.y))
00722 {
00723 throw Exception::OutOfGrid(__FILE__, __LINE__);
00724 }
00725
00726 CoordinateType r(origin_.x + index.x * spacing_.x,
00727 origin_.y + index.y * spacing_.y);
00728
00729 return r;
00730 }
00731
00732 template <class ValueType>
00733 BALL_INLINE
00734 typename TRegularData2D<ValueType>::CoordinateType
00735 TRegularData2D<ValueType>::getCoordinates(Position position) const
00736 throw(Exception::OutOfGrid)
00737 {
00738 if (position >= data_.size())
00739 {
00740 throw Exception::OutOfGrid(__FILE__, __LINE__);
00741 }
00742
00743 Position x = (Position)(position % size_.x);
00744 Position y = (Position)(position / size_.x);
00745
00746 return CoordinateType(origin_.x + (double)x * spacing_.x,
00747 origin_.y + (double)y * spacing_.y);
00748 }
00749
00750 template <typename ValueType>
00751 BALL_INLINE
00752 void TRegularData2D<ValueType>::getEnclosingIndices
00753 (const typename TRegularData2D<ValueType>::CoordinateType& r,
00754 Position& ll, Position& lr, Position& ul, Position& ur) const
00755 throw(Exception::OutOfGrid)
00756 {
00757 if (!isInside(r))
00758 {
00759 throw Exception::OutOfGrid(__FILE__, __LINE__);
00760 }
00761
00762
00763
00764 IndexType position;
00765 position.x = (Position)((r.x - origin_.x) / spacing_.x);
00766 position.y = (Position)((r.y - origin_.y) / spacing_.y);
00767
00768
00769 ll = position.x + size_.x * position.y;
00770 lr = ll + 1;
00771 ul = ll + size_.x;
00772 ur = ul + 1;
00773 }
00774
00775 template <typename ValueType>
00776 BALL_INLINE
00777 void TRegularData2D<ValueType>::getEnclosingValues
00778 (const typename TRegularData2D<ValueType>::CoordinateType& r,
00779 ValueType& ll, ValueType& lr, ValueType& ul, ValueType& ur) const
00780 throw(Exception::OutOfGrid)
00781 {
00782 if (!isInside(r))
00783 {
00784 throw Exception::OutOfGrid(__FILE__, __LINE__);
00785 }
00786
00787
00788 Position ll_id, lr_id, ul_id, ur_id;
00789 getEnclosingIndices(r, ll_id, lr_id, ul_id, ur_id);
00790
00791
00792 ll = data_[ll_id];
00793 lr = data_[lr_id];
00794 ul = data_[ul_id];
00795 ur = data_[ur_id];
00796 }
00797
00798 template <typename ValueType>
00799 BALL_INLINE
00800 ValueType TRegularData2D<ValueType>::getInterpolatedValue
00801 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00802 throw(Exception::OutOfGrid)
00803 {
00804 if (!isInside(r))
00805 {
00806 throw Exception::OutOfGrid(__FILE__, __LINE__);
00807 }
00808
00809 return this->operator () (r);
00810 }
00811
00812 template <typename ValueType>
00813 BALL_INLINE
00814 ValueType TRegularData2D<ValueType>::operator ()
00815 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00816 {
00817 CoordinateType h(r - origin_);
00818 Position x = (Position)(h.x / spacing_.x);
00819 Position y = (Position)(h.y / spacing_.y);
00820
00821
00822 if (x >= (size_.x - 1))
00823 {
00824 x = size_.x - 2;
00825 }
00826 if (y >= (size_.y - 1))
00827 {
00828 y = size_.y - 2;
00829 }
00830
00831 Size l = x + size_.x * y;
00832 CoordinateType r_0(origin_.x + (double)x * spacing_.x,
00833 origin_.y + (double)y * spacing_.y);
00834
00835 double dx = 1.0 - ((r.x - r_0.x) / spacing_.x);
00836 double dy = 1.0 - ((r.y - r_0.y) / spacing_.y);
00837
00838 return data_[l] * dx * dy
00839 + data_[l + 1] * (1.0 - dx) * dy
00840 + data_[l + size_.x] * dx * (1.0 - dy)
00841 + data_[l + size_.x + 1] * (1.0 - dx) * (1.0 - dy);
00842 }
00843
00844 template <typename ValueType>
00845 BALL_INLINE
00846 typename TRegularData2D<ValueType>::IndexType TRegularData2D<ValueType>::getLowerIndex
00847 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00848 throw(Exception::OutOfGrid)
00849 {
00850 if (!isInside(r))
00851 {
00852 throw Exception::OutOfGrid(__FILE__, __LINE__);
00853 }
00854
00855 static IndexType position;
00856 position.x = (Position)((r.x - origin_.x) / spacing_.x);
00857 position.y = (Position)((r.y - origin_.y) / spacing_.y);
00858
00859 return position;
00860 }
00861
00862 template <typename ValueType>
00863 BALL_INLINE
00864 typename TRegularData2D<ValueType>::IndexType TRegularData2D<ValueType>::getClosestIndex
00865 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00866 throw(Exception::OutOfGrid)
00867 {
00868 if (!isInside(r))
00869 {
00870 throw Exception::OutOfGrid(__FILE__, __LINE__);
00871 }
00872
00873 static IndexType position;
00874 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00875 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00876
00877 return position;
00878 }
00879
00880 template <typename ValueType>
00881 BALL_INLINE
00882 const ValueType& TRegularData2D<ValueType>::getClosestValue
00883 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00884 throw(Exception::OutOfGrid)
00885 {
00886 if (!isInside(r))
00887 {
00888 throw Exception::OutOfGrid(__FILE__, __LINE__);
00889 }
00890
00891 static IndexType position;
00892 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00893 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00894
00895 return operator [] (position);
00896 }
00897
00898 template <typename ValueType>
00899 BALL_INLINE
00900 ValueType& TRegularData2D<ValueType>::getClosestValue
00901 (const typename TRegularData2D<ValueType>::CoordinateType& r)
00902 throw(Exception::OutOfGrid)
00903 {
00904 if (!isInside(r))
00905 {
00906 throw Exception::OutOfGrid(__FILE__, __LINE__);
00907 }
00908
00909 static IndexType position;
00910 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00911 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00912
00913 return operator [] (position);
00914 }
00915
00916 template <typename ValueType>
00917 void TRegularData2D<ValueType>::clear()
00918 {
00919 data_.resize(0);
00920
00921 origin_.set(0.0);
00922 dimension_.set(0.0, 0.0);
00923 size_.x = 0;
00924 size_.y = 0;
00925 spacing_.set(1.0, 1.0);
00926 }
00927
00928 template <typename ValueType>
00929 bool TRegularData2D<ValueType>::operator == (const TRegularData2D<ValueType>& data) const
00930 {
00931 return ((origin_ == data.origin_)
00932 && (dimension_ == data.dimension_)
00933 && (size_.x == data.size_.x)
00934 && (size_.y == data.size_.y)
00935 && (data_ == data.data_));
00936 }
00937
00938
00941
00942 template <typename ValueType>
00943 std::ostream& operator << (std::ostream& os, const TRegularData2D<ValueType>& data)
00944 {
00945
00946 os << data.getOrigin().x << " " << data.getOrigin().y
00947 << std::endl
00948 << data.getOrigin().x + data.getDimension().x << " "
00949 << data.getOrigin().y + data.getDimension().y
00950 << std::endl
00951 << data.getSize().x - 1 << " " << data.getSize().y - 1
00952 << std::endl;
00953
00954
00955 std::copy(data.begin(), data.end(), std::ostream_iterator<ValueType>(os, "\n"));
00956 return os;
00957 }
00958
00960 template <typename ValueType>
00961 std::istream& operator >> (std::istream& is, TRegularData2D<ValueType>& grid)
00962 {
00963 typename TRegularData2D<ValueType>::CoordinateType origin;
00964 typename TRegularData2D<ValueType>::CoordinateType dimension;
00965 typename TRegularData2D<ValueType>::IndexType size;
00966
00967 is >> origin.x >> origin.y;
00968 is >> dimension.x >> dimension.y;
00969 is >> size.x >> size.y;
00970
00971 dimension -= origin;
00972 size.x++;
00973 size.y++;
00974
00975 grid.resize(size);
00976 grid.setOrigin(origin);
00977 grid.setDimension(dimension);
00978
00979 std::copy(std::istream_iterator<ValueType>(is),
00980 std::istream_iterator<ValueType>(),
00981 grid.begin());
00982
00983
00984 return is;
00985 }
00987
00988 template <typename ValueType>
00989 void TRegularData2D<ValueType>::binaryWrite(const String& filename) const
00990 throw(Exception::FileNotFound)
00991 {
00992 File outfile(filename.c_str(), std::ios::out|std::ios::binary);
00993 if (!outfile.isValid())
00994 throw Exception::FileNotFound(__FILE__, __LINE__, filename);
00995
00996
00997 BinaryFileAdaptor<BlockValueType> adapt_block;
00998 BinaryFileAdaptor<ValueType> adapt_single;
00999 BinaryFileAdaptor<float> adapt_float;
01000
01001 BinaryFileAdaptor<Size> adapt_size;
01002
01003 adapt_size.setData(data_.size());
01004 outfile << adapt_size;
01005
01006
01007
01008
01009
01010
01011
01012
01013 adapt_float.setData(origin_.x);
01014 outfile << adapt_float;
01015 adapt_float.setData(origin_.y);
01016 outfile << adapt_float;
01017
01018 adapt_float.setData(dimension_.x);
01019 outfile << adapt_float;
01020 adapt_float.setData(dimension_.y);
01021 outfile << adapt_float;
01022
01023 adapt_float.setData(spacing_.x);
01024 outfile << adapt_float;
01025 adapt_float.setData(spacing_.y);
01026 outfile << adapt_float;
01027
01028 BinaryFileAdaptor<IndexType> adapt_index;
01029 adapt_index.setData(size_);
01030 outfile << adapt_index;
01031
01032
01033 const int BLOCK_SIZE = 1024;
01034 Index window_pos = 0;
01035
01036 while (((int)data_.size() - (BLOCK_SIZE + window_pos)) >= 0)
01037 {
01038 adapt_block.setData(* (BlockValueType*)&(data_[window_pos]));
01039 outfile << adapt_block;
01040 window_pos += BLOCK_SIZE;
01041 }
01042
01043
01044 for (Size i = window_pos; i < data_.size(); i++)
01045 {
01046 adapt_single.setData(data_[i]);
01047 outfile << adapt_single;
01048 }
01049
01050
01051 outfile.close();
01052 }
01053
01054 template <typename ValueType>
01055 void TRegularData2D<ValueType>::binaryRead(const String& filename)
01056 throw(Exception::FileNotFound)
01057 {
01058 File infile(filename, std::ios::in|std::ios::binary);
01059 if (!infile.isValid())
01060 {
01061 throw Exception::FileNotFound(__FILE__, __LINE__, filename);
01062 }
01063
01064 BinaryFileAdaptor< BlockValueType > adapt_block;
01065 BinaryFileAdaptor< ValueType > adapt_single;
01066
01067
01068 BinaryFileAdaptor<Size> adapt_size;
01069 BinaryFileAdaptor<float> adapt_float;
01070
01071 infile >> adapt_size;
01072 Size new_size = adapt_size.getData();
01073
01074 infile >> adapt_float;
01075 origin_.x = adapt_float.getData();
01076 infile >> adapt_float;
01077 origin_.y = adapt_float.getData();
01078
01079 infile >> adapt_float;
01080 dimension_.x = adapt_float.getData();
01081 infile >> adapt_float;
01082 dimension_.y = adapt_float.getData();
01083
01084 infile >> adapt_float;
01085 spacing_.x = adapt_float.getData();
01086 infile >> adapt_float;
01087 spacing_.y = adapt_float.getData();
01088
01089 BinaryFileAdaptor<IndexType> adapt_index;
01090 infile >> adapt_index;
01091 size_ = adapt_index.getData();
01092
01093 data_.resize(new_size);
01094
01095
01096 Index window_pos = 0;
01097
01098 while ( ((int)data_.size() - (1024 + window_pos)) >= 0 )
01099 {
01100 infile >> adapt_block;
01101 *(BlockValueType*)(&(data_[window_pos])) = adapt_block.getData();
01102
01103
01104
01105
01106
01107
01108 window_pos+=1024;
01109 }
01110
01111
01112 for (Size i=window_pos; i<data_.size(); i++)
01113 {
01114 infile >> adapt_single;
01115 data_[i] = adapt_single.getData();
01116 }
01117
01118
01119 infile.close();
01120 }
01121 }
01122
01123 #endif // BALL_DATATYPE_TREGULARDATA2D_H