Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
766 | werner | 1 | #ifndef SPATIALANALYSIS_H |
2 | #define SPATIALANALYSIS_H |
||
3 | |||
4 | /******************************************************************************************** |
||
5 | ** iLand - an individual based forest landscape and disturbance model |
||
6 | ** http://iland.boku.ac.at |
||
7 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl |
||
8 | ** |
||
9 | ** This program is free software: you can redistribute it and/or modify |
||
10 | ** it under the terms of the GNU General Public License as published by |
||
11 | ** the Free Software Foundation, either version 3 of the License, or |
||
12 | ** (at your option) any later version. |
||
13 | ** |
||
14 | ** This program is distributed in the hope that it will be useful, |
||
15 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | ** GNU General Public License for more details. |
||
18 | ** |
||
19 | ** You should have received a copy of the GNU General Public License |
||
20 | ** along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
21 | ********************************************************************************************/ |
||
22 | #include "grid.h" |
||
767 | werner | 23 | #include "layeredgrid.h" |
766 | werner | 24 | |
25 | #include <QObject> |
||
1083 | werner | 26 | #include <QJSValue> |
27 | |||
766 | werner | 28 | class RumpleIndex; // forward |
767 | werner | 29 | class SpatialLayeredGrid; // forward |
766 | werner | 30 | /** |
31 | * @brief The SpatialAnalysis class is the scripting class related to extra spatial analysis functions. |
||
767 | werner | 32 | * rumpleIndex: ratio crown surface area / ground area for the whole project area. |
33 | * saveRumpleGrid(): save RU-based grid of rumple indices to an ASCII grid file. |
||
766 | werner | 34 | */ |
35 | class SpatialAnalysis: public QObject |
||
36 | { |
||
37 | Q_OBJECT |
||
767 | werner | 38 | Q_PROPERTY(double rumpleIndex READ rumpleIndexFullArea) |
1085 | werner | 39 | Q_PROPERTY(QList<int> patchsizes READ patchsizes) |
766 | werner | 40 | |
41 | public: |
||
42 | SpatialAnalysis(QObject *parent=0): QObject(parent), mRumple(0) {} |
||
767 | werner | 43 | ~SpatialAnalysis(); |
44 | static void addToScriptEngine(); |
||
45 | |||
46 | double rumpleIndexFullArea(); ///< retrieve the rumple index for the full landscape (one value) |
||
1080 | werner | 47 | /// extract patches ('clumps') and save the resulting grid to 'fileName' (if not empty). Returns a vector with |
48 | /// the number of pixels for each patch-id |
||
1085 | werner | 49 | QList<int> extractPatches(Grid<double> &src, int min_size, QString fileName); |
50 | QList<int> patchsizes() const { return mLastPatches; } |
||
766 | werner | 51 | public slots: |
52 | // API for Javascript |
||
767 | werner | 53 | void saveRumpleGrid(QString fileName); ///< save a grid of rumple index values (resource unit level) to a ESRI grid file (ascii) |
1017 | werner | 54 | void saveCrownCoverGrid(QString fileName); ///< save a grid if crown cover percentages (RU level) to a ESRI grid file (ascii) |
1083 | werner | 55 | QJSValue patches(QJSValue grid, int min_size); |
767 | werner | 56 | |
766 | werner | 57 | private: |
1017 | werner | 58 | void calculateCrownCover(); |
766 | werner | 59 | RumpleIndex *mRumple; |
767 | werner | 60 | SpatialLayeredGrid *mLayers; |
1017 | werner | 61 | FloatGrid mCrownCoverGrid; |
1080 | werner | 62 | Grid<int> mClumpGrid; |
1085 | werner | 63 | QList<int> mLastPatches; |
767 | werner | 64 | friend class SpatialLayeredGrid; |
766 | werner | 65 | |
66 | }; |
||
67 | |||
68 | /** The RumpleIndex is a spatial index relating surface area to ground area. |
||
69 | * In forestry, it is a indicator of vertical heterogeneity. In iLand, the Rumple Index is |
||
70 | * the variability of the maximum tree height on 10m level (i.e. the "Height"-Grid). |
||
912 | werner | 71 | * The RumpleIndex is calculated for each resource unit and also for the full project area. |
766 | werner | 72 | **/ |
73 | class RumpleIndex |
||
74 | { |
||
75 | public: |
||
76 | RumpleIndex(): mLastYear(-1) {} |
||
77 | void setup(); ///< sets up the grid |
||
78 | void calculate(); ///< calculates (or re-calculates) index values |
||
79 | double value(const bool force_recalculate=false); ///< calculates rumple index for the full project area |
||
767 | werner | 80 | const FloatGrid &rumpleGrid() { value(); /* calculate if necessary */ return mRumpleGrid; } ///< return the rumple index for the full project area |
766 | werner | 81 | // |
82 | double test_triangle_area(); |
||
83 | private: |
||
84 | double calculateSurfaceArea(const float *heights, const float cellsize); |
||
85 | FloatGrid mRumpleGrid; |
||
86 | double mRumpleIndex; |
||
87 | int mLastYear; |
||
88 | }; |
||
89 | |||
767 | werner | 90 | |
91 | |||
92 | class SpatialLayeredGrid: public LayeredGridBase |
||
93 | { |
||
94 | public: |
||
95 | SpatialLayeredGrid() { setup(); } |
||
96 | void setup(); ///< initial setup of the grid |
||
777 | werner | 97 | int addGrid(const QString name, FloatGrid *grid); ///< adds a 'grid' named 'name'. returns index of the newly added grid. |
1014 | werner | 98 | const QStringList &gridNames() { return mGridNames; } |
767 | werner | 99 | |
100 | double value(const float x, const float y, const int index) const { checkGrid(index); return mGrids[index]->constValueAt(x,y); } |
||
101 | double value(const QPointF &world_coord, const int index) const { checkGrid(index); return mGrids[index]->constValueAt(world_coord); } |
||
102 | double value(const int ix, const int iy, const int index) const { checkGrid(index); return mGrids[index]->constValueAtIndex(ix,iy);} |
||
103 | double value(const int grid_index, const int index) const { checkGrid(index); return mGrids[index]->constValueAtIndex(grid_index);} |
||
104 | void range(double &rMin, double &rMax, const int index) const { rMin=9999999999.; rMax=-99999999999.; |
||
105 | for (int i=0;i<mGrids[index]->count(); ++i) { |
||
106 | rMin=qMin(rMin, value(i, index)); |
||
107 | rMax=qMax(rMax, value(i,index));}} |
||
108 | |||
109 | private: |
||
110 | inline void checkGrid(const int grid_index) const { if (mGrids[grid_index]==0) const_cast<SpatialLayeredGrid*>(this)->createGrid(grid_index); } ///< helper function that checks if grids are to be created |
||
111 | void createGrid(const int grid_index); ///< create (if necessary) the actual grid |
||
112 | QStringList mGridNames; ///< the list of grid names |
||
113 | QVector<FloatGrid*> mGrids; ///< the grid |
||
114 | |||
115 | |||
116 | }; |
||
766 | werner | 117 | #endif // SPATIALANALYSIS_H |