Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
671 | werner | 1 | /******************************************************************************************** |
2 | ** iLand - an individual based forest landscape and disturbance model |
||
3 | ** http://iland.boku.ac.at |
||
4 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl |
||
5 | ** |
||
6 | ** This program is free software: you can redistribute it and/or modify |
||
7 | ** it under the terms of the GNU General Public License as published by |
||
8 | ** the Free Software Foundation, either version 3 of the License, or |
||
9 | ** (at your option) any later version. |
||
10 | ** |
||
11 | ** This program is distributed in the hope that it will be useful, |
||
12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | ** GNU General Public License for more details. |
||
15 | ** |
||
16 | ** You should have received a copy of the GNU General Public License |
||
17 | ** along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | ********************************************************************************************/ |
||
19 | |||
646 | werner | 20 | #ifndef LAYEREDGRID_H |
21 | #define LAYEREDGRID_H |
||
22 | |||
23 | #include "grid.h" |
||
24 | |||
873 | werner | 25 | /** \class LayeredGrid |
697 | werner | 26 | @ingroup tools |
873 | werner | 27 | This is the base class for multi-layer grids in iLand. Use the LayeredGrid-template class |
28 | for creating actual multi layer grids. The LayeredGridBase can be used for specializations. |
||
646 | werner | 29 | */ |
30 | |||
31 | class LayeredGridBase |
||
32 | { |
||
33 | public: |
||
877 | werner | 34 | // layer description element |
35 | class LayerElement { |
||
36 | public: |
||
37 | LayerElement() {} |
||
889 | werner | 38 | LayerElement(QString aname, QString adesc, GridViewType type): name(aname), description(adesc), view_type(type) {} |
877 | werner | 39 | QString name; |
40 | QString description; |
||
41 | GridViewType view_type; |
||
42 | }; |
||
43 | |||
646 | werner | 44 | // access to properties |
647 | werner | 45 | virtual int sizeX() const=0; |
46 | virtual int sizeY() const=0; |
||
47 | virtual QRectF metricRect() const=0; |
||
48 | virtual QRectF cellRect(const QPoint &p) const=0; |
||
962 | werner | 49 | virtual bool onClick(const QPointF &world_coord) const { Q_UNUSED(world_coord); return false; /*false: not handled*/ } |
646 | werner | 50 | // available variables |
877 | werner | 51 | /// list of stored layers |
1014 | werner | 52 | virtual const QVector<LayeredGridBase::LayerElement> &names()=0; |
877 | werner | 53 | /// get layer index by name of the layer. returns -1 if layer is not available. |
1014 | werner | 54 | virtual int indexOf(const QString &layer_name) |
877 | werner | 55 | { |
56 | for(int i=0;i<names().count();++i) |
||
57 | if (names().at(i).name == layer_name) |
||
58 | return i; |
||
59 | return -1; |
||
60 | } |
||
1085 | werner | 61 | virtual QStringList layerNames() { |
62 | QStringList l; |
||
63 | for(int i=0;i<names().count();++i) |
||
64 | l.append(names().at(i).name); |
||
65 | return l; |
||
66 | } |
||
67 | |||
646 | werner | 68 | // statistics |
69 | /// retrieve min and max of variable 'index' |
||
647 | werner | 70 | virtual void range(double &rMin, double &rMax, const int index) const=0; |
646 | werner | 71 | |
72 | // data access functions |
||
647 | werner | 73 | virtual double value(const float x, const float y, const int index) const = 0; |
648 | werner | 74 | virtual double value(const QPointF &world_coord, const int index) const = 0; |
647 | werner | 75 | virtual double value(const int ix, const int iy, const int index) const = 0; |
76 | virtual double value(const int grid_index, const int index) const = 0; |
||
877 | werner | 77 | // for classified values |
78 | virtual const QString labelvalue(const int value, const int index) const |
||
79 | { |
||
80 | Q_UNUSED(value) |
||
81 | Q_UNUSED(index) |
||
82 | return QLatin1Literal("-"); |
||
83 | } |
||
84 | |||
646 | werner | 85 | }; |
86 | |||
873 | werner | 87 | /** \class LayeredGrid is a template for multi-layered grids in iLand. |
88 | * Use your cell-class for T and provide at minium a value() and a names() function. |
||
89 | * The names() provide the names of the individual layers (used e.g. in the GUI), the value() function |
||
90 | * returns a cell-specific value for a specific layer (given by 'index' parameter). |
||
91 | * */ |
||
646 | werner | 92 | template <class T> |
93 | class LayeredGrid: public LayeredGridBase |
||
94 | { |
||
95 | public: |
||
96 | LayeredGrid(const Grid<T>& grid) { mGrid = &grid; } |
||
717 | werner | 97 | LayeredGrid() { mGrid = 0; } |
647 | werner | 98 | QRectF cellRect(const QPoint &p) const { return mGrid->cellRect(p); } |
99 | QRectF metricRect() const { return mGrid->metricRect(); } |
||
717 | werner | 100 | float cellsize() const { return mGrid->cellsize(); } |
647 | werner | 101 | int sizeX() const { return mGrid->sizeX(); } |
102 | int sizeY() const { return mGrid->sizeY();} |
||
103 | |||
104 | virtual double value(const T& data, const int index) const = 0; |
||
646 | werner | 105 | double value(const T* ptr, const int index) const { return value(mGrid->constValueAtIndex(mGrid->indexOf(ptr)), index); } |
106 | double value(const int grid_index, const int index) const { return value(mGrid->constValueAtIndex(grid_index), index); } |
||
107 | double value(const float x, const float y, const int index) const { return value(mGrid->constValueAt(x,y), index); } |
||
877 | werner | 108 | double value(const QPointF &world_coord, const int index) const { return mGrid->coordValid(world_coord)?value(mGrid->constValueAt(world_coord), index) : 0.; } |
647 | werner | 109 | double value(const int ix, const int iy, const int index) const { return value(mGrid->constValueAtIndex(ix, iy), index); } |
110 | void range(double &rMin, double &rMax, const int index) const { rMin=9999999999.; rMax=-99999999999.; |
||
646 | werner | 111 | for (int i=0;i<mGrid->count(); ++i) { |
112 | rMin=qMin(rMin, value(i, index)); |
||
113 | rMax=qMax(rMax, value(i,index));}} |
||
1085 | werner | 114 | |
115 | /// extract a (newly created) grid filled with the value of the variable given by 'index' |
||
1080 | werner | 116 | /// caller need to free memory! |
1088 | werner | 117 | Grid<double> *copyGrid(const int index) const |
1080 | werner | 118 | { |
1088 | werner | 119 | Grid<double> *data_grid= new Grid<double>(mGrid->metricRect(), mGrid->cellsize()); |
1080 | werner | 120 | double *p = data_grid->begin(); |
121 | for (int i=0;i<mGrid->count();++i) |
||
122 | *p++ = value(i, index); |
||
123 | return data_grid; |
||
124 | } |
||
646 | werner | 125 | |
962 | werner | 126 | |
646 | werner | 127 | protected: |
128 | const Grid<T> *mGrid; |
||
129 | }; |
||
130 | |||
717 | werner | 131 | void modelToWorld(const Vector3D &From, Vector3D &To); |
132 | |||
133 | /** translate |
||
134 | |||
135 | */ |
||
136 | template <class T> |
||
137 | QString gridToESRIRaster(const LayeredGrid<T> &grid, const QString name) |
||
138 | { |
||
1014 | werner | 139 | int index = const_cast<LayeredGrid<T> &>(grid).indexOf(name); |
717 | werner | 140 | if (index<0) |
141 | return QString(); |
||
142 | Vector3D model(grid.metricRect().left(), grid.metricRect().top(), 0.); |
||
143 | Vector3D world; |
||
144 | modelToWorld(model, world); |
||
145 | QString result = QString("ncols %1\r\nnrows %2\r\nxllcorner %3\r\nyllcorner %4\r\ncellsize %5\r\nNODATA_value %6\r\n") |
||
146 | .arg(grid.sizeX()) |
||
147 | .arg(grid.sizeY()) |
||
148 | .arg(world.x(),0,'f').arg(world.y(),0,'f') |
||
149 | .arg(grid.cellsize()).arg(-9999); |
||
150 | |||
151 | QString res; |
||
152 | QTextStream ts(&res); |
||
153 | QChar sep = QChar(' '); |
||
154 | for (int y=grid.sizeY()-1;y>=0;--y){ |
||
155 | for (int x=0;x<grid.sizeX();x++){ |
||
156 | ts << grid.value(x,y,index) << sep; |
||
157 | } |
||
158 | ts << "\r\n"; |
||
159 | } |
||
160 | |||
161 | return result + res; |
||
162 | } |
||
163 | |||
164 | |||
877 | werner | 165 | |
646 | werner | 166 | #endif // LAYEREDGRID_H |
877 | werner | 167 | |
168 | |||
893 | werner | 169 | |
170 | |||
171 |