Subversion Repositories public iLand

Rev

Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1211 werner 1
/********************************************************************************************
2
**    iLand - an individual based forest landscape and disturbance model
3
**    http://iland.boku.ac.at
4
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
5
**
6
**    This program is free software: you can redistribute it and/or modify
7
**    it under the terms of the GNU General Public License as published by
8
**    the Free Software Foundation, either version 3 of the License, or
9
**    (at your option) any later version.
10
**
11
**    This program is distributed in the hope that it will be useful,
12
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
**    GNU General Public License for more details.
15
**
16
**    You should have received a copy of the GNU General Public License
17
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
********************************************************************************************/
1081 werner 19
#include "scriptgrid.h"
20
#include "globalsettings.h"
21
#include "helper.h"
22
#include "expression.h"
23
#include "modelcontroller.h"
1090 werner 24
#include "mapgrid.h"
1081 werner 25
 
1090 werner 26
 
1081 werner 27
#include <QJSEngine>
28
#include <QJSValueIterator>
29
 
1085 werner 30
int ScriptGrid::mDeleted = 0;
31
int ScriptGrid::mCreated = 0;
32
 
1081 werner 33
ScriptGrid::ScriptGrid(QObject *parent) : QObject(parent)
34
{
35
    mGrid = 0;
36
    mVariableName = "x"; // default name
1085 werner 37
    mCreated++;
1081 werner 38
}
39
 
40
ScriptGrid::~ScriptGrid()
41
{
42
    if (mGrid)
43
        delete mGrid;
1085 werner 44
    mDeleted++;
45
    qDebug() << "ScriptGrid::balance: created:" << mCreated << "deleted:" << mDeleted;
1081 werner 46
}
47
 
1091 werner 48
// create a ScriptGrid-Wrapper around "grid". Note: destructing the 'grid' is done via the JS-garbage-collector.
1081 werner 49
QJSValue ScriptGrid::createGrid(Grid<double> *grid, QString name)
50
{
51
    ScriptGrid *g = new ScriptGrid(grid);
52
    if (!name.isEmpty())
53
        g->setName(name);
54
    QJSValue jsgrid = GlobalSettings::instance()->scriptEngine()->newQObject(g);
55
    return jsgrid;
56
}
57
 
58
QJSValue ScriptGrid::copy()
59
{
60
    if (!mGrid)
61
        return QJSValue();
62
 
63
    ScriptGrid *newgrid = new ScriptGrid();
64
    // copy the data
65
    Grid<double> *copy_grid = new Grid<double>(*mGrid);
66
    newgrid->setGrid(copy_grid);
67
 
68
    QJSValue jsgrid = GlobalSettings::instance()->scriptEngine()->newQObject(newgrid);
69
    return jsgrid;
70
}
71
 
72
void ScriptGrid::clear()
73
{
74
    if (mGrid && !mGrid->isEmpty())
75
        mGrid->wipe();
76
}
77
 
78
void ScriptGrid::paint(double min_val, double max_val)
79
{
80
    //if (GlobalSettings::instance()->controller())
81
    //    GlobalSettings::instance()->controller()->addGrid(mGrid, mVariableName, GridViewRainbow, min_val, max_val);
82
}
83
 
1090 werner 84
QString ScriptGrid::info()
85
{
86
    if (!mGrid || mGrid->isEmpty())
87
        return QString("not valid / empty.");
88
    return QString("grid-dimensions: %1/%2 (cellsize: %5, N cells: %3), grid-name='%4'").arg(mGrid->sizeX()).arg(mGrid->sizeY()).arg(mGrid->count()).arg(mVariableName).arg(mGrid->cellsize());
89
}
90
 
1081 werner 91
void ScriptGrid::save(QString fileName)
92
{
93
    if (!mGrid || mGrid->isEmpty())
94
        return;
95
    fileName = GlobalSettings::instance()->path(fileName);
96
    QString result = gridToESRIRaster(*mGrid);
97
    Helper::saveToTextFile(fileName, result);
98
    qDebug() << "saved grid " << name() << " to " << fileName;
99
}
100
 
1090 werner 101
bool ScriptGrid::load(QString fileName)
102
{
103
    fileName = GlobalSettings::instance()->path(fileName);
104
    // load the grid from file
105
    MapGrid mg(fileName, false);
106
    if (!mg.isValid()) {
107
        qDebug() << "ScriptGrid::load(): load not successful of file:" << fileName;
108
        return false;
109
    }
110
    if (mGrid) {
111
        delete mGrid;
112
    }
113
    mGrid = mg.grid().toDouble(); // create a copy of the mapgrid-grid
114
    mVariableName = QFileInfo(fileName).baseName();
115
    return !mGrid->isEmpty();
116
 
117
}
118
 
1081 werner 119
void ScriptGrid::apply(QString expression)
120
{
121
    if (!mGrid || mGrid->isEmpty())
122
        return;
123
 
124
    Expression expr;
125
    double *varptr = expr.addVar(mVariableName);
126
    try {
127
        expr.setExpression(expression);
128
        expr.parse();
129
    } catch(const IException &e) {
130
        qDebug() << "JS - grid:apply(): ERROR: " << e.message();
131
        return;
132
    }
133
 
134
    // now apply function on grid
135
    for (double *p = mGrid->begin(); p!=mGrid->end(); ++p) {
136
        *varptr = *p;
137
        *p = expr.execute();
138
    }
139
 
140
}
141
 
142
void ScriptGrid::combine(QString expression, QJSValue grid_object)
143
{
144
    if (!grid_object.isObject()) {
145
        qDebug() << "ERROR: ScriptGrid::combine(): no valid grids object" << grid_object.toString();
146
        return;
147
    }
148
    QVector< Grid<double>* > grids;
149
    QStringList names;
150
    QJSValueIterator it(grid_object);
151
    while (it.hasNext()) {
152
        it.next();
153
        names.push_back(it.name());
154
        QObject *o = it.value().toQObject();
155
        if (o && qobject_cast<ScriptGrid*>(o)) {
156
            grids.push_back(qobject_cast<ScriptGrid*>(o)->grid());
157
            if (grids.last()->isEmpty() || grids.last()->cellsize() != mGrid->cellsize() || grids.last()->rectangle()!=mGrid->rectangle()) {
1090 werner 158
                qDebug() << "ERROR: ScriptGrid::combine(): the grid " << it.name() << "is empty or has different dimensions:" << qobject_cast<ScriptGrid*>(o)->info();
1081 werner 159
                return;
160
            }
161
        } else {
162
            qDebug() << "ERROR: ScriptGrid::combine(): no valid grid object with name:" << it.name();
163
            return;
164
        }
165
    }
166
    // now add names
167
    Expression expr;
168
    QVector<double *> vars;
169
    for (int i=0;i<names.count();++i)
170
        vars.push_back( expr.addVar(names[i]) );
171
    try {
172
        expr.setExpression(expression);
173
        expr.parse();
174
    } catch(const IException &e) {
175
        qDebug() << "JS - grid:combine(): expression ERROR: " << e.message();
176
        return;
177
    }
178
 
179
    // now apply function on grid
180
    for (int i=0;i<mGrid->count();++i) {
181
        // set variable values in the expression object
182
        for (int v=0;v<names.count();++v)
183
            *vars[v] = grids[v]->valueAtIndex(i);
184
        double result = expr.execute();
185
        mGrid->valueAtIndex(i) = result; // write back value
186
    }
187
}
188
 
189
double ScriptGrid::sum(QString expression)
190
{
191
    if (!mGrid || mGrid->isEmpty())
192
        return -1.;
193
 
194
    Expression expr;
195
    double *varptr = expr.addVar(mVariableName);
196
    try {
197
        expr.setExpression(expression);
198
        expr.parse();
199
    } catch(const IException &e) {
200
        qDebug() << "JS - grid:apply(): ERROR: " << e.message();
201
        return -1.;
202
    }
203
 
204
    // now apply function on grid
205
    double sum = 0.;
206
    for (double *p = mGrid->begin(); p!=mGrid->end(); ++p) {
207
        *varptr = *p;
208
        sum += expr.execute();
209
    }
210
    return sum;
211
}
212