Subversion Repositories public iLand

Rev

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