Subversion Repositories public iLand

Rev

Rev 22 | Rev 27 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
15 Werner 2
#ifndef GRID_H
3
#define GRID_H
4
 
22 Werner 5
#include <QtCore>
15 Werner 6
 
7
 
8
#include <stdexcept>
9
 
10
/** Grid class (template).
11
 
12
  */
13
template <class T>
14
class Grid {
15
public:
16
 
17
    Grid();
18
    Grid(int cellsize, int sizex, int sizey) { mData=0; setup(cellsize, sizex, sizey); }
19
    ~Grid() { if (mData) delete[] mData; }
20
 
18 Werner 21
    bool setup(const float cellsize, const int sizex, const int sizey);
22 Werner 22
    bool setup(const QRectF& rect, const double cellsize);
15 Werner 23
    void initialize(const T& value) {for( T *p = begin();p!=end(); ++p) *p=value;}
24
 
25
    const int sizeX() const { return mSizeX; }
26
    const int sizeY() const { return mSizeY; }
27
    const float metricSizeX() const { return mSizeX*mCellsize; }
28
    const float metricSizeY() const { return mSizeY*mCellsize; }
29
    const float cellsize() const { return mCellsize; }
30
    // query
25 Werner 31
    T& valueAtIndex(const QPoint& pos); ///< value at position defined by indices (x,y)
32
    T& valueAt(const QPointF& posf); ///< value at position defined by metric coordinates
22 Werner 33
    QPoint indexAt(const QPointF& pos) { return QPoint(int((pos.x()-mOffset.x()) / mCellsize),  int((pos.y()-mOffset.y())/mCellsize)); } /// get index of value at position pos (metric)
15 Werner 34
    bool isIndexValid(const QPoint& pos) { return (pos.x()>=0 && pos.x()<mSizeX && pos.y()>=0 && pos.y()<mSizeY); } /// get index of value at position pos (index)
35
    void validate(QPoint &pos) { pos.setX( qMax(qMin(pos.x(), mSizeX-1), 0) );  pos.setY( qMax(qMin(pos.y(), mSizeY-1), 0) );} /// ensure that "pos" is a valid key. if out of range, pos is set to minimum/maximum values.
22 Werner 36
    QPointF getCellCoordinates(const QPoint &pos) { return QPointF( (pos.x()+0.5)*mCellsize+mOffset.x(), (pos.y()+0.5)*mCellsize + mOffset.y());} /// get metric coordinates of the cells center
25 Werner 37
    inline  T* begin() { return mData; } ///< get "iterator" pointer
38
    inline  T* end() { return &(mData[mCount]); } ///< get iterator end-pointer
39
    QPoint indexOf(T* element); ///< retrieve index (x/y) of the pointer element. returns -1/-1 if element is not valid.
15 Werner 40
 
41
 
42
private:
43
    T* mData;
22 Werner 44
    QPointF mOffset;
15 Werner 45
    float mCellsize; /// size of a cell in meter
46
    int mSizeX; /// count of cells in x-direction
47
    int mSizeY; /// count of cells in y-direction
48
    int mCount;
49
};
50
 
51
typedef Grid<float> FloatGrid;
52
 
22 Werner 53
 
54
 
15 Werner 55
template <class T>
22 Werner 56
T&  Grid<T>::valueAtIndex(const QPoint& pos)
57
{
58
    if (isIndexValid(pos)) {
59
        return mData[pos.x()*mSizeX + pos.y()];
60
    }
61
    throw std::logic_error("TGrid: invalid Index!");
62
}
63
 
64
template <class T>
65
T&  Grid<T>::valueAt(const QPointF& posf)
66
{
67
    return valueAtIndex( indexAt(posf) );
68
}
69
 
70
template <class T>
15 Werner 71
Grid<T>::Grid()
72
{
73
    mData=0; mCellsize=0.f;
74
}
75
 
76
template <class T>
18 Werner 77
bool Grid<T>::setup(const float cellsize, const int sizex, const int sizey)
15 Werner 78
{
79
    mSizeX=sizex; mSizeY=sizey; mCellsize=(float)cellsize;
80
    mCount = mSizeX*mSizeY;
81
    if (mData)
82
         delete[] mData;
83
   if (mCount>0)
84
    mData = new T[mCount];
85
   return true;
86
}
87
 
88
template <class T>
22 Werner 89
bool Grid<T>::setup(const QRectF& rect, const double cellsize)
15 Werner 90
{
22 Werner 91
    mOffset.setX(rect.left());
92
    mOffset.setY(rect.top());
93
    int dx = int(rect.width()/cellsize);
94
    if (mOffset.x()+cellsize*dx<rect.right())
95
        dx++;
96
    int dy = int(rect.height()/cellsize);
97
    if (mOffset.y()+cellsize*dy<rect.bottom())
98
        dy++;
99
    return setup(cellsize, dx, dy);
15 Werner 100
}
101
 
25 Werner 102
template <class T>
103
QPoint Grid<T>::indexOf(T* element)
104
{
105
    QPoint result(-1,-1);
106
    if (element==NULL || element<mData || element>=end())
107
        return result;
108
    int idx = element - mData;
109
    result.setX( idx / mSizeX);
110
    result.setY( idx % mSizeX);
111
    return result;
112
}
22 Werner 113
 
15 Werner 114
#endif // GRID_H