1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Date started: 09/28/2004
5 Purpose: XML element class
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
12 #include "FGXMLElement.h"
15 # include <simgear/compiler.h>
17 # ifdef SG_HAVE_STD_INCLUDES
25 # if defined (sgi) && !defined(__GNUC__)
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
43 static const char *IdSrc = "$Id$";
44 static const char *IdHdr = ID_XMLELEMENT;
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50 Element::Element(string nm)
56 // convert ["from"]["to"] = factor, so: from * factor = to
57 convert["M"]["FT"] = 3.2808399;
58 convert["FT"]["M"] = 1.0/convert["M"]["FT"];
59 convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
60 convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
61 convert["FT"]["IN"] = 12.0;
62 convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
63 convert["LBS"]["KG"] = 0.45359237;
64 convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
65 convert["SLUG*FT2"]["KG*M2"] = 1.35594;
66 convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
67 convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
68 convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
69 convert["LBS/FT"]["N/M"] = 14.5939;
70 convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
71 convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
72 convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
73 convert["WATTS"]["HP"] = 0.001341022;
74 convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
75 convert["N"]["LBS"] = 0.22482;
76 convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
77 convert["KTS"]["FT/SEC"] = 1.68781;
78 convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
79 convert["FT*LBS"]["N*M"] = 1.35581795;
80 convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
82 convert["M"]["M"] = 1.00;
83 convert["FT"]["FT"] = 1.00;
84 convert["IN"]["IN"] = 1.00;
85 convert["IN3"]["IN3"] = 1.00;
86 convert["DEG"]["DEG"] = 1.00;
87 convert["RAD"]["RAD"] = 1.00;
88 convert["M2"]["M2"] = 1.00;
89 convert["FT2"]["FT2"] = 1.00;
90 convert["KG*M2"]["KG*M2"] = 1.00;
91 convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
92 convert["KG"]["KG"] = 1.00;
93 convert["LBS"]["LBS"] = 1.00;
94 convert["LBS/FT"]["LBS/FT"] = 1.00;
95 convert["LBS/SEC"]["LBS/SEC"] = 1.00;
96 convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
97 convert["N/M"]["N/M"] = 1.00;
98 convert["N/M/SEC"]["N/M/SEC"] = 1.00;
99 convert["PSI"]["PSI"] = 1.00;
100 convert["PSF"]["PSF"] = 1.00;
101 convert["INHG"]["INHG"] = 1.00;
102 convert["HP"]["HP"] = 1.00;
103 convert["N"]["N"] = 1.00;
104 convert["WATTS"]["WATTS"] = 1.00;
105 convert["LBS/SEC"]["LBS/SEC"] = 1.00;
106 convert["FT/SEC"]["FT/SEC"] = 1.00;
107 convert["KTS"]["KTS"] = 1.00;
108 convert["FT*LBS"]["FT*LBS"] = 1.00;
109 convert["N*M"]["N*M"] = 1.00;
112 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 Element::~Element(void)
116 for (int i=0; i<children.size(); i++) delete children[i];
119 attribute_key.clear();
122 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124 string Element::GetAttributeValue(string attr)
127 for (int i=0; i<attribute_key.size(); i++) {
128 if (attribute_key[i] == attr) select = i;
130 if (select < 0) return string("");
131 else return attributes[attr];
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 double Element::GetAttributeValueAsNumber(string attr)
138 string attribute = GetAttributeValue(attr);
140 if (attribute.empty()) return 99e99;
141 else return (atof(attribute.c_str()));
144 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 Element* Element::GetElement(int el)
148 if (children.size() > el) {
158 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 Element* Element::GetNextElement(void)
162 if (children.size() > element_index+1) {
164 return children[element_index];
171 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 string Element::GetDataLine(int i)
175 if (data_lines.size() > 0) return data_lines[i];
176 else return string("");
179 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 double Element::GetDataAsNumber(void)
183 if (data_lines.size() == 1) {
184 return atof(data_lines[0].c_str());
190 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 int Element::GetNumElements(string element_name)
194 int number_of_elements=0;
195 Element* el=FindElement(element_name);
197 number_of_elements++;
198 el=FindNextElement(element_name);
200 return number_of_elements;
203 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 Element* Element::FindElement(string el)
207 if (el.empty() && children.size() >= 1) {
211 for (int i=0; i<children.size(); i++) {
212 if (el == children[i]->GetName()) {
221 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223 Element* Element::FindNextElement(string el)
226 if (element_index < children.size()) {
227 return children[element_index++];
233 for (int i=element_index; i<children.size(); i++) {
234 if (el == children[i]->GetName()) {
243 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 double Element::FindElementValueAsNumber(string el)
247 Element* element = FindElement(el);
249 return element->GetDataAsNumber();
255 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257 string Element::FindElementValue(string el)
259 Element* element = FindElement(el);
261 return element->GetDataLine();
267 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 double Element::FindElementValueAsNumberConvertTo(string el, string target_units)
271 Element* element = FindElement(el);
273 string supplied_units="";
276 value = element->GetDataAsNumber();
277 supplied_units = element->GetAttributeValue("unit");
278 if (!supplied_units.empty()) {
279 if (convert.find(supplied_units) != convert.end()) {
280 if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
281 value *= convert[supplied_units][target_units];
283 cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
284 << " conversion in FGXMLElement.cpp." << endl;
288 cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
289 << " conversion in FGXMLElement.cpp." << endl;
299 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 double Element::FindElementValueAsNumberConvertFromTo( string el,
302 string supplied_units,
305 Element* element = FindElement(el);
309 value = element->GetDataAsNumber();
310 if (!supplied_units.empty()) {
311 if (convert.find(supplied_units) != convert.end()) {
312 if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
313 value *= convert[supplied_units][target_units];
315 cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
316 << " conversion in FGXMLElement.cpp." << endl;
320 cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
321 << " conversion in FGXMLElement.cpp." << endl;
331 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333 FGColumnVector3 Element::FindElementTripletConvertTo( string target_units)
335 FGColumnVector3 triplet;
338 string supplied_units = GetAttributeValue("unit");
340 item = FindElement("x");
341 if (!item) item = FindElement("roll");
343 value = item->GetDataAsNumber();
344 if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
347 cerr << "Could not find an X triplet item for this column vector." << endl;
351 item = FindElement("y");
352 if (!item) item = FindElement("pitch");
354 value = item->GetDataAsNumber();
355 if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
358 cerr << "Could not find a Y triplet item for this column vector." << endl;
362 item = FindElement("z");
363 if (!item) item = FindElement("yaw");
365 value = item->GetDataAsNumber();
366 if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
369 cerr << "Could not find a Z triplet item for this column vector." << endl;
376 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 void Element::Print(int level)
383 for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
384 cout << "Element Name: " << name;
385 for (i=0; i<attributes.size(); i++) {
386 cout << " " << attribute_key[i] << " = " << attributes[attribute_key[i]];
389 for (i=0; i<data_lines.size(); i++) {
390 for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
391 cout << data_lines[i] << endl;
393 for (i=0; i<children.size(); i++) {
394 children[i]->Print(level);
398 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 void Element::AddAttribute(string name, string value)
402 attribute_key.push_back(name);
403 attributes[name] = value;
406 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 void Element::AddData(string d)
410 int string_start = d.find_first_not_of(" \t");
411 if (string_start > 0) {
412 d.erase(0,string_start);
414 data_lines.push_back(d);
417 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419 } // end namespace JSBSim