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 |