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