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