Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2025 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>
31#include <utils/geom/Boundary.h>
33#include "SUMOSAXAttributes.h"
34
35
36// ===========================================================================
37// static members
38// ===========================================================================
39const std::string SUMOSAXAttributes::ENCODING = " encoding=\"UTF-8\"";
40
41
42// ===========================================================================
43// method definitions
44// ===========================================================================
45SUMOSAXAttributes::SUMOSAXAttributes(const std::string& objectType):
46 myObjectType(objectType) {}
47
48
49const std::string invalid_return<std::string>::value = "";
50template<>
51std::string SUMOSAXAttributes::fromString(const std::string& value) const {
52 if (value == "") {
53 throw EmptyData();
54 }
55 return value;
56}
57
58
60SUMOSAXAttributes::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
88SUMOSAXAttributes::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'
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
123SUMOSAXAttributes::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
147SUMOSAXAttributes::getOptOffsetReporting(int attr, const char* objectid,
148 bool& ok, SUMOTime defaultValue, bool report) const {
149 try {
150 bool isPresent = true;
151 const std::string& val = getString(attr, &isPresent);
152 if (!isPresent) {
153 return defaultValue;
154 }
155 if (val == "begin") {
156 return SUMOTime_MAX;
157 } else {
158 return string2time(val);
159 }
160 } catch (EmptyData&) {
161 if (report) {
162 emitEmptyError(getName(attr), objectid);
163 }
164 } catch (ProcessError&) {
165 if (report) {
166 emitFormatError(getName(attr), "is not a valid time value", objectid);
167 }
168 }
169 ok = false;
170 return -1;
171}
172
173
175SUMOSAXAttributes::getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report) const {
176 int attr = SUMO_ATTR_PERIOD;
177 try {
178 bool isPresent = true;
179 const std::string& val = getString(attr, &isPresent);
180 if (!isPresent) {
181 // try 'freq' as alias for 'period'
182 attr = SUMO_ATTR_FREQUENCY;
183 isPresent = true;
184 const std::string& valFreq = getString(attr, &isPresent);
185 if (!isPresent) {
186 return defaultValue;
187 }
188 return string2time(valFreq);
189 }
190 return string2time(val);
191 } catch (EmptyData&) {
192 if (report) {
193 emitEmptyError(getName(attr), objectid);
194 }
195 } catch (ProcessError&) {
196 if (report) {
197 emitFormatError(getName(attr), "is not a valid time value", objectid);
198 }
199 }
200 ok = false;
201 return -1;
202}
203
204
205void
206SUMOSAXAttributes::emitUngivenError(const std::string& attrname, const char* objectid) const {
207 std::ostringstream oss;
208 oss << "Attribute '" << attrname << "' is missing in definition of ";
209 if (objectid == nullptr || objectid[0] == 0) {
210 oss << "a " << myObjectType;
211 } else {
212 oss << myObjectType << " '" << objectid << "'";
213 }
214 oss << ".";
215 WRITE_ERROR(oss.str());
216}
217
218
219void
220SUMOSAXAttributes::emitEmptyError(const std::string& attrname, const char* objectid) const {
221 std::ostringstream oss;
222 oss << "Attribute '" << attrname << "' in definition of ";
223 if (objectid == nullptr || objectid[0] == 0) {
224 oss << "a " << myObjectType;
225 } else {
226 oss << myObjectType << " '" << objectid << "'";
227 }
228 oss << " is empty.";
229 WRITE_ERROR(oss.str());
230}
231
232
233void
234SUMOSAXAttributes::emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const {
235 std::ostringstream oss;
236 oss << "Attribute '" << attrname << "' in definition of ";
237 if (objectid == nullptr || objectid[0] == 0) {
238 oss << "a " << myObjectType;
239 } else {
240 oss << myObjectType << " '" << objectid << "'";
241 }
242 oss << " " << type << ".";
243 WRITE_ERROR(oss.str());
244}
245
246
247const int invalid_return<int>::value = -1;
248template<>
249int SUMOSAXAttributes::fromString(const std::string& value) const {
250 return StringUtils::toInt(value);
251}
252
253
254const long long int invalid_return<long long int>::value = -1;
255template<>
256long long int SUMOSAXAttributes::fromString(const std::string& value) const {
257 return StringUtils::toLong(value);
258}
259
260
261const double invalid_return<double>::value = -1;
262template<>
263double SUMOSAXAttributes::fromString(const std::string& value) const {
264 return StringUtils::toDouble(value);
265}
266
267
268const bool invalid_return<bool>::value = false;
269template<>
270bool SUMOSAXAttributes::fromString(const std::string& value) const {
271 return StringUtils::toBool(value);
272}
273
274
276template<>
277RGBColor SUMOSAXAttributes::fromString(const std::string& value) const {
278 return RGBColor::parseColor(value);
279}
280
281
283template<>
284Position SUMOSAXAttributes::fromString(const std::string& value) const {
285 StringTokenizer st(value);
286 // check StringTokenizer
287 while (st.hasNext()) {
288 // obtain position
289 StringTokenizer pos(st.next(), ",");
290 // check that position has X-Y or X-Y-Z
291 if ((pos.size() != 2) && (pos.size() != 3)) {
292 throw FormatException("is not a valid position");
293 }
294 // obtain x and y
295 double x = StringUtils::toDouble(pos.next());
296 double y = StringUtils::toDouble(pos.next());
297 // check if return a X-Y or a X-Y-Z Position
298 if (pos.size() == 2) {
299 return Position(x, y);
300 } else {
301 // obtain z
302 double z = StringUtils::toDouble(pos.next());
303 return Position(x, y, z);
304 }
305 }
306 // empty positions aren't allowed
307 throw FormatException("is not a valid position");
308}
309
310
312template<>
313PositionVector SUMOSAXAttributes::fromString(const std::string& value) const {
314 StringTokenizer st(value);
315 PositionVector shape;
316 while (st.hasNext()) {
317 StringTokenizer pos(st.next(), ",");
318 if (pos.size() != 2 && pos.size() != 3) {
319 throw FormatException("is not a valid list of positions");
320 }
321 double x = StringUtils::toDouble(pos.next());
322 double y = StringUtils::toDouble(pos.next());
323 if (pos.size() == 2) {
324 shape.push_back(Position(x, y));
325 } else {
326 double z = StringUtils::toDouble(pos.next());
327 shape.push_back(Position(x, y, z));
328 }
329 }
330 return shape;
331}
332
333
335template<>
336Boundary SUMOSAXAttributes::fromString(const std::string& value) const {
337 StringTokenizer st(value, ",");
338 if (st.size() != 4) {
339 throw FormatException("is not a valid boundary");
340 }
341 const double xmin = StringUtils::toDouble(st.next());
342 const double ymin = StringUtils::toDouble(st.next());
343 const double xmax = StringUtils::toDouble(st.next());
344 const double ymax = StringUtils::toDouble(st.next());
345 return Boundary(xmin, ymin, xmax, ymax);
346}
347
348
350template<>
351SumoXMLEdgeFunc SUMOSAXAttributes::fromString(const std::string& value) const {
352 if (SUMOXMLDefinitions::EdgeFunctions.hasString(value)) {
354 }
355 throw FormatException("is not a valid edge function");
356}
357
358
360template<>
361SumoXMLNodeType SUMOSAXAttributes::fromString(const std::string& value) const {
362 if (SUMOXMLDefinitions::NodeTypes.hasString(value)) {
364 }
365 throw FormatException("is not a valid node type");
366}
367
368
370template<>
371RightOfWay SUMOSAXAttributes::fromString(const std::string& value) const {
372 if (SUMOXMLDefinitions::RightOfWayValues.hasString(value)) {
374 }
375 throw FormatException("is not a valid right of way value");
376}
377
378
380template<>
381FringeType SUMOSAXAttributes::fromString(const std::string& value) const {
382 if (SUMOXMLDefinitions::FringeTypeValues.hasString(value)) {
384 }
385 throw FormatException("is not a valid fringe type");
386}
387
388
390template<>
391ParkingType SUMOSAXAttributes::fromString(const std::string& value) const {
392 if (value == toString(ParkingType::OPPORTUNISTIC)) {
394 } else {
396 }
397}
398
399
400const std::vector<std::string> invalid_return<std::vector<std::string> >::value = std::vector<std::string>();
401template<>
402std::vector<std::string> SUMOSAXAttributes::fromString(const std::string& value) const {
403 const std::vector<std::string>& ret = StringTokenizer(value).getVector();
404 if (ret.empty()) {
405 throw EmptyData();
406 }
407 return ret;
408}
409
410
411const std::vector<int> invalid_return<std::vector<int> >::value = std::vector<int>();
412template<>
413std::vector<int> SUMOSAXAttributes::fromString(const std::string& value) const {
414 const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
415 if (tmp.empty()) {
416 throw EmptyData();
417 }
418 std::vector<int> ret;
419 for (const std::string& s : tmp) {
420 ret.push_back(StringUtils::toInt(s));
421 }
422 return ret;
423}
424
425
426const std::vector<double> invalid_return<std::vector<double> >::value = std::vector<double>();
427template<>
428std::vector<double> SUMOSAXAttributes::fromString(const std::string& value) const {
429 const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
430 if (tmp.empty()) {
431 throw EmptyData();
432 }
433 std::vector<double> ret;
434 for (const std::string& s : tmp) {
435 ret.push_back(StringUtils::toDouble(s));
436 }
437 return ret;
438}
439
440/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define SUMOTime_MAX
Definition SUMOTime.h:34
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 getOptOffsetReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a tls offset (SUMOTime or "begin")
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
get key
int size() const
returns the number of existing substrings
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
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