Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
CommonHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-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/****************************************************************************/
18// Collection of functions used in handlers
19/****************************************************************************/
20#include <config.h>
21
24#include <utils/xml/XMLSubSys.h>
25
26#include "CommonHandler.h"
27
28
29// ===========================================================================
30// method definitions
31// ===========================================================================
32
33CommonHandler::CommonHandler(const std::string& filename) :
34 myFilename(filename) {
35}
36
37
39
40
41void
45
46
47void
51
52
53void
57
58
59bool
63
64
65bool
69
70
71bool
75
76
77bool
81
82
83void
85 // declare Ok Flag
86 bool parsedOk = true;
87 // get key
88 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, parsedOk);
89 // get SumoBaseObject parent
91 // check parent
92 if ((SumoBaseObjectParent == nullptr) || (SumoBaseObjectParent->getTag() == SUMO_TAG_ROOTFILE)) {
93 writeError(TL("Parameters must be defined within an object"));
94 } else if (SumoBaseObjectParent->getTag() == SUMO_TAG_PARAM) {
95 writeError(TL("Parameters cannot be defined within another parameter."));
96 } else if ((SumoBaseObjectParent->getTag() != SUMO_TAG_ERROR) && parsedOk) {
97 // get tag str
98 const std::string parentTagStr = toString(SumoBaseObjectParent->getTag());
99 // circumventing empty string value
100 const std::string value = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
101 // show warnings if values are invalid
102 if (key.empty()) {
103 writeError(TLF("Error parsing key from % generic parameter. Key cannot be empty", parentTagStr));
105 writeError(TLF("Error parsing key from % generic parameter. Key contains invalid characters", parentTagStr));
106 } else {
107 // insert parameter in SumoBaseObjectParent
108 SumoBaseObjectParent->addParameter(key, value);
109 }
110 }
111}
112
113
116 // locate route in childrens
117 for (const auto& embeddedRoute : sumoBaseObject->getSumoBaseObjectChildren()) {
118 if ((embeddedRoute->getTag() == SUMO_TAG_ROUTE) && (!embeddedRoute->hasStringAttribute(SUMO_ATTR_ID))) {
119 return embeddedRoute;
120 }
121 }
122 return nullptr;
123}
124
125
126void
127CommonHandler::checkParsedParent(const SumoXMLTag currentTag, const std::vector<SumoXMLTag>& parentTags, bool& ok) {
128 if (parentTags.size() > 0) {
129 std::string tagsStr;
130 for (auto it = parentTags.begin(); it != parentTags.end(); it++) {
131 tagsStr.append(toString(*it));
132 if ((it + 1) != parentTags.end()) {
133 if ((it + 2) != parentTags.end()) {
134 tagsStr.append(", ");
135 } else {
136 tagsStr.append(" or ");
137 }
138 }
139 }
140 // obtain parent
142 if (parent == nullptr) {
143 ok = writeError(TLF("'%' must be defined within the definition of a %.", toString(currentTag), tagsStr));
144 } else if ((parent->getTag() != SUMO_TAG_ERROR) && std::find(parentTags.begin(), parentTags.end(), parent->getTag()) == parentTags.end()) {
145 if (parent->hasStringAttribute(SUMO_ATTR_ID)) {
146 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found % '%').", toString(currentTag), tagsStr,
147 toString(parent->getTag()), parent->getStringAttribute(SUMO_ATTR_ID)));
148 } else {
149 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found %).", toString(currentTag), tagsStr,
150 toString(parent->getTag())));
151 }
152 }
153 }
154}
155
156
157bool
158CommonHandler::checkListOfVehicleTypes(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& vTypeIDs) {
159 for (const auto& vTypeID : vTypeIDs) {
160 if (!SUMOXMLDefinitions::isValidTypeID(vTypeID)) {
161 return writeError(TLF("Could not build % with ID '%' in netedit; '%' ist not a valid vType ID.", toString(tag), id, vTypeID));
162 }
163 }
164 return true;
165}
166
167
168bool
170 if (obj->getParentSumoBaseObject() == nullptr) {
171 return false;
173 return true;
175 return true;
176 } else {
177 return false;
178 }
179}
180
181
182bool
184 if (obj == nullptr) {
185 return false;
186 } else if (!obj->hasStringAttribute(SUMO_ATTR_ID)) {
187 return false;
188 } else {
189 SumoXMLTag tag = obj->getTag();
190 const std::string id = obj->getStringAttribute(SUMO_ATTR_ID);
191 const bool hasRoute = obj->hasStringAttribute(SUMO_ATTR_ROUTE);
192 const bool hasEmbeddedRoute = (getEmbeddedRoute(obj) != nullptr);
193 const bool overEdges = obj->hasStringAttribute(SUMO_ATTR_FROM) && obj->hasStringAttribute(SUMO_ATTR_TO);
196 if (hasRoute && hasEmbeddedRoute) {
197 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have an external route and an embedded route in the same definition.", toString(tag), id));
198 }
199 if ((overEdges + overJunctions + overTAZs) > 1) {
200 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have multiple from-to attributes.", toString(tag), id));
201 }
202 if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) > 1) {
203 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have from-to attributes and route attributes in the same definition.", toString(tag), id));
204 }
205 if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) == 0) {
206 return writeError(TLF("Could not build % with ID '%' in netedit; Requires either a route or an embedded route or a from-to attribute (Edges, junctions or TAZs).", toString(tag), id));
207 }
208 return true;
209 }
210}
211
212
213bool
215 const auto parent = obj->getParentSumoBaseObject();
216 if (parent == nullptr) {
217 return false;
218 } else if (!parent->wasCreated()) {
219 return false;
220 } else if ((parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW)) {
221 return true;
222 } else {
223 return false;
224 }
225}
226
227
228bool
230 const auto parent = obj->getParentSumoBaseObject();
231 if (parent == nullptr) {
232 return false;
233 } else if (!parent->wasCreated()) {
234 return false;
235 } else if ((parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
236 return true;
237 } else {
238 return false;
239 }
240}
241
242
243bool
245 const auto parent = obj->getParentSumoBaseObject();
246 if (parent == nullptr) {
247 return false;
248 } else if (!parent->wasCreated()) {
249 return false;
250 } else if ((parent->getTag() == SUMO_TAG_ROUTE) || (parent->getTag() == SUMO_TAG_TRIP) ||
251 (parent->getTag() == SUMO_TAG_VEHICLE) || (parent->getTag() == SUMO_TAG_FLOW) ||
252 (parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW) ||
253 (parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
254 return true;
255 } else {
256 return false;
257 }
258}
259
260
261bool
262CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const int value, const bool canBeZero) {
263 if (canBeZero) {
264 if (value < 0) {
265 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative.", toString(tag), id, toString(attribute)));
266 } else {
267 return true;
268 }
269 } else {
270 if (value <= 0) {
271 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero.", toString(tag), id, toString(attribute)));
272 } else {
273 return true;
274 }
275 }
276}
277
278
279bool
280CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const double value, const bool canBeZero) {
281 if (canBeZero) {
282 if (value < 0) {
283 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), toString(value)));
284 } else {
285 return true;
286 }
287 } else {
288 if (value <= 0) {
289 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), toString(value)));
290 } else {
291 return true;
292 }
293 }
294}
295
296
297bool
298CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const SUMOTime value, const bool canBeZero) {
299 if (canBeZero) {
300 if (value < 0) {
301 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), time2string(value)));
302 } else {
303 return true;
304 }
305 } else {
306 if (value <= 0) {
307 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), time2string(value)));
308 } else {
309 return true;
310 }
311 }
312}
313
314
315bool
316CommonHandler::checkFileName(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const std::string& value) {
318 return true;
319 } else {
320 return writeError(TLF("Could not build % with ID '%' in netedit; % is invalid % ()", toString(tag), id, toString(attribute), value));
321 }
322}
323
324
325bool
326CommonHandler::checkValidAdditionalID(const SumoXMLTag tag, const std::string& value) {
327 if (value.empty()) {
328 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
329 } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
330 return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
331 } else {
332 return true;
333 }
334}
335
336
337bool
338CommonHandler::checkValidDetectorID(const SumoXMLTag tag, const std::string& value) {
339 if (value.empty()) {
340 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
341 } else if (!SUMOXMLDefinitions::isValidDetectorID(value)) {
342 return writeError(TLF("Could not build % with ID '%' in netedit; detector ID contains invalid characters.", toString(tag), value));
343 } else {
344 return true;
345 }
346}
347
348
349bool
350CommonHandler::checkValidDemandElementID(const SumoXMLTag tag, const std::string& value) {
351 if (value.empty()) {
352 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
353 } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
354 return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
355 } else {
356 return true;
357 }
358}
359
360
361void
362CommonHandler::writeWarningOverwriting(const SumoXMLTag tag, const std::string& id) {
363 WRITE_WARNING(TLF("Overwriting % with ID '%'", toString(tag), id));
364}
365
366
367bool
368CommonHandler::writeWarningDuplicated(const SumoXMLTag tag, const std::string& id, const SumoXMLTag checkedTag) {
369 WRITE_WARNING(TLF("Could not build % with ID '%' in netedit; Found another % with the same ID.", toString(tag), id, toString(checkedTag)));
370 return false;
371}
372
373
374bool
375CommonHandler::writeError(const std::string& error) {
376 WRITE_ERROR(error);
378 return false;
379}
380
381
382bool
383CommonHandler::writeErrorInvalidPosition(const SumoXMLTag tag, const std::string& id) {
384 return writeError(TLF("Could not build % with ID '%' in netedit; Invalid position over lane.", toString(tag), id));
385}
386
387
388bool
389CommonHandler::writeErrorEmptyEdges(const SumoXMLTag tag, const std::string& id) {
390 return writeError(TLF("Could not build % with ID '%' in netedit; List of edges cannot be empty.", toString(tag), id));
391}
392
393
394bool
395CommonHandler::writeErrorInvalidLanes(const SumoXMLTag tag, const std::string& id) {
396 return writeError(TLF("Could not build % with ID '%' in netedit; List of lanes isn't valid.", toString(tag), id));
397}
398
399
400bool
401CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::string& id, const SumoXMLTag parentTag, const std::string& parentID) {
402 return writeError(TLF("Could not build % with ID '%' in netedit; % parent with ID '%' doesn't exist.", toString(tag), id, toString(parentTag), parentID));
403}
404
405
406bool
407CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const SumoXMLTag parentTag, const std::string& parentID) {
408 return writeError(TLF("Could not build % in netedit; % parent with ID '%' doesn't exist.", toString(tag), toString(parentTag), parentID));
409}
410
411
412bool
414 return writeError(TLF("Could not build % in netedit; % parent doesn't exist.", toString(tag), toString(parentTag)));
415}
416
417/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_ROOTFILE
root file
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_ROUTE
description of a route
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_ERROR
tag used for indicate that there is an error (usually loading elements in handlers)
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_TO_JUNCTION
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_ID
@ SUMO_ATTR_KEY
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
bool checkStopParents(CommonXMLStructure::SumoBaseObject *obj)
check stop parents
CommonXMLStructure::SumoBaseObject * getEmbeddedRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get embedded route from children
virtual ~CommonHandler()
Destructor.
void checkParsedParent(const SumoXMLTag currentTag, const std::vector< SumoXMLTag > &parentTags, bool &ok)
check parsed parents
void forceRemainElements()
force remain elements (used if we're reloading elements)
bool checkContainerPlanParents(CommonXMLStructure::SumoBaseObject *obj)
check container plan parents
bool writeError(const std::string &error)
write error and enable error creating element
bool myErrorCreatingElement
flag for mark if a element wasn't created
CommonHandler()=delete
invalidate default onstructor
void writeWarningOverwriting(const SumoXMLTag tag, const std::string &id)
write warning overwritting element
bool isForceRemainElements() const
force remain elements (used if we're reloading elements)
bool checkValidDetectorID(const SumoXMLTag tag, const std::string &value)
check if the given detector ID is valid
bool writeErrorInvalidParent(const SumoXMLTag tag, const std::string &id, const SumoXMLTag parentTag, const std::string &parentID)
write error "invalid parent element" giving ids of current and parent element
bool myAbortLoading
abort loading
bool checkListOfVehicleTypes(const SumoXMLTag tag, const std::string &id, const std::vector< std::string > &vTypeIDs)
check list of IDs
void parseParameters(const SUMOSAXAttributes &attrs)
parse generic parameters
bool writeWarningDuplicated(const SumoXMLTag tag, const std::string &id, const SumoXMLTag checkedTag)
write warning duplicated element
bool isForceOverwriteElements() const
force overwritte elements (used if we're reloading elements)
bool writeErrorEmptyEdges(const SumoXMLTag tag, const std::string &id)
write error "empty edges"
bool checkWithinDistribution(CommonXMLStructure::SumoBaseObject *obj)
check if the given object is within a distribution (VType or routes)
bool myOverwriteElements
overwrite elements
bool checkValidAdditionalID(const SumoXMLTag tag, const std::string &value)
check if the given additional ID is valid
bool checkFileName(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const std::string &value)
check if the given filename is valid
void abortLoading()
abort loading
bool writeErrorInvalidPosition(const SumoXMLTag tag, const std::string &id)
write error "invalid position"
bool isAbortLoading() const
abort loading
CommonXMLStructure myCommonXMLStructure
common XML Structure
bool writeErrorInvalidLanes(const SumoXMLTag tag, const std::string &id)
write error "invalid list of lanes"
bool checkVehicleParents(CommonXMLStructure::SumoBaseObject *obj)
check vehicle parents
bool checkNegative(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const int value, const bool canBeZero)
check if the given int value is NOT negative
bool checkValidDemandElementID(const SumoXMLTag tag, const std::string &value)
check if the given demand elmement ID is valid
bool myRemainElements
remain elements
bool isErrorCreatingElement() const
get flag for mark if a element wasn't created
void forceOverwriteElements()
force overwritte elements (used if we're reloading elements)
bool checkPersonPlanParents(CommonXMLStructure::SumoBaseObject *obj)
check person plan parents
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
SumoXMLTag getTag() const
get XML myTag
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
const std::vector< SumoBaseObject * > & getSumoBaseObjectChildren() const
get SumoBaseObject children
CommonXMLStructure::SumoBaseObject * getCurrentSumoBaseObject() const
get current editedSumoBaseObject
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static bool isValidFilename(const std::string &value)
whether the given string is a valid attribute for a filename (for example, a name)
static bool isValidDetectorID(const std::string &value)
whether the given string is a valid id for an detector
static bool isValidParameterKey(const std::string &value)
whether the given string is a valid key for a parameter