Subversion Repositories public iLand

Rev

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

Rev 567 Rev 568
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/environment.cpp':
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/environment.cpp':
2
#include "global.h"
2
#include "global.h"
3
#include "environment.h"
3
#include "environment.h"
4
#include "helper.h"
4
#include "helper.h"
5
#include "csvfile.h"
5
#include "csvfile.h"
6
#include "gisgrid.h"
6
#include "gisgrid.h"
7
7
8
#include "climate.h"
8
#include "climate.h"
9
#include "speciesset.h"
9
#include "speciesset.h"
10
10
11
/** Represents the physical simulation site with regard to climate, soil properties and such.
11
/** Represents the physical simulation site with regard to climate, soil properties and such.
12
    Data is read from various sources and presented to the core model with a standardized interface.
12
    Data is read from various sources and presented to the core model with a standardized interface.
13
*/
13
*/
14
Environment::Environment()
14
Environment::Environment()
15
{
15
{
16
    mInfile = 0;
16
    mInfile = 0;
17
    mGrid = 0;
17
    mGrid = 0;
18
    mGridMode = false;
18
    mGridMode = false;
19
    mCurrentSpeciesSet = 0;
19
    mCurrentSpeciesSet = 0;
20
    mCurrentClimate = 0;
20
    mCurrentClimate = 0;
21
}
21
}
22
Environment::~Environment()
22
Environment::~Environment()
23
{
23
{
24
    if (mInfile) {
24
    if (mInfile) {
25
        delete mInfile;
25
        delete mInfile;
26
    }
26
    }
27
    if (mGrid)
27
    if (mGrid)
28
        delete mGrid;
28
        delete mGrid;
29
}
29
}
30
30
31
bool Environment::loadFromFile(const QString &fileName)
31
bool Environment::loadFromFile(const QString &fileName)
32
{
32
{
33
    QString source = Helper::loadTextFile(GlobalSettings::instance()->path(fileName));
33
    QString source = Helper::loadTextFile(GlobalSettings::instance()->path(fileName));
34
    if (source.isEmpty())
34
    if (source.isEmpty())
35
        throw IException(QString("Environment: input file does not exist or is empty (%1)").arg(fileName));
35
        throw IException(QString("Environment: input file does not exist or is empty (%1)").arg(fileName));
36
    return loadFromString(source);
36
    return loadFromString(source);
37
}
37
}
38
38
39
// ******** specific keys *******
39
// ******** specific keys *******
40
const QString speciesKey = "model.species.source";
40
const QString speciesKey = "model.species.source";
41
const QString climateKey = "model.climate.tableName";
41
const QString climateKey = "model.climate.tableName";
42
42
43
bool Environment::loadFromString(const QString &source)
43
bool Environment::loadFromString(const QString &source)
44
{
44
{
45
    try {
45
    try {
46
        if (mInfile)
46
        if (mInfile)
47
            delete mInfile;
47
            delete mInfile;
48
        mInfile = new CSVFile();
48
        mInfile = new CSVFile();
49
49
50
        mInfile->loadFromString(source);
50
        mInfile->loadFromString(source);
51
        mKeys = mInfile->captions();
51
        mKeys = mInfile->captions();
52
52
53
        XmlHelper xml(GlobalSettings::instance()->settings());
53
        XmlHelper xml(GlobalSettings::instance()->settings());
54
        mSpeciesSets.clear(); // note: the objects are not destroyed - potential memory leak.
54
        mSpeciesSets.clear(); // note: the objects are not destroyed - potential memory leak.
55
        mClimate.clear();
55
        mClimate.clear();
56
        mRowCoordinates.clear();
56
        mRowCoordinates.clear();
57
        mCreatedObjects.clear();
57
        mCreatedObjects.clear();
58
58
59
        int index;
59
        int index;
60
        if (mGridMode) {
60
        if (mGridMode) {
61
            int id = mInfile->columnIndex("id");
61
            int id = mInfile->columnIndex("id");
62
            if (id<0)
62
            if (id<0)
63
                throw IException("Environment:: (grid mode) input file has no 'id' column!");
63
                throw IException("Environment:: (grid mode) input file has no 'id' column!");
64
            for (int row=0;row<mInfile->rowCount();row++) {
64
            for (int row=0;row<mInfile->rowCount();row++) {
65
                mRowCoordinates[mInfile->value(row, id).toString()] = row;
65
                mRowCoordinates[mInfile->value(row, id).toString()] = row;
66
            }
66
            }
67
67
68
        } else {
68
        } else {
69
            // ***  Matrix mode ******
69
            // ***  Matrix mode ******
70
            // each row must contain 'x' and 'y' coordinates
70
            // each row must contain 'x' and 'y' coordinates
71
            // setup coordinates (x,y)
71
            // setup coordinates (x,y)
72
            int ix,iy;
72
            int ix,iy;
73
            ix = mInfile->columnIndex("x");
73
            ix = mInfile->columnIndex("x");
74
            iy = mInfile->columnIndex("y");
74
            iy = mInfile->columnIndex("y");
75
            if (ix<0 || iy<0)
75
            if (ix<0 || iy<0)
76
                throw IException("Environment:: (matrix mode) input file has no x/y coordinates!");
76
                throw IException("Environment:: (matrix mode) input file has no x/y coordinates!");
77
            for (int row=0;row<mInfile->rowCount();row++) {
77
            for (int row=0;row<mInfile->rowCount();row++) {
78
                QString key=QString("%1_%2")
78
                QString key=QString("%1_%2")
79
                        .arg(mInfile->value(row, ix).toString())
79
                        .arg(mInfile->value(row, ix).toString())
80
                        .arg(mInfile->value(row, iy).toString());
80
                        .arg(mInfile->value(row, iy).toString());
81
                mRowCoordinates[key] = row;
81
                mRowCoordinates[key] = row;
82
            }
82
            }
83
        }
83
        }
84
84
85
85
86
86
87
        // ******** setup of Species Sets *******
87
        // ******** setup of Species Sets *******
88
        if ((index = mKeys.indexOf(speciesKey))>-1) {
88
        if ((index = mKeys.indexOf(speciesKey))>-1) {
89
            DebugTimer t("environment:load species");
89
            DebugTimer t("environment:load species");
90
            QStringList speciesNames = mInfile->column(index);
90
            QStringList speciesNames = mInfile->column(index);
91
            speciesNames.removeDuplicates();
91
            speciesNames.removeDuplicates();
92
            qDebug() << "creating species sets:" << speciesNames;
92
            qDebug() << "creating species sets:" << speciesNames;
93
            foreach (const QString &name, speciesNames) {
93
            foreach (const QString &name, speciesNames) {
94
                xml.setNodeValue(speciesKey,name); // set xml value
94
                xml.setNodeValue(speciesKey,name); // set xml value
95
                // create species sets
95
                // create species sets
96
                SpeciesSet *set = new SpeciesSet();
96
                SpeciesSet *set = new SpeciesSet();
97
                mSpeciesSets.push_back(set);
97
                mSpeciesSets.push_back(set);
98
                mCreatedObjects[name] = (void*)set;
98
                mCreatedObjects[name] = (void*)set;
99
                set->setup();
99
                set->setup();
100
            }
100
            }
101
            qDebug() << mSpeciesSets.count() << "species sets created.";
101
            qDebug() << mSpeciesSets.count() << "species sets created.";
102
        } else {
102
        } else {
103
            // no species sets specified
103
            // no species sets specified
104
            SpeciesSet *speciesSet = new SpeciesSet();
104
            SpeciesSet *speciesSet = new SpeciesSet();
105
            mSpeciesSets.push_back(speciesSet);
105
            mSpeciesSets.push_back(speciesSet);
106
            speciesSet->setup();
106
            speciesSet->setup();
107
            mCurrentSpeciesSet = speciesSet;
107
            mCurrentSpeciesSet = speciesSet;
108
        }
108
        }
109
109
110
        // ******** setup of Climate *******
110
        // ******** setup of Climate *******
111
        if ((index = mKeys.indexOf(climateKey))>-1) {
111
        if ((index = mKeys.indexOf(climateKey))>-1) {
112
            DebugTimer t("environment:load climate");
112
            DebugTimer t("environment:load climate");
113
            QStringList climateNames = mInfile->column(index);
113
            QStringList climateNames = mInfile->column(index);
114
            climateNames.removeDuplicates();
114
            climateNames.removeDuplicates();
115
            qDebug() << "creating climatae: " << climateNames;
115
            qDebug() << "creating climatae: " << climateNames;
116
            foreach (QString name, climateNames) {
116
            foreach (QString name, climateNames) {
117
                xml.setNodeValue(climateKey,name); // set xml value
117
                xml.setNodeValue(climateKey,name); // set xml value
118
                // create climate sets
118
                // create climate sets
119
                Climate *climate = new Climate();
119
                Climate *climate = new Climate();
120
                mClimate.push_back(climate);
120
                mClimate.push_back(climate);
121
                mCreatedObjects[name]=(void*)climate;
121
                mCreatedObjects[name]=(void*)climate;
122
                climate->setup();
122
                climate->setup();
123
            }
123
            }
124
            qDebug() << mClimate.count() << "climates created";
124
            qDebug() << mClimate.count() << "climates created";
125
        } else {
125
        } else {
126
            // no climate defined - setup default climate
126
            // no climate defined - setup default climate
127
            Climate *c = new Climate();
127
            Climate *c = new Climate();
128
            mClimate.push_back(c);
128
            mClimate.push_back(c);
129
            c->setup();
129
            c->setup();
130
            mCurrentClimate = c;
130
            mCurrentClimate = c;
131
        }
131
        }
132
        if (!mCurrentClimate && mClimate.count()>0)
132
        if (!mCurrentClimate && mClimate.count()>0)
133
            mCurrentClimate = mClimate[0];
133
            mCurrentClimate = mClimate[0];
134
        if (!mCurrentSpeciesSet && mSpeciesSets.count()>0)
134
        if (!mCurrentSpeciesSet && mSpeciesSets.count()>0)
135
            mCurrentSpeciesSet = mSpeciesSets[0];
135
            mCurrentSpeciesSet = mSpeciesSets[0];
136
        return true;
136
        return true;
137
137
138
    } catch(const IException &e) {
138
    } catch(const IException &e) {
139
        QString addMsg;
139
        QString addMsg;
140
        if (!mClimate.isEmpty())
140
        if (!mClimate.isEmpty())
141
            addMsg = QString("last Climate: %1 ").arg(mClimate.last()->name());
141
            addMsg = QString("last Climate: %1 ").arg(mClimate.last()->name());
142
        if (!mSpeciesSets.isEmpty())
142
        if (!mSpeciesSets.isEmpty())
143
            addMsg += QString("last Speciesset table: %1").arg(mSpeciesSets.last()->name());
143
            addMsg += QString("last Speciesset table: %1").arg(mSpeciesSets.last()->name());
144
        QString error_msg = QString("An error occured during the setup of the environment: \n%1\n%2").arg(e.toString()).arg(addMsg);
144
        QString error_msg = QString("An error occured during the setup of the environment: \n%1\n%2").arg(e.toString()).arg(addMsg);
145
        qDebug() << error_msg;
145
        qDebug() << error_msg;
146
        Helper::msg(error_msg);
146
        Helper::msg(error_msg);
147
        return false;
147
        return false;
148
    }
148
    }
149
}
149
}
150
150
151
/** sets the "pointer" to a "position" (metric coordinates).
151
/** sets the "pointer" to a "position" (metric coordinates).
152
    All specified values are set (also the climate/species-set pointers).
152
    All specified values are set (also the climate/species-set pointers).
153
*/
153
*/
154
void Environment::setPosition(const QPointF position)
154
void Environment::setPosition(const QPointF position)
155
{
155
{
156
    // no changes occur, when the "environment" is not loaded
156
    // no changes occur, when the "environment" is not loaded
157
    if (!isSetup())
157
    if (!isSetup())
158
        return;
158
        return;
159
    QString key;
159
    QString key;
160
    int ix, iy, id;
-
 
-
 
160
    int ix=-1, iy=-1, id=-1;
161
    if (mGridMode) {
161
    if (mGridMode) {
162
        // grid mode
162
        // grid mode
163
        id = mGrid->value(position);
163
        id = mGrid->value(position);
164
        key = QString::number(id);
164
        key = QString::number(id);
165
        if (id==-1)
165
        if (id==-1)
166
            return; // no data for the resource unit
166
            return; // no data for the resource unit
167
    } else {
167
    } else {
168
        // access data in the matrix by resource unit indices
168
        // access data in the matrix by resource unit indices
169
        ix = int(position.x() / 100.); // suppose size of 1 ha for each coordinate
169
        ix = int(position.x() / 100.); // suppose size of 1 ha for each coordinate
170
        iy = int(position.y() / 100.);
170
        iy = int(position.y() / 100.);
171
        key=QString("%1_%2").arg(ix).arg(iy);
171
        key=QString("%1_%2").arg(ix).arg(iy);
172
    }
172
    }
173
173
174
    if (mRowCoordinates.contains(key)) {
174
    if (mRowCoordinates.contains(key)) {
175
        XmlHelper xml(GlobalSettings::instance()->settings());
175
        XmlHelper xml(GlobalSettings::instance()->settings());
176
        int row = mRowCoordinates[key];
176
        int row = mRowCoordinates[key];
177
        QString value;
177
        QString value;
178
        if (logLevelInfo()) qDebug() << "settting up point" << position << "with row" << row;
178
        if (logLevelInfo()) qDebug() << "settting up point" << position << "with row" << row;
179
        for (int col=0;col<mInfile->colCount(); col++) {
179
        for (int col=0;col<mInfile->colCount(); col++) {
180
            if (mKeys[col]=="x" || mKeys[col]=="y" || mKeys[col]=="id") // ignore "x" and "y" keys
180
            if (mKeys[col]=="x" || mKeys[col]=="y" || mKeys[col]=="id") // ignore "x" and "y" keys
181
                continue;
181
                continue;
182
            value = mInfile->value(row,col).toString();
182
            value = mInfile->value(row,col).toString();
183
            if (logLevelInfo()) qDebug() << "set" << mKeys[col] << "to" << value;
183
            if (logLevelInfo()) qDebug() << "set" << mKeys[col] << "to" << value;
184
            xml.setNodeValue(mKeys[col], value);
184
            xml.setNodeValue(mKeys[col], value);
185
            // special handling for constructed objects:
185
            // special handling for constructed objects:
186
            if (mKeys[col]==speciesKey)
186
            if (mKeys[col]==speciesKey)
187
                mCurrentSpeciesSet = (SpeciesSet*)mCreatedObjects[value];
187
                mCurrentSpeciesSet = (SpeciesSet*)mCreatedObjects[value];
188
            if (mKeys[col]==climateKey)
188
            if (mKeys[col]==climateKey)
189
                mCurrentClimate = (Climate*)mCreatedObjects[value];
189
                mCurrentClimate = (Climate*)mCreatedObjects[value];
190
190
191
        }
191
        }
192
192
193
    } else {
193
    } else {
194
        if (mGridMode)
194
        if (mGridMode)
195
            throw IException(QString("Environment:setposition: invalid grid id (or not present in input file): %1m/%2m (mapped to id %3).")
195
            throw IException(QString("Environment:setposition: invalid grid id (or not present in input file): %1m/%2m (mapped to id %3).")
196
                             .arg(position.x()).arg(position.y()).arg(id));
196
                             .arg(position.x()).arg(position.y()).arg(id));
197
        else
197
        else
198
            throw IException(QString("Environment:setposition: invalid coordinates (or not present in input file): %1m/%2m (mapped to indices %3/%4).")
198
            throw IException(QString("Environment:setposition: invalid coordinates (or not present in input file): %1m/%2m (mapped to indices %3/%4).")
199
                             .arg(position.x()).arg(position.y()).arg(ix).arg(iy));
199
                             .arg(position.x()).arg(position.y()).arg(ix).arg(iy));
200
    }
200
    }
201
}
201
}
202
202
203
bool Environment::setGridMode(const QString &grid_file_name)
203
bool Environment::setGridMode(const QString &grid_file_name)
204
{
204
{
205
    mGrid = new GisGrid();
205
    mGrid = new GisGrid();
206
    mGrid->loadFromFile(grid_file_name);
206
    mGrid->loadFromFile(grid_file_name);
207
    mGridMode = true;
207
    mGridMode = true;
208
    return true;
208
    return true;
209
}
209
}
210
 
210