Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 : /****************************************************************************/
14 : /// @file DataHandler.cpp
15 : /// @author Jakob Erdmann
16 : /// @date Jun 2021
17 : ///
18 : // The XML-Handler for data elements loading
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <utils/common/FileBucket.h>
23 : #include <utils/common/MsgHandler.h>
24 : #include <utils/common/StringUtils.h>
25 : #include <utils/xml/XMLSubSys.h>
26 :
27 : #include "DataHandler.h"
28 :
29 :
30 : // ===========================================================================
31 : // method definitions
32 : // ===========================================================================
33 :
34 0 : DataHandler::DataHandler(FileBucket* fileBucket) :
35 : CommonHandler(fileBucket),
36 0 : SUMOSAXHandler(fileBucket->getFilename()) {
37 0 : }
38 :
39 :
40 0 : DataHandler::~DataHandler() {}
41 :
42 :
43 : bool
44 0 : DataHandler::parse() {
45 : // run parser and return result
46 0 : return XMLSubSys::runParser(*this, getFileName());
47 : }
48 :
49 :
50 : void
51 0 : DataHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
52 : // check if loading was aborted
53 0 : if (!myAbortLoading) {
54 : // switch tag
55 0 : switch (obj->getTag()) {
56 : // Stopping Places
57 0 : case SUMO_TAG_INTERVAL:
58 0 : if (buildDataInterval(obj,
59 : obj->getStringAttribute(SUMO_ATTR_ID),
60 : obj->getDoubleAttribute(SUMO_ATTR_BEGIN),
61 : obj->getDoubleAttribute(SUMO_ATTR_END))) {
62 0 : obj->markAsCreated();
63 : }
64 : break;
65 0 : case SUMO_TAG_EDGE:
66 0 : if (buildEdgeData(obj,
67 : obj->getStringAttribute(SUMO_ATTR_ID),
68 0 : obj->getParameters())) {
69 0 : obj->markAsCreated();
70 : }
71 : break;
72 0 : case SUMO_TAG_EDGEREL:
73 0 : if (buildEdgeRelationData(obj,
74 : obj->getStringAttribute(SUMO_ATTR_FROM),
75 : obj->getStringAttribute(SUMO_ATTR_TO),
76 0 : obj->getParameters())) {
77 0 : obj->markAsCreated();
78 : }
79 : break;
80 0 : case SUMO_TAG_TAZREL:
81 0 : if (buildTAZRelationData(obj,
82 : obj->getStringAttribute(SUMO_ATTR_FROM),
83 : obj->getStringAttribute(SUMO_ATTR_TO),
84 0 : obj->getParameters())) {
85 0 : obj->markAsCreated();
86 : }
87 : break;
88 : default:
89 : break;
90 : }
91 : // now iterate over childrens
92 0 : for (const auto& child : obj->getSumoBaseObjectChildren()) {
93 : // call this function recursively
94 0 : parseSumoBaseObject(child);
95 : }
96 : }
97 0 : }
98 :
99 :
100 : void
101 0 : DataHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
102 : // obtain tag
103 : const SumoXMLTag tag = (element == 0) ? SUMO_TAG_ROOTFILE : static_cast<SumoXMLTag>(element);
104 : // open SUMOBaseOBject
105 0 : myCommonXMLStructure.openSUMOBaseOBject();
106 : // check tag
107 : try {
108 0 : switch (tag) {
109 : // interval
110 0 : case SUMO_TAG_INTERVAL:
111 0 : parseInterval(attrs);
112 : break;
113 : // datas
114 0 : case SUMO_TAG_EDGE:
115 0 : parseEdgeData(attrs);
116 : break;
117 0 : case SUMO_TAG_EDGEREL:
118 0 : parseEdgeRelationData(attrs);
119 : break;
120 0 : case SUMO_TAG_TAZREL:
121 0 : parseTAZRelationData(attrs);
122 : break;
123 0 : case SUMO_TAG_PARAM:
124 0 : WRITE_WARNING(TL("Data elements cannot load attributes as params"));
125 0 : myCommonXMLStructure.abortSUMOBaseOBject();
126 : break;
127 0 : default:
128 : // tag cannot be parsed in routeHandler
129 0 : myCommonXMLStructure.abortSUMOBaseOBject();
130 : break;
131 : }
132 0 : } catch (InvalidArgument& e) {
133 0 : writeError(e.what());
134 0 : }
135 0 : }
136 :
137 :
138 : void
139 0 : DataHandler::myEndElement(int element) {
140 : // obtain tag
141 : const SumoXMLTag tag = static_cast<SumoXMLTag>(element);
142 : // get last inserted object
143 0 : CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
144 : // close SUMOBaseOBject
145 0 : myCommonXMLStructure.closeSUMOBaseOBject();
146 0 : if (obj) {
147 : // check tag
148 0 : switch (tag) {
149 : // only interval
150 0 : case SUMO_TAG_INTERVAL:
151 : // parse object and all their childrens
152 0 : parseSumoBaseObject(obj);
153 : // delete object (and all of their childrens)
154 0 : delete obj;
155 : break;
156 : default:
157 : break;
158 : }
159 : }
160 0 : }
161 :
162 :
163 : void
164 0 : DataHandler::parseInterval(const SUMOSAXAttributes& attrs) {
165 : // declare Ok Flag
166 0 : bool parsedOk = true;
167 : // needed attributes
168 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
169 0 : const double begin = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, "", parsedOk));
170 0 : const double end = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_END, "", parsedOk));
171 : // continue if flag is ok
172 0 : if (parsedOk) {
173 : // set tag
174 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_INTERVAL);
175 : // add all attributes
176 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
177 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_BEGIN, begin);
178 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_END, end);
179 : } else {
180 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
181 : }
182 0 : }
183 :
184 :
185 : void
186 0 : DataHandler::parseEdgeData(const SUMOSAXAttributes& attrs) {
187 : // declare Ok Flag
188 0 : bool parsedOk = true;
189 : // needed attributes
190 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
191 : // fill attributes
192 0 : getAttributes(attrs, {SUMO_ATTR_ID});
193 : // continue if flag is ok
194 0 : if (parsedOk) {
195 : // set tag
196 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGE);
197 : // add all attributes
198 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
199 : } else {
200 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
201 : }
202 0 : }
203 :
204 :
205 : void
206 0 : DataHandler::parseEdgeRelationData(const SUMOSAXAttributes& attrs) {
207 : // declare Ok Flag
208 0 : bool parsedOk = true;
209 : // needed attributes
210 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
211 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
212 : // fill attributes
213 0 : getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
214 : // continue if flag is ok
215 0 : if (parsedOk) {
216 : // set tag
217 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGEREL);
218 : // add all attributes
219 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
220 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
221 : } else {
222 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
223 : }
224 0 : }
225 :
226 :
227 : void
228 0 : DataHandler::parseTAZRelationData(const SUMOSAXAttributes& attrs) {
229 : // declare Ok Flag
230 0 : bool parsedOk = true;
231 : // needed attributes
232 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
233 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
234 : // fill attributes
235 0 : getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
236 : // continue if flag is ok
237 0 : if (parsedOk) {
238 : // set tag
239 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TAZREL);
240 : // add all attributes
241 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
242 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
243 : } else {
244 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
245 : }
246 0 : }
247 :
248 :
249 : void
250 0 : DataHandler::getAttributes(const SUMOSAXAttributes& attrs, const std::vector<SumoXMLAttr> avoidAttributes) const {
251 : // transform avoidAttributes to strings
252 : std::vector<std::string> avoidAttributesStr;
253 0 : for (const SumoXMLAttr& avoidAttribute : avoidAttributes) {
254 0 : avoidAttributesStr.push_back(toString(avoidAttribute));
255 : }
256 : // iterate over attributes and fill parameters map
257 0 : for (const std::string& attribute : attrs.getAttributeNames()) {
258 0 : if (std::find(avoidAttributesStr.begin(), avoidAttributesStr.end(), attribute) == avoidAttributesStr.end()) {
259 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addParameter(attribute, attrs.getStringSecure(attribute, ""));
260 : }
261 0 : }
262 0 : }
263 :
264 :
265 : void
266 0 : DataHandler::checkParent(const SumoXMLTag currentTag, const SumoXMLTag parentTag, bool& ok) {
267 : // check that parent SUMOBaseObject's tag is the parentTag
268 0 : if ((myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject() &&
269 0 : (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getTag() == parentTag)) == false) {
270 0 : writeError(toString(currentTag) + " must be defined within the definition of a " + toString(parentTag));
271 0 : ok = false;
272 : }
273 0 : }
274 :
275 : /****************************************************************************/
|