Subversion Repositories public iLand

Rev

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

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