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