Subversion Repositories public iLand

Rev

Rev 247 | Rev 252 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 247 Rev 250
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/management.cpp':
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/management.cpp':
2
#include "global.h"
2
#include "global.h"
3
#include "management.h"
3
#include "management.h"
4
#include "helper.h"
4
#include "helper.h"
5
#include "model.h"
5
#include "model.h"
6
#include "resourceunit.h"
6
#include "resourceunit.h"
7
#include "tree.h"
7
#include "tree.h"
8
#include "expressionwrapper.h"
8
#include "expressionwrapper.h"
9
9
10
#include "climateconverter.h"
10
#include "climateconverter.h"
11
#include "csvfile.h"
11
#include "csvfile.h"
12
#include "scriptglobal.h"
12
#include "scriptglobal.h"
13
13
14
#include <QtScript>
14
#include <QtScript>
15
#include <QTextEdit>
15
#include <QTextEdit>
16
QObject *Management::scriptOutput = 0;
16
QObject *Management::scriptOutput = 0;
17
17
18
QScriptValue script_debug(QScriptContext *ctx, QScriptEngine *eng)
18
QScriptValue script_debug(QScriptContext *ctx, QScriptEngine *eng)
19
 {
19
 {
20
     QString value = ctx->argument(0).toString();
20
     QString value = ctx->argument(0).toString();
21
     if (Management::scriptOutput) {
21
     if (Management::scriptOutput) {
22
         QTextEdit *e = qobject_cast<QTextEdit*>(Management::scriptOutput);
22
         QTextEdit *e = qobject_cast<QTextEdit*>(Management::scriptOutput);
23
         if (e)
23
         if (e)
24
             e->append(value);
24
             e->append(value);
25
     } else {
25
     } else {
26
         qDebug() << "Script:" << value;
26
         qDebug() << "Script:" << value;
27
     }
27
     }
28
     return QScriptValue();
28
     return QScriptValue();
29
     //return ctx->thisObject().property(name);
29
     //return ctx->thisObject().property(name);
30
 }
30
 }
31
31
32
// global output function
32
// global output function
33
QString Management::executeScript(QString cmd)
33
QString Management::executeScript(QString cmd)
34
{
34
{
35
    DebugTimer t("execute javascript");
35
    DebugTimer t("execute javascript");
36
    if (mEngine)
36
    if (mEngine)
37
        mEngine->evaluate(cmd);
37
        mEngine->evaluate(cmd);
38
    if (mEngine->hasUncaughtException())
38
    if (mEngine->hasUncaughtException())
39
        return QString( "Script Error occured: %1").arg( mEngine->uncaughtException().toString());
39
        return QString( "Script Error occured: %1").arg( mEngine->uncaughtException().toString());
40
    else
40
    else
41
        return QString();
41
        return QString();
42
}
42
}
43
43
44
Management::Management()
44
Management::Management()
45
{
45
{
46
    // setup the engine
46
    // setup the engine
47
    mEngine = new QScriptEngine();
47
    mEngine = new QScriptEngine();
48
    QScriptValue objectValue = mEngine->newQObject(this);
48
    QScriptValue objectValue = mEngine->newQObject(this);
49
    QScriptValue dbgprint = mEngine->newFunction(script_debug);
49
    QScriptValue dbgprint = mEngine->newFunction(script_debug);
50
    mEngine->globalObject().setProperty("management", objectValue);
50
    mEngine->globalObject().setProperty("management", objectValue);
51
    mEngine->globalObject().setProperty("print",dbgprint);
51
    mEngine->globalObject().setProperty("print",dbgprint);
52
52
53
    // globals object: instatiate here, but ownership goes to script engine
53
    // globals object: instatiate here, but ownership goes to script engine
54
    ScriptGlobal *global = new ScriptGlobal();
54
    ScriptGlobal *global = new ScriptGlobal();
55
    QScriptValue glb = mEngine->newQObject(global,QScriptEngine::ScriptOwnership);
55
    QScriptValue glb = mEngine->newQObject(global,QScriptEngine::ScriptOwnership);
56
    mEngine->globalObject().setProperty("Globals", glb);
56
    mEngine->globalObject().setProperty("Globals", glb);
57
    // other object types
57
    // other object types
58
    ClimateConverter::addToScriptEngine(*mEngine);
58
    ClimateConverter::addToScriptEngine(*mEngine);
59
    CSVFile::addToScriptEngine(*mEngine);
59
    CSVFile::addToScriptEngine(*mEngine);
60
60
61
61
62
}
62
}
63
63
64
Management::~Management()
64
Management::~Management()
65
{
65
{
66
    delete mEngine;
66
    delete mEngine;
67
}
67
}
68
68
69
void Management::loadScript(const QString &fileName)
69
void Management::loadScript(const QString &fileName)
70
{
70
{
71
    mScriptFile = fileName;
71
    mScriptFile = fileName;
72
    QString program = Helper::loadTextFile(fileName);
72
    QString program = Helper::loadTextFile(fileName);
73
    if (program.isEmpty())
73
    if (program.isEmpty())
74
        return;
74
        return;
75
75
76
    mEngine->evaluate(program);
76
    mEngine->evaluate(program);
77
    qDebug() << "management script loaded";
77
    qDebug() << "management script loaded";
78
    if (mEngine->hasUncaughtException())
78
    if (mEngine->hasUncaughtException())
79
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
79
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
80
80
81
}
81
}
82
82
83
void Management::remain(int number)
83
void Management::remain(int number)
84
{
84
{
85
    qDebug() << "remain called (number): " << number;
85
    qDebug() << "remain called (number): " << number;
86
    Model *m = GlobalSettings::instance()->model();
86
    Model *m = GlobalSettings::instance()->model();
87
    AllTreeIterator at(m);
87
    AllTreeIterator at(m);
88
    QList<Tree*> trees;
88
    QList<Tree*> trees;
89
    while (Tree *t=at.next())
89
    while (Tree *t=at.next())
90
        trees.push_back(t);
90
        trees.push_back(t);
91
    int to_kill = trees.count() - number;
91
    int to_kill = trees.count() - number;
92
    qDebug() << trees.count() << " standing, targetsize" << number << ", hence " << to_kill << "trees to remove";
92
    qDebug() << trees.count() << " standing, targetsize" << number << ", hence " << to_kill << "trees to remove";
93
    for (int i=0;i<to_kill;i++) {
93
    for (int i=0;i<to_kill;i++) {
94
        int index = irandom(0, trees.count());
94
        int index = irandom(0, trees.count());
95
        trees[index]->die();
95
        trees[index]->die();
96
        trees.removeAt(index);
96
        trees.removeAt(index);
97
    }
97
    }
98
    mRemoved += to_kill;
98
    mRemoved += to_kill;
99
}
99
}
100
100
101
101
102
// from the range percentile range pctfrom to pctto (each 1..100)
102
// from the range percentile range pctfrom to pctto (each 1..100)
103
int Management::kill(int pctfrom, int pctto, int number)
103
int Management::kill(int pctfrom, int pctto, int number)
104
{
104
{
105
    if (mTrees.isEmpty())
105
    if (mTrees.isEmpty())
106
        return 0;
106
        return 0;
107
    int index_from = limit(int(pctfrom/100. * mTrees.count()), 0, mTrees.count());
107
    int index_from = limit(int(pctfrom/100. * mTrees.count()), 0, mTrees.count());
108
    int index_to = limit(int(pctto/100. * mTrees.count()), 0, mTrees.count());
108
    int index_to = limit(int(pctto/100. * mTrees.count()), 0, mTrees.count());
109
    if (index_from>=index_to)
109
    if (index_from>=index_to)
110
        return 0;
110
        return 0;
111
    qDebug() << "attempting to remove" << number << "trees between indices" << index_from << "and" << index_to;
111
    qDebug() << "attempting to remove" << number << "trees between indices" << index_from << "and" << index_to;
112
    int i;
112
    int i;
113
    int count = number;
113
    int count = number;
114
    if (index_to-index_from <= number)  {
114
    if (index_to-index_from <= number)  {
115
        // kill all
115
        // kill all
116
        for (i=index_from; i<index_to; i++)
116
        for (i=index_from; i<index_to; i++)
117
            mTrees.at(i).first->die();
117
            mTrees.at(i).first->die();
118
        count = index_to - index_from;
118
        count = index_to - index_from;
119
    } else {
119
    } else {
120
        // kill randomly the provided number
120
        // kill randomly the provided number
121
        int cancel = 1000;
121
        int cancel = 1000;
122
        while(number>=0) {
122
        while(number>=0) {
123
            int rnd_index = irandom(index_from, index_to);
123
            int rnd_index = irandom(index_from, index_to);
124
            if (mTrees[rnd_index].first->isDead()) {
124
            if (mTrees[rnd_index].first->isDead()) {
125
                if (--cancel<0) {
125
                if (--cancel<0) {
126
                    qDebug() << "Management::kill: canceling search." << number << "trees left.";
126
                    qDebug() << "Management::kill: canceling search." << number << "trees left.";
127
                    count-=number; // not all trees were killed
127
                    count-=number; // not all trees were killed
128
                    break;
128
                    break;
129
                }
129
                }
130
                continue;
130
                continue;
131
            }
131
            }
132
            cancel = 1000;
132
            cancel = 1000;
133
            number--;
133
            number--;
134
            mTrees[rnd_index].first->die();
134
            mTrees[rnd_index].first->die();
135
        }
135
        }
136
    }
136
    }
137
    qDebug() << count << "removed.";
137
    qDebug() << count << "removed.";
138
    return count; // killed
138
    return count; // killed
139
}
139
}
140
140
141
void Management::run()
141
void Management::run()
142
{
142
{
143
    mTrees.clear();
143
    mTrees.clear();
144
    mRemoved=0;
144
    mRemoved=0;
145
    qDebug() << "Management::run() called";
145
    qDebug() << "Management::run() called";
146
    QScriptValue mgmt = mEngine->globalObject().property("manage");
146
    QScriptValue mgmt = mEngine->globalObject().property("manage");
147
    int year = GlobalSettings::instance()->currentYear();
147
    int year = GlobalSettings::instance()->currentYear();
148
    mgmt.call(QScriptValue(), QScriptValueList()<<year);
148
    mgmt.call(QScriptValue(), QScriptValueList()<<year);
149
    if (mEngine->hasUncaughtException())
149
    if (mEngine->hasUncaughtException())
150
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
150
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
151
151
152
    if (mRemoved>0) {
152
    if (mRemoved>0) {
153
        foreach(ResourceUnit *ru, GlobalSettings::instance()->model()->ruList())
153
        foreach(ResourceUnit *ru, GlobalSettings::instance()->model()->ruList())
154
           ru->cleanTreeList();
154
           ru->cleanTreeList();
155
   }
155
   }
156
}
156
}
157
157
-
 
158
int Management::filter(QVariantList idList)
-
 
159
{
-
 
160
    QHash<int, int> ids;
-
 
161
    foreach(const QVariant &v, idList)
-
 
162
        ids[v.toInt()] = 1;
-
 
163
-
 
164
    QList<QPair<Tree*, double> >::iterator tp=mTrees.begin();
-
 
165
    while (tp!=mTrees.end()) {
-
 
166
        if (!ids.contains(tp->first->id()) )
-
 
167
            tp = mTrees.erase(tp);
-
 
168
        else
-
 
169
            tp++;
-
 
170
    }
-
 
171
    return mTrees.count();
-
 
172
}
-
 
173
-
 
174
int Management::filter(QString filter)
-
 
175
{
-
 
176
    TreeWrapper tw;
-
 
177
    Expression expr(filter,&tw);
-
 
178
    qDebug() << "filtering with" << filter;
-
 
179
    QList<QPair<Tree*, double> >::iterator tp=mTrees.begin();
-
 
180
    while (tp!=mTrees.end()) {
-
 
181
        tw.setTree(tp->first);
-
 
182
        if (!expr.execute())
-
 
183
             tp = mTrees.erase(tp);
-
 
184
        else
-
 
185
            tp++;
-
 
186
    }
-
 
187
    return mTrees.count();
-
 
188
}
158
189
159
int Management::load(QString filter)
190
int Management::load(QString filter)
160
{
191
{
161
    TreeWrapper tw;
192
    TreeWrapper tw;
162
    Model *m = GlobalSettings::instance()->model();
193
    Model *m = GlobalSettings::instance()->model();
163
    mTrees.clear();
194
    mTrees.clear();
164
    AllTreeIterator at(m);
195
    AllTreeIterator at(m);
165
    if (filter.isEmpty()) {
196
    if (filter.isEmpty()) {
166
        while (Tree *t=at.next())
197
        while (Tree *t=at.next())
167
            if (!t->isDead())
198
            if (!t->isDead())
168
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
199
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
169
    } else {
200
    } else {
170
        Expression expr(filter,&tw);
201
        Expression expr(filter,&tw);
171
        qDebug() << "filtering with" << filter;
202
        qDebug() << "filtering with" << filter;
172
        while (Tree *t=at.next()) {
203
        while (Tree *t=at.next()) {
173
            tw.setTree(t);
204
            tw.setTree(t);
174
            if (!t->isDead() && expr.execute())
205
            if (!t->isDead() && expr.execute())
175
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
206
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
176
        }
207
        }
177
    }
208
    }
178
    return mTrees.count();
209
    return mTrees.count();
179
}
210
}
180
211
181
bool treePairValue(const QPair<Tree*, double> &p1, const QPair<Tree*, double> &p2)
212
bool treePairValue(const QPair<Tree*, double> &p1, const QPair<Tree*, double> &p2)
182
{
213
{
183
    return p1.second < p2.second;
214
    return p1.second < p2.second;
184
}
215
}
185
216
186
void Management::sort(QString statement)
217
void Management::sort(QString statement)
187
{
218
{
188
    TreeWrapper tw;
219
    TreeWrapper tw;
189
    Expression sorter(statement, &tw);
220
    Expression sorter(statement, &tw);
190
    // fill the "value" part of the tree storage with a value for each tree
221
    // fill the "value" part of the tree storage with a value for each tree
191
    for (int i=0;i<mTrees.count(); ++i) {
222
    for (int i=0;i<mTrees.count(); ++i) {
192
        tw.setTree(mTrees.at(i).first);
223
        tw.setTree(mTrees.at(i).first);
193
        mTrees[i].second = sorter.execute();
224
        mTrees[i].second = sorter.execute();
194
   }
225
   }
195
   // now sort the list....
226
   // now sort the list....
196
   qSort(mTrees.begin(), mTrees.end(), treePairValue);
227
   qSort(mTrees.begin(), mTrees.end(), treePairValue);
197
}
228
}
198
229
199
double Management::percentile(int pct)
230
double Management::percentile(int pct)
200
{
231
{
201
    if (mTrees.count()==0)
232
    if (mTrees.count()==0)
202
        return -1.;
233
        return -1.;
203
    int idx = int( (pct/100.) * mTrees.count());
234
    int idx = int( (pct/100.) * mTrees.count());
204
    if (idx>=0 && idx<mTrees.count())
235
    if (idx>=0 && idx<mTrees.count())
205
        return mTrees.at(idx).second;
236
        return mTrees.at(idx).second;
206
    else
237
    else
207
        return -1;
238
        return -1;
208
}
239
}
209
 
240