Subversion Repositories public iLand

Rev

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

Rev Author Line No. Line
1
 
3 Werner 2
 
3
#include "tree.h"
16 Werner 4
#include "core/grid.h"
30 Werner 5
#include "imagestamp.h"
3 Werner 6
 
38 Werner 7
#include "core/stamp.h"
8
#include "treespecies.h"
9
 
13 Werner 10
Expression Tree::rScale=Expression();
11
Expression Tree::hScale=Expression();
39 Werner 12
FloatGrid *Tree::m_grid = 0;
40 Werner 13
int Tree::m_statPrint=0;
14
int Tree::m_nextId=0;
15
 
3 Werner 16
Tree::Tree()
17
{
38 Werner 18
    m_Dbh = 0;
19
    m_Height = 0;
20
    m_species = 0;
40 Werner 21
    m_id = m_nextId++;
3 Werner 22
}
38 Werner 23
 
15 Werner 24
/** get distance and direction between two points.
38 Werner 25
  returns the distance (m), and the angle between PStart and PEnd (radians) in referenced param rAngle. */
3 Werner 26
float dist_and_direction(const QPointF &PStart, const QPointF &PEnd, float &rAngle)
27
{
28
    float dx = PEnd.x() - PStart.x();
29
    float dy = PEnd.y() - PStart.y();
30
    float d = sqrt(dx*dx + dy*dy);
31
    // direction:
32
    rAngle = atan2(dx, dy);
33
    return d;
34
}
35
 
30 Werner 36
void Tree::stampOnGrid(ImageStamp& stamp, FloatGrid& grid)
3 Werner 37
{
38
 
39
    // use formulas to derive scaling values...
38 Werner 40
    rScale.setVar("height", m_Height);
41
    rScale.setVar("dbh", m_Dbh);
42
    hScale.setVar("height", m_Height);
43
    hScale.setVar("dbh", m_Dbh);
3 Werner 44
 
45
    double r = rScale.execute();
46
    double h = hScale.execute();
47
    stamp.setScale(r, h); // stamp uses scaling values to calculate impact
15 Werner 48
    mImpactRadius = r;
3 Werner 49
 
50
    float cell_value, r_cell, phi_cell;
38 Werner 51
    QPoint ul = grid.indexAt(QPointF(m_Position.x()-r, m_Position.y()-r) );
52
    QPoint lr =  grid.indexAt( QPointF(m_Position.x()+r, m_Position.y()+r) );
9 Werner 53
    QPoint centercell=grid.indexAt(position());
3 Werner 54
    grid.validate(ul); grid.validate(lr);
55
    QPoint cell;
56
    QPointF cellcoord;
57
    int ix, iy;
58
    mOwnImpact=0.f;
6 Werner 59
    mImpactArea=0.f;
3 Werner 60
    for (ix=ul.x(); ix<lr.x(); ix++)
61
        for (iy=ul.y(); iy<lr.y(); iy++) {
62
        cell.setX(ix); cell.setY(iy);
32 Werner 63
        cellcoord = grid.cellCoordinates(cell);
38 Werner 64
        r_cell = dist_and_direction(m_Position, cellcoord, phi_cell);
9 Werner 65
        if (r_cell > r && cell!=centercell)
3 Werner 66
            continue;
67
        // get value from stamp at this location (given by radius and angle)
68
        cell_value = stamp.get(r_cell, phi_cell);
69
        // add value to cell
6 Werner 70
        mOwnImpact+=(1. - cell_value);
71
        mImpactArea++;
72
        grid.valueAtIndex(cell)*=cell_value;
3 Werner 73
    }
74
}
75
 
30 Werner 76
float Tree::retrieveValue(ImageStamp& stamp, FloatGrid& grid)
3 Werner 77
{
78
 
38 Werner 79
    rScale.setVar("height", m_Height);
80
    rScale.setVar("dbh", m_Dbh);
81
    hScale.setVar("height", m_Height);
82
    hScale.setVar("dbh", m_Dbh);
3 Werner 83
    double r = rScale.execute();
84
    double h = hScale.execute();
85
    stamp.setScale(r, h); // stamp uses scaling values to calculate impact
86
 
7 Werner 87
    float stamp_value, cell_value, r_cell, phi_cell;
38 Werner 88
    QPoint ul = grid.indexAt(QPointF(m_Position.x()-r, m_Position.y()-r) );
89
    QPoint lr =  grid.indexAt( QPointF(m_Position.x()+r, m_Position.y()+r) );
9 Werner 90
    QPoint centercell=grid.indexAt(position());
3 Werner 91
    grid.validate(ul); grid.validate(lr);
92
    QPoint cell;
93
    QPointF cellcoord;
94
    int ix, iy;
95
    float value=0.f;
96
 
97
    int counting_cells=0;
98
    for (ix=ul.x(); ix<lr.x(); ix++)
99
        for (iy=ul.y(); iy<lr.y(); iy++) {
100
 
101
        cell.setX(ix); cell.setY(iy);
32 Werner 102
        cellcoord = grid.cellCoordinates(cell);
38 Werner 103
        r_cell = dist_and_direction(m_Position, cellcoord, phi_cell);
9 Werner 104
        if (r_cell>r && cell!=centercell)
3 Werner 105
            continue;
106
        counting_cells++;
107
        // get value from stamp at this location (given by radius and angle)
7 Werner 108
        stamp_value = stamp.get(r_cell, phi_cell);
109
        cell_value =  grid.valueAtIndex(QPoint(ix,iy));
110
        if (stamp_value>0.)
111
           value += cell_value / stamp_value;
3 Werner 112
        // sum up values of cell
113
        //value += cell_value;
7 Werner 114
        //value += grid.valueAtIndex(QPoint(ix,iy)); // - cell_value;
3 Werner 115
    }
9 Werner 116
    if (counting_cells>0)
117
        mImpact = value / float(counting_cells);
118
    else
119
        mImpact=1;
3 Werner 120
    return mImpact;
121
}
122
 
38 Werner 123
 
124
void Tree::setup()
125
{
126
    if (m_Dbh<=0 || m_Height<=0)
127
        return;
128
    // check stamp
129
   Q_ASSERT_X(m_species!=0, "Tree::setup()", "species is NULL");
130
   m_stamp = m_species->stamp(m_Dbh, m_Height);
131
}
39 Werner 132
 
133
void Tree::applyStamp()
134
{
135
    Q_ASSERT(m_grid!=0);
136
    if (!m_stamp)
137
        return;
138
 
40 Werner 139
    QPoint pos = m_grid->indexAt(m_Position);
140
    int offset = m_stamp->offset();
141
    pos-=QPoint(offset, offset);
142
    QPoint p;
143
 
144
    int x,y;
145
    for (x=0;x<m_stamp->size();++x) {
146
        for (y=0;y<m_stamp->size(); ++y) {
147
           p = pos + QPoint(x,y);
148
           if (m_grid->isIndexValid(p))
149
               m_grid->valueAtIndex(p)+=(*m_stamp)(x,y);
150
        }
151
    }
152
    m_statPrint++; // count # of stamp applications...
39 Werner 153
}
40 Werner 154
 
155
double Tree::readStamp()
156
{
157
    float crown_radius = dbh()/10; // cm -> m
158
    const Stamp *stamp = m_species->readerStamp(crown_radius);
159
    if (!stamp)
160
        return 0.;
161
    QPoint pos = m_grid->indexAt(m_Position);
162
    int offset = stamp->offset();
163
    pos-=QPoint(offset, offset);
164
    QPoint p;
165
 
166
    int x,y;
167
    double sum=0.;
168
    for (x=0;x<stamp->size();++x) {
169
        for (y=0;y<stamp->size(); ++y) {
170
           p = pos + QPoint(x,y);
171
           if (m_grid->isIndexValid(p))
172
               sum += m_grid->valueAtIndex(p) * (*stamp)(x,y);
173
        }
174
    }
175
    mImpact = sum;
176
    qDebug() << "Tree #"<< id() << "value" << sum;
177
    return sum;
178
}
179
 
180
void Tree::resetStatistics()
181
{
182
    m_statPrint=0;
183
    m_nextId=1;
184
}