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