1 /***************************************************************************
2 property.cpp - description
3 -------------------
4 begin : may 18th, 2008
5 copyright : (C) 2008 by Duong Khang NGUYEN
6 email : neoneurone @ gmail com
7
8 $Id: property.cpp 375 2008-10-28 14:47:15Z neoneurone $
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * any later version. *
17 * *
18 ***************************************************************************/
19
20 // OpenCity headers
21 #include "property.h"
22
23 // Libraries headers
24 #include "xpath_processor.h"
25 #include "xpath_static.h"
26
27
28
29 using namespace TinyXPath;
30
31
32 /*=====================================================================*/
33 /* PRIVATE METHODS */
34 /*=====================================================================*/
35 Property*
LoadProperties(string filename)36 Property::LoadProperties( string filename )
37 {
38 // Parameters checking
39 OPENCITY_DEBUG( "Loading file: " << filename );
40 assert( filename != "" );
41
42 // Load the XML metadata file
43 TiXmlDocument xml;
44 if (!xml.LoadFile(filename) || xml.Error()) {
45 OPENCITY_FATAL( xml.ErrorDesc() );
46 abort();
47 }
48
49 // Get the root element
50 TiXmlNode* pRoot = xml.RootElement();
51 if (pRoot == NULL) {
52 OPENCITY_FATAL( xml.ErrorDesc() );
53 abort();
54 }
55
56 // Initialize few work variables
57 TiXmlNode* pNode = NULL;
58 TiXmlElement* pElement = NULL;
59 TiXmlAttribute* pAttribute = NULL;
60 Property* pProperty = new Property();
61
62 // Select the "/object/property/cost" node
63 pNode = XNp_xpath_node(pRoot, OC_METADATA_COST_NODE);
64 assert( pNode != NULL );
65 // Get the <cost> node and fill the structure with the model cost properties
66 pElement = pNode->ToElement();
67 pElement->QueryIntAttribute( "build", (int*)&pProperty->uiBuildCost );
68 pElement->QueryIntAttribute( "destroy", (int*)&pProperty->uiDestroyCost );
69 pElement->QueryIntAttribute( "support", (int*)&pProperty->uiSupportCost );
70 pElement->QueryIntAttribute( "income", (int*)&pProperty->uiIncome );
71
72 // RCI ========================================================================
73 // Select the "/object/property/r/need" node
74 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_R_NODE);
75 assert( pNode != NULL );
76 // Get the <cost> node and fill the structure with the model cost properties
77 pElement = pNode->ToElement();
78 pElement->QueryIntAttribute( "min", (int*)&pProperty->sResidence.mmNeed.iMin);
79 pElement->QueryIntAttribute( "max", (int*)&pProperty->sResidence.mmNeed.iMax);
80
81 // Select the "/object/property/r/provide" node
82 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_R_NODE);
83 assert( pNode != NULL );
84 // Get the <cost> node and fill the structure with the model cost properties
85 pElement = pNode->ToElement();
86 pElement->QueryIntAttribute( "min", (int*)&pProperty->sResidence.mmProvide.iMin);
87 pElement->QueryIntAttribute( "max", (int*)&pProperty->sResidence.mmProvide.iMax);
88
89 // Select the "/object/property/c/need" node
90 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_C_NODE);
91 assert( pNode != NULL );
92 // Get the <cost> node and fill the structure with the model cost properties
93 pElement = pNode->ToElement();
94 pElement->QueryIntAttribute( "min", (int*)&pProperty->sCommerce.mmNeed.iMin);
95 pElement->QueryIntAttribute( "max", (int*)&pProperty->sCommerce.mmNeed.iMax);
96
97 // Select the "/object/property/c/provide" node
98 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_C_NODE);
99 assert( pNode != NULL );
100 // Get the <cost> node and fill the structure with the model cost properties
101 pElement = pNode->ToElement();
102 pElement->QueryIntAttribute( "min", (int*)&pProperty->sCommerce.mmProvide.iMin);
103 pElement->QueryIntAttribute( "max", (int*)&pProperty->sCommerce.mmProvide.iMax);
104
105 // Select the "/object/property/i/need" node
106 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_I_NODE);
107 assert( pNode != NULL );
108 // Get the <cost> node and fill the structure with the model cost properties
109 pElement = pNode->ToElement();
110 pElement->QueryIntAttribute( "min", (int*)&pProperty->sIndustry.mmNeed.iMin);
111 pElement->QueryIntAttribute( "max", (int*)&pProperty->sIndustry.mmNeed.iMax);
112
113 // Select the "/object/property/i/provide" node
114 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_I_NODE);
115 assert( pNode != NULL );
116 // Get the <cost> node and fill the structure with the model cost properties
117 pElement = pNode->ToElement();
118 pElement->QueryIntAttribute( "min", (int*)&pProperty->sIndustry.mmProvide.iMin);
119 pElement->QueryIntAttribute( "max", (int*)&pProperty->sIndustry.mmProvide.iMax);
120
121 // WEG ========================================================================
122 // Select the "/object/property/w/need" node
123 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_W_NODE);
124 assert( pNode != NULL );
125 // Get the <cost> node and fill the structure with the model cost properties
126 pElement = pNode->ToElement();
127 pElement->QueryIntAttribute( "min", (int*)&pProperty->sWater.mmNeed.iMin);
128 pElement->QueryIntAttribute( "max", (int*)&pProperty->sWater.mmNeed.iMax);
129
130 // Select the "/object/property/w/provide" node
131 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_W_NODE);
132 assert( pNode != NULL );
133 // Get the <cost> node and fill the structure with the model cost properties
134 pElement = pNode->ToElement();
135 pElement->QueryIntAttribute( "min", (int*)&pProperty->sWater.mmProvide.iMin);
136 pElement->QueryIntAttribute( "max", (int*)&pProperty->sWater.mmProvide.iMax);
137
138 // Select the "/object/property/e/need" node
139 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_E_NODE);
140 assert( pNode != NULL );
141 // Get the <cost> node and fill the structure with the model cost properties
142 pElement = pNode->ToElement();
143 pElement->QueryIntAttribute( "min", (int*)&pProperty->sElectricity.mmNeed.iMin);
144 pElement->QueryIntAttribute( "max", (int*)&pProperty->sElectricity.mmNeed.iMax);
145
146 // Select the "/object/property/e/provide" node
147 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_E_NODE);
148 assert( pNode != NULL );
149 // Get the <cost> node and fill the structure with the model cost properties
150 pElement = pNode->ToElement();
151 pElement->QueryIntAttribute( "min", (int*)&pProperty->sElectricity.mmProvide.iMin);
152 pElement->QueryIntAttribute( "max", (int*)&pProperty->sElectricity.mmProvide.iMax);
153
154 // Select the "/object/property/g/need" node
155 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_G_NODE);
156 assert( pNode != NULL );
157 // Get the <cost> node and fill the structure with the model cost properties
158 pElement = pNode->ToElement();
159 pElement->QueryIntAttribute( "min", (int*)&pProperty->sGas.mmNeed.iMin);
160 pElement->QueryIntAttribute( "max", (int*)&pProperty->sGas.mmNeed.iMax);
161
162 // Select the "/object/property/e/provide" node
163 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_G_NODE);
164 assert( pNode != NULL );
165 // Get the <cost> node and fill the structure with the model cost properties
166 pElement = pNode->ToElement();
167 pElement->QueryIntAttribute( "min", (int*)&pProperty->sGas.mmProvide.iMin);
168 pElement->QueryIntAttribute( "max", (int*)&pProperty->sGas.mmProvide.iMax);
169
170 // TN ========================================================================
171 // Select the "/object/property/t/need" node
172 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_T_NODE);
173 assert( pNode != NULL );
174 // Get the <cost> node and fill the structure with the model cost properties
175 pElement = pNode->ToElement();
176 pElement->QueryIntAttribute( "min", (int*)&pProperty->sTraffic.mmNeed.iMin);
177 pElement->QueryIntAttribute( "max", (int*)&pProperty->sTraffic.mmNeed.iMax);
178
179 // Select the "/object/property/t/provide" node
180 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_T_NODE);
181 assert( pNode != NULL );
182 // Get the <cost> node and fill the structure with the model cost properties
183 pElement = pNode->ToElement();
184 pElement->QueryIntAttribute( "min", (int*)&pProperty->sTraffic.mmProvide.iMin);
185 pElement->QueryIntAttribute( "max", (int*)&pProperty->sTraffic.mmProvide.iMax);
186
187 // Select the "/object/property/nature/need" node
188 pNode = XNp_xpath_node(pRoot, OC_METADATA_NEED_NATURE_NODE);
189 assert( pNode != NULL );
190 // Get the <cost> node and fill the structure with the model cost properties
191 pElement = pNode->ToElement();
192 pElement->QueryIntAttribute( "min", (int*)&pProperty->sNature.mmNeed.iMin);
193 pElement->QueryIntAttribute( "max", (int*)&pProperty->sNature.mmNeed.iMax);
194
195 // Select the "/object/property/nature/provide" node
196 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROVIDE_NATURE_NODE);
197 assert( pNode != NULL );
198 // Get the <cost> node and fill the structure with the model cost properties
199 pElement = pNode->ToElement();
200 pElement->QueryIntAttribute( "min", (int*)&pProperty->sNature.mmProvide.iMin);
201 pElement->QueryIntAttribute( "max", (int*)&pProperty->sNature.mmProvide.iMax);
202
203 // ??? ========================================================================
204 // Select the "/object/property" node
205 pNode = XNp_xpath_node(pRoot, OC_METADATA_PROPERTY_NODE);
206 assert( pNode != NULL );
207 // Get the <cost> node and fill the structure with the model cost properties
208 pElement = pNode->ToElement();
209 pElement->QueryIntAttribute( "inhabitant", (int*)&pProperty->uiInhabitant );
210 pElement->QueryIntAttribute( "worker", (int*)&pProperty->uiWorker );
211 pElement->QueryIntAttribute( "radius", (int*)&pProperty->uiRadius );
212
213 // Select the "/object/property/@type" attribute
214 pAttribute = XAp_xpath_attribute(pRoot, OC_METADATA_STRUCTURE_TYPE_ATTRIBUTE);
215 assert( pAttribute != NULL );
216 pProperty->eStructureType = _Str2Type(pAttribute->ValueStr());
217
218 // Select the "/object/property/direction/@value" attribute
219 pAttribute = XAp_xpath_attribute(pRoot, OC_METADATA_DIRECTION_ATTRIBUTE);
220 assert( pAttribute != NULL );
221 pProperty->eDirection = _Str2Direction(pAttribute->ValueStr());
222
223 // Select the "/object/model" node
224 pNode = XNp_xpath_node(pRoot, OC_METADATA_MODEL_NODE);
225 assert( pNode != NULL );
226 // Get the <model> node and fill the structure with the model dimension
227 pElement = pNode->ToElement();
228 pElement->QueryIntAttribute( "width", (int*)&pProperty->uiWidth );
229 pElement->QueryIntAttribute( "length", (int*)&pProperty->uiLength );
230 pElement->QueryFloatAttribute( "height", &pProperty->fHeight );
231
232 // Debug
233 /*
234 OPENCITY_DEBUG(
235 endl <<
236 "W/L/H: " <<
237 pProperty->uiWidth << "/" << pProperty->uiLength << "/" << pProperty->fHeight << " | " <<
238 "B/D/S/I: " <<
239 pProperty->uiBuildCost << "/" << pProperty->uiDestroyCost << "/" << pProperty->uiSupportCost << "/" << pProperty->uiIncome << " | " <<
240 "Dir: " <<
241 pProperty->eDirection << " | " <<
242 "Type: " <<
243 pProperty->eStructureType << " | " <<
244 "i/w/r: " <<
245 pProperty->uiInhabitant << "/" << pProperty->uiWorker << "/" << pProperty->uiRadius << " | " <<
246 endl <<
247 "r/c/i: " <<
248 pProperty->sResidence.mmNeed.iMin << "-" << pProperty->sResidence.mmNeed.iMax << " " <<
249 pProperty->sResidence.mmProvide.iMin << "-" << pProperty->sResidence.mmProvide.iMax << " / " <<
250 pProperty->sCommerce.mmNeed.iMin << "-" << pProperty->sCommerce.mmNeed.iMax << " " <<
251 pProperty->sCommerce.mmProvide.iMin << "-" << pProperty->sCommerce.mmProvide.iMax << " / " <<
252 pProperty->sIndustry.mmNeed.iMin << "-" << pProperty->sIndustry.mmNeed.iMax << " " <<
253 pProperty->sIndustry.mmProvide.iMin << "-" << pProperty->sIndustry.mmProvide.iMax << " / " <<
254 endl <<
255 "w/e/g: " <<
256 pProperty->sWater.mmNeed.iMin << "-" << pProperty->sWater.mmNeed.iMax << " " <<
257 pProperty->sWater.mmProvide.iMin << "-" << pProperty->sWater.mmProvide.iMax << " / " <<
258 pProperty->sElectricity.mmNeed.iMin << "-" << pProperty->sElectricity.mmNeed.iMax << " " <<
259 pProperty->sElectricity.mmProvide.iMin << "-" << pProperty->sElectricity.mmProvide.iMax << " / " <<
260 pProperty->sGas.mmNeed.iMin << "-" << pProperty->sGas.mmNeed.iMax << " " <<
261 pProperty->sGas.mmProvide.iMin << "-" << pProperty->sGas.mmProvide.iMax << " / " <<
262 endl <<
263 "t/n: " <<
264 pProperty->sTraffic.mmNeed.iMin << "-" << pProperty->sTraffic.mmNeed.iMax << " " <<
265 pProperty->sTraffic.mmProvide.iMin << "-" << pProperty->sTraffic.mmProvide.iMax << " / " <<
266 pProperty->sNature.mmNeed.iMin << "-" << pProperty->sNature.mmNeed.iMax << " " <<
267 pProperty->sNature.mmProvide.iMin << "-" << pProperty->sNature.mmProvide.iMax
268 );
269 */
270
271 return pProperty;
272 }
273
274
275 /*=====================================================================*/
276 const OPENCITY_STRUCTURE_TYPE
_Str2Type(const string & rcstrType)277 Property::_Str2Type(const string& rcstrType)
278 {
279 OPENCITY_STRUCTURE_TYPE type = OC_TYPE_UNDEFINED;
280
281 if (rcstrType =="r") type = OC_TYPE_RESIDENCE; else
282 if (rcstrType =="c") type = OC_TYPE_COMMERCE; else
283 if (rcstrType =="i") type = OC_TYPE_INDUSTRY; else
284 if (rcstrType =="w") type = OC_TYPE_WATER; else
285 if (rcstrType =="e") type = OC_TYPE_ELECTRICITY; else
286 if (rcstrType =="g") type = OC_TYPE_GAS; else
287 if (rcstrType =="government") type = OC_TYPE_GOVERNMENT; else
288 if (rcstrType =="path") type = OC_TYPE_PATH; else
289 if (rcstrType =="tree") type = OC_TYPE_TREE; else
290 if (rcstrType =="vehicle") type = OC_TYPE_VEHICLE;
291
292 return type;
293 }
294
295
296 /*=====================================================================*/
297 const OPENCITY_DIRECTION
_Str2Direction(const string & rcstrDir)298 Property::_Str2Direction(const string& rcstrDir)
299 {
300 OPENCITY_DIRECTION dir = OC_DIR_UNDEFINED;
301
302 if (rcstrDir == "on") dir = OC_DIR_O_N; else
303 if (rcstrDir == "oe") dir = OC_DIR_O_E; else
304 if (rcstrDir == "os") dir = OC_DIR_O_S; else
305 if (rcstrDir == "ow") dir = OC_DIR_O_W; else
306 if (rcstrDir == "sn") dir = OC_DIR_S_N; else
307 if (rcstrDir == "we") dir = OC_DIR_W_E; else
308 if (rcstrDir == "ne") dir = OC_DIR_N_E; else
309 if (rcstrDir == "nw") dir = OC_DIR_N_W; else
310 if (rcstrDir == "se") dir = OC_DIR_S_E; else
311 if (rcstrDir == "sw") dir = OC_DIR_S_W; else
312 if (rcstrDir == "sne") dir = OC_DIR_S_N_E; else
313 if (rcstrDir == "swe") dir = OC_DIR_S_W_E; else
314 if (rcstrDir == "snw") dir = OC_DIR_S_N_W; else
315 if (rcstrDir == "nwe") dir = OC_DIR_N_W_E; else
316 if (rcstrDir == "snwe") dir = OC_DIR_S_N_W_E;
317
318 return dir;
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354