Subversion Repositories public iLand

Rev

Rev 284 | Rev 315 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
269 werner 2
#include "global.h"
3
#include "environment.h"
280 werner 4
#include "helper.h"
5
#include "csvfile.h"
269 werner 6
 
7
 
8
#include "climate.h"
280 werner 9
#include "speciesset.h"
269 werner 10
 
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.
13
*/
14
Environment::Environment()
15
{
280 werner 16
    mInfile=0;
269 werner 17
}
280 werner 18
Environment::~Environment()
19
{
314 werner 20
    if (mInfile) {
280 werner 21
        delete mInfile;
314 werner 22
        qDeleteAll(mSpeciesSets);
23
        qDeleteAll(mClimate);
24
    }
280 werner 25
}
26
 
27
bool Environment::loadFromFile(const QString &fileName)
28
{
284 werner 29
    QString source = Helper::loadTextFile(GlobalSettings::instance()->path(fileName));
280 werner 30
    if (source.isEmpty())
31
        throw IException(QString("Environment: input file does not exist or is empty (%1)").arg(fileName));
32
    return loadFromString(source);
33
}
34
 
281 werner 35
// ******** specific keys *******
36
const QString speciesKey = "model.species.source";
37
const QString climateKey = "model.climate.tableName";
38
 
280 werner 39
bool Environment::loadFromString(const QString &source)
40
{
41
    try {
42
        if (mInfile)
43
            delete mInfile;
44
        mInfile = new CSVFile();
45
 
46
        mInfile->loadFromString(source);
47
        mKeys = mInfile->captions();
48
 
49
        XmlHelper xml(GlobalSettings::instance()->settings());
50
        mSpeciesSets.clear(); // note: the objects are not destroyed - potential memory leak.
51
        mClimate.clear();
52
        mRowCoordinates.clear();
281 werner 53
        mCreatedObjects.clear();
54
 
280 werner 55
        int index;
56
        // setup coordinates (x,y)
57
        int ix,iy;
58
        ix = mInfile->columnIndex("x");
59
        iy = mInfile->columnIndex("y");
60
        if (ix<0 || iy<0)
61
            throw IException("Environment:: input file has no x/y coordinates!");
62
        for (int row=0;row<mInfile->rowCount();row++) {
63
            QString key=QString("%1_%2")
64
                        .arg(mInfile->value(row, ix).toString())
65
                        .arg(mInfile->value(row, iy).toString());
66
            mRowCoordinates[key] = row;
67
        }
68
 
69
 
281 werner 70
 
280 werner 71
        // ******** setup of Species Sets *******
72
        if ((index = mKeys.indexOf(speciesKey))>-1) {
73
            DebugTimer t("environment:load species");
74
            QStringList speciesNames = mInfile->column(index);
75
            speciesNames.removeDuplicates();
76
            qDebug() << "creating species sets:" << speciesNames;
77
            foreach (const QString &name, speciesNames) {
78
                xml.setNodeValue(speciesKey,name); // set xml value
79
                // create species sets
80
                SpeciesSet *set = new SpeciesSet();
81
                set->setup();
82
                mSpeciesSets.push_back(set);
281 werner 83
                mCreatedObjects[name] = (void*)set;
280 werner 84
            }
85
            qDebug() << mSpeciesSets.count() << "species sets created.";
314 werner 86
        } else {
87
            // no species sets specified
88
            SpeciesSet *speciesSet = new SpeciesSet();
89
            mSpeciesSets.push_back(speciesSet);
90
            speciesSet->setup();
91
            mCurrentSpeciesSet = speciesSet;
280 werner 92
        }
93
 
94
        // ******** setup of Climate *******
95
        if ((index = mKeys.indexOf(climateKey))>-1) {
96
            DebugTimer t("environment:load climate");
97
            QStringList climateNames = mInfile->column(index);
98
            climateNames.removeDuplicates();
99
            qDebug() << "creating climatae: " << climateNames;
100
            foreach (QString name, climateNames) {
101
                xml.setNodeValue(climateKey,name); // set xml value
102
                // create climate sets
103
                Climate *climate = new Climate();
104
                climate->setup();
105
                mClimate.push_back(climate);
106
            }
107
            qDebug() << mClimate.count() << "climates created";
314 werner 108
        } else {
109
            // no climate defined - setup default climate
110
            Climate *c = new Climate();
111
            c->setup();
112
            mClimate.push_back(c);
113
            mCreatedObjects["default_climate"]=(void*)c; // prepare clean cleanup
114
            mCurrentClimate = c;
280 werner 115
        }
116
        return true;
117
 
118
    } catch(const IException &e) {
119
        QString error_msg = QString("An error occured during the setup of the environment: \n%1").arg(e.toString());
120
        qDebug() << error_msg;
121
        Helper::msg(error_msg);
122
        return false;
123
    }
124
}
125
 
126
 
127
void Environment::setPosition(const QPointF position)
128
{
281 werner 129
    // no changes occur, when the "environment" is not loaded
130
    if (!isSetup())
131
        return;
280 werner 132
 
133
    int ix, iy;
134
    ix = int(position.x() / 100.); // suppose size of 1 ha for each coordinate
135
    iy = int(position.y() / 100.);
136
    QString key=QString("%1_%2").arg(ix).arg(iy);
137
    if (mRowCoordinates.contains(key)) {
138
        XmlHelper xml(GlobalSettings::instance()->settings());
139
        int row = mRowCoordinates[key];
140
        QString value;
141
        qDebug() << "settting up point" << position << "with row" << row;
142
        for (int col=0;col<mInfile->colCount(); col++) {
281 werner 143
            if (mKeys[col]=="x" || mKeys[col]=="y") // ignore "x" and "y" keys
280 werner 144
                continue;
145
            value = mInfile->value(row,col).toString();
146
            qDebug() << "set" << mKeys[col] << "to" << value;
147
            xml.setNodeValue(mKeys[col], value);
281 werner 148
            // special handling for constructed objects:
149
            if (mKeys[col]==speciesKey)
150
                mCurrentSpeciesSet = (SpeciesSet*)mCreatedObjects[value];
151
            if (mKeys[col]==climateKey)
152
                mCurrentClimate = (Climate*)mCreatedObjects[value];
153
 
280 werner 154
        }
155
 
156
    } else
157
        throw IException(QString("Environment:setposition: invalid coordinates (or not present in input file): %1/%2").arg(position.x()).arg(position.y()));
158
}