Subversion Repositories public iLand

Rev

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

Rev Author Line No. Line
671 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
********************************************************************************************/
19
 
243 werner 20
#include "global.h"
242 werner 21
#include "climateconverter.h"
243 werner 22
#include "csvfile.h"
23
 
793 werner 24
#include <QJSEngine>
25
#include <QJSValue>
243 werner 26
#include <QtSql>
242 werner 27
 
248 werner 28
/** @class ClimateConverter
29
  Converts text-file-based data into the iLand climate data format.
243 werner 30
  For the iLand format see the wiki (ClimateFormat). For each column (i.e. year,month, day,
31
  temp, prec, rad, vpd), an expression providing access to the columns of the input file calculates
32
  the respective output value. Propertes tableName and fileName define the input file and the
33
  name of the output table (located in the "climate"-database of iLand) respectively.
34
*/
247 werner 35
/** @group script
36
  @class ClimateConverter
37
  This is the Scripting related documentation for the ClimateConverter tool.
38
*/
793 werner 39
//Q_SCRIPT_DECLARE_QMETAOBJECT(ClimateConverter, QObject*)
40
void ClimateConverter::addToScriptEngine(QJSEngine &engine)
242 werner 41
{
42
    // about this kind of scripting magic see: http://qt.nokia.com/developer/faqs/faq.2007-06-25.9557303148
793 werner 43
    //QJSValue cc_class = engine.scriptValueFromQMetaObject<ClimateConverter>();
242 werner 44
    // the script name for the object is "ClimateConverter".
793 werner 45
    QObject *cc = new ClimateConverter();
46
    QJSValue cc_class = engine.newQObject(cc);
242 werner 47
    engine.globalObject().setProperty("ClimateConverter", cc_class);
48
}
49
 
766 werner 50
ClimateConverter::ClimateConverter(QObject *)
242 werner 51
{
244 werner 52
    mCaptions = true;
242 werner 53
    bindExpression(mExpYear, 0);
54
    bindExpression(mExpMonth, 1);
55
    bindExpression(mExpDay, 2);
56
 
57
    bindExpression(mExpTemp, 3);
414 werner 58
    bindExpression(mExpMinTemp, 4);
242 werner 59
 
414 werner 60
    bindExpression(mExpPrec, 5);
61
    bindExpression(mExpRad, 6);
62
    bindExpression(mExpVpd, 7);
242 werner 63
}
64
 
414 werner 65
 
66
 
242 werner 67
void ClimateConverter::bindExpression(Expression &expr, int index)
68
{
243 werner 69
    expr.setExpression(QString("c%1").arg(index) ); // "cX" is the default expression
242 werner 70
    for (int i=0;i<10;i++)
71
        mVars[index*10 + i] = expr.addVar( QString("c%1").arg(i) );
72
}
73
 
74
void ClimateConverter::run()
75
{
76
    mExpYear.setExpression(mYear);
77
    mExpMonth.setExpression(mMonth);
78
    mExpDay.setExpression(mDay);
79
 
80
    mExpTemp.setExpression(mTemp);
414 werner 81
    mExpMinTemp.setExpression(mMinTemp);
242 werner 82
    mExpPrec.setExpression(mPrec);
83
    mExpRad.setExpression(mRad);
84
    mExpVpd.setExpression(mVpd);
243 werner 85
    // prepare output database
244 werner 86
    if (mDatabase.isEmpty()) {
87
        qDebug() << "ClimateConverter: database is empty!";
88
        return;
89
    }
90
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","cctemp");
91
    db.setDatabaseName(mDatabase);
92
    if (!db.open()) {
93
        qDebug() << "ClimateConverter: invalid database: " << db.lastError().text();
94
        return;
95
    }
96
 
97
    QSqlQuery creator(db);
243 werner 98
    if (mTableName.isEmpty()) {
99
        qDebug() << "ClimateConverter::run: invalid climate database or table name.";
100
    }
244 werner 101
    QString sql=QString("CREATE TABLE %1 ( " \
102
                "year INTEGER, month INTEGER, day INTEGER, " \
414 werner 103
                "temp REAL, min_temp REAL, prec REAL, rad REAL, vpd REAL)").arg(mTableName);
242 werner 104
 
243 werner 105
    QString drop=QString("drop table if exists %1").arg(mTableName);
244 werner 106
 
243 werner 107
    creator.exec(drop); // drop table (if exists)
244 werner 108
    if (creator.lastError().isValid()) {
109
        qDebug() << "ClimateConverter: Sql-Error (drop):" << creator.lastError().text();
110
        return;
111
    }
243 werner 112
    creator.exec(sql); // (re-)create table
244 werner 113
    if (creator.lastError().isValid()) {
114
        qDebug() << "ClimateConverter: Sql-Error (create table):" << creator.lastError().text();
115
        return;
116
    }
117
 
243 werner 118
    // prepare insert statement
414 werner 119
    sql = QString("insert into %1 (year, month, day, temp, min_temp, prec, rad, vpd) values (?,?,?, ?,?,?,?,?)").arg(mTableName);
243 werner 120
    creator.prepare(sql);
244 werner 121
    if (creator.lastError().isValid()) {
122
        qDebug() << "ClimateConverter: Sql-Error (prepare):" << creator.lastError().text();
123
        return;
124
    }
243 werner 125
    // load file
126
    if (mFileName.isEmpty()) {
127
        qDebug() << "ClimateConverter::run: empty filename.";
128
        return;
129
    }
244 werner 130
    CSVFile file;
131
    file.setHasCaptions(mCaptions);
132
    file.loadFile(mFileName);
243 werner 133
    if (!file.rowCount()) {
134
        qDebug() << "ClimateConverter::run: cannot load file:" << mFileName;
135
        return;
136
    }
244 werner 137
 
243 werner 138
    // do this for each row
139
    double value;
140
    int year, month, day;
414 werner 141
    double temp, min_temp, prec, rad, vpd;
243 werner 142
    int rows=0;
244 werner 143
    db.transaction();
243 werner 144
    for (int row=0;row<file.rowCount(); row++) {
145
        // fetch values from input file
146
        for (int col=0;col<file.colCount(); col++) {
245 werner 147
            value = file.value(row, col).toDouble();
243 werner 148
            // store value in each of the expression variables
414 werner 149
            for (int j=0;j<8;j++)
243 werner 150
                *(mVars[j*10 + col]) = value; // store in the locataion mVars[x] points to.
242 werner 151
        }
243 werner 152
        // calculate new values....
153
        year = (int)mExpYear.execute();
154
        month = (int)mExpMonth.execute();
155
        day = (int)mExpDay.execute();
156
        temp = mExpTemp.execute();
414 werner 157
        min_temp = mExpMinTemp.execute();
243 werner 158
        prec = mExpPrec.execute();
159
        rad = mExpRad.execute();
160
        vpd = mExpVpd.execute();
244 werner 161
        //qDebug() << year << month << day << temp << prec << rad << vpd;
243 werner 162
        // bind values
163
        creator.bindValue(0,year);
164
        creator.bindValue(1,month);
165
        creator.bindValue(2,day);
166
        creator.bindValue(3,temp);
414 werner 167
        creator.bindValue(4,min_temp);
168
        creator.bindValue(5,prec);
169
        creator.bindValue(6,rad);
170
        creator.bindValue(7,vpd);
243 werner 171
        creator.exec();
172
        rows++;
173
        if (creator.lastError().isValid()) {
174
            qDebug() << "ClimateConverter: Sql-Error:" << creator.lastError().text();
244 werner 175
            return;
243 werner 176
        }
242 werner 177
    }
244 werner 178
    db.commit();
179
    creator.clear();
180
    db.close();
181
    QSqlDatabase::removeDatabase("cctemp");
243 werner 182
    qDebug() << "ClimateConverter::run: processing complete." << rows << "rows inserted.";
244 werner 183
 
242 werner 184
}