Eclipse SUMO - Simulation of Urban MObility
SUMOSAXAttributes.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2007-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Encapsulated SAX-Attributes
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <string>
25 #include <iostream>
26 #include <sstream>
28 #include <utils/common/RGBColor.h>
31 #include <utils/geom/Boundary.h>
33 #include "SUMOSAXAttributes.h"
34 
35 
36 // ===========================================================================
37 // static members
38 // ===========================================================================
39 const std::string SUMOSAXAttributes::ENCODING = " encoding=\"UTF-8\"";
40 
41 
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
45 SUMOSAXAttributes::SUMOSAXAttributes(const std::string& objectType):
46  myObjectType(objectType) {}
47 
48 
49 const std::string invalid_return<std::string>::value = "";
50 template<>
51 std::string SUMOSAXAttributes::fromString(const std::string& value) const {
52  if (value == "") {
53  throw EmptyData();
54  }
55  return value;
56 }
57 
58 
60 SUMOSAXAttributes::getSUMOTimeReporting(int attr, const char* objectid,
61  bool& ok, bool report) const {
62  try {
63  bool isPresent = true;
64  const std::string& val = getString(attr, &isPresent);
65  if (!isPresent) {
66  if (report) {
67  emitUngivenError(getName(attr), objectid);
68  }
69  ok = false;
70  return -1;
71  }
72  return string2time(val);
73  } catch (EmptyData&) {
74  if (report) {
75  emitEmptyError(getName(attr), objectid);
76  }
77  } catch (ProcessError&) {
78  if (report) {
79  emitFormatError(getName(attr), "is not a valid time value", objectid);
80  }
81  }
82  ok = false;
83  return -1;
84 }
85 
86 
88 SUMOSAXAttributes::getPeriod(const char* objectid, bool& ok, bool report) const {
89  int attr = SUMO_ATTR_PERIOD;
90  try {
91  bool isPresent = true;
92  const std::string& val = getString(attr, &isPresent);
93  if (!isPresent) {
94  // try 'freq' as alias for 'period'
95  attr = SUMO_ATTR_FREQUENCY;
96  isPresent = true;
97  const std::string& valFreq = getString(attr, &isPresent);
98  if (!isPresent) {
99  if (report) {
101  }
102  ok = false;
103  return -1;
104  }
105  return string2time(valFreq);
106  }
107  return string2time(val);
108  } catch (EmptyData&) {
109  if (report) {
110  emitEmptyError(getName(attr), objectid);
111  }
112  } catch (ProcessError&) {
113  if (report) {
114  emitFormatError(getName(attr), "is not a valid time value", objectid);
115  }
116  }
117  ok = false;
118  return -1;
119 }
120 
121 
122 SUMOTime
123 SUMOSAXAttributes::getOptSUMOTimeReporting(int attr, const char* objectid,
124  bool& ok, SUMOTime defaultValue, bool report) const {
125  try {
126  bool isPresent = true;
127  const std::string& val = getString(attr, &isPresent);
128  if (!isPresent) {
129  return defaultValue;
130  }
131  return string2time(val);
132  } catch (EmptyData&) {
133  if (report) {
134  emitEmptyError(getName(attr), objectid);
135  }
136  } catch (ProcessError&) {
137  if (report) {
138  emitFormatError(getName(attr), "is not a valid time value", objectid);
139  }
140  }
141  ok = false;
142  return -1;
143 }
144 
145 
146 SUMOTime
147 SUMOSAXAttributes::getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report) const {
148  int attr = SUMO_ATTR_PERIOD;
149  try {
150  bool isPresent = true;
151  const std::string& val = getString(attr, &isPresent);
152  if (!isPresent) {
153  // try 'freq' as alias for 'period'
154  attr = SUMO_ATTR_FREQUENCY;
155  isPresent = true;
156  const std::string& valFreq = getString(attr, &isPresent);
157  if (!isPresent) {
158  return defaultValue;
159  }
160  return string2time(valFreq);
161  }
162  return string2time(val);
163  } catch (EmptyData&) {
164  if (report) {
165  emitEmptyError(getName(attr), objectid);
166  }
167  } catch (ProcessError&) {
168  if (report) {
169  emitFormatError(getName(attr), "is not a valid time value", objectid);
170  }
171  }
172  ok = false;
173  return -1;
174 }
175 
176 
177 void
178 SUMOSAXAttributes::emitUngivenError(const std::string& attrname, const char* objectid) const {
179  std::ostringstream oss;
180  oss << "Attribute '" << attrname << "' is missing in definition of ";
181  if (objectid == nullptr || objectid[0] == 0) {
182  oss << "a " << myObjectType;
183  } else {
184  oss << myObjectType << " '" << objectid << "'";
185  }
186  oss << ".";
187  WRITE_ERROR(oss.str());
188 }
189 
190 
191 void
192 SUMOSAXAttributes::emitEmptyError(const std::string& attrname, const char* objectid) const {
193  std::ostringstream oss;
194  oss << "Attribute '" << attrname << "' in definition of ";
195  if (objectid == nullptr || objectid[0] == 0) {
196  oss << "a " << myObjectType;
197  } else {
198  oss << myObjectType << " '" << objectid << "'";
199  }
200  oss << " is empty.";
201  WRITE_ERROR(oss.str());
202 }
203 
204 
205 void
206 SUMOSAXAttributes::emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const {
207  std::ostringstream oss;
208  oss << "Attribute '" << attrname << "' in definition of ";
209  if (objectid == nullptr || objectid[0] == 0) {
210  oss << "a " << myObjectType;
211  } else {
212  oss << myObjectType << " '" << objectid << "'";
213  }
214  oss << " " << type << ".";
215  WRITE_ERROR(oss.str());
216 }
217 
218 
219 const int invalid_return<int>::value = -1;
220 template<>
221 int SUMOSAXAttributes::fromString(const std::string& value) const {
222  return StringUtils::toInt(value);
223 }
224 
225 
226 const long long int invalid_return<long long int>::value = -1;
227 template<>
228 long long int SUMOSAXAttributes::fromString(const std::string& value) const {
229  return StringUtils::toLong(value);
230 }
231 
232 
233 const double invalid_return<double>::value = -1;
234 template<>
235 double SUMOSAXAttributes::fromString(const std::string& value) const {
236  return StringUtils::toDouble(value);
237 }
238 
239 
240 const bool invalid_return<bool>::value = false;
241 template<>
242 bool SUMOSAXAttributes::fromString(const std::string& value) const {
243  return StringUtils::toBool(value);
244 }
245 
246 
248 template<>
249 RGBColor SUMOSAXAttributes::fromString(const std::string& value) const {
250  return RGBColor::parseColor(value);
251 }
252 
253 
255 template<>
256 Position SUMOSAXAttributes::fromString(const std::string& value) const {
257  StringTokenizer st(value);
258  // check StringTokenizer
259  while (st.hasNext()) {
260  // obtain position
261  StringTokenizer pos(st.next(), ",");
262  // check that position has X-Y or X-Y-Z
263  if ((pos.size() != 2) && (pos.size() != 3)) {
264  throw FormatException("is not a valid position");
265  }
266  // obtain x and y
267  double x = StringUtils::toDouble(pos.next());
268  double y = StringUtils::toDouble(pos.next());
269  // check if return a X-Y or a X-Y-Z Position
270  if (pos.size() == 2) {
271  return Position(x, y);
272  } else {
273  // obtain z
274  double z = StringUtils::toDouble(pos.next());
275  return Position(x, y, z);
276  }
277  }
278  // empty positions aren't allowed
279  throw FormatException("is not a valid position");
280 }
281 
282 
284 template<>
285 PositionVector SUMOSAXAttributes::fromString(const std::string& value) const {
286  StringTokenizer st(value);
287  PositionVector shape;
288  while (st.hasNext()) {
289  StringTokenizer pos(st.next(), ",");
290  if (pos.size() != 2 && pos.size() != 3) {
291  throw FormatException("is not a valid list of positions");
292  }
293  double x = StringUtils::toDouble(pos.next());
294  double y = StringUtils::toDouble(pos.next());
295  if (pos.size() == 2) {
296  shape.push_back(Position(x, y));
297  } else {
298  double z = StringUtils::toDouble(pos.next());
299  shape.push_back(Position(x, y, z));
300  }
301  }
302  return shape;
303 }
304 
305 
307 template<>
308 Boundary SUMOSAXAttributes::fromString(const std::string& value) const {
309  StringTokenizer st(value, ",");
310  if (st.size() != 4) {
311  throw FormatException("is not a valid boundary");
312  }
313  const double xmin = StringUtils::toDouble(st.next());
314  const double ymin = StringUtils::toDouble(st.next());
315  const double xmax = StringUtils::toDouble(st.next());
316  const double ymax = StringUtils::toDouble(st.next());
317  return Boundary(xmin, ymin, xmax, ymax);
318 }
319 
320 
322 template<>
323 SumoXMLEdgeFunc SUMOSAXAttributes::fromString(const std::string& value) const {
324  if (SUMOXMLDefinitions::EdgeFunctions.hasString(value)) {
326  }
327  throw FormatException("is not a valid edge function");
328 }
329 
330 
332 template<>
333 SumoXMLNodeType SUMOSAXAttributes::fromString(const std::string& value) const {
334  if (SUMOXMLDefinitions::NodeTypes.hasString(value)) {
335  return SUMOXMLDefinitions::NodeTypes.get(value);
336  }
337  throw FormatException("is not a valid node type");
338 }
339 
340 
342 template<>
343 RightOfWay SUMOSAXAttributes::fromString(const std::string& value) const {
344  if (SUMOXMLDefinitions::RightOfWayValues.hasString(value)) {
346  }
347  throw FormatException("is not a valid right of way value");
348 }
349 
350 
352 template<>
353 FringeType SUMOSAXAttributes::fromString(const std::string& value) const {
354  if (SUMOXMLDefinitions::FringeTypeValues.hasString(value)) {
356  }
357  throw FormatException("is not a valid fringe type");
358 }
359 
360 
362 template<>
363 ParkingType SUMOSAXAttributes::fromString(const std::string& value) const {
364  if (value == toString(ParkingType::OPPORTUNISTIC)) {
366  } else {
368  }
369 }
370 
371 
372 const std::vector<std::string> invalid_return<std::vector<std::string> >::value = std::vector<std::string>();
373 template<>
374 std::vector<std::string> SUMOSAXAttributes::fromString(const std::string& value) const {
375  const std::vector<std::string>& ret = StringTokenizer(value).getVector();
376  if (ret.empty()) {
377  throw EmptyData();
378  }
379  return ret;
380 }
381 
382 
383 const std::vector<int> invalid_return<std::vector<int> >::value = std::vector<int>();
384 template<>
385 std::vector<int> SUMOSAXAttributes::fromString(const std::string& value) const {
386  const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
387  if (tmp.empty()) {
388  throw EmptyData();
389  }
390  std::vector<int> ret;
391  for (const std::string& s : tmp) {
392  ret.push_back(StringUtils::toInt(s));
393  }
394  return ret;
395 }
396 
397 
398 const std::vector<double> invalid_return<std::vector<double> >::value = std::vector<double>();
399 template<>
400 std::vector<double> SUMOSAXAttributes::fromString(const std::string& value) const {
401  const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
402  if (tmp.empty()) {
403  throw EmptyData();
404  }
405  std::vector<double> ret;
406  for (const std::string& s : tmp) {
407  ret.push_back(StringUtils::toDouble(s));
408  }
409  return ret;
410 }
411 
412 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
ParkingType
Numbers representing special SUMO-XML-attribute values Information on whether a car is parking on the...
FringeType
classifying boundary nodes
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
RightOfWay
algorithms for computing right of way
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_FREQUENCY
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:239
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOTime getOptPeriod(const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read the SUMOTime 'period' attribute.
T fromString(const std::string &value) const
SUMOSAXAttributes(const std::string &objectType)
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
void emitFormatError(const std::string &attrname, const std::string &type, const char *objectid) const
virtual std::string getName(int attr) const =0
Converts the given attribute id into a man readable string.
void emitEmptyError(const std::string &attrname, const char *objectid) const
std::string myObjectType
the object type to use in error reporting
static const std::string ENCODING
The encoding of parsed strings.
void emitUngivenError(const std::string &attrname, const char *objectid) const
SUMOTime getPeriod(const char *objectid, bool &ok, bool report=true) const
Tries to read the SUMOTime 'period' attribute.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
static StringBijection< SumoXMLNodeType > NodeTypes
node types
static StringBijection< SumoXMLEdgeFunc > EdgeFunctions
edge functions
static StringBijection< RightOfWay > RightOfWayValues
righ of way algorithms
static StringBijection< FringeType > FringeTypeValues
fringe types
T get(const std::string &str) const
std::vector< std::string > getVector()
return vector of strings
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter